Bezprzewodowy czujnik poziomu wody

Bezprzewodowy czujnik poziomu wody

Urządzenia Internetu Rzeczy to nie zawsze zaawansowane, sterowane głosem układy automatyki domowej. Elementem IoT jest też prosty czujnik poziomu wody w zbiorniku, dołączony do domowej sieci Wi-Fi. W artykule opisano właśnie takie urządzenie, które dodatkowo może sterować pompą elektryczną.

W artykule zaprezentujemy bezprzewodowy kontroler poziomu wody, bazujący na mikrokontrolerach ESP32 oraz ESP8266. Układ został wyposażony w zabezpieczenie napięciowe i prądowe, aby chronić silnik pompy i wyeliminować ryzyko awarii. Do przesyłu danych zastosowano protokół ESP-NOW. Kluczowe cechy systemu – założenia projektowe autora, to:

  • komunikacja bezprzewodowa,
  • ochrona przed przepięciami i zapadami napięcia,
  • ochrona przed przeciążeniem i pracą pompy na sucho,
  • wbudowane przyciski do konfiguracji systemu,
  • możliwość zapisu ustawień w pamięci flash,
  • wyświetlacz TFT o przekątnej 1,8 cala,
  • pomiar i prezentacja danych takich jak napięcie, prąd, moc i współczynnik mocy silnika pompy,
  • przełącznik wyboru trybu pracy,
  • przycisk do dopełniania zbiornika.

Dlaczego regulator poziomu wody?

Dla autora głównym celem budowy tego sterownika jest sterowanie napełnianiem zbiornika wody, gdy jego stan spada do 50% pojemności. Prezentowane tutaj urządzenie jest drugą wersją kontrolera. Wcześniejszy system zawierał wodoodporny czujnik ultradźwiękowy do pomiaru poziomu wody. Kontroler używany był przez rok. Głównym problemem tamtego urządzenia było tworzenie się kropel wody na powierzchni przetwornika ultradźwiękowego, co powodowało fałszywe odczyty. Zwykle działo się tak w czasie deszczu. Jako że zbiornik na wodę stał w trudno dostępnym miejscu, wspinanie się i czyszczenie czujnika ultradźwiękowego w deszczową pogodę było naprawdę problematyczne. Potrzebne było niezawodne i trwałe rozwiązanie.

Autor rozważał początkowo jakiś inny, bardziej zaawansowany czujnik poziomu wody, np. sensor ciśnienia, jednak z uwagi na brak dostępności tego rodzaju sensorów w miejscu zamieszkania zdecydował się finalnie na klasyczny pływak, aktywujący się, gdy poziom wody osiągnie 50%. Kluczową zmianą, względem poprzedniej generacji urządzenia, było przejście na komunikację bezprzewodową. W poprzedniej wersji zastosowano kabel CAT 6 do podłączenia czujnika ultradźwiękowego do sterownika, ale przy długości 50 metrów podłączenie było dosyć trudne z uwagi na problemy elektryczne (duża długość przewodu) i praktyczne (doprowadzenie 50 metrów przewodu od sterownika do zbiornika wody nie jest trywialne).

W nowym kontrolerze autor zastosował protokół ESP-NOW do przesyłania danych. Używa on układu ESP32U w module odbiornika i ESP07S w module nadajnika. W teście uzyskano zasięg prawie 450 metrów (w linii wzroku), umieszczając nadajnik na szczycie budynku, co jest naprawdę dobrym osiągnięciem, biorąc pod uwagę fakt, że nie są używane żadne zewnętrzne moduły bezprzewodowe. Inną nową cechą sterownika jest ochrona przed wysokim i niskim napięciem, przeciążeniem i suchobiegiem. Zabezpieczenie przed przeciążeniem i suchobiegiem działa poprzez pomiar poboru prądu silnika. Gdy silnik pracuje na sucho, pobór prądu znacznie się zmniejsza. Z użyciem biblioteki Emonlib do pomiaru napięcia i prądu monitorowana jest praca i status pompy.

Potrzebne elementy

Nadajnik

Do budowy nadajnika potrzebne będą następujące elementy:

  • moduł z mikrokontrolerem ESP 07S,
  • antena dla modułu z ESP,
  • stabilizator LDO LM2950G-3.3,
  • przyciski (microswitche) SMD – 2 sztuki,
  • kondensator elektrolityczny 2200 μF,
  • oporniki 10 kΩ/SMD0805 (3 sztuki),
  • opornik 100 kΩ/SMD0805,
  • opornik 330 kΩ/SMD0805,
  • opornik 22 kΩ/SMD0805,
  • złącze śrubowe na PCB,
  • złącze RMC,
  • ogniwo 18650,
  • moduł ładowarki TP4056,
  • czujnik pływakowy,
  • przełącznik pływakowy P43 (do funkcji dopełniania zbiornika),
  • wodoodporna obudowa,
  • ogniwo słoneczne 5 V,
  • płytka drukowana.

Odbiornik

Do zestawienia odbiornika potrzebne nam będą:

  • moduł z mikrokontrolerem ESP32U,
  • antena dla modułu z ESP,
  • stabilizator AMS1117-3.3,
  • tranzystor MOSFET AO3400,
  • przycisk (microswitch) SMD – 2 sztuki,
  • wyświetlacz TFT o przekątnej 1,7 cala ze sterownikiem ST7735,
  • trójpozycyjny przełącznik kołyskowy,
  • dwupozycjny przełącznik kołyskowy,
  • przycisk dwupozycyjny z diodą LED,
  • przekaźnik 5 V ze stykami do 40 A,
  • sensor do pomiaru prądu (do 25 A),
  • transformator pomiarowy ZMPT101B do pomiaru napięcia,
  • złącza RMC,
  • złącze śrubowe do PCB,
  • dioda 1N4007,
  • kondensator elektrolityczny 10 μF (3 sztuki),
  • kondensator 100 nF w obudowie SMD0805,
  • kondensator 4,7 μF w obudowie SMD1206 (2 sztuki),
  • opornik 82 kΩ o mocy 1 W,
  • rezystor 10 kΩ w obudowie SMD0805 (9 sztuk),
  • rezystor 1 kΩ w obudowie SMD0805,
  • rezystor 470 kΩ w obudowie SMD0805,
  • rezystor 220 kΩ w obudowie SMD0805,
  • wodoodporna obudowa,
  • śruby M3,
  • płytka drukowana.

Natomiast do zestawienia dodatkowej płytki z przyciskami, którą podłącza się do sterownika, potrzebne są:

  • przyciski (microswitche) SMD – 3 sztuki,
  • rezystor 10 kΩ w obudowie SMD0805,
  • rezystor 4,7 kΩ w obudowie SMD0805,
  • rezystor 20 kΩ w obudowie SMD0805,
  • płytka drukowana.

Budowa układu

Autor zaprojektował dla układu 3 płytki drukowane: nadajnik, odbiornik i płytka z przyciskami. Ich schematy pokazane są odpowiednio na rysunku 1, rysunku 2 oraz rysunku 3.

Rysunek 1. Schemat ideowy modułu nadajnika

Płytki zostały wykonane w oprogramowaniu EasyEDA. Dostęp do tego pakietu (w chmurze) jest bezpłatny dla hobbystów, więc każdy może otworzyć i edytować te projekty. Jest to szczególnie istotne, jeśli chcemy zamawiać je w zakładzie produkcyjnym, gdyż pozwala to na zmodyfikowanie projektu pod kątem specyficznych wymagań danego, konkretnego zakładu.

Rysunek 2. Schemat ideowy modułu odbiornika

Ponadto, z poziomu EasyEDA można wygenerować wszystkie niezbędne pliki produkcyjne – pliki Gerber, odwiert (pliki dla drukarki numerycznej), a także pliki dla frezarek, dokumentacja do produkcji masek do nakładania pasty lutowniczej itd. Można wygenerować też zestaw plików dla maszyn pick & place, aby możliwy był montaż automatyczny płytek. Linki do projektów płytek znajdują się w artykule źródłowym (patrz linki na końcu artykułu). Po wykonaniu płytek PCB należy przylutować w pierwszej kolejności wszystkie elementy SMD, a następnie elementy przewlekane.

Rysunek 3. Schemat ideowy modułu z przyciskami

Oprogramowanie

Oprogramowanie korzysta z protokołu ESP-NOW do transmisji danych pomiędzy sensorem a odbiornikiem. ESP-NOW to protokół opracowany przez firmę Espressif do komunikacji pomiędzy jej urządzeniami z wykorzystaniem sieci bezprzewodowej, ale bez konieczności instalacji routera w sieci Wi-Fi. Istotnie upraszcza to implementację systemu, a także samo oprogramowanie – wystarczy skorzystać z odpowiednich bibliotek.

Listing 1. Fragment oprogramowania układowego nadajnika

C#include <ESP8266WiFi.h>
#include <espnow.h>

#define NUM_SAMPLES 10

int float_switch1_pin = 13;
int float_switch2_pin = 12;
int float_switch1;
int float_switch2;

// Adres MAC odbiornika
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
int sum = 0;
unsigned char sample_count = 0;

// Przykładowa struktura do przesyłu danych
typedef struct struct_message {   
 int Float_switch1;
 int Float_switch2;
 int a;
 float BatV;
} struct_message;

// Wiadomość o zdefiniowanej strukturze
struct_message myData;

// Odwołanie po wysłaniu danych
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
 Serial.print(“Last Packet Send Status: “);
 if (sendStatus == 0) {
   Serial.println(“Delivery success”);
 } else {
   Serial.println(“Delivery fail”);
 }
}

void setup() {
 Serial.begin(115200);
 pinMode(float_switch1_pin, INPUT);
 pinMode(float_switch2_pin, INPUT);
 WiFi.mode(WIFI_STA);

 // Inicjalizacja ESP-NOW
 if (esp_now_init() != 0) {
   Serial.println(“Error initializing ESP-NOW”);
   return;
 }
 // Definicja roli urządzenia
 esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
 // Rejestracja call-backu
 esp_now_register_send_cb(OnDataSent);
 // Rejestracja nadajnika w sieci ESP-NOW
 esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}

void loop() {
 // Odczyt stanu pływaków
 float_switch1 = digitalRead(float_switch1_pin);
 float_switch2 = digitalRead(float_switch2_pin);
 // Przesłanie stanu do struktury danych
 myData.Float_switch1 = float_switch1;
 myData.Float_switch2 = float_switch2;
 myData.a = 1;
 
 while (sample_count < NUM_SAMPLES) {
   // Odczyt napięcia baterii
   sum += analogRead(A0);
   sample_count++;
   delay(10);
 }
 // Średnie napięcie baterii
 myData.BatV = ((float)sum / (float)NUM_SAMPLES * 1) / 1024.0;
 sample_count = 0;
 sum = 0;

 // Wysłanie danych przez ESP-NOW
 esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));

 ESP.deepSleep(20000000, WAKE_NO_RFCAL);
 delay(100);
}

Fragment kodu programu nadajnika pokazuje listing 1, a dla odbiornika listing 2. Pełne oprogramowanie dostępne jest na stronie z projektem.

Listing 2. Fragment oprogramowania układowego odbiornika

TFT_eSPI tft = TFT_eSPI();

Preferences preferences;

// Przykładowa struktura do przesyłu danych
typedef struct struct_message {
 int Float_switch1;
 int Float_switch2;
 int a;
 float BatV;
} struct_message;

// Wiadomość o zdefiniowanej strukturze
struct_message myData;


// Odwołanie po odebraniu danych
void OnDataRecv(const uint8_t * mac,
               const uint8_t *incomingData,
                int len) {        
 memcpy(&myData, incomingData, sizeof(myData));
 Serial.print(“Bytes received: “);
 Serial.println(len);
 Serial.print(“Int: “);
 Serial.println(myData.a);
 Serial.print(“Battery voltage: “);
 Serial.println(myData.BatV * Batv_Calib);
 Serial.print(“float1: “);
 Serial.println(float_switch1);
 Serial.print(“float2: “);
 Serial.println(float_switch2);
}

void setup() {
 Serial.begin(115200);
 WiFi.mode(WIFI_STA);

 // Konfiguracja ustawień
 preferences.begin(“settings”, false);
 Vmax      = preferences.getInt(“value”, 250);
 Vmin      = preferences.getInt(“value1”, 180);
 Imax      = preferences.getFloat(“value2”, 5.2);
 Imin      = preferences.getFloat(“value3”, 3.8);
 Delay     = preferences.getInt(“value4”, 5);
 V_Cutoff  = preferences.getInt(“value5”, 0);
 I_Cutoff  = preferences.getInt(“value6”, 0);
 RST_Delay = preferences.getInt(“value7”, 1);
 
 // Inicjalizacja ESP-NOW
 if (esp_now_init() != ESP_OK) {
   Serial.println(“Error initializing ESP-NOW”);
   return;
 }

 // Rejestracja call-backu
 esp_now_register_recv_cb(OnDataRecv);
 // Inicjalizacja ekranu
 tft.init();
 tft.fillScreen(TFT_BLACK);
 pinMode(relaypin, OUTPUT);
 pinMode(topup_pin, INPUT_PULLUP);
 myData.Float_switch2 = 0;
 // Napięcie: kalibracja, przesunięcier fazowe
 emon1.voltage(voltagepin, 346, 1.7);
 // Prąd: kalibracja
 emon1.current(currentpin, 11.261);

}

void loop() {
 unsigned long currentTime = millis();

 float_switch1 = myData.Float_switch1;
 float_switch2 = myData.Float_switch2;
 modepinvalue = analogRead(modepin);
 topup_value  = digitalRead(topup_pin);
 readbutton();  // Odczyt przycisków
 options();   // Ustawianie opcji
 // Oblicza liczbę [przejść napięcia przez zero
 emon1.calcVI(20, 2000);           
 voltage = emon1.Vrms;

 // (...) – pełna zaimplementowana automatyka ograniczeń,
 // uzalezniona od konkretnej instalacji
 // Przykładowy kod automatyki, z oryginalnego systemu,
 // dostępny jest na stronie z projektem

 pointer1 = constrain(pointer1, 20, 132);
 pointer2 = constrain(pointer2, 0, 0);
 Vmax        = constrain(Vmax, 0, 325);
 Vmin        = constrain(Vmin, 0, 325);
 Imax        = constrain(Imax, 0, 13);
 Imin        = constrain(Imin, 0, 13);
 Delay       = constrain(Delay, 0, 60);
 RST_Delay   = constrain(RST_Delay, 0, 60);

 // Wyświetlenie odpowiedniego ekranu
 switch (screen) {
   case 0:
     screen_0();
     break;
   case 1:
     screen_1();
     break;
   case 2:
     screen_2();
     break;
   case 3:
     screen_3();
     break;
 }

 // Zapis danych do pamięci
 preferences.putInt(“value”, Vmax);
 preferences.putInt(“value1”, Vmin);
 preferences.putFloat(“value2”, Imax);
 preferences.putFloat(“value3”, Imin);
 preferences.putInt(“value4”, Delay);
 preferences.putInt(“value5”, V_Cutoff);
 preferences.putInt(“value6”, I_Cutoff);
 preferences.putInt(“value7”, RST_Delay);
}

Zanim kod ten zostanie wprowadzony do Arduino IDE, skompilowany i wgrany do odpowiednich modułów, konieczne jest zainstalowanie wsparcia dla tych układów (ESP8266 oraz ESP32) i wymaganych bibliotek:

Następnie należy skonfigurować bibliotekę TFT_eSPI do współpracy z układem ESP32. W pliku User_Setup.h, będącym częścią biblioteki, należy zmienić wybrane sterowniki oraz zdefiniować piny, do których podłączony jest sterownik wyświetlacza TFT. W źródłowym artykule znajduje się link do tutoriala dokładnie objaśniający, jak należy korzystać z tej biblioteki. Przed przesłaniem kodu do ESP07S (nadajnika – listing 1) należy wprowadzić adres MAC odbiornika. Adres MAC odbiornika można poznać, wgrywając do modułu ekstremalnie prosty szkic, który zwróci przez port szeregowy adres MAC, pokazany na listingu 3.

Listing 3. Prosty program wyświetlający adres MAC modułu

#include <WiFi.h>

void setup(){
 Serial.begin(115200);
 Serial.println();
 Serial.print("ESP Board MAC Address:  ");
 Serial.println(WiFi.macAddress());
}

Budowa

Autor do zamknięcia odbiornika wykorzystał komercyjną obudowę z PCV z pokrywką, wykonaną w technice druku 3D. W pokrywce umieszczony jest wyświetlacz i przyciski (fotografia 1).

Fotografia 1. Panel przedni urządzenia, wykonany w technice druku 3D

W obudowie umieszczono wszystkie komponenty wraz z zasilaczem 5 V, podłączonym do sieci 230 V. Przewód fazowy i neutralny podłączone są do zacisku śrubowego płytki drukowanej, a jeden przewód silnika przechodzi do normalnie rozwartego styku przekaźnika, drugi jest natomiast podłączony do przewodu neutralnego (fotografia 2).

Fotografia 2. Wnętrze odbiornika

Obudowa głównego modułu sensora pokazana jest na fotografii 3. W otworach przewodów nadajnika zastosowano silikon RTV, aby zapobiec przedostawaniu się wody do środka.

Fotografia 3. Obudowa modułu sensora

Działanie układu

W systemie zastosowano dwa wyłączniki pływakowe. Gdy pierwszy (czerwony) wyłącznik pływakowy jest w niskiej pozycji, silnik włącza się automatycznie, a gdy jest w wysokiej pozycji, silnik wyłącza się automatycznie. Więc po co drugi (biały) pływak? Służy do realizacji funkcji uzupełniania. Biały wyłącznik pływakowy znajduje się tuż pod rurą przelewową. Jeśli chcemy napełnić zbiornik, ale czerwony pływak jest nadal w pozycji wysokiej, można nacisnąć przycisk doładowania, a silnik wyłączy się automatycznie, gdy woda dotknie białego przełącznika pływakowego. Ten kontroler ma 3 tryby: AUTO, OFF, MANUAL. Tryb ręczny jest jak normalny przełącznik, który włącza silnik. W tym trybie silnik nie ma żadnych zabezpieczeń.

Do menu ustawień można wejść tylko po przełączeniu w tryb OFF. W ustawieniach można zdefiniować maksymalne bezpieczne poziomy napięcia i prądu silnika, a także zdefiniować opóźnienia w systemie, sterować stanem zabezpieczenia napięciowego i prądowego oraz opóźnieniem przy resecie systemu. Menu informacyjne pokazuje na wyświetlaczu układu aktualne napięcie, prąd, moc, współczynnik mocy i napięcie akumulatora nadajnika.

Nikodem Czechowski, EP

Źródła:
http://bit.ly/3UhKqif
https://oshwlab.com/electronics220903/wlc-v2
https://oshwlab.com/electronics220903/wlc-transmitter
https://oshwlab.com/electronics220903/button_breakout_board

Artykuł ukazał się w
Elektronika Praktyczna
grudzień 2022

Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik kwiecień 2024

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio maj - czerwiec 2024

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje kwiecień 2024

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna kwiecień 2024

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich maj 2024

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów