Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

ArduFarmBot - Part 2:Remote Station an IoT Implementation

Componenten en benodigdheden

Arduino Nano R3
× 1
Espressief ESP8266 ESP-01
× 1
DHT22-temperatuursensor
× 1
ky18
× 1
hydrometer
× 1
Relais (algemeen)
× 2
lcd 4X20
× 1
SparkFun Drukknopschakelaar 12 mm
× 3
LED (generiek)
× 3

Apps en online services

ThingSpeak-API

Over dit project

Deze tutorial is een vervolg op ArduFarmBot:Controlling a Tomato Home Farm met Arduino en IoT

In het eerste deel maken we een lokaal controlestation dat informatie van een tomatenplantage vastlegt, zoals temperatuur, relatieve luchtvochtigheid, lichtsterkte en bodemvochtigheid. Op basis van die gegevens besliste de ArduFarmBot automatisch hoeveel (en wanneer) de plantage warmte en water moest krijgen. Het lokale station dat op deel 1 werd ontwikkeld, maakte ook handmatige tussenkomst van een operator mogelijk om de waterpomp en de elektrische lamp te bedienen. In dit deel 2 zullen we een IoT-aanpak implementeren waarbij deze "handmatige interventie" ook op afstand via internet mogelijk zal zijn. Het blokschema laat zien hoe we dit gaan doen.

Houd er rekening mee dat de vastgelegde gegevens worden verzonden naar een "Cloud Storage-service" (in ons geval Thinkspeak.com). Ook een speciale website, de "Remote Control-pagina", zal deze gegevens in bijna realtime controleren en weergeven. Op deze webpagina kunnen de pomp en de lamp ook op afstand worden geactiveerd.

Stap 1:Stuklijst

  • Arduino Nano - ($7,50)
  • Temperatuur- en vochtigheidssensor DHT22 of DHT11 - ($3,66)
  • Lichtsterktesensor - AD-018 Fotoweerstandsmodule. of een equivalent - ($ 0,71)
  • 2X Bodemvochtsensor - ($ 1,99) (Optioneel, kan zelfgemaakt zijn)
  • LCD I2C 20X4 ($13,99)
  • LED's (1X) ($0,20)
  • Esp8266 Seriële Wifi Draadloze Transceiver Module Esp-01 - ($5.96)
  • Actieve zoemer - Ky-12 of gelijkwaardig ($ 0,60)
  • 2 X 5v relaismodule ($11,60)
  • Draden springen (S1.00)
  • 10KOhms weerstand - ($0,03)
  • 2.2K Ohm weerstand - ($0,03)
  • 1,0K Ohm weerstand - ($0,03)
  • 220 Ohm weerstand - ($0,03)
  • Arduino Nano Shield ("Funduino") - ($ 7,28)
  • Membraantoetsenbord (4 toetsen) - ($ 6,65)
  • Plastic doos

Stap 2:De hardware voltooien

Uitgaande van het Local Station dat in deel 1 is ontwikkeld, is de enige extra HW die nodig is de ESP8266. Het bovenstaande blokschema toont alle PIN-verbindingen van Arduino en hoofdcomponenten. De enige zorg die u moet hebben, heeft te maken met het spanningsniveau. De ESP8266 werkt met 3,3V, dus de Rx-pin die niet rechtstreeks op Nano Tx-pin (D3) moet worden aangesloten. Er moet een spanningsniveau worden gebruikt. In ons geval zullen we een spanningsdeler bouwen die als spanningsniveau-omzetter kan worden gebruikt. De bovenstaande diagrammen laten in meer detail zien hoe u de ESP8266 aansluit. Als je meer wilt weten over de ESP8266, bekijk dan mijn tutorials:

  • De ESP8266 Deel 3 - Arduino-LED's op afstand activeren
  • De ESP8266 deel 1 - seriële wifi-module voor Arduino
  • De ESP8266 deel 2 - Arduino-webserver

Merk op dat we de ESP8266 gebruiken die is aangesloten op Nano Pin 2 (Tx) en Pin 3 (Rx), met behulp van de bibliotheek SoftSerial. Als u die digitale pinnen wilt "bevrijden", kunt u afwisselend de Nano Serial-pinnen 0 en 1 gebruiken. Onthoud alleen dat u ze moet loskoppelen wanneer u de code naar Nano uploadt.

OPMERKING:Als u de BUZZER wilt aansluiten, moet u dit doen op pin D17 (hetzelfde als pin A3). Het is goed om een ​​geluid te hebben als je een communicatiefout hebt. Ik heb het tijdens de testfase gebruikt, weggelaten bij het eindproject (de hw, maar daar is de code op voorbereid). Het is aan jou of je het hebt of niet.

U kunt de onderstaande code gebruiken om uw ESP8266 te testen en/of in te stellen:

FC9DBPKIT682FY7.ino

Stap 3:De ESP8266-verbinding

Om de ArduFarmBot met internet te verbinden, gebruiken we de ESP8266, een eenvoudige, goedkope en gemakkelijk te programmeren module voor IoT-projecten. Zodra de module is geïnstalleerd, is het eerste wat u moet doen een "Reset" toepassen op de CH-PD-pin.

/******************************************* ********** Reset functie om communicatie te accepteren*********************************** ********************/void reset8266(void){ pinMode(CH_PD, OUTPUT); digitalWrite (CH_PD, LAAG); vertraging (300); digitalWrite(CH_PD, HOOG); Serial.print ("8266 reset OK"); lcd.wissen(); lcd.println("8266 reset OK ");}  

Laten we na het resetten verbinding maken met uw lokale netwerk met uw inloggegevens (wijzig in de code:GEBRUIKERSNAAM en WACHTWOORD) en om de module te starten als een "STA:Station Mode" (CWMODE =1):

/******************************************* ********* WiFi aansluiten **************************************** ***********/void connectWiFi(void){ sendData("AT+RST\r\n", 2000, DEBUG); // reset sendData("AT+CWJAP=\"USERNAME\",\"PASSWORD\"\r\n", 2000, DEBUG); // Verbind netwerkvertraging (3000); sendData("AT+CWMODE=1\r\n", 1000, DEBUG); sendData("AT+CIFSR\r\n", 1000, DEBUG); // Toon IP-adres lcd.clear(); lcd.print("8266 Verbonden"); Serial.println("8266 Verbonden");} 

Om gegevens naar ESP8266 te sturen, moet de functie sendData() werd gebruikt:

/******************************************* ********** Stuur AT-commando's naar module*********************************** ****************/String sendData(String-opdracht, const int time-out, boolean debug){ String response =""; esp8266.print(opdracht); lange int-tijd =millis(); while ( ((time + time-out)> millis()) { while (esp8266.available()) { // De esp heeft data, dus toon de output naar het seriële venster char c =esp8266.read(); // lees het volgende teken. reactie +=c; } } if (debug) { Serial.print(respons); } antwoord terug;} 

De bovenstaande functies worden aangeroepen tijdens de "Setup Phase" van onze Code. Als alles correct is gedaan, zou u bij Serial Monitor soortgelijke berichten als hierboven moeten zien.

Stap 4:Cloud Storage-gegevens:de ThinkSpeak.com

Alle gegevens die door de ArduFarmBot worden vastgelegd, worden geüpload naar de cloud, met behulp van de gratis service van "ThinkSpeak.com".

Bij de functie "Loop()" (nadat we gegevens hebben vastgelegd met readSensors() ), zullen we een specifieke functie aanroepen om de vastgelegde gegevens te uploaden:updateDataThingSpeak();

/******************************************* ********** Verzend gegevens naar thingspeak.com*********************************** ****************/void updateDataThingSpeak(void){ startThingSpeakCmd (); cmd =bericht; cmd +="&field1="; //veld 1 voor DHT-temperatuur cmd +=tempDHT; cmd +="&field2="; //veld 2 voor DHT-vochtigheid cmd +=humDHT; cmd +="&field3="; //veld 3 voor LDR-helderheid cmd +=lumen; cmd +="&field4="; //veld 4 voor gegevens over bodemvocht cmd +=bodemvocht; cmd +="&field5="; //veld 5 voor PUMP Status cmd +=pumpStatus; cmd +="&field6="; //veld 6 voor LAMP Status cmd +=lampStatus; cmd +="\r\n"; sendThingSpeakCmd();}  

Om die gegevens te verzenden, moet u eerst de communicatie met ThingSpeak starten. We zullen dit doen met behulp van de finction:startThingSpeakCmd ();

/******************************************* ********** Start de communicatie met ThingSpeak.com*********************************** ****************/void startThingSpeakCmd(void){ cmd ="AT+CIPSTART=\"TCP\",\""; cmd +=IP; cmd +=" \",80"; esp8266.println(cmd); vertraging (2000); if(esp8266.find("Fout")) { Serial.println("ESP8266 START FOUT"); opbrengst; } Serial.println ("Thinkspeak Comm Started"); cmd ="";} 

Zodra het kanaal is geopend met ThingSpeak en de "cmd"-string is samengesteld met de gegevens, is het tijd om alles naar het corresponderende kanaal op ThingSpeak te uploaden met behulp van de functie:sendThingSpeakCmd();

/******************************************* ******** * Update kanaal ThingSpeak.com*********************************** ****************/String sendThingSpeakCmd(void){ esp8266.print("AT+CIPSEND="); esp8266.println(cmd.length()); if(esp8266.find(">")){ esp8266.print(cmd); Serieel.println(""); Serieel.println(""); Serieel.println(cmd); vertraging (500); String messageBody =""; while (esp8266.available()) { String line =esp8266.readStringUntil('\n'); if (line.length() ==1) {//werkelijke inhoud begint na een lege regel (die lengte heeft 1) messageBody =esp8266.readStringUntil('\n'); Serial.print("Bericht ontvangen:"); Serial.println(messageBody); } } bericht terugBody; } else{ esp8266.println("AT+CIPCLOSE"); Serial.println ("ESP8266 CIPSEND-FOUT:OPNIEUW VERZENDEN"); //Opnieuw verzenden... error=1; retourneer "fout"; }} 

De bovenstaande functies zijn gebaseerd op een geweldige en gedetailleerde tutorial ontwikkeld door Michalis Vasilakis. Voor meer details, zie zijn tutorial:Arduino IOT:Temperature and Humidity (met ESP8266 WiFi).

De foto toont het ArduFarmBot-kanaal op ThingSpeak.com.

Stap 5:Bediening van de actuatoren vanaf het web

Op dit moment zijn we alle verzamelde data aan het uploaden en opslaan in de cloud. Dit is erg goed en handig voor monitoring op afstand, maar wat gebeurt er als we op basis van die gegevens ook de pomp of de lamp willen inschakelen, onafhankelijk van het lokale automatische programma? Om dat te doen, moeten we ook gegevens uit de cloud "downloaden" en de controller opdracht geven om op basis van die opdrachten te handelen.

We zullen specifieke velden maken op ons ThinkSpeak-kanaal om de actuatoren te bedienen:

Veld 7:

  • Data =1 ==> POMP moet AAN zijn
  • Data =0 ==> POMP moet UIT staan

Veld 8:

  • Data =1 ==> LAMP moet AAN zijn
  • Data =0 ==> LAMP moet UIT zijn

OK, maar hoe stel je die velden rechtstreeks in ThingSpeak in? We kunnen het doen, bijvoorbeeld door een "PlugIn" rechtstreeks bij ThinksPeak te schrijven, of we kunnen een externe website gebruiken om het te doen (dit is onze keuze). Hoe dan ook, in beide gevallen zou je een commando moeten gebruiken als:

api.thingspeak.com/update?key=YOUR_WRITE_KEY&field7=1 

Met het bovenstaande commando (en met behulp van de Write Key van je kanaal), schrijf je bijvoorbeeld "1" op veld 7, wat betekent dat de PUMP moet worden ingeschakeld. Je kunt het eenvoudig testen door de bovenstaande opdrachtregel in je browser te schrijven, het corresponderende veld op je kanaal zal worden gewijzigd. Als terugkeer toont de browser een witte pagina met een enkel nummer in de linkerbovenhoek, overeenkomend met de sequentiële gegevensinvoer in uw kanaal.

50% van het werk is gedaan, nu moet je dit "commando" (gegevens op het veld) lezen op het lokale ArduFarmBot-station.

De opdracht om dit te doen wordt hieronder weergegeven. Het krijgt de laatste gegevens die in het specifieke veld zijn geschreven (dat zal in ons geval een "opdracht" zijn.

api.thingspeak.com/channels/CHANNEL_ID/fields/7/last 

Op dezelfde manier als voorheen, kunt u de opdrachtregel testen met uw webbrowser. In dit geval toont de browser u de gegevens over dat specifieke veld. Zie de foto hierboven.

Keer terug naar "aarde", laten we een functie schrijven die dit "laatste veld" zal lezen:

/******************************************* ********** Lees gegevens uit veld7 van thingspeak.com ******************************* ****************/int readLastDataField7(){ startThingSpeakCmd (); // "GET /channels/CHANNEL_ID/fields/7/last"; cmd =msgReadLastDataField7; cmd +="\r\n"; String messageDown =sendThingSpeakCmd(); Serial.print("Opdracht ontvangen:"); Serial.println(messageDown[7]); int commando =messageDown[7]-48; return commando;} 

De bovenstaande functie retourneert de gegevens in veld 7 ("1" of "0"). Een soortgelijke functie moet worden geschreven voor veld 8.

Zodra we de inhoud van beide velden hebben, zouden we ze moeten gebruiken voor een functie die de actuatoren op dezelfde manier zal aansturen als met de "handmatige commandofunctie":

/******************************************* ********** Ontvang opdrachten van thingSpeak.com*********************************** ****************/void ReceiveCommands(){field7Data =readLastDataField7(); if (field7Data ==1) { digitalWrite (PUMP_PIN, HOOG); pompstatus =1; toonDataLCD(); } if (field7Data ==0) { digitalWrite (PUMP_PIN, LAAG); pompstatus =0; toonDataLCD(); } vertraging (500); field8Data =readLastDataField8(); if (field8Data ==1) { digitalWrite (LAMP_PIN, HOOG); lampstatus =1; toonDataLCD(); } if (field8Data ==0) { digitalWrite (LAMP_PIN, LAAG); lampstatus =0; toonDataLCD(); } vertraging (500); } 

Dus vanaf nu kunt u de opdrachtregel in uw browser gebruiken om de pomp en de lamp op afstand aan/uit te zetten. De bovenstaande foto laat zien hoe de ontvangen opdracht op uw seriële monitor zal verschijnen.

Een andere belangrijke overweging is de "coördinatie" tussen lokale en remote commando's. We moeten de readLocalCmd() functie . wijzigen om ook de Thinkspeak Field 7 en 8 respectievelijk bij te werken met pomp- en lampstatus (op hun correspondent "IF-statement". Zie de volledige code aan het einde van deze tutorial):

field7Data =pumpStatus;field8Data =lampStatus; 

Nu zijn "filed7Data" en "field8Data" gesynchroniseerd met de webpagina-opdrachten en ook met lokale opdrachtacties wanneer u op een knop drukt. Laten we dus de aplyCmd() . updaten functie, dat is degene die verantwoordelijk is voor het in-/uitschakelen van de actuatoren:

/******************************************* ********** Ontvang commando's en handel op actuatoren*********************************** ****************/void aplyCmd(){ if (field7Data ==1) digitalWrite(PUMP_PIN, HIGH); if (field7Data ==0) digitalWrite (PUMP_PIN, LAAG); if (field8Data ==1) digitalWrite (LAMP_PIN, HOOG); if (field8Data ==0) digitalWrite(LAMP_PIN, LOW);} 

Wanneer u uw tests start, zult u zich realiseren dat elk commando dat u handmatig op lokaal of via internet uitvoert, zal worden overwonnen door de automatische acties die worden gedefinieerd door de functie autoControlPlantation() ; Op dit punt moet u overwegen wie de "baas" zal zijn, die het laatste woord heeft! In ons geval zullen we het volgende definiëren:

  • Elke luscyclus, dat het bijna "altijd" is, zullen we kijken of er op een knop wordt gedrukt
  • Ongeveer elke minuut zouden we een "pooling" moeten doen bij ThingSpeak en kijken of we daar een bestelling hebben ontvangen.
  • Ongeveer elke 10 minuten zullen we de sensoren lezen, de gegevens op ThingSpeak bijwerken en, belangrijker nog, de automatische acties ondernemen. Die acties worden uitgevoerd onafhankelijk van wat handmatig is geselecteerd en zal worden behouden.

U kunt het veranderen, zoals u dat wilt. Dat is het goede aan het gebruik van een programmeerbare processor om dingen te besturen!

Er zullen nu dus 2 timers worden gebruikt, een voor het bundelen van de commando's op afstand en een andere voor het uitlezen van de sensoren (dezelfde die we eerder hebben gebruikt:

lange sampleTimingSeconds =75; // ==> ******** Definieer de sampletijd in seconden om sensoren te lezen *********int reverseElapsedTimeSeconds =0;long startTiming =0;long elapsedTime =0;long poolingRemoteCmdSeconds =20; // ==> ******** Definieer de pooling-tijd in seconden voor nieuwe ThingSpeak-commando's ********* lange startRemoteCmdTiming =0; lang verstrekenRemoteCmdTime =0; 

Dus de loop() functie moet nu worden herschreven zoals hieronder:

void loop() { elapsedRemoteCmdTime =millis()-startRemoteCmdTiming; // Start timer voor het poolen van externe commando's elapsedTime =millis()-startTiming; // Start timer voor metingen reverseElapsedTimeSeconds =ronde (sampleTimingSeconds - elapsedTime/1000); leesLocalCmd(); //Lees de status van de lokale knop showDataLCD (); if (elapsedRemoteCmdTime> (poolingRemoteCmdSeconds*1000)) {ontvangstCommands(); updateDataThingSpeak(); startRemoteCmdTiming =millis(); } if (elapsedTime> (sampleTimingSeconds*1000)) { readSensors(); autoControlPlantation(); updateDataThingSpeak(); startTiming =millis(); }} 

Stap 6:Een speciale webpagina implementeren

Op dit moment is onze ArduFarmBot operationeel en kan deze vanaf het web worden bestuurd. U kunt de gegevens op de Thinkspeak-site controleren en ook opdrachten verzenden met een browser, maar deze "weboplossing" kan natuurlijk niet als een "elegante" worden beschouwd! De beste manier om een ​​volledige IoT-oplossing te implementeren, is door een complete webpagina te ontwikkelen die alle gegevens weergeeft, ook met knoppen om de actuatoren te activeren.

Ik kies voor de Byethost, een gratis webhost, heel gemakkelijk en eenvoudig om uw pagina's te beheren. Ik heb ook van de gelegenheid gebruik gemaakt om op dit project toe te passen wat ik heb geleerd tijdens een fantastische online specialisatie aan Coursera/University of Michigan:leer websites te ontwerpen en te maken (bouw een responsieve en toegankelijke webportfolio met HTML5, CSS3 en JavaScript ).

Ik zal niet in detail treden hoe een dergelijke pagina te ontwikkelen, als dit niet het centrale doel van deze tutorial is, maar ik zal hier de HTML-, CSS- en JavaScript-broncodes opnemen. En zodra iemand interesse heeft in hoe ik de resultaten heb gekregen, kunnen we dit terzijde bespreken met behulp van het opmerkingenbord aan het einde van het project.

Het is belangrijk om te benadrukken dat deze pagina niet rechtstreeks werkt met het ArduFarmBot Local Control Station. Wat het echt doet, is interactie met het ThinkSpeak-kanaal zoals hieronder:

  • Sensorgegevens lezen op velden 1, 2, 3, 4
  • Actorstatus aflezen op velden 5 en 6
  • Gegevens schrijven op velden 7 en 8
  • Lokale weergegevens van Yahoo-services lezen

Het item 4 hierboven is niet echt cruciaal voor het project, maar er zijn altijd aanvullende gegevens beschikbaar voor het geval u op afstand acties wilt ondernemen, onafhankelijk van wat er lokaal gebeurt met uw tomatenplantage. Een andere overweging is dat je die gegevens bijvoorbeeld op een ander ThingSpeak-kanaal kunt opslaan en naar je Arduino kunt downloaden, met weergegevens op een lokaal LCD-scherm (ik heb dit ontwikkeld op een ander cool project dat prima werkte! Ik laat het hier achter als een suggestie om jij).

FQOK9ENIT653YX5.zip

Stap 7:Keer terug naar de hersenen. Een sensor-actuatormatrixbenadering:

In het eerste deel van dit project hebben we enkele voorlopige overwegingen gedefinieerd over hoe de actuatoren zouden moeten werken, afhankelijk van de uitlezing van de sensoren. We hebben alleen een eenvoudige keuze gemaakt, maar wat gebeurt er als we een complexere situatie hebben? Verschillende voorwaarden? Wat we gaan ontwikkelen is een "Sensor - Actuator matrixbenadering".

Op een matrix werden voor elke sensor gedefinieerd, de toestand ervan en hoe de output van actuatoren zou moeten zijn. Het resultaat is te zien in het onderstaande Excel-spreadsheet. Op het Excel-bestand staan ​​twee spreadsheets. De tabel met een filter en een versie waarin u meerdere sensorcondities kunt selecteren en kunt zien hoe de actuatoren werken door deze selectie.

Zodra de Matrix is ​​gedefinieerd, moeten we deze naar onze code vertalen. Een array van 18 regels en 10 kolommen is gemaakt om de voorwaarden van Sensor-Actuator Matrix te "kopiëren":

 // +---SOIL----+-LIGHT-+---TEMP---+---ACTUAT----+ // SL SM SH LL LH TL TM TH Pomp Lampboolean SDf [18] [10] ={{ 1, 0, 0, 0, 1, 0, 0, 1, 1, 0 }, { 1, 0, 0, 0, 1, 0, 1, 0, 1 , 0 }, { 1, 0, 0, 0, 1, 1, 0, 0, 1, 1 }, { 1, 0, 0, 1, 0, 0, 0, 1, 1, 0 }, { 1 , 0, 0, 1, 0, 0, 1, 0, 1, 0 }, { 1, 0, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 1, 0, 0 , 1, 0, 0, 1, 0, 0 }, { 0, 1, 0, 0, 1, 0, 1, 0, 0, 0 }, { 0, 1, 0, 0, 1, 1, 0 , 0, 0, 1 }, { 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 }, { 0, 1, 0, 1, 0, 0, 1, 0, 0, 1 }, { 0, 1, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 }, { 0, 0 , 1, 0, 1, 0, 1, 0, 0, 0 }, { 0, 0, 1, 0, 1, 1, 0, 0, 0, 1 }, { 0, 0, 1, 1, 0 , 0, 0, 1, 0, 0 }, { 0, 0, 1, 1, 0, 0, 1, 0, 0, 1 }, { 0, 0, 1, 1, 0, 1, 0, 0 , 0, 1 }, }; 

Om met de Matrix te werken, maken we een functie defSensorStatus () . Deze functie test voor elke regel of de voorwaarde van de 8 eerste kolommen WAAR is. Zo ja, dan wordt de voorwaarde van de laatste 2 kolommen uitgevoerd.

Bijvoorbeeld:

if (1 en 0 en 0 en 0 en 1 en 0 en 0 en 1) { pumpStatus =1; lampStatus =0}else if (1 en 0 en 0 en 0 en 1 en 0 en 1 en 0) { pumpStatus =1; lampStatus =0} 

enzovoort.

Binnen de bovenstaande functie wordt een andere array gemaakt met de status van elke sensormeting:

booleaanse snsSts[8]={0, 0, 0, 0, 0, 0, 0, 0}; // SL, SM, SH, LL, LH, TL, TM, TH 

Deze variabele array wordt ook gebruikt voor het LOG-register.

F2HWXBYITA8WIN1.xlsx

Stap 8:Code-optimalisatie

Tijdens het ontwikkelingsproces van de ArduFarmBot realiseren we ons dat er enkele wijzigingen in de oorspronkelijke specificatie moeten worden aangebracht:

Weergave:

Het LCD-scherm moet standaard UIT zijn en elke keer dat een sensormeting nodig is, kunnen we het handmatig "AAN" zetten. Deze voorwaarde is geïmplementeerd in de code en de knop "Sensors Read" moet worden gebruikt zoals in de "toggle"-modus om het LCD-scherm op elk moment AAN/UIT te zetten. Zet het scherm AAN of UIT om de sensormetingen bij te werken voor weergave, maar wordt niet gebruikt door ArduFarmBot voor zijn normale functies.

Initiële installatie:

Wanneer de ArduFarmBot is ingeschakeld (of gereset), wordt op het LCD-scherm de "initiële set-up" weergegeven. Om het programma te starten, moet de knop "Sensoren" worden ingedrukt. De getoonde initiële informatie (zie de bovenstaande foto) is:

  • KOUDE temperatuur (d.w.z. 12oC)
  • DROGE Bodemvochtigheid (d.w.z. 30%)
  • NATTE Bodemvochtigheid (d.w.z. 60%)
  • DONKER licht (d.w.z. 40%)
  • P_ON Pomptijd AAN (d.w.z. 10s)
  • SCAN Tijd om sensoren te lezen (d.w.z. 600s)
  • SW_Vertion (d.w.z. 4.1)

Logboek:

Voor auditdoeleinden hebben we een LOG gemaakt met de metingen en bedieningen van onze ArduFarmBot. Bij elke leescyclus, de functie:storeDataLogEEPROM() is geëxecuteerd.

/******************************************* ********** Opslag van loggegevens op Arduino EEPROM ******************************* ****************/void storeDataLogEEPROM(void){ for (int i =0; i<8; i++) { logData =logData + (snsSts[i])<<1; } EEPROM.write (memoAddr, logData); memoAddr++; logData =0; logData =logData + pompStatus; logData =logData <<1; logData =logData + lampStatus; EEPROM.write (memoAddr, logData); EEPROM.write (0, memoAddr+1); logData =0; if ((memoAddr+1) ==1023) memoAddr=1; else memoAddr++;}  

Zoals opgemerkt in de laatste stap, wat zal worden opgeslagen in de Arduino EEPROM is de inhoud, een beetje van de array snsSts[] plus pomp- en lampstatus. Hierboven ziet u het LOG op de seriële monitor.

Alle ArduFarmBot-code is opgesplitst in verschillende bestanden om het gemakkelijker te begrijpen te zijn. Merk op dat er 2 nieuwe bestanden zijn toegevoegd aan dit tweede deel:

  • communicatie.ino (ThingSpeak en ESP8266 specifieke functies)
  • stationCredentials.h (ThingSpeak Channel ID en specifieke toetsen om op het kanaal te schrijven)

Last but not least, toen de code eindigde met een redelijke grootte, besloten we de constante gegevens op te slaan in flash (programma) geheugen in plaats van in SRAM. Daarvoor gebruiken we het PROGMEM-sleutelwoord dat een variabele modifier is. Bijvoorbeeld, in plaats van het volgende te gebruiken:

#define DHTPIN 5 

We gebruikten:

const PROGMEM byte DHTPIN =5; 

Het sleutelwoord PROGMEN vertelt de compiler "zet deze informatie in het flashgeheugen", in plaats van in SRAM, waar het normaal gesproken naartoe zou gaan. U moet ook de bibliotheek avr/pgmspace.h opnemen in het hoofdbestand van uw code.

Een andere goede procedure om het gebruik van SRAM te verminderen, is commentaar geven op (of verwijderen) van alle Serial.Print ()-regels die u tijdens de ontwikkeling hebt gebruikt voor het opsporen van fouten. U zult zich realiseren dat de code die bijvoorbeeld wordt gebruikt om het LOG op Serial Monitor te tonen, wordt becommentarieerd in de onderstaande bestanden.

Hieronder vindt u de volledige ArduFarmBot Arduino-code. Vergeet niet de dummy-gegevens op credentials.h te wijzigen met uw kanaal-ID en schrijfsleutel. Gebruik ook op communication.ino uw echte gebruikersnaam en wachtwoord om de ESP 8266 op internet te verbinden.

FTUT5VIIT67U8ME.ino FWMIPSSIT67U8MG.ino FJPGZNKIT67U8MK.ino FQH3X9VIT67U8NA.ino F15MY4YIT67U8NB.ino FVU64X1IT67U8NC.h FZ057E3IT67U8P5.h

Stap 9:De MJRovai Home Farm

De onderstaande foto's tonen opeenvolgende foto's van ArduFarmBot die mijn eerste tomatenplantage bestuurt.

De onderstaande fotoreeks toont mijn 2e plantage-evolutie van zaadplantage tot het moment om de beste planten te selecteren (ongeveer 45 dagen) en de transplantaties van de beste 6 planten.

Stap 10:Conclusie

Dat is alles Mensen! ...Voor nu!

Zoals altijd hoop ik dat dit project anderen kan helpen hun weg te vinden in de spannende wereld van elektronica, IoT en Robotica!

Binnenkort publiceren we waarschijnlijk het derde en laatste deel van ons project waarvan ik hoop dat het een heel goed recept wordt van een biologische pasta met tomatensaus.

Op bovenstaande foto zie je trouwens de eerste levenszucht op de plantage van Mauricio! En voordat je gaat, neem een ​​kijkje en de nieuwe ArduFarmBot, het boek!, waar ik alle projecten in een vriendelijker formaat inpak:

ArduFarmBot, the Book!

"ArduFarmBot, the book" is also at Amazon.com! You can get it, by clicking hereThe book uses the electronic controller ArduFarmBot as a basis for teaching how to work in both HW and SW, with:

  • LCD and OLED type displays;
  • LEDs and buttons;
  • Activation of pumps and lamps via relays and
  • Sensors such as:DHT22 (temperature and relative air humidity), DS18B20 (soil temperature), YL69 (soil moisture) and LDR (luminosity).

All key stages of the project are documented in detail through explanatory texts, block diagrams, high-resolution color photos, electrical diagrams using Fritzing application, complete codes stored in GitHub and YouTube videos.

Two versions of the electronic controller ArduFarmBot are developed in detail in the book. From capture of data coming from a garden, such as air and soil temperature, relative humidity, soil moisture and luminosity, the ArduFarmBot helps to control when a crop should receive heat and water. Control will happen automatically, locally and remotely via internet. The book is divided into 3 parts. In the first part, the Arduino Nano is the starting point for development of a local version of ArduFarmBot , that can be controlled both, manually and automatically.

In the second part, the book dives into automation design, introducing remote operation through the creation of a webpage. The ESP8266-01 is used for Wi-Fi connection, sending data to an important web service in the field of IoT, the ThingSpeak.com .

In the third part, a second version of ArduFarmBot is developed, introducing the NodeMCU ESP8266-12E , a powerful and versatile IoT device, which replaces both the Arduino Nano and the ESP8266-01 , used in the earlier parts of the book.

In this last part of the book, a new service platform of the IoT universe, the Blynk , is also explored.

Download the book, give it a review and please use the message board here to give us any comment, suggestion or critic!

For more projects, please visit my blog:MJRoBot.org

Saludos from the south of the world!

See you at my next project!

Thank you

Marcelo

Code

  • Codefragment #1
  • Codefragment #2
  • Codefragment #3
  • Codefragment #4
  • Codefragment #5
  • Code snippet #6
  • Code snippet #9
  • Code snippet #10
  • Codefragment #11
  • Code snippet #12
  • Code snippet #13
  • Code snippet #14
  • Code snippet #15
Codefragment #1Platte tekst
/**************************************************** Reset funtion to accept communication****************************************************/void reset8266(void){ pinMode(CH_PD, OUTPUT); digitalWrite(CH_PD, LOW); vertraging (300); digitalWrite(CH_PD, HIGH); Serial.print("8266 reset OK"); lcd.wissen(); lcd.println("8266 reset OK ");}
Codefragment #2Platte tekst
/**************************************************** Connect WiFi****************************************************/void connectWiFi(void){ sendData("AT+RST\r\n", 2000, DEBUG); // reset sendData("AT+CWJAP=\"USERNAME\",\"PASSWORD\"\r\n", 2000, DEBUG); //Connect network delay(3000); sendData("AT+CWMODE=1\r\n", 1000, DEBUG); sendData("AT+CIFSR\r\n", 1000, DEBUG); // Show IP Adress lcd.clear(); lcd.print("8266 Connected"); Serial.println("8266 Connected");}
Codefragment #3Platte tekst
/**************************************************** Send AT commands to module****************************************************/String sendData(String command, const int timeout, boolean debug){ String response =""; esp8266.print(command); long int time =millis(); while ( (time + timeout)> millis()) { while (esp8266.available()) { // The esp has data so display its output to the serial window char c =esp8266.read(); // read the next character. response +=c; } } if (debug) { Serial.print(response); } return response;}
Codefragment #4Platte tekst
/**************************************************** Transmit data to thingspeak.com****************************************************/void updateDataThingSpeak(void){ startThingSpeakCmd (); cmd =msg; cmd +="&field1="; //field 1 for DHT temperature cmd +=tempDHT; cmd +="&field2="; //field 2 for DHT humidity cmd +=humDHT; cmd +="&field3="; //field 3 for LDR luminosity cmd +=lumen; cmd +="&field4="; //field 4 for Soil Moisture data cmd +=soilMoist; cmd +="&field5="; //field 5 for PUMP Status cmd +=pumpStatus; cmd +="&field6="; //field 6 for LAMP Status cmd +=lampStatus; cmd +="\r\n"; sendThingSpeakCmd();}
Codefragment #5Platte tekst
/**************************************************** Start communication with ThingSpeak.com****************************************************/void startThingSpeakCmd(void){ cmd ="AT+CIPSTART=\"TCP\",\""; cmd +=IP; cmd +="\",80"; esp8266.println(cmd); vertraging (2000); if(esp8266.find("Error")) { Serial.println("ESP8266 START ERROR"); opbrengst; } Serial.println("Thinkspeak Comm Started"); cmd ="";}
Code snippet #6Plain text
/*************************************************** * Update channel ThingSpeak.com****************************************************/String sendThingSpeakCmd(void){ esp8266.print("AT+CIPSEND="); esp8266.println(cmd.length()); if(esp8266.find(">")){ esp8266.print(cmd); Serieel.println(""); Serieel.println(""); Serial.println(cmd); vertraging (500); String messageBody =""; while (esp8266.available()) { String line =esp8266.readStringUntil('\n'); if (line.length() ==1) { //actual content starts after empty line (that has length 1) messageBody =esp8266.readStringUntil('\n'); Serial.print("Message received:"); Serial.println(messageBody); } } return messageBody; } else{ esp8266.println("AT+CIPCLOSE"); Serial.println("ESP8266 CIPSEND ERROR:RESENDING"); //Resend... error=1; return "error"; }}
Code snippet #9Plain text
/**************************************************** Read data from field7 of thingspeak.com****************************************************/int readLastDataField7(){ startThingSpeakCmd (); // "GET /channels/CHANNEL_ID/fields/7/last"; cmd =msgReadLastDataField7; cmd +="\r\n"; String messageDown =sendThingSpeakCmd(); Serial.print("Command received:"); Serial.println(messageDown[7]); int command =messageDown[7]-48; return command;}
Code snippet #10Plain text
/**************************************************** Receive Commands from thingSpeak.com****************************************************/void receiveCommands(){ field7Data =readLastDataField7(); if (field7Data ==1) { digitalWrite(PUMP_PIN, HIGH); pumpStatus =1; showDataLCD(); } if (field7Data ==0) { digitalWrite(PUMP_PIN, LOW); pumpStatus =0; showDataLCD(); } delay (500); field8Data =readLastDataField8(); if (field8Data ==1) { digitalWrite(LAMP_PIN, HIGH); lampStatus =1; showDataLCD(); } if (field8Data ==0) { digitalWrite(LAMP_PIN, LOW); lampStatus =0; showDataLCD(); } delay (500); }
Codefragment #11Platte tekst
/**************************************************** Receive Commands and act on actuators****************************************************/void aplyCmd(){ if (field7Data ==1) digitalWrite(PUMP_PIN, HIGH); if (field7Data ==0) digitalWrite(PUMP_PIN, LOW); if (field8Data ==1) digitalWrite(LAMP_PIN, HIGH); if (field8Data ==0) digitalWrite(LAMP_PIN, LOW);}
Code snippet #12Plain text
long sampleTimingSeconds =75; // ==> ******** Define Sample time in seconds to read sensores *********int reverseElapsedTimeSeconds =0;long startTiming =0;long elapsedTime =0;long poolingRemoteCmdSeconds =20; // ==> ******** Define Pooling time in seconds for new ThingSpeak commands *********long startRemoteCmdTiming =0; long elapsedRemoteCmdTime =0;
Code snippet #13Plain text
void loop() { elapsedRemoteCmdTime =millis()-startRemoteCmdTiming; // Start timer for pooling remote commands elapsedTime =millis()-startTiming; // Start timer for measurements reverseElapsedTimeSeconds =round (sampleTimingSeconds - elapsedTime/1000); readLocalCmd(); //Read local button status showDataLCD(); if (elapsedRemoteCmdTime> (poolingRemoteCmdSeconds*1000)) { receiveCommands(); updateDataThingSpeak(); startRemoteCmdTiming =millis(); } if (elapsedTime> (sampleTimingSeconds*1000)) { readSensors(); autoControlPlantation(); updateDataThingSpeak(); startTiming =millis(); }}
Code snippet #14Plain text
 // +---SOIL----+-LIGHT-+---TEMP---+---ACTUAT----+ // SL SM SH LL LH TL TM TH Pump Lampboolean SDf [18] [10] ={{ 1, 0, 0, 0, 1, 0, 0, 1, 1, 0 }, { 1, 0, 0, 0, 1, 0, 1, 0, 1, 0 }, { 1, 0, 0, 0, 1, 1, 0, 0, 1, 1 }, { 1, 0, 0, 1, 0, 0, 0, 1, 1, 0 }, { 1, 0, 0, 1, 0, 0, 1, 0, 1, 0 }, { 1, 0, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 }, { 0, 1, 0, 0, 1, 0, 1, 0, 0, 0 }, { 0, 1, 0, 0, 1, 1, 0, 0, 0, 1 }, { 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 }, { 0, 1, 0, 1, 0, 0, 1, 0, 0, 1 }, { 0, 1, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 1, 0, 1, 0, 0, 0 }, { 0, 0, 1, 0, 1, 1, 0, 0, 0, 1 }, { 0, 0, 1, 1, 0, 0, 0, 1, 0, 0 }, { 0, 0, 1, 1, 0, 0, 1, 0, 0, 1 }, { 0, 0, 1, 1, 0, 1, 0, 0, 0, 1 }, };
Code snippet #15Plain text
/**************************************************** Storage of Log data at Arduino EEPROM****************************************************/void storeDataLogEEPROM(void){ for (int i =0; i<8; i++) { logData =logData + (snsSts[i])<<1; } EEPROM.write (memoAddr, logData); memoAddr++; logData =0; logData =logData + pumpStatus; logData =logData <<1; logData =logData + lampStatus; EEPROM.write (memoAddr, logData); EEPROM.write (0, memoAddr+1); logData =0; if ((memoAddr+1) ==1023) memoAddr=1; else memoAddr++;} 
ArduFarmBot GitHub
https://github.com/Mjrovai/ArduFarmBot

Schema's

ardufarmbot_qpNcBDX6Jr.fzz

Productieproces

  1. IoT-implementatietrends
  2. 6-Shooter:Arduino-drankmengstation
  3. Multitemperatuursensor
  4. MotionSense
  5. 3D-printer brandveiligheid
  6. IoT-meter met Arduino, Yaler en IFTTT
  7. Arduino afstotende elektromagnetische levitatie
  8. Grijperbot met afstandsbediening
  9. Arduino aangedreven weerballon datalogger
  10. $10 draagbaar Arduino-weerstation (AWS)
  11. CoroFence - Thermische Detector🖖