Skapa din första IoT Ethernet-enhet. Del 5: Sakernas Internet, Home Automation (5 / 8 steg)
Steg 5: Programvara översikt - del B
Ingressen
För att framgångsrikt sammanställa detta Källkod behöver du följande extra bibliotek (det finns några);
PubSubClient.h
- Av: Nick O'Leary
- Syfte: Gör det möjligt för enheten att publicera eller prenumerera MQTT ämnen med en viss mäklare
- Från: https://github.com/knolleary/pubsubclient
DHT.h
- Av: Adafruit
- Syfte: Library for DHT temperatur/hygrometergivare
- Från: https://github.com/adafruit/DHT-sensor-library
Bounce2.h
- Av: Thomas O Fredericks
- Syfte: Input switch de studsa i programvara
- Från: https://github.com/thomasfredericks/Bounce2
LiquidCrystal_I2C_PCF8574.h
- Av: Steve Quinn
- Syfte: Bibliotek för att kontrollera, läsa från och skriva till LCD visas
- Från:
Adafruit_GFX.h
- Av: Adafruit
- Syfte: Utökad grafik bibliotek för användning med ILI9341
- Från: https://github.com/adafruit/Adafruit-GFX-Library
Adafruit_ILI9341.h
- Av: Adafruit
- Syfte: Biblioteket för att skriva till ILI9341 TFT-skärm
- Från: https://github.com/adafruit/Adafruit_ILI9431
DS1307.h
- Av: Paul Stoffregen
- Syfte: Bibliotek drivrutin för realtids klocka chip DS1307Z +
- Från: https://github.com/PaulStoffregen/DS1307RTC
Time.h
- Av: Paul Stoffregen
- Syfte: Bibliotek för användning med DS1307Z RTC att manipulera tiden
- Från: https://github.com/PaulStoffregen/Time
Adafruit_BMP085.h
- Av: Adafruit
- Syfte: Bibliotek för att tillgång till barometertrycket sensor
- Från: https://github.com/adafruit/Adafruit-BMP085-Library
Fullständig information också ges i källkoden nedan.
Du behöver också veta;
- IP-adressen på din MQTT mäklare (i IPv4 format AAA. BBB. CCC. DDD): IP-adress server()
- En gratis IP-adressen för enheten IoT om du inte vill använda den 'USE_DHCP_FOR_IP_ADDR' #define i koden.
Kodöversikt
Vid start ansluter programvaran till Ethernetnätverket med de medskickade anslutningsinformation som ovan.
När du är ansluten till ett LAN publicerar IoT enheten dess detaljer i följande MQTT ämnen;
- /EthernetDevice/SwVerConfirm: Detta innehåller en länkad sträng, kommaavgränsad, bildas av generiska enhetsnamnet, unika MAC-adressen för enheten och namnet på filen Arduino används för att programmera enheten. i detta fall "WIZNet5100,de:ad:be:ef:fe:ed,MQTTEthernetAll6_5.ino".
- /EthernetDevice/Temp1Status: Vid första anslutningen till nätverket publicerar detta ämne ett "Connected" meddelande till mäklaren. Därefter är det brukade publicera den lokala temperaturen i grad Celsius korrekt med 2 decimaler. Uppdateringar utfärdas endast om det finns en förändring i temperatur för att förhindra att denna Sakernas Internet "överbelastning" nätverket.
- /EthernetDevice/Humd1Status: Liknande till Temp1Status, men är en representation av de lokala luftfuktigheten skalas i procent.
- /EthernetDevice/HeatInd1Status: Liknar både Temp1Status och Humd1Status, men i detta ögonblick programvaran beräknar de nya värme indexet från temperatur och luftfuktighetsvärdena.
- /EthernetDevice/Barometric1Status: Liknande till Temp1Status, Humd1Status och HeatInd1Status, men är en representation av lokala barometertrycket nivå mäts i hPa eller mBar.
Det sedan prenumererar på följande MQTT ämnen;
- /EthernetDevice/SwVerCommand: När anmälan tas emot på detta ämne svarar enheten med en /EthernetDevice/SwVerConfirm publikation. Detta är en sändning svar. dvs. alla enheter kunde svara.
- /EthernetDevice/de: ad: vara: ef: fe: ed / SwVerCommand : när anmälan har mottagits av detta ämne enheten svarar med en /EthernetDevice/SwVerConfirm publikation. Detta är en riktad svar. dvs. endast denna enhet kommer att svara.
- /EthernetDevice/Led1Command: Produktionen ligger när anmälan har mottagits av detta ämne enheten ledde. Nyttolast '1' = Led på nyttolast "0" = Led av. När ett kommando har actioned kommer att enheten svara genom att publicera Led status via /EthernetDevice/Led1Confirm ämnet "På" eller "Off"
- /EthernetDevice/Button1Status : när anmälan av publikation tas emot på detta ämne enheten kommer att svara genom att publicera den aktuella knappen statusen via ett /EthernetDeviceButton1Command ämne "Tryckt" eller "Släppas". På detta sätt kan knappen status kontrolleras vid varje given tidpunkt. Notera även om tillståndet knappen ändras självständigt, via en knapptryckning då enheten automatiskt publicerar ett /EthernetDevice/Button1Command ämne.
- /EthernetDevice/SetTime: När anmälan av en publikation tas emot på detta ämne uppdaterar enheten systemklockan (DS1307Z +) med detta värde. Nyttolasten måste vara av formuläret "Hh: mm" (24 HR klocka).
- /EthernetDevice/SetDate: När anmälan av en publikation tas emot på detta ämne uppdaterar enheten systemklockan (DS1307Z +) med detta datumvärde. Nyttolasten måste vara i form "DD/MM/ÅÅ", UK format men kan lätt ändras.
- /EthernetDevice/SetLoggingCommand: När anmälan av en publikation tas emot på detta ämne uppdaterar enheten loggning tillståndsdatorn. En nyttolast på 0 = nära nuvarande logfile, 1 = öppen/starta ny loggfil. En ny loggfil namn bildas genom att sammanfoga DD/MM med hh: mm att bilda "DDMMHHMM.csv". På detta sätt bildas ett unikt filnamn på varje öppning. Som Arduino SD kort biblioteket har gamla DOS 8.3 filnamn konventionen begränsning, innebär detta att en period av minst en minut innan nya filen öppningar skall förlöpa. Annars är det möjligt att skriva över en tidigare öppnad fil (inom samma minuten). Inte en stor fråga men en värt att påpeka.
- /EthernetDevice/SetLoggingPeriodCommand: När anmälan av en publikation tas emot på detta ämne enheten kommer att uppdatera den system variabeln iLoggingPeriodInMinutes, som används för att styra perioden på vilka aktuella lokala Temp/fukt/BarometricPressure, Remote Temp/luftfuktighet loggas till SD-kort. Nyttolasten måste vara av formuläret "Hh: mm" (24 HR klocka).
- /EthernetDevice/GetLoggingStatus: När anmälan av en publikation tas emot på detta ämne enheten kommer att svara genom att publicera den aktuella statusen för loggning styra variabla currentLoggingStatus via /EthernetDevice/GetLoggingStatusConfirm ämne. Värdet "0" = logga inaktiva (eLoggingInactive) och '1' = loggning aktiverad (eLoggingActive). Denna räknas typ har specifikt vägda värden 0 och 1 för eLoggingInactive och eLoggingActive respektive, av helt enkelt lägga till numeriskt kompensera för Ascii '0' det returnerade värdet kommer att vara en '0' eller ' 1'.
- /EthernetDevice/GetLoggingPeriodStatus: När anmälan av en publikation tas emot på detta ämne att enheten svara genom att publicera den aktuella loggning perioden "Hh: mm" (24 HR klocka) format via ett /EthernetDevice/GetLogginPeriodConfirm ämne.
- /WiFiDevice/Temp1Status : liknar /EthernetDevice/Temp1Status , men innehåller IoT WiFi fjärrenheten temperatur
- /WiFiDevice/Humd1Status : som ovan i /EthernetDevice/Humd1Status men för luftfuktigheten på remote IoT WiFi-enhet.
När klar programvaran nu droppar in i en loop som övervakar mäklare anslutningar tillsammans med eventuella förändringar i knappen status logfile status, loggning periodens förändringar, loggning status uppdateringar (via MQTT ämne publikationer eller via en lokal knapptryckning att stänga eller öppna loggningsfilen), lokal temperatur eller luftfuktighet eller nya publikationer av avlägsen temperatur och luftfuktighet. En sammanfattning av lokala barometriskt tryck, temperatur och luftfuktighet förändringar både lokala och fjärranslutna, tillsammans med nuvarande CSV filnamn, datum och tid visas i systemet LCD i realtid och upprepas tillsammans med uppritade trender på TFT-systemet.
Hantering logga data till fil
Loggning av alla lokala temperatur, luftfuktighet, barometertryck och avlägsen temperatur, fuktighet görs i .csv form (kommaseparerade variabel) Detta är att möjliggöra direkt import till Microsoft Excel (TM) så att det blir relativt enkelt att skapa fina grafer för att visualisera de registrerade uppgifterna.
Loggningen styrs via användning av en "programvara stat maskin" som registrerar de olika staterna att loggning kan ockupera (dessa återspeglar räknas typ eLoggingStatusType eLoggingInactive, eLoggingActive, eLoggingInitialise och eLoggingFault). Ett diagram av denna stat maskin ingår ovan. De blå cirklarna är de olika staterna och linjer eller "övergångar" mellan dem Visa någon legitim post eller avsluta till eller från dessa stater. Texten ovanför varje övergång visar tillståndet för att flytta mellan staterna och texten under den övergång visar alla åtgärder som krävs för att flytta mellan stater.
Ändringar av loggning uppnås genom att ange variabel newLoggingStatus till staten av val och sedan anropa funktionen updateLogging() . Som kallas automatiskt på varje pass av den huvudsakliga loop().
Statliga maskin logiken i funktionen updateLogging() hand tar om den nödvändiga statliga övergångar och åtgärder som uppdaterar TFT- och LCD-skärmarna för byte av filnamn eller clearing loggfilnamnet om loggning avslutas.
Hantering av skärmen rullning
Skärmen rullning är ett intressant ämne så jag tänkte jag skulle lägga till några kommentarer om hur jag uppnått det.
Från andra diagrammet ovan har jag skildras en typisk serie av skärmen tomter från bilder 1... 5. här kan du se de data trend linje (gul) framsteg från vänster till höger på skärmen tills skärmen tomt 7 nås och vi har slut på minne för att spara de 7: e data Rita punkt. Enkel vi kan göra en lite längre matris som du säger. Sedan bara rita den nya punkten. Väl inte kan vi bara rita den nya punkten som det kommer att vara av visningen längst till höger som i skärmen 6. En lösning på detta skulle vara att använda huvudet och svans pekare (märkt här som H och T), sedan bara rensa skärmen och åter Rita alla punkter mellan svans och huvud. Det skulle fungera för att bläddra höger till vänster i skärmen tomt 7. Men det finns en annan grundläggande fråga med detta tillvägagångssätt, om inte vi besitter en Turingmaskin (https://en.wikipedia.org/wiki/Turing_machine) vi kan inte fortsätta att lägga till vår matris på obestämd tid. Vi behöver en mer effektiv algoritm.
Lösningen är att flytta huvudet (eller svans) pekaren tillbaka rundan till början av vår matris att lagra nästa Rita en gång det "faller bort slutet" i matrisen. På detta sätt kan en databuffert för fast storlek användas. Skärmen uppdateras sedan på exakt samma sätt som beskrivs ovan. Faktiskt den plottning görs från H-1 och T-1, men detta är en liten detalj. Se skärmen tomter 8 och 9.
I praktiken har vi skapat en "cirkulär" buffert från en "linjär". Se bild tre ovan.
Detta är exakt den algoritm som jag använde i funktionen updateTrendScreen() för att få skärmen för att bläddra från höger till vänster.
Naturligtvis jag lagt några tweaks för att optimera uppdatering och göra det flöde lite bättre, men dess i huvudsak samma.
Jag lämnade ut en liten kosmetisk optimering, du kan se det?