Dies ist eine alte Version des Dokuments!
Inhaltsverzeichnis
Erste Schritte mit dem ESP8266 / NodeMCU Board mit Lua
Ziel:
Messen von Temperaturen und anderen Parametern im Haus mit dem NodeMCU Board ⇒ http://www.nodemcu.com/
Der ESP8266-Chip ist zwar schon etwas länger auf dem Markt (2015?) aber für die meisten Aufgaben in dem Bereich noch sehr leistungsfähig.
Hersteller Espressif (China) ⇒ https://www.espressif.com/
Übersicht über die verschiedenen Module ⇒https://www.esp8266.com/wiki/doku.php?id=esp8266-module-family
Architektur ESP8266
SoC (System of a Chip)
- CPU: 32-Bit RISC (Xtensa LX106), 80…160MHz
- Speicher:
- interner RAM: 64kByte + 94kByte
- extern: SPI-Schnittstelle für Flash-Speicher (bis 128MBit)
- Netzwerk fähig über WLAN:
- Built-in: TCP/IP protocol stack (IPv4)
- 802.11 b/g/n (Tx: +20…+14dBm; Rx:-91…-72dbm)
- WPA/WPA2; WEP/TKIP/AES
- Wif-Mode: Station, SoftAP, Station+SoftAP
- UART, I2C, PWM, SPI, GPIOs, ADC
- 3,3V, 0,01mA…250mA (sleep…send)
Das NodeMCU Mpdul
Das NodeMCU ESP8266 ist mit dem ESP-12E ausgestattet
ESP-12E
- UART, RESET, ADC, SPI, 9 GPIOs
- 4 MByte Flash
Mein Board hat die Versionsnummer NodeMCU ESP12E DEVKIT V2 (doit) (NodeMCU v1.0 with ESP-12E module).
Die Besonderheit hinter diesem NodeMCU Board ist die Firmeware, die es erlaubt ohne C mit der Script Sprache Lua eigene Software für den Controller zu entwickeln. Inzwischen kann die Firmeware mit den meisten ESP Chips verwendet werden und ist nicht mehr an das Board ansich gebunden.
Pin Belegung
Lua für die Programmierung
Lua Übersicht ⇒ https://bladehunter.lima-city.de/lua/book/
Ablauf für das Projekt
- NodeMCU ESP8266 WiFi-Modul Modul beschaffen ( z.b. bei Reichelt ⇒ https://www.reichelt.de/nodemcu-esp8266-wifi-modul-debo-jt-esp8266-p219900.html)
- Aktuelle Firmware erstellen lassen ⇒ Bei Erstellen der Firmware auf die Libaries für das jweilige Projekt achten ( wie die DHT Lib für einen Temperatur Sensor)
- Aktuelle Firmeware auf die NodeMCU kopieren
- Lua Code entwerfen
- Lua Code auf dem Controller Board ausführen
Hardware bereitstellen
Controller anschließen
Controller per USB Kabel anstecken.
In meinen Fall wird der Controller problemlos per USB erkannt, die richtigen Treiber liegen bei mir bereits schon vor ( ch340g ? bzw. den CP210x ⇒ https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers ).
Firmware bereitstellen
Arbeitsverzeichnis anlegen wie c:\entwickung\nodeMCU .
Repository
Im ersten Schritt von GitHup das Repository clonen
cd c:\entwickung\nodeMCU git clone https://github.com/nodemcu/nodemcu-firmware.git
Das ist im ersten Schritt optional, da sich die Firmware auch per Cloud Service erstellen lässt.
Tools für das Flaschen des Chips
Leider ist diese Version im Firmware Repository nicht die neuste, daher nun das Tool direkt geladen
https://github.com/espressif/esptool
cd C:\entwicklung\nodeMCU git clone https://github.com/espressif/esptool.git
Flash Image erzeugen
Da unter Windows doch meist ein Übersetzen von solcher Software „arbeitsintensiv“ ist, den Online Service dazu verwenden.
Über den Link https://nodemcu-build.com/index.php ein Image erstellen lassen, dazu E-Mail hinterlegen und die passenden Module für das jeweilige Projekt auswählen
In meine Fall die DHT Library um als erstes Projekt einen Temperatur und Luftfeuchtigkeitessensor für den Keller zu entwicklen.
Liste der verwendeten Libs für dieses Projekt ⇒ am2320 dht ds18b20 file gpio http i2c net node rtcmem rtctime sntp tmr uart wifi.
Per Mail erfolgt eine Benachrichtigung das der Compile Vorgang abgeschlossen ist.
Die Float Firmware herunterladen.
Image auf den Controller laden
Nach dem Clone des espressif/esptool Repositories liegt das Tool zum Flaschen hier⇒C:\entwicklung\nodeMCU\esptool, Abhängigkeiten mit „C:\Python34\python.exe pip install esptool “ installieren.
# Bei Bedarf fehlende Libs mit pip nachladen! ( oder das ganze Tool mit importieren!) C:\Python34\python.exe pip install esptool cd C:\entwicklung\nodeMCU\esptool # Test aufruf mit C:\Python34\python.exe .\esptool.py # Port suchen mit C:\Python34\python.exe esptool.py chip_id esptool.py v2.7-dev Found 2 serial ports Serial port COM5 Connecting.... Detecting chip type... ESP8266 Chip is ESP8266EX ... #Flash Größe auslesen C:\Python34\python.exe esptool.py flash_id .. Device: 4016 Detected flash size: 4MB ...
Nun sehen wir das der ESP auf COM 5 antwortet.
Flashen:
cd C:\entwicklung\nodeMCU\esptool #zuvor alles löschen, bei meine war ein Arduino IDE Image aufgespielt, nach dem 1. Flash mit dem NodeMCU seltsames verhalten, wirre Zeichen auf COM5 ausgeben daher zuerst löschen dann flaschen C:\Python34\python.exe esptool.py --port COM5 erase_flash # Image auf den Controller laden C:\Python34\python.exe esptool.py --port COM5 write_flash -fm qio 0x00000 C:\entwicklung\nodeMCU\nodemcu-master-9-modules-2019-01-10-15-49-46-float.bin esptool.py v2.7-dev Serial port COM5 Connecting.... Detecting chip type... ESP8266 Chip is ESP8266EX Features: WiFi MAC: 18:fe:34:e0:b7:a4 Uploading stub... Running stub... Stub running... Configuring flash size... Auto-detected Flash size: 4MB Flash params set to 0x0040 Compressed 438272 bytes to 284139... Wrote 438272 bytes (284139 compressed) at 0x00000000 in 24.9 seconds (effective 140.8 kbit/s)... Hash of data verified. Leaving... Hard resetting via RTS pin...
Nun wissen wir auch das dieses Modul 4MB Flash Size hat!
nodemcu-uploader
Alternativ:
cd /c/entwicklung/nodeMCU git clone https://github.com/kmpm/nodemcu-uploader.git
Tools für die Entwicklung aufsetzen
ESPlorer
cd /c/entwicklung/nodeMCU git clone https://github.com/4refr0nt/ESPlorer.git
Oder einfacher direkt als lauffähige Version über https://esp8266.ru/esplorer/ Dokumentation siehe http://esp8266.ru/download/esp8266-doc/Getting%20Started%20with%20the%20ESPlorer%20IDE%20-%20Rui%20Santos.pdf
Nach dem Start (doppel Click auf ESPlorer.jar) haben wir das erste Problemchen, leider habe ich ärgerlicher Weise ein 4K Display ⇒ alles viel zu klein …..
In der Bat Datei den direkten Pfad zur Java Exe angeben und die „Java dpi awarene“ ausschalten:
Find java.exe and/or javaw.exe likely found in C:\Program Files\Java\jre(version#)\bin. Right click on it and select -> Properties. Go to Compatibility tab. Check Override high DPI scaling behavior. Choose System for Scaling performed by: Click OK.
Quelle Google
Nun kann auch ohne Lupe mit dem Tool gearbeitet werden.
Ablauf
Leider ergeben sich nach jeden neuen Aufspielen der Firmware ein paar Problem bei den ersten Verbindung-Versuchen zum Controller Board.
- Nach dem Aufspielen der Firmware Board USB abstecken und erneut verbinden
- Boud Rate kann sich ändern, verschiedene Werte ausprobieren!
Im ESPLorer den Com Port und die BPS einstellen, bei mir hat es nach dem ersten Flash nur mit 9600, beim zweiten Flash mit 115200 geklappt.
Probleme
Gelegentlich wird zwar in der Log Ausgaben ein SUCESS angezeigt, aber es scheint nicht zu klappen dann einen der Button wie „Chip Info“ drücken, um etwas zum Controller zu senden.
Communication with MCU..Waiting answer from ESP - Timeout reached. Command aborted.
Befehlt zum Controller senden ( z.b. mit Button „Chip Info“),
Got answer! Communication with MCU established. AutoDetect firmware... Can't autodetect firmware, because proper answer not received (may be unknown firmware). Please, reset module or continue.
Diese Meldung ist nicht so kritisch, hier noch keine Lösung gefunden.
Initalisieren
Zur Initalisierung mit dem Format Button im ersten Schritt Filesystem auf dem Controller einrichten.
Firmware Status anzeigen lassen
Button „Rest“ drücken:
NodeMCU custom build by frightanic.com branch: master commit: 11592951b90707cdcb6d751876170bf4da82850d SSL: false modules: dht,file,gpio,http,net,node,tmr,uart,wifi build created on 2019-01-12 23:59 powered by Lua 5.1.4 on SDK 2.2.1(6ab97e9)
Hier kann auch gut ausgelesen werden welche Module zur Verfügung stehen.
NodeMCU-Tool
Alternativ für die Kommando Zeile (Vorraussetzung Node ist komplett installiert!)
cd /c/entwicklung/nodeMCU https://github.com/AndiDittrich/NodeMCU-Tool.git
Installation:
npm install nodemcu-tool -g
Aufruf:
cd C:\entwicklung\nodeMCU\NodeMCU-Tool\bin node nodemcu-tool.js
Funktioniert bei mir noch nicht so recht, Device wird nicht erkannt.
Datenbank bereitstellen
Lua Code für die Auswertung des DHT22 Sensors erstellen
Zum Glück gibt es ja im Netz bereits viele Vorlagen wie so ein ein erstes Hello World Projekt aussehen kann.
hier ist ein gutes Beispiel zum starten mit dem Temperatur Sensor ⇒ https://www.limpkin.fr/index.php?post/2016/04/17/A-Small-Collection-of-NodeMCU-Lua-Scripts-for-Data-Collection
In meine Fall will ich die folgende Funktionalität am Ende erreichen:
Schritt 1
- Messen von Temperatur und Luftfeuchtigkeit im Kellerraum
- Protokollieren in einer Influx DB, Auswerten mit Grafana ( siehe auch Odroid HC1 Monitoring Appliance mit InfluxDB und Grafana .
Schritt 2
- Messen von Temperatur und Luftfeuchtigkeit auch im Außenbereich
- Steuern eines Lüfters ⇒ falls Luft außen trocken, Luft nach innen, falls im Keller trockener aus.
- Protokollieren Messwerte und Lüfterstatus
Hardware vorbereiten
NodeMCU Modul auf ein Steckbrett stecken, Pin 2 mit dem Datenpin des Sensors verbinden, GND und 3,3v an den Sensor anschließen.
DHT22 - von vorn links = 1
- 1 - VCC ⇒ 3V3
- 2 - Data ⇒ D2
- 3 - NC
- 4 - GND ⇒ GND
Details zum DHT22 Accuracy: (1% humidity accuracy und 0.5C temperature accuracy )
Im Vergleich wird dann noch folgender Sensor getestet:
AM2320 mit I2C (3% humidity accuracy und 0.5C temperature accuracy )
- VDD - ⇒ 3V3
- SDA - I2C data in/out, ⇒ drekt auf D2
- GND - ⇒ GND
- SCL - I2C clock ⇒ drekt auf D1
Details zum AM2320
Liefert aktuell deutlich niedrigere Werte, seltsam
Honeywell humidity sensor
± 1,7% RH (HIH9000 Series), ± 2,0% RH (HIH8000 Series), ± 3,0% RH (HIH7000 Series) und ± 4,0% RH (HIH6100 Series).
https://sensing.honeywell.com/sensors/humidity-sensors/HIH6000-series http://www.gunook.com/esp8266-wifi-temp-feuchtigkeitsuberwachung-web-app-mit-arduino-ide/
Vergleich
Vergleich der Chips ⇒ http://www.kandrsmith.org/RJS/Misc/Hygrometers/calib_many.html und https://www.heise.de/make/artikel/Internet-of-Things-Sensoren-zur-Umweltanalyse-3641125.html
Genereller Ablauf
Auf dem Controller wird eine Datei init.lua hinterlegt. Beim Start des Kontrollers wird diese Datei ausgeführt und lädt dann bei Bedarf den weiteren Sourcecode nach.
In der init.lua kann zum Beispiel der Connect zum Wifi Netz konfiguriert werden.
Wifi Connection hinterlegen
--init.lua -- Modus definieren - Client wifi.setmode(wifi.STATION) -- Konfig Tabelle für den Zugriff station_cfg={} station_cfg.ssid="GPI_HOME" station_cfg.pwd="xxxxTopSecretxxxx" -- Konfig nicht im Flash speichern station_cfg.save=false wifi.sta.config(station_cfg) -- Anmelden wifi.sta.connect() -- zeit stellen -- hier über ntp dienst Zeit abfragen und richtig setze -- SNTP Module einbinden! -- -- Single shot sync time with a server on the local network. sntp.sync("224.0.1.1", function(sec, usec, server, info) print('sync', sec, usec, server) end, function() print('failed!') end ) -- im ersten Schritt einfach setzen .-) rtctime.set(1547585804, 0) -- je 1000 ms warten und prüfen tmr.alarm(1, 500, 1, function() -- prüfe ob die Verbindung schon geklappt hat if wifi.sta.getip() == nil then print("Try to establish connection") else -- Konfiguration ausgeben print("ESP8266 mode :: " .. wifi.getmode() ) print("MAC address :: " .. wifi.ap.getmac()) print("IP :: " .. wifi.sta.getip()) -- Timer stop tmr.unregister(1) end end) tmr.alarm(2, 5000, 1, function() -- prüfe ob die Verbindung schon geklappt hat if wifi.sta.getip() == nil then print("Try to establish connection") else -- rufe die eigentliche Logik auf dofile ("dht.lua") dofile ("sendData.lua") --print(temp) end end)
Ausgabe:
Try to establish connection Try to establish connection Try to establish connection Try to establish connection ESP8266 mode :: 1 MAC address :: 1a:fe:34:e0:b7:a4 IP :: 192.168.0.123 DHT22 Temperatur :: 23.7 - Luftfeuchtigkeit :: 36 DHT22 Temperatur :: 23.7 - Luftfeuchtigkeit :: 36
DHT Modul auswerten und auf die Console schreiben
-- an welchen Pin ist die Datenleitung angeschlossen pin = 2 -- Werte auslesen status, temp, humi, temp_dec, humi_dec = dht.read(pin) -- prüfen ob werte gefunden wurden if status == dht.OK then -- Wenn Float Firmware im Einsatz -- können auch Nachkommastellen ausgegeben werden print("DHT22 Temperatur :: "..temp.." -".." Luftfeuchtigkeit :: "..humi) elseif status == dht.ERROR_CHECKSUM then print( "DHT Checksum error!" ) elseif status == dht.ERROR_TIMEOUT then print( "DHT22 nicht gefunden" ) end
am2320:
sda, scl = 2, 1 i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once am2320.setup() tmr.alarm(4, 5000, 1, function() print("---- try to read from the sensor ") humi, temp = am2320.read() print(string.format("RH: %s%%", humi / 10)) print(string.format("Temperature: %s degrees C", temp / 10)) end)
Daten direkt in die InfluxDB Schreiben
Im nächsten Schritt müssen nun die Daten vom Controller in die Influx Datenbank geschrieben werden.
Über das Rest Interface ist es recht einfach direkt in die InfluxDB zu schreiben siehe ⇒ https://docs.influxdata.com/influxdb/v1.3/guides/writing_data/
Die Daten müssen in diesem Format übergeben werden ⇒ https://docs.influxdata.com/influxdb/v1.3/write_protocols/line_protocol_reference/
<measurement>[,<tag_key>=<tag_value>[,<tag_key>=<tag_value>]] <field_key>=<field_value>[,<field_key>=<field_value>] [<timestamp>]
Übersicht für ein Beispiel mit 3 Schlüsseln und 3 Werte + Timestamp
Sehr wichtig ist die Angabe des Timestamps in Unix nanoseconds!
Dazu legen wir ein Send Modul für die Daten an:
Test Prototyp:
influx_db_ip="http://10.15.169.67:8086" influx_uri="/write?db=JBR" print(" try to send data to :: " .. influx_db_ip .. influx_uri ) -- get the time sec, usec, rate = rtctime.get() -- set the data body_data = 'messung,keller=getranke temperatur='..temp..',feuchtigkeit='.. humi ..' '.. sec ..'000000000' http.post(influx_db_ip .. influx_uri ,'Content-Type: application/json\r\n' ,body_data , function(code, data) if (code < 0) then print("HTTP request failed") else print(code, data) end end)
In Grafana auswerten
Hilfsfunktionen
Alle Wlan Netze in der Umgebung anzeigen
-- Auf Access Point stellen wifi.setmode(wifi.STATION) -- Callback fuer wifi.sta.getap(): -- Liste der gefundenen APs ausgeben function listap(t) for k,v in pairs(t) do print(k.." : "..v) end end -- Scan-Filter scan_cfg = { ssid=nil, bssid=nil, channel=0, show_hidden=1 } -- jede 3 Sekunden Liste der gefundenen WLAN-APs ermitteln/ausgeben tmr.alarm(0,3000,1,function() wifi.sta.getap(scan_cfg, 1, listap2) end)
Doku siehe ⇒ https://nodemcu.readthedocs.io/en/master/en/modules/wifi/#wifistagetap
Doku und Material zum Thema
Stoffsammlung für erste Schritte mit dem ESP8266 und dem NodeMCU Board mit Lua.
Der Chip