Przykład budowy stacji pogody HamNET na bazie WR740 oraz Arduino Pro Mini. Waldek SP2ONG Do budowy stacji pogody potrzebujemy: - WR740 z wgranym firmware HamNET - Arduino Pro Mini wersja 3.3V (8 MHz) - BMP180 czujnik cienienia od 300 do 1100 hpa - DHT 22 czujnik wilgotności 0-100% oraz temperatury od -40 do +80 C - opornik 10 kom (lub w przedziale od 4k7 do 10 kom) Dlaczego wybrałem WR740. Jest tani, ma UART który należy wyprowadzić piny z poziomami napięć 3.3V takie jakie ma Arduino Pro Mini 3.3V wiec nie ma potrzeby robić konwersji napięć. Można spróbować to zrobić z każdym innym HamNET routerem który ma dostęp do wyjścia UART tylko upewnić się jaki poziom napięć jest potrzebny i czy mam dostęp do punktu zasilania aby podłączyć do Arduino. Poniżej schemat połączeń :
Aby podłączyć Arduino do UART WR740 musisz podlutować jeden kable brakujący do TX UART pod spodem płytki szukaj na stronie http://wiki.openwrt.org/toh/tp-link/tl-wr740n Zwróć uwagę że BMP180 czujnik cienienia jest podłączony do pinów A4 i A5 które są osobno wyprowadzone a nie w głównym rzędzie na brzegu płytki Arduino Pro Mini. Poniżej skrypt który pobiera dane z UART WR740 i zapisuje do pliku /tmp/wx.txt ====== skrypt /etc/config/wxget.lua ====== rserial=io.open("/dev/ttyath0","r") while true do chaine = nil while chaine==nil do --to get and to lose the flush chaine=rserial:read();rserial:flush() outstr=os.date("%y-%m-%d %X", os.time()).." "..string.gsub(chaine,"sensors: ","Sensors: ") -- the record file f = assert(io.open("/tmp/wx.txt", "a")) f:write(string.gsub(outstr,"sensors: ","").."\n"); f:close() Należy go wpisac w /etc/rc.local przed wiereszem 'exit 0' # ustawiamy UART WR740 /dev/ttyath0 ( zawartość stty ma być w jednej linii!!! stty -F /dev/ttyath0 9600 cs8 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok - echoctl -echoke noflsh -ixon -crtscts (sleep 3; lua /etc/config/wxget.lua) &
Program dla Arduino Pro Mini wersja 8 MHz MiniWeather.ino Wprowadz swoje dane tzn wysokosc stacji nad poziomem morza oraz cienie w Twojej okolicy nad poziomem morza (patrz czerwony kolor w kodzie) // https://github.com/adafruit/adafruit-bmp085-library // https://github.com/adafruit/dht-sensor-library #include <DHT.h> #define DHTPIN 2 // numer pinu sygnałowego Digital nr #define DHTTYPE DHT22 // typ czujnika #include <Wire.h> #include <Adafruit_BMP085.h> Adafruit_BMP085 bmp; // Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!) // Connect GND to Ground // Connect SCL to i2c clock - on \'168/\'328 Arduino Uno/Duemilanove/etc thats Analog 5 // Connect SDA to i2c data - on \'168/\'328 Arduino Uno/Duemilanove/etc thats Analog 4 // EOC is not used, it signifies an of conversion // XCLR is a reset pin, also not used here DHT dht(dhtpin, DHTTYPE,3); // definicja czujnika, wartosc 3 jest dla Arduino Pro Mini 8 Mhz // Altitude of Home location Weather Station in meters // Mozesz pobrac poziom elewacji z strony: http://www.mapdevelopers.com/elevation_calculator.php #define ALTITUDE 76.0 // Pressure at Sea Level in your location poszukaj w lokalnych serwisach pogodowych // wartość cisnienia w Twjojej okolicy zredukowana do poziomu morza float sealevelpressure=101550; void setup() { Serial.begin(9600); // otworzenie portu szeregowego dht.begin(); // inicjalizacja czujnika // BMP Init // Jako parametr mozemy podac dokladnosc - domyslnie 3 // 0 - niski pobór energii - najszybszy pomiar // 1 - standardowy pomiar // 2 - wysoka precyzja // 3 - super wysoka precyzja - najwolniejszy pomiar if (!bmp.begin()) { Serial.println("Nie odnaleziono czujnika BMP085/BMP180"); while (1) {} } } void loop() { // Odczyt temperatury i wilgotności powietrza, cisnienia float t = dht.readtemperature(); float tf = dht.readtemperature(true); float h = dht.readhumidity(); float p = bmp.readpressure(); float p0= bmp.readsealevelpressure(altitude);
// Sprawdzamy czy są odczytane wartości if (isnan(t) isnan(h) isnan(tf) isnan(p)) { // Jeśli nie, wyświetlamy informację o błędzie Serial.println("Blad odczytu danych z czujnikow"); } else { // Format lini: // Sensors: H TC TF PR PS A // H - wilgostnosc, TC - temp w C, TF - Temp w F // PR - cisnienie otoczenia, PS - cienienie do poziomu morza // A - wyskosc npm wyliczona Serial.print("Sensors: "); Serial.print(h,1); Serial.print(" "); Serial.print(dht.readTemperature(),1); Serial.print(" "); Serial.print(dht.readTemperature(true),1); Serial.print(" "); Serial.print(bmp.readPressure()/100.0,1); Serial.print(" "); Serial.print(bmp.readSealevelPressure(ALTITUDE)/100.0,1); Serial.print(" "); Serial.print(bmp.readAltitude(p0),1); Serial.println(" "); // 10 sekund opoznienia } delay(10000); } Arduino Pro Mini połączyłem do komputera poprzez konwerter USB<->UART który miął wyprowadzenie 3.3V. Podczas wgrywania programu do Arduino Pro Mini należy nacisnąć przycisk RESET kliknąć ikonkę ładowania programu do Arduino i po 2 sekundach puścić klawisz RESET i program zostanie załadowany. Możemy sprawdzić czy wszystko poprawnie działa włączając monitorowanie portu szeregowego i co 10 sekund powinno pojawiać się informacja z pomiarów: Sensors: xx xx xx xx xx Jeśli wszystko OK możemy podłączyć do naszego routera i po uruchomieniu go mamy w pliku /tmp/wx.txt informacje o pomiarach Możemy zmodyfikować strone /www/cgi-bin/status naszego routera gdzie bdzie można
zobaczyć nasze wartości z stacji. W pliku status poszukaj pierwszej linii w poniższym tekście i resztę należy dołożyć do tego pliku:... print(trim(f:read("*a")))?></td></tr></table><br></fieldset> <??> <fieldset style="margin-left:22px;margin-right:22px;"><leg><b><font color="brown"> Mini Weather Station </font></b></leg> <table><thead><tr style="background-color:#cccc99;"> <th>temperature [ C] </th> <th>humidity [%] </th> <th>pressure [hpa] </th> <th>pressure at Sea Level [hpa] </th> <th>altitude [m] </th> </tr></thead><tr align="center" style="background-color: #f1f6fa;color:#000099;"><td><? local f=io.popen("tail -n1 /tmp/wx.txt cut -f4 -d\" \"")?></td><td><? local f=io.popen("tail -n1 /tmp/wx.txt cut -f3 -d\" \"")?></td><td><? local f=io.popen("tail -n1 /tmp/wx.txt cut -f6 -d\" \"")?></td><td><? local f=io.popen("tail -n1 /tmp/wx.txt cut -f7 -d\" \"")?></td><td><? local f=io.popen("tail -n1 /tmp/wx.txt cut -f8 -d\" \"")?></td></tr> </table> <b>date of measurement:</b> <font color=#000099><? local f=io.popen("tail -n1 /tmp/wx.txt cut -b 1-16")?> UTC</dont></fieldset> <center><img src=/images/logo-hamnetpl.png alt="" title="hamnet PL"> </html> </body>
Adaptacja projektu do innych routerów HamNET Opisany projekt można łatwo zaadaptować do innych routerów HamNET. Na przykład Nanostation2 i WA5210G maja wyprowadzone piny na płycie UART TTL 3.3V oraz zasilanie 3.3V więc praktycznie wymaga tylko to podłączenie Arduino Pro Mini w wersji 3.3V 8 MHz do UART podobnie jak do WR740. Opis pinów UART: http://wiki.openwrt.org/toh/ubiquiti/nanostation Ważnym elementem jest to zablokowanie wysyłanie informacji z kernela do konsoli via
UART. Bez rekompilacji firmware możemy to zrobić wg opisu na stronie: http://wiki.openwrt.org/doc/recipes/terminate.console.on.serial W przypadku Nanostation2/WA5210G /etc/inittab ma: ::sysinit:/etc/init.d/rcs S boot ::shutdown:/etc/init.d/rcs K shutdown ttys0::askfirst:/bin/ash --login tty1::askfirst:/bin/ash login więc musimy zakomerować linie #ttys0::askfirst:/bin/ash --login oraz w pliku /etc/sysctl.conf w pierwszej linii wpisać: kernel.printk = 0 4 1 7 następnie przeładować urządzenie. Następnie postępujemy zgodnie z opisem jak przedstawiono dla WR740. Zwróć uwagę że w skrypcie wxget.lua oraz rc.local należy zmienić z /dev/ttyath0 na /dev/ttys0. W przypadku WA5210/NS2 mam już gotowa obudowa wodoszczelna wiec należy zgrabnie umieścić tam Arduino i wyprowadzi kabelki tylko aby czujniki pomiarowe były na zewnątrz w specjalnej obudowie aby pomiary były poprawne. Poniżej zdjęcie złącza J3 WA5210G gdzie mamy wyprowadzony UART w TTL 3.3V
Montaż czujników w specjalnej obudowie. Czujniki BMP180 i DHT22 muszą być umieszczone w obudowie specjalnej do tego przeznaczonej aby pomiary były w miarę wiarygodne. Taka obudowę można wykonać wykorzystując do tego podstawki pod donice w kolorze białym np. firmy LAMELA 7 sztuk najmniejsze oraz jedną większą od góry (koszt ok 95 gr za sztukę) Polecam watki na forach gdzie możecie znaleźć dokładne opisy jak zrobić taka obudowę: http://sacilemeteo.altervista.org/schermo.html http://stacjepogody.waw.pl/index.php?topic=230.45 WX APRS Bikon Jeśli nasza stacja pogody HamNET działa i mam dostęp do sieci amprnet możemy raporty o stanie pomiarów wysyłać do APRS servera. Tworzymy plik o nazwie wxaprs w katalogu /etc/config o następującej treści:
#!/usr/bin/lua -- Simple WX APRS Becaon s object to aprs server by SP2ONG socket= require("socket") socket.timeout=5 tcp =assert(socket.tcp()) tcp:settimeout(5) -- APRS Server IP wpisz IP dostępny APRS server, w przykładzie server DB0TV host="44.225.125.2" port="14580" -- Your callsign call="nocall-13" --- Your passcode passcode="xxxxxx" -- Lat corrdinates lat="5312.12n" -- Lon corridnates lon="01812.12e" -- comment comment="wx City" -- get wx report local f=io.popen("tail -n1 /tmp/wx.txt cut -f5 -d\" \"") tf=math.floor(tonumber(f:read("*a"))) local f=io.popen("tail -n1 /tmp/wx.txt cut -f3 -d\" \"") h=math.floor(tonumber(f:read("*a"))) -- s Preassure at Sea Level local f=io.popen("tail -n1 /tmp/wx.txt cut -f7 -d\" \"") p=tonumber(f:read("*a"))*10 -- Temp must have lenght 3 chars lt=tonumber(string.len(tf)) if lt<=2 and tf>0 then nsp=3-lt tff=string.rep("0",nsp)..tf if lt==2 and tf<0 then tt=tf*(-1) lt=string.len(tt) nsp=2-lt tt=string.rep("0",nsp)..tt tff="-"..tt tf=tff -- humidity 100%, h must be "00"
if h==100 then h="00" report="t"..tf.."h"..h.."b"..p -- becaon bikon=call..">aprs,tcpip*:!"..lat.."/"..lon.."_.../...g..."..report..comment.."\r\n" -- login to APRS Server login="user "..call.." pass "..passcode.." v1.0 HamNET-Mesh\r\n" -- open connect tcp:connect(host, port); --- s login local ok, err = tcp:s(login); if ok ~=nil then -- s beacon local ok, err = tcp:s(bikon); tcp:close() os.execute("logger -t 'WX APRS beacon' 'APRS Server - OK'") else msg="logger -t 'WX APRS beacon' 'APRS Server - "..err.."' " os.execute(msg) Po zapisaniu pliku i wpisaniu w polu call i passcode oraz lat i lon swoich danych zmieniamy atrybut pliki komą: chmod 0755 wxaprs następnie wpisujemy w pliku /etc/crontabs/root następujące linie: */15 * * * * /etc/config/wxaprs 20,40 * * * * echo "" > /tmp/wx.txt i wykonujemy polecenie: /etc/init.d/cron restart
Dzięki temu Twoja HamNET-WX stacja pogodny będzie na mapie APRS jak moja poniżej na obrazku.