Dziś chciałbym podzielić się przykładem aplikacji sieciowej IoT korzystającej z modułu NodeMCU z układem ESP8266 oraz z modułu KAmodLSM303 z akcelerometrem i magnetometrem. Moduł z ESP8266 będzie przekazywał odczyty z akcelerometru LSM303D do dowolnego urządzenia, które będzie mogło połączyć się z nim przez sieć.
Pozostałe części cyklu:
Obsługa I2C w NodeMCU
Obsługa I2C w NodeMCU jest banalnie prosta, zaczynam od konfiguracji interfejsu:
1 |
i2c.setup(0, 2, 1, i2c.SLOW) |
Pierwszy argument (0) to identyfikator interfejsu i2c, kolejne dwa parametry to numery linii, których chcemy użyć jako SDA i SCL, ostatni parametr określa czy I2C ma pracować ze standardową częstotliwością 100kHz (i2c.SLOW) czy z częstotliwością 400kHz (i2c.FAST). W chwili obecnej i2c w NodeMCU działa tylko z częstotliwością 100kHz.
Do przesyłania informacji w NodeMCU używamy czterech funkcji: i2c.start, i2c.stop, i2c.write i i2c.read, nie będę się zagłębiał w teorię, myślę, że kod moich funkcji odczytu i zapisu rejestru przez i2c wyjaśni wszystko:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
-- adres ukladu LSM303 w module KAmodLSM303 addr = 0x1d -- funkcja odczytuje rejestr o adresie regaddr readreg = function (regaddr) i2c.start(0) i2c.address(0, addr, i2c.TRANSMITTER) i2c.write(0, regaddr) i2c.stop(0) i2c.start(0) i2c.address(0, addr, i2c.RECEIVER) i2cres = i2c.read(0, 1) i2c.stop(0) return i2cres; end -- funkcja zapisuje wartosc val do rejestru regaddr writereg = function(regaddr, val) i2c.start(0) i2c.address(0, addr, i2c.TRANSMITTER) i2c.write(0, regaddr) i2c.write(0, val) i2c.stop(0) end |
Konfiguracja WiFi w NodeMCU
Chciałbym, aby mój moduł NodeMCU pracował jako access point o nazwie KAmodLSM303 z hasłem 12345678 i standardowymi ustawieniami IP (192.168.1.1/255.255.255.0). Ten kod również nie wymaga komentarza:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
-- konfiguracja Access Pointu WiFi print("Konfiguracja WiFi...") ipcfg = {} ipcfg.ip="192.168.1.1" ipcfg.netmask="255.255.255.0" ipcfg.gateway="192.168.1.1" wifi.ap.setip(ipcfg) cfg={} cfg.ssid="KAmodLSM303" cfg.pwd="12345678" wifi.ap.config(cfg) wifi.setmode(wifi.SOFTAP) |
Serwer TCP
Tutaj niektórzy mogą mieć problem ze zrozumieniem składni, przynajmniej ja miałem, więc na początek kilka wyjaśnień:
- w Lua bardzo często używa się funkcji jako parametrów dla innych funkcji. Mam tu na myśli sens inny niż suma(pierwiastek(2), pierwiastek(3)), chodzi o coś podobnego do przekazania wskaźnika do funkcji w języku C
- w Lua często deklaruje się funkcje w tym miejscu, w którym przekazuje się je jako parametr, podobnie jak
Chcąc uruchomić serwer TCP tworzymy obiekt serwera (zmienna server), potem metodą listen konfigurujemy go do nasłuchiwania na porcie 111 i podajemy jako drugi argument funkcję, która będzie wywoływana przy każdym nawiązaniu połączenia otrzymując jako parametr zmienną c typu net.socket, ta funkcja z kolei ustawia dla obiektu c funkcję obsługi zdarzeń, w moim przypadku będzie to jedno zdarzenie – receive, czyli zdarzenie odebrania danych od klienta. Trochę to skomplikowane, ale opis i przejrzenie kodu powinny pozwolić zrozumieć o co chodzi.
W funkcji obsługującej zdarzenie odebrania danych zapalana jest dioda modułu NodeMCU, wysyłane są dane z rejestru czujnika LSM303 o adresie 0x28 i pięciu następnych (rejestry zawierają odczyty akcelerometru), na koniec dioda jest gaszona.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
-- uruchomienie serwera TCP na porcie 111 -- i deklaracja funkcji wywolywanej -- w momencie odebrania danych print("Uruchamianie serwera TCP...") server = net.createServer(net.TCP, 10) gpio.write(0, 1) server:listen(111,function(c) c:on("receive", function(c, recvdata) -- zapal diode LED gpio.write(0, 0) -- odczytaj rejestry z danymi -- akcelerometru v = "" for i=0,5 do v = v .. readreg(0x28+i) end -- wyslij dane c:send(v) -- zgas diode LED gpio.write(0, 1) end) end) |
Mamy już gotowy serwer, który udostępnia dane odczytane z akcelerometru, następnym razem zajmę się stroną odbierającą i przetwarzającą te dane.
Płytki NodeMCU oraz KAmodLSM303 dostarczył sklep internetowy dla elektroników Kamami.pl.