Innehållsförteckning:

IoT Made Ease: ESP-MicroPython-MQTT-ThingSpeak: 12 steg
IoT Made Ease: ESP-MicroPython-MQTT-ThingSpeak: 12 steg

Video: IoT Made Ease: ESP-MicroPython-MQTT-ThingSpeak: 12 steg

Video: IoT Made Ease: ESP-MicroPython-MQTT-ThingSpeak: 12 steg
Video: How to Publish DHT11 Sensor Data from NodeMCU to Mosquitto MQTT Broker over LAN | NodeMCU | MQTT | 2024, Juli
Anonim
IoT Made Ease: ESP-MicroPython-MQTT-ThingSpeak
IoT Made Ease: ESP-MicroPython-MQTT-ThingSpeak

I min tidigare handledning, MicroPython på ESP med Jupyter, lärde vi oss hur man installerar och kör MicroPython på en ESP -enhet. Genom att använda Jupyter Notebook som vår utvecklingsmiljö lärde vi oss också hur man läser från sensorer (temperatur, luftfuktighet och ljusstyrka). Vi använder flera kommunikationsprotokoll och metoder, Analog, Digital, 1-Wire och I2C, den sista för att visa våra fångade data på en OLED -skärm.

Nu, på denna handledning med ett MQTT -protokoll, kommer vi att få all fångad data och skicka dem till en IoT -tjänst, ThingSpeak.com och till en mobilapp (Thingsview), där vi kan logga och spela med data.

Här är blockschemat för vårt projekt:

Bild
Bild

Steg 1: BoM - materialräkning

  1. NodeMCU - 8,39 US $
  2. DHT22 temperatur- och relativ fuktighetssensor - 9,95 USD
  3. DS18B20 Vattentät temperatursensor - 5,95 USD
  4. OLED Display SSD1366- 8,99 USD (tillval)
  5. LDR (1x)
  6. Lysdioder (1x) (tillval)
  7. Tryckknapp (1x)
  8. Motstånd 4K7 ohm (2x)
  9. Motstånd 10K ohm (1x)
  10. Motstånd 220 ohm (1x)

Steg 2: Hw

Hw
Hw

Hw som vi kommer att använda här är i princip samma som används i självstudien: Micropython på ESP med Jupyter. Se den för alla HW -anslutningar.

Undantaget är Servo, som vi inte kommer att användas i detta projekt.

Ovan kan du se hela HW. Anslut enheterna som visas där.

Steg 3: Micropython, REPL, Jupyter

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

Du måste ha en Micropython -tolk laddad på din ESP -enhet. När den har laddats bör du programmera din ESP med hjälp av tillgängliga tillgängliga sätt/IDE: er, till exempel:

  • REPL
  • Jupyter anteckningsbok
  • Mu
  • ESPCut (endast Windows)
  • … etc

I min handledning, Micropython på ESP Med hjälp av Jupyter, detaljerade jag hur jag laddar ner och installerar MicroPython -tolk, ESPTool för att hantera ESP -enheter och hur jag använder Jupyter Notebook som utvecklingsmiljö. Använd gärna det som är bekvämare för dig.

Jag brukar göra all utveckling på Jupyter Notebook, och när jag fått den slutliga koden kopierar jag dem till Geany och laddar den på min ESP med Ampy.

Steg 4: Sensorer

Sensorer
Sensorer

Låt oss installera biblioteken, definiera GPIO, skapa objekt, funktioner för alla sensorer individuellt:

A. DHT (temperatur och luftfuktighet)

Låt oss installera DHT -biblioteket och skapa ett objekt:

från dht import DHT22

från maskinimport Pin dht22 = DHT22 (Pin (12))

Skapa nu en funktion för att läsa DHT -sensor:

def readDht ():

dht22.measure () retur dht22.temperatur (), dht22.fuktighet () Testa DHT -funktionen

print (readDht ())

Resultatet ska vara till exempel:

(17.7, 43.4)

B. DS18B20 (yttre temperatur)

Låt oss installera biblioteken och skapa ett objekt:

importera onewire, ds18x20

importtid # Definiera vilken pin den 1-trådiga enheten ska anslutas ==> pin 2 (D4) dat = Pin (2) # skapa onewire-objektet ds = ds18x20. DS18X20 (onewire. OneWire (dat)) Sök efter enheter på bu

sensorer = ds.scan ()

print ('hittade enheter:', sensorer)

Det utskrivna resultatet är inte riktigt viktigt, det vi behöver är den första detekterade sensorn: sensorer [0]. Och nu kan vi bygga en funktion för att läsa sensordata:

def readDs ():

ds.convert_temp () time.sleep_ms (750) returnerar ds.read_temp (sensorer [0])

Det är alltid viktigt att testa sensorn med den skapade funktionen

print (readDs ()) Om du får ett temperaturvärde är din kod korrekt

17.5

C. LDR (Ljusstyrka)

LDR kommer att använda den analoga stiftet i vårt ESP (det är bara en för ESP8266 och flera för ESP32).

Se min ESP32 -handledning för mer information.

Samma som gjort tidigare:

# importbibliotek

från maskinimport ADC # Definiera objekt adc = ADC (0) En enkel funktion: adc.read () kan användas för att läsa ADC -värdet. Men kom ihåg att den interna ADC: n kommer att omvandla spänningar mellan 0 och 3,3V i motsvarande digitala värden, som varierar från 0 till 1023. När vi väl är intresserade av "Luminosity", kommer vi att betrakta Max ljus som det maximala fångade värdet från sensorn (i min fall 900) och minsta ljus som i mitt fall är 40. Med dessa värden kan vi "kartlägga" värdet från 40 till 900 i 0 till 100% av ljusstyrkan. För det kommer vi att skapa en ny funktion

def readLdr ():

lumPerct = (adc.read ()-40)*(10/86) # konvertera i procent ("karta") returrunda (lumPerct)

Du bör testa funktionen med utskrift (readLDR ()). Resultatet ska vara ett heltal mellan o och 100.

D. Tryckknapp (digital ingång)

Här använder vi en tryckknapp som en digital sensor, men det kan vara ett "eko" av ett ställdon (till exempel en pump som var PÅ/AV).

# definiera stift 13 som en ingång och aktivera ett internt uppdragningsmotstånd:

button = Pin (13, Pin. IN, Pin. PULL_UP) # Function to read button state: def readBut (): return button.value ()

Du kan testa knappen som läser funktionsutskriften (readBut ()). Utan att trycka på resultatet ska vara "1". Genom att trycka på knappen ska resultatet vara "0"

Steg 5: Fånga och visa lokalt all sensordata

Fånga och visa lokalt all sensordata
Fånga och visa lokalt all sensordata

Nu när vi har skapat en funktion för varje sensor, låt oss skapa den sista som kommer att läsa dem alla samtidigt:

def colectData ():

temp, hum, = readDht () extTemp = readDs () lum = readLdr () butSts = readBut () returtemp, hum, extTemp, lum, butSts Nu om du använder

print (colectData ())

Kommer att resultera i en tupel som inkluderar all fångad data från sensorer:

(17.4, 45.2, 17.3125, 103, 1)

Vi kan också välja att visa dessa data på en lokal skärm:

# importera bibliotek och skapa objekt i2c

från maskinimport I2C i2c = I2C (scl = Pin (5), sda = Pin (4)) # importbibliotek och skapa objekt oled import ssd1306 i2c = I2C (scl = Pin (5), sda = Pin (4)) oled = ssd1306. SSD1306_I2C (128, 64, i2c, 0x3c) # skapa en funktion: 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 () # visa data med funktionen displayData (temp, hum, extTemp, lum, butSts)

Som tillval kommer jag också att inkludera lysdioden som ska lysa när vi börjar läsa sensorer, slockna när data visas. Om du gör detta kan du bekräfta att programmet fungerar när ESP kopplas från datorn och körs automatiskt.

Så huvudfunktionen skulle vara:

# Huvudfunktion för att läsa alla sensorer

def main (): # displaydata med en funktion led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off ()

Så, genom att köra main (), får vi sensordata visas på OLED som visas på bilden.

Steg 6: Kör Local Station Code vid ESP-start

Kör den lokala stationskoden vid ESP-start
Kör den lokala stationskoden vid ESP-start

Vi kan ha allt som utvecklats hittills på en enda fil som ska köras av vår ESP.

Låt oss öppna vilken textredigerare som helst och koda den:

# importera allmänna bibliotek

från maskinimport Pinimporttid # definiera pin 0 som output led = Pin (0, Pin. OUT) # DHT från dht import DHT22 dht22 = DHT22 (Pin (12)) # Funktion för att läsa DHT def readDht (): dht22.mätning () retur dht22.temperatur (), dht22.humidity () # DS18B20 import onewire, ds18x20 # Definiera vilken stift 1-trådsenheten ska anslutas ==> pin 2 (D4) dat = Pin (2) # Skapa onewire objekt ds = ds18x20. DS18X20 (onewire. OneWire (dat)) # sök efter enheter på bussensorerna = ds.scan () # funktion för att läsa DS18B20 def readDs (): ds.convert_temp () time.sleep_ms (750) retur rund (ds.read_temp (sensorer [0]), 1) # LDR från maskinimport ADC # Definiera objekt adc = ADC (0) # funktion för att läsa luminosity def readLdr (): lumPerct = (adc.read ()-40) *(10/86) # konvertera i procent ("karta") returrunda (lumPerct) # definiera stift 13 som en ingång och aktivera ett internt pull-up-motstånd: knapp = Pin (13, Pin. IN, Pin. PULL_UP) # Funktion för att läsa knappläge: def readBut (): returknapp. Värde () # Funktion för att läsa all data: def cole ctData (): temp, hum, = readDht () extTemp = readDs () lum = readLdr () butSts = readBut () returtemp, hum, extTemp, lum, butSts # importbibliotek och skapa objekt i2c från maskinimport I2C i2c = I2C (scl = Pin (5), sda = Pin (4)) # importbibliotek och skapa objekt oled import ssd1306 i2c = I2C (scl = Pin (5), sda = Pin (4)) oled = ssd1306. SSD1306_I2C (128, 64, i2c, 0x3c) # skapa en funktion: 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 ("Knapp:" + str (butSts), 0, 57) oled.show () # Huvudfunktion för att läsa alla sensorer def main (): # displaydata med en funktion led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off () '' '-- ----- kör huvudfunktionen -------- '' 'main ()

Spara det, till exempel som localData.py.

För att köra den här koden direkt på din terminal behöver du Ampy.

Först, på Terminal, låt oss informera Ampy om vår seriella port:

exportera AMPY_PORT =/dev/tty. SLAB_USBtoUART

Nu kan vi se filerna i vår ESP -rotkatalog:

ampy ls

Som ett svar får vi boot.py, det är den första filen som körs i systemet.

Låt oss nu använda Ampy för att ladda vårt python -skript LocalData.py som /main.py, så manuset körs strax efter start:

ampy lägger localData.py /main /py

Om vi använder kommandoförstärkaren ls nu ser du två filer inuti ESP: boot.py och main.py

Om du återställer din ESP kommer programmet localData.py att köras automatiskt och sensordata visas på displayen.

Ovanstående terminalutskriftsskärm visar vad vi har gjort.

Med ovanstående kod kommer displayen att visas bara en gång, men vi kan definiera en loop på huvudfunktionen (), som visar data för varje definierat tidsintervall (PUB_TIME_SEC), och till exempel tills vi trycker på knappen:

# loop få data tills knappen trycks in

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

Variabeln PUB_TIME_SEC måste deklareras när du vill ha dina prover.

För att förbättra vår kod skulle det vara bra att informera om att vi kommer att gå ut från slingan, för det kommer vi att definiera 2 nya allmänna funktioner, en för att rensa displayen och en annan för att blinka LED -lampan ett visst antal gånger.

# Rensa displayen:

def displayClear (): oled.fill (0) oled.show () # skapa en blinkningsfunktion def blinkLed (num): för i inom intervallet (0, num): led.on () sleep (0,5) led.off () sömn (0,5)

Så nu kan vi skriva om vår huvudfunktion ():

while button.value ():

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

Den slutliga koden kan laddas ner från min GitHub: localData.py och även Jupyter Notebook som används för utveckling av fullständig kod: Jupyter Local Data Development.

Steg 7: Anslutning av ESP till lokal WiFi

Ansluter ESP till lokal WiFi
Ansluter ESP till lokal WiFi

Nätverksmodulen används för att konfigurera WiFi -anslutningen. Det finns två WiFi -gränssnitt, ett för stationen (när ESP8266 ansluter till en router) och ett för åtkomstpunkten (för andra enheter att ansluta till ESP8266). Här kommer vår ESP att anslutas till det lokala nätverket. Låt oss ringa biblioteket och definiera våra nätverksuppgifter:

importera nätverk

WiFi_SSID = "DITT SSID" WiFi_PASS = "DITT LÖSENORD"

Funktionen nedan kan användas för att ansluta ESP till ditt lokala nätverk:

def do_connect ():

wlan = network. WLAN (network. STA_IF) wlan.active (True) om det inte är wlan.isconnected (): skriv ut ('ansluter till nätverk …') wlan.connect (WiFi_SSID, WiFi_SSID) medan det inte är wlan.isconnected (): passera print ('nätverkskonfiguration:', wlan.ifconfig ())

Genom att köra funktionen kan du få IP -adressen som ett resultat:

do_connect ()

Resultatet blir:

nätverkskonfiguration: ('10.0.1.2 ',' 255.255.255.0 ', '10.0.1.1', '10.0.1.1 ')

Var, i mitt fall, 10.0.1.2, ESP IP -adressen.

Steg 8: The ThingSpeak

The ThingSpeak
The ThingSpeak

Vid denna tidpunkt lärde vi oss att fånga data från alla sensorer och visa dem på vår OLED. Nu är det dags att se hur man skickar dessa data till en IoT -plattform, ThingSpeak.

Låt oss börja!

Först måste du ha ett konto på ThinkSpeak.com. Följ sedan instruktionerna för att skapa en kanal och notera ditt kanal -ID och Skriv API -nyckel.

Ovan kan du se de 5 fälten som kommer att användas på vår kanal.

Steg 9: MQTT -protokoll och ThingSpeak -anslutning

MQTT -protokoll och ThingSpeak -anslutning
MQTT -protokoll och ThingSpeak -anslutning

MQTT är en publicerings-/prenumerationsarkitektur som utvecklats främst för att ansluta bandbredd och strömbegränsade enheter över trådlösa nätverk. Det är ett enkelt och lätt protokoll som körs över TCP/IP -uttag eller WebSockets. MQTT via WebSockets kan säkras med SSL. Utgivnings-/prenumerationsarkitekturen gör det möjligt att skicka meddelanden till klientenheterna utan att enheten kontinuerligt behöver polla servern.

MQTT -mäklaren är den centrala kommunikationspunkten, och den ansvarar för att skicka alla meddelanden mellan avsändarna och de rättmätiga mottagarna. En klient är en enhet som ansluter till mäklaren och kan publicera eller prenumerera på ämnen för att komma åt informationen. Ett ämne innehåller routningsinformation för mäklaren. Varje klient som vill skicka meddelanden publicerar dem till ett visst ämne, och varje klient som vill ta emot meddelanden prenumererar på ett visst ämne. Mäklaren levererar alla meddelanden med matchande ämne till lämpliga kunder.

ThingSpeak ™ har en MQTT -mäklare på URL: en mqtt.thingspeak.com och port 1883. ThingSpeak -mäklaren stöder både MQTT -publicering och MQTT -prenumeration.

I vårt fall kommer vi att använda: MQTT Publish

Bild
Bild

Figuren beskriver ämnesstrukturen. Skriv -API -nyckeln krävs för att publicera. Mäklaren erkänner en korrekt CONNECT -fråga med CONNACK.

MQTT-protokollet stöds i ett inbyggt bibliotek i Micropython-binärfilerna-detta protokoll kan användas för att skicka data från din ESP8266, över WIFI, till en gratis molndatabas.

Låt oss använda umqtt.simple -biblioteket:

från umqtt.simple import MQTTClient

Och när vi känner till vårt SERVER -ID är det möjligt att skapa vårt MQTT -klientobjekt:

SERVER = "mqtt.thingspeak.com"

klient = MQTTClient ("umqtt_client", SERVER)

Nu, med dina ThingSpeak -referenser till hands:

CHANNEL_ID = "DITT KANAL -ID"

WRITE_API_KEY = "DIN NYCKEL HÄR"

Låt oss skapa vår MQTT "Ämne":

topic = "kanaler/" + CHANNEL_ID + "/publicera/" + WRITE_API_KEY

Låt oss få våra data att skickas till ThingSpeak IoT Service, med hjälp av den skapade funktionen och koppla dess svar till specifika datavariabler:

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

Med dessa variabler uppdaterade kan vi skapa vår "MQTT Payload":

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

Och det är allt! Vi är redo att skicka data till ThinsSpeak, helt enkelt med hjälp av de tre kodraderna nedan:

client.connect ()

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

Om du nu går till din kanalsida (som min ovan) kommer du att se att vart och ett av de fem fälten kommer att ha data relaterade till dina sensorer.

Steg 10: Sensordatalogger

Sensordatalogger
Sensordatalogger

Nu när vi vet att med bara några få kodrader är det möjligt att ladda upp data till en IoT -tjänst, låt oss skapa en loop -funktion för att göra det automatiskt med regelbundna intervall (liknande det vi har gjort med "Lokal data ").

Med samma variabel (PUB_TIME_SEC), som deklarerats tidigare, skulle en enkel huvudfunktion för att kontinuerligt fånga data, logga dem på vår kanal vara:

medan det är sant:

temp, hum, extTemp, lum, butSts = colectData () nyttolast = "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)

Observera att endast "nyttolast" måste uppdateras när "ämne" är relaterat till vår kanaluppgifter och kommer inte att ändras.

När du letar efter din ThingSpeak -kanalsida kommer du att observera att data laddas kontinuerligt till varje fält. Du kan täcka LDR, lägga handen på temp/hum -sensorer, trycka på knappen etc. och se hur kanalen automatiskt "loggar" dessa data för framtida analyser.

Vanligtvis, för dataloggning, bör vi försöka använda så mindre ström som möjligt, så vi skulle inte använda lysdioden eller displayen lokalt. Det är också vanligt med ESP -enheter, lägg dem på "djup sömn", där mikroprocessorn kommer att vara på sitt lägsta energiförbrukning tills det är dags att fånga data och skicka dem till IoT -plattformen.

Men när idén väl lär sig här, låt oss också inkludera displayen och lysdioden som vi gjorde tidigare. Om vi gör det kommer vår "logger" -funktion att vara:

while button.value ():

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

Hela microPython -skriptet hittar du här: dataLoggerTS_EXT.py och Jupyter -anteckningsboken som användes för utveckling finns också här: IoT ThingSpeak Data Logger EXT.ipynb.

För att ladda upp skriptet till ESP använder du kommandot på din terminal:

ampy sätta dataLoggerTS.py /main.py

Och tryck på ESP - reset -knappen. Du kommer att få ESP att fånga data och logga dem på ThingSpeak.com tills botten hålls intryckt (vänta tills lysdioden blinkar 3 gånger och OLED släcks).

Steg 11: ThingView -appen

ThingView -appen
ThingView -appen

Data som loggas kan visas direkt på ThingSpeak.com -webbplatsen eller via en APP, till exempel ThingsView!

ThingView är en APP utvecklad av CINETICA, som låter dig visualisera dina ThingSpeak -kanaler på ett enkelt sätt, bara ange kanal -ID och du är redo att gå.

För offentliga kanaler kommer programmet att respektera dina Windows -inställningar: färg, tidsskala, diagramtyp och antal resultat. Den nuvarande versionen stöder rad- och kolumndiagram, spline -diagrammen visas som linjediagram.

För privata kanaler kommer data att visas med standardinställningarna, eftersom det inte går att läsa de privata windows -inställningarna endast med API -nyckeln.

ThingView -appen kan laddas ner för ANDROID och IPHONE.

Steg 12: Slutsats

Slutsats
Slutsats

Som alltid hoppas jag att detta projekt kan hjälpa andra att hitta in i den spännande världen av elektronik!

För mer information och slutkod, besök min GitHub -förråd: IoT_TS_MQTT

För fler projekt, besök min blogg: MJRoBot.org

Hälsningar från södra världen!

Vi ses i min nästa instruerbara!

Tack, Marcelo

Rekommenderad: