Inhoudsopgave:

IoT Made Ease: ESP-MicroPython-MQTT-ThingSpeak - Ajarnpa
IoT Made Ease: ESP-MicroPython-MQTT-ThingSpeak - Ajarnpa

Video: IoT Made Ease: ESP-MicroPython-MQTT-ThingSpeak - Ajarnpa

Video: IoT Made Ease: ESP-MicroPython-MQTT-ThingSpeak - Ajarnpa
Video: Implementing MQTT using Micropython and ESP32 2024, Juli-
Anonim
IoT gemakkelijk gemaakt: ESP-MicroPython-MQTT-ThingSpeak
IoT gemakkelijk gemaakt: ESP-MicroPython-MQTT-ThingSpeak

In mijn vorige tutorial, MicroPython op ESP met Jupyter, hebben we geleerd hoe we MicroPython op een ESP-apparaat kunnen installeren en uitvoeren. Met Jupyter Notebook als onze ontwikkelomgeving leerden we ook lezen van sensoren (temperatuur, vochtigheid en helderheid). We gebruiken verschillende communicatieprotocollen en -methoden, analoog, digitaal, 1-draads en I2C, deze laatste om onze vastgelegde gegevens op een OLED-scherm.

Nu, in deze tutorial met behulp van een MQTT-protocol, zullen we alle vastgelegde gegevens krijgen, ze naar een IoT-service, ThingSpeak.com en naar een mobiele app (Thingsview) sturen, waar we kunnen loggen en met gegevens kunnen spelen.

Hier het blokschema van ons project:

Afbeelding
Afbeelding

Stap 1: Stuklijst - Stuklijst

  1. NodeMCU - US$ 8,39
  2. DHT22 Temperatuur- en relatieve vochtigheidssensor - USD 9,95
  3. DS18B20 Waterdichte temperatuursensor - USD 5.95
  4. OLED-scherm SSD1366- USD 8,99 (optioneel)
  5. LDR (1x)
  6. LED's (1x) (Optioneel)
  7. Drukknop (1x)
  8. Weerstand 4K7 ohm (2x)
  9. Weerstand 10K ohm (1x)
  10. Weerstand 220 ohm (1x)

Stap 2: De Hw

de Hw
de Hw

De Hw die we hier zullen gebruiken, is in principe dezelfde als in de tutorial: Micropython op ESP met Jupyter. Raadpleeg het voor alle HW-aansluitingen.

De uitzondering is de Servo, die we in dit project niet zullen gebruiken.

Hierboven zie je de volledige HW. Sluit de apparaten aan zoals daar weergegeven.

Stap 3: Micropython, REPL, Jupyter

Micropython, REPL, Jupyter
Micropython, REPL, Jupyter
Micropython, REPL, Jupyter
Micropython, REPL, Jupyter

U moet een Micropython-interpreter op uw ESP-apparaat hebben geladen. Eenmaal geladen, moet u uw ESP programmeren met behulp van een van de beschikbare manieren/IDE's, zoals:

  • REPL
  • Jupyter-notitieboekje
  • Mu
  • ESPCut (alleen Windows)
  • … enzovoort

In mijn tutorial, Micropython over ESP Jupyter gebruiken, heb ik beschreven hoe ik MicroPython-interpreter, ESPTool download en installeer om ESP-apparaten te beheren en hoe Jupyter Notebook als ontwikkelomgeving te gebruiken. Voel je vrij om te gebruiken wat voor jou prettiger is.

Ik maak meestal alle ontwikkeling op Jupyter Notebook, en zodra ik de definitieve code heb, kopieer ik ze naar Geany en laad ik deze op mijn ESP met Ampy.

Stap 4: Sensoren

Sensoren
Sensoren

Laten we de bibliotheken installeren, GPIO definiëren, objecten maken, functies voor alle sensoren afzonderlijk:

A. DHT (temperatuur en vochtigheid)

Laten we de DHT-bibliotheek installeren en een object maken:

van dht import DHT22

van machine-import Pin dht22 = DHT22(Pin (12))

Maak nu een functie om de DHT-sensor te lezen:

def leesDht():

dht22.measure() retour dht22.temperatuur(), dht22.humidity() DHT-functie testen

print (readDht())

Het resultaat moet bijvoorbeeld zijn:

(17.7, 43.4)

B. DS18B20 (externe temperatuur)

Laten we de bibliotheken installeren en een object maken:

import onewire, ds18x20

import time # Bepaal op welke pin het 1-draads apparaat wordt aangesloten ==> pin 2 (D4) dat = Pin(2) # maak het eendraads object ds = ds18x20. DS18X20(onewire. OneWire(dat)) Scannen naar apparaten in de bu

sensoren = ds.scan()

print('gevonden apparaten:', sensoren)

Het afgedrukte resultaat is niet echt belangrijk, wat we nodig hebben is de eerste gedetecteerde sensor: sensoren[0]. En nu kunnen we een functie bouwen om sensorgegevens te lezen:

def leesDs():

ds.convert_temp() time.sleep_ms(750) return ds.read_temp(sensors[0])

Het is altijd belangrijk om de sensor te testen met behulp van de gemaakte functie

print(leesDs()) Als je een temperatuurwaarde krijgt, is je code correct

17.5

C. LDR (helderheid)

De LDR zal de analoge pin van onze ESP gebruiken (het is er maar één in het geval van ESP8266 en meerdere voor ESP32).

Raadpleeg mijn ESP32-zelfstudie voor meer informatie.

Hetzelfde als eerder gedaan:

# bibliotheek importeren

van machine import ADC # Definieer object adc = ADC(0) Een eenvoudige functie: adc.read() kan worden gebruikt om de ADC-waarde te lezen. Maar onthoud dat de interne ADC spanningen tussen 0 en 3,3 V omzet in corresponderende digitale waarden, variërend van 0 tot 1023. Als we eenmaal geïnteresseerd zijn in "Luminosity", zullen we Max light beschouwen als de maximale vastgelegde waarde van de sensor (in mijn geval 900) en minimaal licht dat in mijn geval 40 is. Met die waarden kunnen we de waarde van 40 tot 900 "in kaart brengen" in 0 tot 100% helderheid. Daarvoor zullen we een nieuwe functie maken

def leesLdr():

lumPerct = (adc.read()-40)*(10/86) # convert in percentage ("map") retourronde (lumPerct)

U moet de functie testen met print (readLDR()). Het resultaat moet een geheel getal zijn tussen o en 100.

D. Drukknop (digitale ingang)

Hier gebruiken we een drukknop als digitale sensor, maar het kan een "echo" zijn van een actuator (bijvoorbeeld een pomp die AAN/UIT is geschakeld).

# definieer pin 13 als ingang en activeer een interne pull-up-weerstand:

button = Pin(13, Pin. IN, Pin. PULL_UP) # Functie om knopstatus te lezen: def readBut(): return button.value()

U kunt de knop testen met de functie print(readBut()). Zonder te drukken zou het resultaat "1" moeten zijn. Als u op de knop drukt, moet het resultaat "0" zijn

Stap 5: Alle sensorgegevens lokaal vastleggen en weergeven

Alle sensorgegevens lokaal vastleggen en weergeven
Alle sensorgegevens lokaal vastleggen en weergeven

Nu we voor elke sensor één functie hebben gemaakt, gaan we de laatste maken die ze allemaal tegelijkertijd leest:

def colectData():

temp, hum, = readDht() extTemp = readDs() lum = readLdr() butSts = readBut() return temp, hum, extTemp, lum, butSts Als je nu

print(colectData())

Zal resulteren in een tuple die alle vastgelegde gegevens van sensoren bevat:

(17.4, 45.2, 17.3125, 103, 1)

We kunnen die gegevens optioneel ook op een lokaal display tonen:

# importeer bibliotheek en maak object i2c

van machine import I2C i2c = I2C(scl=Pin(5), sda=Pin(4)) # importeer bibliotheek en maak object oled import ssd1306 i2c = I2C(scl=Pin(5), sda=Pin(4)) oled = ssd1306. SSD1306_I2C(128, 64, i2c, 0x3c) # maak een functie aan: def displayData(temp, hum, extTemp, lum, butSts): oled.fill(0) oled.text("Temp: " + str(temp) + "oC", 0, 4) oled.text("Hum: " + str(hum) + "%", 0, 16) oled.text("ExtTemp: " + str(extTemp) + "oC", 0, 29) oled.text("Lumin: " + str(lum) + "%", 0, 43) oled.text("Knop: " + str(butSts), 0, 57) oled.show() # data weergeven met de functie displayData(temp, hum, extTemp, lum, butSts)

Als optie zal ik ook de LED opnemen die AAN is wanneer we sensoren beginnen te lezen, en UIT gaat nadat die gegevens worden weergegeven. Als u dit doet, kunt u bevestigen dat het programma werkt wanneer de ESP is losgekoppeld van de pc en automatisch wordt uitgevoerd.

Dus de hoofdfunctie zou zijn:

# Hoofdfunctie om alle sensoren te lezen

def main(): # data weergeven met een functie led.on() temp, hum, extTemp, lum, butSts = colectData() displayData(temp, hum, extTemp, lum, butSts) led.off()

Dus door main() uit te voeren, krijgen we de sensorgegevens weergegeven op OLED zoals weergegeven in de afbeelding.

Stap 6: De lokale stationscode uitvoeren bij het opstarten van ESP

De lokale stationscode uitvoeren bij het opstarten van ESP
De lokale stationscode uitvoeren bij het opstarten van ESP

We kunnen alles wat tot nu toe is ontwikkeld in een enkel bestand laten uitvoeren door onze ESP.

Laten we een willekeurige teksteditor openen en er alle code op plakken:

# importeer algemene bibliotheken

van machine import Pin import tijd # definieer pin 0 als output led = Pin(0, Pin. OUT) # DHT van dht import DHT22 dht22 = DHT22(Pin (12)) # Functie om DHT te lezen def readDht(): dht22.measure () return dht22.temperature(), dht22.humidity() # DS18B20 import onewire, ds18x20 # Bepaal op welke pin het 1-draads apparaat wordt aangesloten ==> pin 2 (D4) dat = Pin(2) # Maak de eendraads object ds = ds18x20. DS18X20(onewire. OneWire(dat)) # scan naar apparaten op de bus sensoren = ds.scan() # functie om DS18B20 te lezen def readDs(): ds.convert_temp() time.sleep_ms(750) return round(ds.read_temp(sensors[0]), 1) # LDR van machine import ADC # Definieer object adc = ADC(0) #function om helderheid te lezen def readLdr(): lumPerct = (adc.read()-40) *(10/86) # convert in percentage ("map") return round(lumPerct) # definieer pin 13 als ingang en activeer een interne Pull-up weerstand: knop = Pin(13, Pin. IN, Pin. PULL_UP) # Functie om knopstatus te lezen: def readBut(): return button.value() # Functie om alle gegevens te lezen: def cole ctData(): temp, hum, = readDht() extTemp = readDs() lum = readLdr() butSts = readBut() return temp, hum, extTemp, lum, butSts # importeer bibliotheek en maak object i2c van machine import I2C i2c = I2C(scl=Pin(5), sda=Pin(4)) # importeer bibliotheek en maak object oled import ssd1306 i2c = I2C(scl=Pin(5), sda=Pin(4)) oled = ssd1306. SSD1306_I2C(128, 64, i2c, 0x3c) # maak een functie aan: def displayData(temp, hum, extTemp, lum, butSts): oled.fill(0) oled.text("Temp: " + str(temp) + "oC", 0, 4) oled.text("Hum: " + str(hum) + "%", 0, 16) oled.text("ExtTemp: " + str(extTemp) + "oC", 0, 29) oled. text("Lumin: " + str(lum) + "%", 0, 43) oled.text("Button: " + str(butSts), 0, 57) oled.show() # Hoofdfunctie om alle sensoren uit te lezen def main(): # data weergeven met een functie led.on() temp, hum, extTemp, lum, butSts = colectData() displayData(temp, hum, extTemp, lum, butSts) led.off() '''- ----- hoofdfunctie uitvoeren --------''' main()

Sla het op, bijvoorbeeld als localData.py.

Om deze code rechtstreeks op uw terminal uit te voeren, heeft u Ampy nodig.

Laten we eerst Ampy op Terminal informeren over onze seriële poort:

export AMPY_PORT=/dev/tty. SLAB_USBtoUART

Nu kunnen we de bestanden zien die zich in onze ESP-hoofdmap bevinden:

ampy ls

Als reactie krijgen we boot.py, dat is het eerste bestand dat in het systeem wordt uitgevoerd.

Laten we nu Ampy gebruiken om ons python Script LocalData.py als /main.py te laden, zodat het script net na het opstarten wordt uitgevoerd:

ampy zet localData.py /main/py

Als we nu de opdracht amp ls gebruiken, ziet u 2 bestanden in de ESP.: boot.py en main.py

Als u uw ESP reset, wordt het programma localData.py automatisch uitgevoerd en worden de sensorgegevens op het display weergegeven.

Het bovenstaande Terminal-afdrukscherm laat zien wat we hebben gedaan.

Met bovenstaande code wordt het display slechts één keer weergegeven, maar we kunnen een lus op de main()-functie definiëren, die gegevens toont over elk gedefinieerd tijdsinterval (PUB_TIME_SEC), en bijvoorbeeld totdat we op de knop drukken:

# loop gegevens ophalen totdat de knop wordt ingedrukt

while button.value(): led.on() temp, hum, extTemp, lum, butSts = colectData() displayData(temp, hum, extTemp, lum, butSts) led.off() time.sleep(PUB_TIME_SEC)

De variabele PUB_TIME_SEC moet zijn gedeclareerd tegen de tijd dat u uw samples wilt hebben.

Om onze code meer te verbeteren, zou het goed zijn om te informeren dat we uit de lus zullen gaan, daarvoor zullen we 2 nieuwe algemene functies definiëren, een voor het wissen van het display en een andere om de LED een bepaald aantal keren te laten knipperen.

# Duidelijke weergave:

def displayClear(): oled.fill(0) oled.show() # maak een knipperfunctie def blinkLed(num): for i in range(0, num): led.on() sleep(0.5) led.off() slaap(0.5)

Dus we kunnen nu onze main() functie herschrijven:

terwijl knop.waarde():

led.on() temp, hum, extTemp, lum, butSts = colectData() displayData(temp, hum, extTemp, lum, butSts) led.off() time.sleep(PUB_TIME_SEC) blinkLed(3) displayClear()

De definitieve code kan worden gedownload van mijn GitHub: localData.py en ook de Jupyter Notebook die wordt gebruikt voor de ontwikkeling van de volledige code: Jupyter Local Data Development.

Stap 7: De ESP verbinden met lokale wifi

De ESP verbinden met lokale wifi
De ESP verbinden met lokale wifi

De netwerkmodule wordt gebruikt om de wifi-verbinding te configureren. Er zijn twee wifi-interfaces, een voor het station (wanneer de ESP8266 verbinding maakt met een router) en een voor het toegangspunt (voor andere apparaten om verbinding te maken met de ESP8266). Hier wordt onze ESP verbonden met het lokale netwerk. Laten we de bibliotheek bellen en onze netwerkreferenties definiëren:

netwerk importeren

WiFi_SSID = "UW SSID" WiFi_PASS = "UW WACHTWOORD"

Met onderstaande functie kunt u de ESP verbinden met uw lokale netwerk:

def do_connect():

wlan = network. WLAN(network. STA_IF) wlan.active(True) if not wlan.isconnected(): print('connecting to network…') wlan.connect(WiFi_SSID, WiFi_SSID) while not wlan.isconnected(): pass print('netwerkconfiguratie:', wlan.ifconfig())

Als u de functie uitvoert, kunt u als resultaat het IP-adres krijgen:

do_connect()

Het resultaat zal zijn:

netwerkconfiguratie: ('10.0.1.2', '255.255.255.0', '10.0.1.1', '10.0.1.1')

Waren, in mijn geval, 10.0.1.2, is het ESP IP-adres.

Stap 8: The ThingSpeak

Het DingSpreek
Het DingSpreek

Op dit punt hebben we geleerd hoe we gegevens van alle sensoren kunnen vastleggen en weergeven op onze OLED. Nu is het tijd om te kijken hoe je die gegevens naar een IoT-platform, de ThingSpeak, kunt sturen.

Laten we beginnen!

Ten eerste moet u een account hebben op ThinkSpeak.com. Volg vervolgens de instructies om een kanaal te maken en noteer uw kanaal-ID en schrijf-API-sleutel.

Hierboven zie je de 5 velden die op ons kanaal zullen worden gebruikt.

Stap 9: MQTT-protocol en ThingSpeak-verbinding

MQTT-protocol en ThingSpeak-verbinding
MQTT-protocol en ThingSpeak-verbinding

MQTT is een publiceer/abonneer-architectuur die voornamelijk is ontwikkeld om bandbreedte en stroombeperkte apparaten via draadloze netwerken te verbinden. Het is een eenvoudig en lichtgewicht protocol dat over TCP/IP-sockets of WebSockets loopt. MQTT via WebSockets kan worden beveiligd met SSL. Dankzij de architectuur voor publiceren/abonneren kunnen berichten naar de clientapparaten worden gepusht zonder dat het apparaat continu de server hoeft te pollen.

De MQTT-makelaar is het centrale communicatiepunt en is verantwoordelijk voor het verzenden van alle berichten tussen de afzenders en de rechtmatige ontvangers. Een client is elk apparaat dat verbinding maakt met de broker en onderwerpen kan publiceren of erop kunnen abonneren om toegang te krijgen tot de informatie. Een onderwerp bevat de routeringsinformatie voor de makelaar. Elke klant die berichten wil verzenden, publiceert ze naar een bepaald onderwerp, en elke klant die berichten wil ontvangen, abonneert zich op een bepaald onderwerp. De makelaar levert alle berichten met het bijbehorende onderwerp aan de juiste klanten.

ThingSpeak™ heeft een MQTT-broker op de URL mqtt.thingspeak.com en poort 1883. De ThingSpeak-broker ondersteunt zowel MQTT-publicatie als MQTT-abonnee.

In ons geval gebruiken we: MQTT Publish

Afbeelding
Afbeelding

De figuur beschrijft de onderwerpstructuur. De Write API Key is vereist om te publiceren. De makelaar bevestigt een correcte CONNECT-aanvraag bij CONNACK.

Het MQTT-protocol wordt ondersteund in een ingebouwde bibliotheek in de binaire bestanden van Micropython - dit protocol kan worden gebruikt om gegevens van uw ESP8266 via WIFI naar een gratis clouddatabase te verzenden.

Laten we de bibliotheek umqtt.simple gebruiken:

van umqtt.simple import MQTTClient

En als we onze SERVER-ID kennen, is het mogelijk om ons MQTT-clientobject te maken:

SERVER = "mqtt.thingspeak.com"

client = MQTTClient("umqtt_client", SERVER)

Nu, met uw ThingSpeak-referenties bij de hand:

CHANNEL_ID = "UW KANAAL-ID"

WRITE_API_KEY = "UW SLEUTEL HIER"

Laten we onze MQTT "Topic" maken:

topic = "kanalen/" + CHANNEL_ID + "/publish/" + WRITE_API_KEY

Laten we ervoor zorgen dat onze gegevens naar ThingSpeak IoT Service worden verzonden, met behulp van de gemaakte functie en de reactie ervan koppelen aan specifieke gegevensvariabelen:

temp, brom, extTemp, lum, butSts = colectData()

Met die variabelen bijgewerkt, kunnen we onze "MQTT Payload" maken:

payload = "field1="+str(temp)+"&field2="+str(hum)+"&field3="+str(extTemp)+"&field4="+str(lum)+"&field5="+str(butSts)

En dat is het! We zijn klaar om gegevens naar ThinsSpeak te sturen, door simpelweg de onderstaande 3 regels code te gebruiken:

cliënt.connect()

client.publish(topic, payload) client.disconnect()

Als je nu naar je kanaalpagina gaat (zoals de mijne hierboven), zul je zien dat elk van de 5 velden gegevens bevat die verband houden met je sensoren.

Stap 10: Sensor datalogger

Sensor datalogger
Sensor datalogger

Nu we weten dat het met slechts een paar regels code mogelijk is om gegevens naar een IoT-service te uploaden, laten we een lusfunctie maken om dit automatisch met een regelmatig tijdsinterval te doen (vergelijkbaar met wat we hebben gedaan met "Lokale gegevens ").

Met behulp van dezelfde variabele (PUB_TIME_SEC), eerder gedeclareerd, zou een eenvoudige hoofdfunctie om continu gegevens vast te leggen, zijn:

terwijl waar:

temp, hum, extTemp, lum, butSts = colectData() payload = "field1="+str(temp)+"&field2="+str(hum)+"&field3="+str(extTemp)+"&field4="+ str(lum)+"&field5="+str(butSts) client.connect() client.publish(topic, payload) client.disconnect() time.sleep(PUB_TIME_SEC)

Houd er rekening mee dat alleen de "payload" moet worden bijgewerkt, zodra "onderwerp" gerelateerd is aan onze kanaalreferentie en niet zal veranderen.

Als u uw ThingSpeak-kanaalpagina zoekt, zult u zien dat de gegevens continu naar elk veld worden geladen. U kunt de LDR afdekken, uw hand op temp/brom-sensoren leggen, op de knop drukken, enz. en zien hoe het kanaal deze gegevens automatisch "logt" voor toekomstige analyse.

Gewoonlijk moeten we voor datalogging proberen zo min mogelijk stroom te gebruiken, dus we zouden de LED of het display niet lokaal gebruiken. Het is ook gebruikelijk bij ESP-apparaten om ze in "diepe slaap" te zetten, waarbij de microprocessor op minimale energie staat totdat het tijd is om gegevens vast te leggen en naar het IoT-platform te sturen.

Maar als het idee eenmaal aan het leren is, laten we ook het display en de LED opnemen zoals we eerder deden. Als u dat doet, is onze "logger"-functie:

terwijl knop.waarde():

led.on() temp, hum, extTemp, lum, butSts = colectData() displayData(temp, hum, extTemp, lum, butSts) led.off() temp, hum, extTemp, lum, butSts = colectData() payload = "field1="+str(temp)+"&field2="+str(hum)+"&field3="+str(extTemp)+"&field4="+str(lum)+"&field5="+str(butSts)-client.connect() client.publish(topic, payload) client.disconnect() time.sleep(PUB_TIME_SEC) blinkLed(3) displayClear()

Het volledige microPython-script is hier te vinden: dataLoggerTS_EXT.py en de Jupyter-notebook die voor de ontwikkeling is gebruikt, zijn ook hier te vinden: IoT ThingSpeak Data Logger EXT.ipynb.

Om het script op ESP te uploaden, gebruikt u op uw terminal de opdracht:

ampy put dataLoggerTS.py /main.py

En druk op de ESP - reset-knop. U laat de ESP gegevens vastleggen en loggen op ThingSpeak.com totdat de onderkant ingedrukt wordt gehouden (wacht tot de LED 3 keer knippert en de OLED uitgaat).

Stap 11: De ThingView-app

De ThingView-app
De ThingView-app

De geregistreerde gegevens kunnen direct op de ThingSpeak.com-site worden bekeken of via een APP, bijvoorbeeld ThingsView!

ThingView is een APP ontwikkeld door CINETICA, waarmee u uw ThingSpeak-kanalen op een gemakkelijke manier kunt visualiseren, voer gewoon de kanaal-ID in en u bent klaar om te gaan.

Voor openbare kanalen respecteert de applicatie uw Windows-instellingen: kleur, tijdschaal, grafiektype en het aantal resultaten. De huidige versie ondersteunt lijn- en kolomdiagrammen, de splinediagrammen worden weergegeven als lijndiagrammen.

Voor privékanalen worden de gegevens weergegeven met de standaardinstellingen, omdat er geen manier is om de instellingen voor privévensters alleen met de API-sleutel te lezen.

De ThingView APP kan worden gedownload voor ANDROID en IPHONE.

Stap 12: Conclusie

Conclusie
Conclusie

Zoals altijd hoop ik dat dit project anderen kan helpen hun weg te vinden in de opwindende wereld van elektronica!

Ga voor meer informatie en de definitieve code naar mijn GitHub-depot: IoT_TS_MQTT

Ga voor meer projecten naar mijn blog: MJRoBot.org

Saludos uit het zuiden van de wereld!

Tot ziens in mijn volgende instructable!

Bedankt, Marcelo

Aanbevolen: