Kurs Arduino – Pomiar wilgotności gleby
Zgodnie z zapowiedzią, w tym odcinku mamy zająć się od strony praktycznej tematem specyficznych czujników wilgotności. Już na początku muszę się przyznać, że bałem się tego tematu. Tematu bardzo interesującego, ale specyficznego i trudnego. Chodzi mianowicie o pomiar wilgotności gleby.
W ramach kursu Arduino omawialiśmy już wiele czujników wilgotności, ale były to czujniki określające wilgotność powietrza, czyli zawartość pary wodnej w powietrzu. Szeroko omawialiśmy pojęcia wilgotności bezwzględnej i względnej, wyrażanej w procentach (%RH). Z wilgotnością gleby jest zupełnie inaczej, bo nie chodzi tu o zawartość pary wodnej, tylko najprawdziwszej wody w postaci cieczy. Wilgotność gleby też wyrażana jest w procentach, ale są to „inne procenty”, niż w przypadku wilgotności względnej powietrza.
Moje obawy wynikały między innymi z faktu, że wcale nie jest łatwo mierzyć wilgotność gleby. Ściślej biorąc jedna kwestia to procentowa zawartość wody w glebie, a druga to tak zwany… potencjał wodny, inaczej siła ssąca gleby, wyrażony w ujemnych wartościach ciśnienia (hektopaskalach). Najprościej mówiąc, nawet gdy w glebie woda jest, może być bezużyteczna dla roślin, które nie mogą jej „zassać”, gdy gleba ją „silnie trzyma”. Potencjał wodny mierzony jest za pomocą tensjometrów (nie tensometrów, które służą do pomiaru naprężeń). Wilgotność i potencjał wodny są ze sobą związane, ale nie jest to zależność liniowa i zależy od właściwości (składu) gleby.
Od razu trzeba podkreślić, że tanie, kosztujące kilka złotych, „czujniki wilgotności gleby” według fotografii 1, są bezwartościowe, ponieważ po pierwsze szybko ulegają zniszczeniu (korozji elektrolitycznej), a po drugie wcale nie mierzą wilgotności gleby, tylko jej przewodność elektryczną, a ta jest zależna nie tylko od ilości wody, ale też bardzo silnie od zawartości elektrolitów – soli mineralnych, czyli w praktyce nawozów.
Dobre, trwałe i stabilne czujniki wilgotności gleby wykorzystują pomiar przenikalności dielektrycznej gleby, która jest silnie zależna od zawartości wody (względna przenikalność dielektryczna powietrza to oczywiście 1, wody 80, a cząstek stałych 2…8). Zależnie od metody mówi się o pracujących impulsowo czujnikach TDR oraz o częściej spotykanych czujnikach FDR (frequency domain reflectometers), które potocznie nazywane są czujnikami pojemnościowymi i pracują przy częstotliwości pomiarowej rzędu 100MHz. Do niedawna czujniki takie były bardzo kosztowne.
Ja kilka miesięcy wcześniej nabyłem drogą kupna stosunkowo tani (około 150zł) chiński czujnik FDR-100, pokazany na fotografii 2.
Moja obawy wynikały z kilku powodów. Po pierwsze, czujnik był zaskakująco tani w porównaniu z konkurencją. Po drugie pomimo usilnych starań nie udało mi się zmusić sprzedawcy, żeby dostarczył mi prawidłową dokumentację. Kupiłem wersję z interfejsem RS-485, a sprzedawca dostarczył kartę katalogową wersji z wyjściem analogowym, dla mnie niemal bezwartościową.
Obawy potęgował fakt, że mimo usilnych poszukiwań w Internecie nie znalazłem informacji o mojej wersji FDR-100 z wyjściem RS-485. Owszem, znalazłem dokumentację „prawie” takich samych czujników. Na dwóch chińskich stronach znalazłem nie tylko dokumentację, ale też całe pakiety z opisami i oprogramowaniem, ale wszystko… po chińsku, bez wersji angielskich.
Wszystkie uzyskane informacje dały mi przekonanie, że wszelkie tego rodzaju czujniki wykorzystują protokół MODBUS. Był jednak problem z ustaleniem parametrów transmisji, wykorzystanych rejestrów oraz z czymś tak elementarnym jak funkcje poszczególnych wyprowadzeń (kabelków). Myślę, że warto opisać szczegółowo moje perypetie i poszukiwania, ponieważ może to być pomocą dla Czytelników, którzy napotkają podobne problemy z takim i innym chińskim sprzętem, praktycznie pozbawionym dokumentacji. Natomiast obszerne informacje o łączu RS-485 oraz o standardzie MODBUS ukażą się już niedługo w nowym cyklu o sposobach transmisji danych, którego pierwszy odcinek znajdziecie na stronie 28 tego wydania EdW.
„Prawie” takie same
Podstawowy problem dotyczył „kabelkologii”.
Rysunek 3 pokazuje znalezione w Sieci wyprowadzenia takich czujników. Niektóre mają pięć przewodów, a ten piąty (ekran) może być wykorzystywany do konfiguracji (przez dołączenie do plusa zasilania, a nie do masy). Mój czujnik ma cztery kabelki, więc pasowałaby wersja środkowa. Nie odważyłem się jednak podłączyć zasilania bez wcześniejszego zbadania omomierzem rezystancji między kabelkami i to przy obu biegunowościach omomierza. Wyniki widoczne są na rysunku 4.
Omomierz nie wykazuje przejścia między kabelkiem brązowym, a pozostałymi, co wskazuje, że jest to „plus zasilania”, a konkretnie wejście stabilizatora napięcia. Natomiast miedzy pozostałymi wyprowadzeniami przy obu biegunowościach omomierza występują rezystancje. W łączu RS-485 linia jest symetryczna względem masy, więc rysunek 4 wskazuje, że masa to kabelek czarny. Przewody szary i niebieski to linia RS-485, tylko nie wiadomo która jest jej żyła dodatnia, która ujemna.
Wątpliwości co do zakresu napięć zasilania zostały szybko wyjaśnione. Co prawda w większości materiałów w Internecie podany jest zakres napięć zasilania 5V…24VDC, jednak na moim czujniku był wyraźny napis (fotografia 5), że wynosi on 7–24VDC.
Dla bezpieczeństwa do pierwszych prób użyłem zasilacza laboratoryjnego z ograniczeniem prądowym ustawionym na 50mA, w którym napięcie zacząłem zwiększać od 0,6 wolta wzwyż. Przy zasilaniu około 3V prąd zaczął pomału wzrastać. Okazało się, że przyrząd co około 1,7 sekundy pobiera impuls prądu. W spoczynku pobór wynosi około 3mA w 270-milisekundowym impulsie wzrasta podczas właściwego pomiaru do około 48mA, co pokazane jest na rysunku 6 (1dz = 10mA).
Na obu liniach łącza RS-485 pojawiały się niewielkie paczki słabych przebiegów zmiennych, stałe napięcie na jednej z nich wynosiło około 0,18VDC, na drugiej 0VDC, co mogło być jakąś wstępną i niepewną wskazówką co do biegunowości żył.
W każdym razie odetchnąłem z ulgą! Czujnik pracował, trzeba się było tylko z nim „dogadać”.
To był kolejny problem. Opisy „prawie” takich samych czujników zawierały odmienne wskazówki. Po pierwsze wiadomo, że symetryczne łącze RS-485 jest bliskim krewnym jakże popularnego łącza szeregowego (RS-232). Po drugie wiadomo, że w standardzie MODBUS w najpopularniejszej wersji RTU ramki – znaki są 8-bitowe, a dodatkowo występują dwa bity stopu (albo bit kontroli parzystości i jeden bit stopu). Standardowe prędkości transmisji MODBUS to albo 19200bps albo 9600bps.
Tymczasem informacje i wskazówki z chińskich źródeł były inne. W większości źródeł podana jest domyślna „fabryczna” prędkość transmisji czujników wilgotności równa 4800bps, często podawana w postaci 4800, 8, N, 1. Tylko w niektórych źródłach zapisy były bliższe „modbasowi”, a mianowicie 9600, 8, N, 2.
Wiadomo, że urządzenia podrzędne MODBUS mają adresy (1…247). W niektórych źródłach było podane, że adres czujnika to 1, ale były też informacje, że wynosi on 255. Przy pewnych czujnikach pojawia się informacja (zwykle bez szczegółów), iż użytkownik może go zmienić.
Znalezione informacje wskazywały, że produkowane są „prawie” takie same czujniki, o takim samym wyglądzie, ale różniące się funkcjami i organizacją „wnętrza”.
I tak istnieją wersje realizujące trzy funkcje: pomiar procentowej wilgotności gleby, pomiar temperatury oraz pomiar przewodności elektrycznej. Natomiast ja kupiłem najtańszą wersję, według opisu jedynie z pomiarem wilgotności.
Co ciekawe i ważne, w pewnej angielskojęzycznej karcie chińskiego czujnika wilgotności gleby było dużo mniej informacji, niż w oryginalnej karcie w języku chińskim. Wypływa z tego ważny wniosek: trzeba przeglądać także chińskie wersje, nawet gdy dostępne są wersje angielskie (prawdopodobnie skrócone). W tej chińskiej karcie zamieszczona była obszerna tabela, z której część pokazana jest na rysunku 7. Oprócz chińskich „krzaczków” mamy tu pełną informację po angielsku!
I tak w pierwszej kolumnie są parametry dostępne w poszczególnych (16-bitowych) rejestrach. W kolumnie drugiej mamy adresy rejestrów, podane w postaci szesnastkowej i dziesiętnej). W kolumnie trzeciej podane jest, jak należy traktować 16-bitową liczbę w rejestrze. W większości są to liczby całkowite bez znaku (UINT16), a wyjątkiem jest pierwszy rejestr o adresie 0, który zawiera liczbę całkowitą ze znakiem (INT16), która niesie informację o zmierzonej temperaturze (w zakresie –40…+80°C).
W kolumnie czwartej podano, jakie rozkazy standardu MODBUS można wykorzystać do obsługi danego rejestru. Tylko nieco może dziwić fakt, że z sześciu „najniższych” rejestrów można odczytywać zmierzone dane za pomocą zarówno rozkazu 3 (Read Holding Register), jak też rozkazu 4 (Read Input Register). Wyższe rejestry można odczytywać (rozkazem 3), ale przede wszystkim można do nich wpisywać dane (rozkazami 6, 16). Jak widać z tabeli, w ten sposób można ustawić/zmienić między innymi: typ gleby (SOILTYPE), co potrzebne jest do wewnętrznych przeliczeń, jednostki temperatury (TEMPUNIT), adres czujnika – urządzenia Slave (ADDRESS) oraz prędkość transmisji (BAUDRATE). W niepokazanej części tabeli są informacje o kolejnych rejestrach.
W kolumnie piątej podane jest jak liczba w rejestrze ma się do „realnej wartości”. Wreszcie kolumna szósta pokazuje fabryczne wartości domyślne.
Pięknie, tylko tabela ta nie odnosi się do mojego czujnika! A opisy innych czujników zawierają odmienne dane. Nie szkodzi, zebrane informacje i tak są cenne, bo dają pojęcie, czego powinienem się spodziewać po swoim czujniku.
Docelowo czujnik ma współpracować z Arduino, jednak wcześniej trzeba poznać jego tajemnice, przynajmniej te podstawowe. W tym celu podłączyłem przewody czujnika nie do Arduino, tylko do… laptopa, oczywiście za pomocą popularnego konwertera USB-RS485, co pokazane jest na fotografii 8.
Z uwagi na krótkie przewody nie włączyłem rezystorów dopasowujących linię RS-485. Aby mieć pojęcie co dzieje się na magistrali RS-485, do jednej z linii dołączyłem oscyloskop.
Użyty prosty konwerter ma tylko dwa zaciski śrubowe linii RS-485, ale ja na wszelki wypadek rozebrałem obudowę i do obwodu masy przylutowałem przewód, który połączyłem z masą czujnika wilgotności. Takie bezpośrednie połączenie mas zapobiegnie ewentualnym kłopotom z zakłóceniami i przepływem prądów wyrównawczych.
Użyty konwerter USB-RS485 zawiera znaną kostkę CH340 (i translator MAX485), więc nie musiałem instalować żadnych sterowników. W systemie Windows konwerter i dołączony doń czujnik zostały wykryte jako COM15.
Do kompletu potrzebny był jeszcze jakiś program, który potrafi nadawać i odbierać komunikaty MODBUS. Jest kilka darmowych takich programów, w tym prosty i popularny Radzio! Modbus Master Simulator, stworzony przez polskiego Autora (http://en.radzio.dxp.pl/modbus-master-simulator/). Programu nie trzeba instalować, plik RMMS.exe można uruchomić z dowolnego katalogu. Po uruchomieniu trzeba program skonfigurować (Connection – Settings) jak na rysunku 9.
Pozostawiamy MODBUS RTU. Choć z rozwijanej listy nie można wybrać portu COM15, można to po prostu wpisać w okienko. Ja wybrałem ustawienia popularne dla systemów MODBUS: 9600bps, brak kontroli parzystości (N) i dwa bity stopu, żeby ramka miała 11 bitów.
Po skonfigurowaniu otwieramy okno-arkusz (File – New), co daje obraz mniej więcej jak na rysunku 10.
Teraz kliknięcie ikonki wskazanej zieloną strzałką spowoduje próbę nawiązania łączności z czujnikiem.
Rysunek 11 pokazuje paczki impulsów – zapytania wysyłane z komputera do czujnika co mniej więcej 2 sekundy. Ale nie ma odpowiedzi. Nic dziwnego, przecież mamy kilka źródeł niepewności:
– Nie wiemy jaki jest (fabryczny) adres naszego czujnika (Device ID) w zakresie 1…255
– Nie wiemy w których rejestrach (Address) naszego czujnika szukać wyników pomiaru (a może być po 10000 rejestrów każdego czterech rodzajów).
– Nie wiemy też czy prawidłowe są ustawienia transmisji z rysunku 9.
– Nie wiemy czy żyły linii RS-485 nie są dołączone odwrotnie.
Ponadto zapewne potrzebnej nam informacji nie ma w jednobitowych rejestrach Coil status (fioletowa strzałka), tylko trzeba jej szukać albo w 16-bitowych Input Registers lub Holding Registers.
W każdym razie trochę przypomina to szukanie igły w stogu siana. Już jedno nieprawidłowe ustawienie uniemożliwi dostęp do szukanych danych.
Przyznam się, że ja w tych poszukiwaniach miałem sporo szczęścia i podstawowe dane znalazłem dosłownie po kilku minutach. Ale mogło to trwać o wiele, wiele dłużej.
Po pierwsze okazało się, że przypadkiem żyły linii były dołączone prawidłowo. Po drugie, intuicja mnie nie zawiodła i ustawienia transmisji z rysunku 9 (9600, 8, N, 2) okazały się prawidłowe.
W okienku wybrałem Holding Registers, a adres urządzenia (1) zmieniłem na 0.
Tak, właśnie na 0, ponieważ w systemie MOSDBUS jest to adres rozgłoszeniowy (broadcasting address), na który powinny reagować wszystkie dołączone urządzenia, o dowolnych rzeczywistych adresach z zakresu 1…255. Gdy już znalazłem rejestry z danymi, zacząłem też poszukiwać adresu i okazało się, że ten czujnik ma „modbasowy” adres 2. Mój wstępny sukces zilustrowany jest na fotografii 12 oraz na rysunku 13.
Jak widać, w moim czujniku o numerze-adresie 2 (Device ID), w dwóch pierwszych rejestrach Holding Registers są jakieś dane. Okazało się, że w pierwszym rejestrze o numerze 0 jest podana zawartość wilgoci w procentach. Jednak system MODBUS operuje dość skąpymi danymi, więc nie jest to ładnie podana wilgotność, zapisana w kodzie ASCII, tylko 16-bitowa liczba całkowita, którą, dla uzyskania prawidłowego wyniku, trzeba podzielić przez 10. Zwróć uwagę, że w przypadku czujnika opisanego na rysunku 7 , liczbę z rejestru temperatury i wilgotności trzeba dzielić przez 100, a nie przez 10. Wracając do rysunku 13: w rejestrze o zerowym adresie jest wartość 2, co oznacza wilgotność 0,2% – czujnik wtedy leżał po prostu na blacie biurka.
Natomiast w drugim rejestrze o adresie 1 zawarta jest liczba, która najwyraźniej jest „surową”, nieobrobioną wartością z przetwornika ADC.
Włożenie czujnika do wody (fotografia 12) dało pożądany wynik widoczny na rysunku 14.
Rysunek 15a pokazuje, że po wysłaniu zapytania, czujnik odsyła odpowiedź, a rysunek 15b przedstawia więcej szczegółów.
Miałem też cichą nadzieję, że oprócz wilgotności znajdę też gdzieś w innym rejestrze wartość temperatury, jednak dość długie i żmudne „ręczne” przeszukiwanie kolejnych pojedynczych rejestrów nie dało rezultatów.
Znalazłem tylko w Holding Registers o adresach 4096…4099 niezmienne dane, jak pokazuje rysunek 16.
W rejestrze 4096 zapisana jest liczba 2, więc najwidoczniej jest adres ID urządzenia (który zapewne można zmienić, ale czego nie próbowałem). W następnych najprawdopodobniej są dane konfigurujące czujnik, jednak rozpisanie ich w postaci szesnastkowej i dwójkowej nie wyjaśniło jakie mają znaczenie.
Nie wnikałem w dalsze szczegóły, cieszyłem się tym, że mam wszystkie podstawowe dane niezbędne do praktycznego wykorzystania czujnika wilgotności gleby.
W artykule UR018 przedstawione są dalsze zmagania z tym czujnikiem wilgotności gleby.
Piotr Górecki