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

IoT Made Easy met UNO, ESP-01, ThingSpeak &MIT App Inventor

Componenten en benodigdheden

Arduino UNO
× 1
Espressief ESP8266 ESP-01
× 1
DHT22-temperatuursensor
× 1
DS18B20 1-draads digitale temperatuursensor voor gebruik op aarde
× 1
LDR - Lichtafhankelijke weerstand
× 1
2-kanaals DC 5V-relaismodule
× 1

Apps en online services

Arduino IDE
ThingSpeak-API
MIT App Inventor

Over dit project

Ons doel zal zijn om in principe informatie te verzamelen van een lokale eenheid en deze naar internet te sturen. Een gebruiker waar ook ter wereld die naar deze informatie kijkt, zal beslissingen nemen door commando's op afstand te sturen naar de actuatoren, die zich ook in deze lokale eenheid zullen bevinden. Elke sensor of actuator kan worden gebruikt.

Het overgrote deel van mijn werk aan de IoT-arena maakte gebruik van NodeMCU en meer recentelijk de ESP32. Maar ik denk dat het belangrijk is om mijn vroege stappen niet te vergeten, een paar jaar geleden, toen ik IoT begon te leren met behulp van een Arduino UNO en de oude en goede ESP8266-01.

Dus besluit ik hier om terug te keren naar die tijd (met een beetje meer ervaring nu) en die geweldige apparaten opnieuw te verkennen, ze te verbinden met de cloud, met behulp van de ThingSpeak.com-webservice. We zullen ook onderzoeken hoe we dingen op afstand kunnen bedienen door een Android-app te gebruiken die is ontwikkeld met behulp van de MIT AppInventor.

Het "centrum van ons IoT-project" wordt ThingSpeak.com. De lokale eenheid (UNO/ESP-01) zal gegevens van sensoren en actuatorstatus vastleggen, verzenden ze naar het internet, "schrijven" op een specifiek ThingSpeak.com Statuskanaal . De lokale eenheid zal ook ontvangen gegevens van internet, "lezen" ze van specifieke ThingSpeak Actuator-kanalen .

Een Android-app wordt ook lezen die gegevens van het ThingSpeak.com Status Channel en ze voor de gebruiker weer te geven. Op dezelfde manier kan de gebruiker, op basis van die statusinformatie, opdrachten naar actuatoren sturen, schrijven ze op ThingSpeak Actuator-kanalen (zie het bovenstaande blokdiagram om de gegevensstroom beter te begrijpen).

Dus wat zullen we doen? Het blokschema dat in de volgende stap wordt getoond, geeft ons een overzicht van het uiteindelijke project:

Stap 1:Inleiding

Met behulp van gemeenschappelijke sensoren zal ons project verschillende gegevens vastleggen en naar de cloud sturen, waar iedereen ze via internet kan zien. Om met die gegevens te werken, gebruiken we de service van ThingSpeak.com, een open IoT-platform waarmee we die gegevens kunnen verzamelen, analyseren en ernaar kunnen handelen.

De gegevens die moeten worden verzameld door sensoren zal zijn:

  • Luchttemperatuur en relatieve vochtigheid
  • Bodemtemperatuur en vochtigheid
  • Helderheid

Het project heeft 2 actuatoren :

  • Elektrische pomp
  • Elektrische lamp

De status van die actuatoren ("ON/OFF") moet ook naar de cloud worden gestuurd.

Het idee zal dus zijn om die gegevens van de sensoren, bijvoorbeeld een plantage, vast te leggen en naar de cloud te sturen. Op basis van die gegevens moet een gebruiker de beslissing nemen op basis van die uitspraken:

  • Zet de pomp AAN als de bodemvochtigheid te laag is
  • Zet de lamp AAN als de bodemtemperatuur te laag is

Om onze actuatoren op afstand te bedienen, gebruiken we een Android-app.

Stap 2:Stuklijst - Stuklijst

Enkele van de belangrijkste componenten die hier worden vermeld, hebben een link en een indicatieve prijs in USD. Die links zijn alleen ter informatie.

  • Arduino UNO (microcontroller) - $10,00
  • ESP8266-01 (communicatiemodule) - $ 3,50
  • DHT22 (lucht- en relatieve vochtigheidssensor) - $9,00
  • DS18B20 (1-draads digitale temperatuursensor voor gebruik op aarde) - $ 6,00
  • YL-69 + LM393 (bodemvochtigheidssensor) - $ 2,00
  • LDR (helderheidssensor) - $ 0,20
  • 2 x LED's (rood en groen)
  • 1 x 2-kanaals DC 5V-relaismodule met optocoupler-trigger op laag niveau - $ 7,00
  • 5V DC-pomp - $ 3,00
  • 220V-lamp
  • 2 x 330 ohm weerstand (te gebruiken met LED's)
  • 2 x 10K ohm weerstand (te gebruiken met DHT22 en LDR)
  • 1 x 4K7 ohm weerstand (te gebruiken met DS18B20
  • Protobord
  • Truien
  • Externe 5V DC-voeding voor relais

Stap 3:De hardware

Laten we het Project HW monteren. Het ideaal is om ons project op onderdelen te installeren en te testen. Als suggestie kunnen we de volgende stappen volgen:

  • Installeer en test alle sensoren lokaal
  • Installeer en configureer de ESP-01 (BareMinimum)
  • Verander de ESP-01-installatie voor zijn definitieve configuratie en test deze
  • Configureer het ThingsPeak-statuskanaal
  • Installeer ThingsPeak-code in uw Arduino en controleer de status van de sensoren in de cloud
  • Ontwikkel de eerste versie van de Android-app om de status en berichten weer te geven
  • Installeer actuatoren (LED's en relais)
  • ThingSpeak Actuators-kanalen configureren
  • Installeer en test Arduino-code met actuatoren
  • Ontwikkel de definitieve versie van de Android-app

Stap 4:Sensoren aansluiten

We moeten een aantal bibliotheken op onze IDE hebben geïnstalleerd om de sensoren goed te kunnen lezen. Controleer of u alle bibliotheken hebt geïnstalleerd. Hun initiële configuratie zou moeten zijn:

// DS18B20#include #include #define ONE_WIRE_BUS 5 // DS18B20 op pin D5 OneWire oneWire(ONE_WIRE_BUS);DallasTemperature DS18B20(&oneWire);int soilTemp =0; //DHT#include "DHT.h"#include int pinoDHT =11;int tipoDHT =DHT22;DHT dht(pinoDHT, tipoDHT); int airTemp =0;int airHum =0;// LDR (Light)#define ldrPIN 1int light =0;// Bodemvochtigheid#define soilHumPIN 0int soilHum =0; 

Laten we over Setup en loop schrijven:

void setup(){ Serial.begin(9600); DS18B20.begin(); dht.begin();}void loop(){ readSensors(); displaySensoren(); vertraging (10000);} 

En laten we ten slotte twee specifieke functies schrijven, een voor het lezen van onze sensoren en een andere om hun waarden op Serial Monitor weer te geven:

/********* Lees Sensors-waarde ***********/void readSensors(void){ airTemp =dht.readTemperature(); airHum =dht.readHumidity(); DS18B20.requestTemperaturen(); bodemTemp =DS18B20.getTempCByIndex(0); // Sensor 0 legt de bodemtemperatuur vast in Celsius soilHum =map (analogRead (soilHumPIN), 1023, 0, 0, 100); light =map(analogRead(ldrPIN), 1023, 0, 0, 100); //LDRDark:0 ==> licht 100% }/********* Display Sensors-waarde ***********/void displaySensors(void){ Serial.print (" airTemp (oC):"); Serieel.println (airTemp); Serial.print ("airHum (%):"); Seriële.println (airHum); Serial.print ("soilTemp (oC):"); Serial.println (soilTemp); Serial.print ("soilHum (%):"); Serial.println (soilHum); Serial.print ("licht (%):"); Serial.println (licht); Serial.println ("");} 

De onderstaande afbeelding van de seriële monitor toont ons de sensorwaarden.

De code kan worden gedownload van mijn GITHUB:Sens ors_Test.ino

Stap 5:​ESP8266-01 Initiële configuratie

De ESP-01 zal worden gebruikt als een seriële brug, wat betekent dat we hem zullen programmeren met behulp van "AT-commando's". Het eerste is om er zeker van te zijn dat uw ESP-01 op de juiste baudrate-communicatiesnelheid staat. In ons geval 9.600 bauds. Gewoonlijk is de ESP-01 af fabriek geprogrammeerd met 115.200 baud en moeten we dit veranderen naar 9.600 baud.

Eerst moet u de ESP-01 aansluiten zoals hierboven weergegeven.

Sluit vervolgens de Arduino aan op je computer, open de IDE en laad het voorbeeld dat staat in Bestand> Voorbeelden> 01.Basics> BareMinimum. Dit is een lege code om ervoor te zorgen dat er geen communicatieconflict is tussen Arduino en ESP.

We hebben deze code naar de Arduino overgebracht voordat we deze op de ESP-01S hebben aangesloten om ervoor te zorgen dat de Arduino geen seriële communicatie (TX en RX) gebruikt. Dit is belangrijk voor ESP om goed te kunnen communiceren.

Open uw IDE Serial Monitor en verander de snelheid naar 115.200 baud Begin met het verzenden van een "AT"-commando op uw IDE Serial Monitor. De ESP-01 zou "OK" moeten retourneren

Laten we vervolgens de snelheid wijzigen. Daarvoor kun je het commando gebruiken:

AT + CIOBAUD =9600 

Merk op dat de ESP-01 mogelijk terugkeert naar de fabrieksprogrammering (ik weet niet of dit te wijten is aan de FW-versie). In mijn geval moest ik tenminste een ander commando gebruiken om de BaudRate definitief te veranderen:

AT+ UART_DEF=,,,, 

Bijvoorbeeld:9600 baud / 8 databits / 1 stopbits en geen pariteit en flow control:

AT + UART_DEF =9600,8,1,0,0 

Wijzig in het selectievak onder aan uw seriële monitor de snelheid in "9600 baud". Test de communicatie:typ aan de bovenkant van het venster AT en zie het antwoord OK. Nu moet je de module configureren in Station Mode om op te treden als Cliënt van uw wifi-netwerk. Gebruik het commando:

 AT + CWMODE =1 

Nu moeten we de module verbinden met je wifi-netwerk.

Gebruik hiervoor de onderstaande opdrachten, waarbij u "netwerknaam" vervangt door de naam van uw wifi-netwerk en "netwerknaam" door uw wachtwoord. Bewaar de aanhalingstekens.

AT + CWJAP ="netwerknaam", "netwerknaam"  

Als u het onderstaande antwoord ziet, is uw verbinding correct tot stand gebracht:

WIFI VERBONDEN WIFI GOT IP 

Voer de opdracht uit om het IP-adres te vinden:

AT + CIFSR  

En noteer het IP-adres dat in uw seriële monitor zal verschijnen. Mogelijk hebt u het in de toekomst nodig.

Stap 6:De ESP-01 testen

Zodra we de ESP-01 hebben geconfigureerd, moeten we deze op het uiteindelijke circuit installeren. Daarvoor moeten we de eerder gemaakte bedrading VERANDEREN en de ESP-01 aansluiten op onze UNO zoals hieronder:

  • ESP-01 RX (geel) naar UNO-pin D7
  • ESP-01 TX (oranje) naar UNO-pin D6
  • ESP-01 Ch-Pd (Bruin) naar Vcc (3,3V)
  • ESP-01 Reset (Blauw) naar UNO Pin D8
  • ESP-01 Vcc (Rood) tot 3.3V
  • ESP-01 Gnd (zwart) naar UNO GND

Laten we een eenvoudige test doen om te controleren of onze ESP-01 correct is geïnstalleerd en getest. Voer de onderstaande code in:

#include  SoftwareSerial esp8266(6,7); //Rx ==> Pin 6; TX ==> Pin7 #define speed8266 9600 void setup() {esp8266.begin (speed8266); Serieel.begin(speed8266); Serial.println("ESP8266 Setup test - gebruik AT coomands");}void loop() { while(esp8266.available()) { Serial.write(esp8266.read()); } while(Serial.available()) { esp8266.write(Serial.read()); }} 

Probeer nu enkele AT-commando's en bekijk het resultaat op uw seriële monitor:

* AT =====> ESP8266 retourneert OK* AT+RST =====> ESP8266 herstart en retourneert OK* AT+GMR =====> ESP8266 retourneert AT-versie; SDK-versie; ID kaart; OK* AT+CW-MODUS? => ESP8266 retourneert modustype* AT+CWLAP ===> ESP8266 retourneert toegangspunten sluiten* AT+CIFSR ===> ESP8266 retourneert ontworpen IP-adres 

De code kan worden gedownload van mijn GITHUB:ESP_AT_Config.ino

Als je elke keer dat er een reset plaatsvindt (of je Arduino wordt uit- of ingeschakeld) verbinding wilt maken met het wifi-netwerk en je inloggegevens wilt invoeren, voeg dan een oproep toe aan de connectWiFi () functie aan het einde van de setup () functie:

setup(){ ... connectWiFi(); } 

De connectWiFi () functie moet aan het einde van uw hoofdcode .ino staan:

void connectWiFi(void){ sendData("AT+RST\r\n", 2000, 0); // reset sendData("AT+CWJAP=\"UW GEBRUIKERSNAAM\",\"UW PASWOORD\"\r\n", 2000, 0); // Verbind netwerkvertraging (3000); sendData("AT+CWMODE=1\r\n", 1000, 0); sendData("AT+CIFSR\r\n", 1000, 0); // Toon IP-adres Serial.println ("8266 Verbonden");} 

Merk op dat de bovenstaande functie een andere sendData (data) . aanroept functie, die zich ook in uw code zou moeten bevinden:

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

Stap 7:Sensoren en ESP-01 aansluiten

Zodra we alle sensoren hebben geïnstalleerd en getest en ook onze ESP-01 goed werkt, laten we eens kijken en klaar zijn om gegevens naar internet te sturen.

Stap 8:The ThingSpeak

Een van de belangrijkste onderdelen van ons project is het ThingSpeak, een open IoT-platform waarmee we verzamelde gegevens kunnen verzamelen, analyseren en ernaar kunnen handelen. Als je dat nog niet hebt gedaan, ga dan naar ThingSpeak aanmelden en maak je account aan.

Maak vervolgens een nieuw kanaal waar we onze 2 actuatoren, 5 sensoren en een reserveveldstatus hebben:

  • Veld 1:Actuator 1
  • Veld 2:Actuator 2
  • Veld 3:Luchttemperatuur in oC
  • Gearchiveerd 4:Luchtvochtigheid in %
  • Veld 5:Bodemtemperatuur in oC
  • Veld 6:Bodemvochtigheid in %
  • Veld 7:Lichtsterkte in %
  • Veld 8:Reserve

Veld 8 zal als reserve worden gelaten om te worden gebruikt voor toekomstige uitbreidingen of voor het opsporen van fouten. Ik zal het bijvoorbeeld gebruiken als een "teller" voor elke communicatiefout die optreedt tijdens Arduino/ESP-01-handshake met ThingSpeak.com.

Zodra je je kanaal hebt gemaakt (in dit geval ons statuskanaal), is het belangrijk om je sleutels te noteren, zoals hieronder wordt weergegeven.

Stap 9:Status naar de cloud verzenden

Op dit moment hebben we onze Cloud Service beschikbaar en onze sensoren verzamelen gegevens lokaal. Laten we die waarden nemen en ze naar ThingSpeak.com sturen. We zullen SCHRIJVEN op het ThingSpeak-kanaal en daarvoor moeten we een GET-string sturen. We doen het in 3 delen:

We sturen een "Start cmd":

AT+CIPSTART="TCP","184.106.153.149",80 

Volg de "lengte" van het commando:

AT+CIPSEND=116 

En de GET-string zelf, die in de daarvoor bestemde velden op het Statuskanaal schrijft:

GET /update?api_key=YOUR_WRITE_KEY_HERE&field1=pump&fieldlamp=0&field3=airTemp&field4=airHum&field5=soilTemp&field6=soilHum&field7=light&field8=spare

De onderstaande code zal het werk voor ons doen en het bovenstaande PrintScreen toont het resultaat op Serial Monitor:

// Thingspeak String statusChWriteKey ="6SRPQQKIE6AJVQE6"; // Status kanaal-ID:385184#include SoftwareSerial EspSerial(6, 7); // Rx, Tx#define HARDWARE_RESET 8// DS18B20#include #include #define ONE_WIRE_BUS 5 // DS18B20 op pin D5 OneWire oneWire(ONE_WIRE_BUS);DallasTemperature&One DS18B); =0;//DHT#include "DHT.h"#include int pinoDHT =11;int tipoDHT =DHT22;DHT dht(pinoDHT, tipoDHT); int airTemp =0;int airHum =0;// LDR (Light)#define ldrPIN 1int light =0;// Bodemvochtigheid#define soilHumPIN 0int soilHum =0;// Variabelen voor gebruik met timerslong writeTimingSeconds =17; // ==> Definieer de sampletijd in seconden om data te verzenden long startWriteTiming =0;long elapsedWriteTime =0;// Variabelen die moeten worden gebruikt met Actuatorsboolean pump =0; booleaanse lamp =0; int spare =0;boolean error;void setup(){Serial.begin(9600); pinMode (HARDWARE_RESET, UITGANG); digitalWrite (HARDWARE_RESET, HOOG); DS18B20.begin(); dht.begin(); EspSerial.begin(9600); // Comunicacao com Modulo WiFi EspHardwareReset(); // Reset Modulo WiFi startWriteTiming =millis(); // starten van de "programmaklok"}void loop(){ start://label error=0; elapsedWriteTime =millis()-startWriteTiming; if (elapsedWriteTime> (writeTimingSeconds*1000)) { readSensors(); writeThingSpeak(); startWriteTiming =millis(); } if (error==1) //Opnieuw verzenden als verzending niet is voltooid {Serial.println(" <<<>>>"); vertraging (2000); ga beginnen; //ga naar label "start" }}/********* Lees Sensors-waarde *************/void readSensors(void){airTemp =dht.readTemperature(); airHum =dht.readHumidity(); DS18B20.requestTemperaturen(); bodemTemp =DS18B20.getTempCByIndex(0); // Sensor 0 legt de bodemtemperatuur vast in Celcius light =map (analogRead (ldrPIN), 1023, 0, 0, 100); //LDRDark:0 ==> licht 100% bodemHum =kaart (analogRead (soilHumPIN), 1023, 0, 0, 100); }/********** Conexao com TCP com Thingspeak ******/void writeThingSpeak(void){ startThingSpeakCmd(); // preparacao da string GET String getStr ="GET /update?api_key="; getStr +=statusChWriteKey; getStr +="&field1="; getStr +=String (pomp); getStr +="&field2="; getStr +=String (lamp); getStr +="&field3="; getStr +=String (airTemp); getStr +="&field4="; getStr +=String (airHum); getStr +="&field5="; getStr +=String (bodemTemp); getStr +="&field6="; getStr +=String (bodemHum); getStr +="&field7="; getStr +=String (licht); getStr +="&field8="; getStr +=String (reserve); getStr +="\r\n\r\n"; sendThingSpeakGetCmd(getStr); }/********* ESP resetten ***********/void EspHardwareReset(void){ Serial.println("Resetten......."); digitalWrite (HARDWARE_RESET, LAAG); vertraging (500); digitalWrite (HARDWARE_RESET, HOOG); delay(8000);//Tempo nodig om te komen tot een ler Serial.println("RESET"); }/********* Start de communicatie met ThingSpeak*************/void startThingSpeakCmd(void){ EspSerial.flush();//limpa o buffer antes de começar a gravar String cmd ="AT+CIPSTART=\"TCP\",\""; cmd +="184.106.153.149"; // Endereco IP van api.thingspeak.com cmd +="\",80"; EspSerial.println(cmd); Serial.print("enviado ==> Start cmd:"); Serieel.println(cmd); if(EspSerial.find("Fout")) { Serial.println("AT+CIPSTART fout"); opbrengst; }}/********* stuur een GET-cmd naar ThingSpeak *************/String sendThingSpeakGetCmd(String getStr){ String cmd ="AT+CIPSEND="; cmd +=String(getStr.length()); EspSerial.println(cmd); Serial.print("enviado ==> lengte cmd:"); Serieel.println(cmd); if(EspSerial.find((char *)">")) { EspSerial.print(getStr); Serial.print("enviado ==> getStr:"); Serial.println(getStr); delay(500);//tempo para processar o GET, sem este delay apresenta busy no proximo command String messageBody =""; while (EspSerial.available()) { String line =EspSerial.readStringUntil('\n'); if (line.length() ==1) {//werkelijke inhoud begint na een lege regel (die lengte heeft 1) messageBody =EspSerial.readStringUntil('\n'); } } Serial.print("MessageBody ontvangen:"); Serial.println(messageBody); bericht terugBody; } else { EspSerial.println("AT+CIPCLOSE"); // waarschuw gebruiker Serial.println ("ESP8266 CIPSEND-FOUT:OPNIEUW VERZENDEN"); //Opnieuw verzenden... reserve =reserve + 1; fout=1; retourneer "fout"; } }  

De code kan worden gedownload van mijn GITHUB:SendingStatusTS_EXT.ino

Stap 10:Het eerste deel van de Android-app - Statusbewaking

Laten we ons eerste deel van de Android-app maken.

Eerst ontwerpen we de gebruikersinterface. Het bovenstaande Print Screen hierboven toont de belangrijkste zichtbare en niet-zichtbare elementen. Daarna moeten we de blokken ontwerpen (de onderstaande nummers komen overeen met de bovenstaande figuren):

Elke 2 seconden (gedefinieerd door Clock1), zullen we een procedure aanroepen met de naam:"readArduino".

  • Het resultaat van een dergelijke procedure is de waarde voor elk van de Status-variabelen die op het scherm moet worden weergegeven.
  • Houd er rekening mee dat we de waarden "0" en "1" van de status van de aandrijving zullen "converteren" naar "UIT" en "AAN" voor een beter begrip.
  • Die waarden ("Status") worden weergegeven op overeenkomstige "labels"
  • De statusvariabelen moeten worden gedeclareerd als Globaal.
  • De procedure "readArduino" zal in feite het Status Channel op ThingSpeak lezen. We moeten dus de URL definiëren die naar Thingspeak moet worden verzonden. Daarvoor moeten 3 globale variabelen worden gedeclareerd en samengevoegd om de URL te maken die naar TS moet worden verzonden. Er moet een GET worden verzonden naar de webcomponent met de naam "ArduFarmBotStatusCh"
  • De tekst van het vorige commando zal aankomen als JSon-formaat. Deze tekst moet worden verwerkt zodat elk veld moet worden gelezen en opgeslagen op de corresponderende globale variabele.
  • Het laatste wat je hoeft te doen is de "Alarm"-procedure aan te roepen, die de status van twee bodemsensoren zal analyseren. Als de temperatuur te laag is (in ons geval 10oC), moet er een melding worden weergegeven. Hetzelfde geldt voor de luchtvochtigheid, als deze lager is dan 60%. Merk op dat we een andere timer hebben gedefinieerd (Clock2), geprogrammeerd om elke 1 seconde af te gaan. Dit is alleen om de kleur van berichttekst te "wisselen" (van wit naar rood). Hierdoor zal het bericht "knipperen".

De laatste foto hierboven laat de uiteindelijke app zien die werkt.

De app-code kan worden gedownload van mijn GITHUB:ArduFarmBot_Status_App_EXT.aia

Stap 11:Actuators installeren (LED's en relais)

Laten we onze HW afmaken.

Daarvoor moeten we onze Actuators installeren. Zoals u zich herinnert, zullen we op afstand opdrachten ontvangen om een ​​pomp en een lamp AAN en UIT te zetten. De Arduino-uitgang activeert een relais (en een LED) om die acties te krijgen.

We zullen een relaismodule gebruiken die een Optocoupler Low-Level Trigger heeft. We zullen er ook 5V aan leveren via een aparte pin, dus we hoeven niet de vereiste stroom op de ingangspin te leveren. Dat doet de module voor ons.

De bovenstaande afbeelding laat zien hoe de aandrijvingen moeten worden aangesloten. Merk op dat de Realy GND NIET VERBONDEN is met Arduino GND. Dit zal helpen om geen ruis te introduceren wanneer het relais werkt.

Voor de eenvoud heb ik de sensoren uit het diagram gehaald. Maar u kunt het circuit van de actuatoren aan uw project toevoegen zonder de sensoren te verwijderen die u al hebt geïnstalleerd en getest.

Stap 12:De ThingSpeak Actuators-kanalen configureren

Op dezelfde manier als voor de Status, zullen we 2 nieuwe kanalen maken, één voor elke actuator. Noteer van elk van hen de kanaal-ID, lees- en schrijfsleutels. We schrijven alleen op veld 1 van elk van die kanalen. Dus in mijn geval bijvoorbeeld:

Kanaal-ID 375598 ==> LED rood (pomp)

  • Veld1 =0 ==> Pomp UIT
  • Veld1 =1 ==> Pomp AAN

Kanaal-ID 375599 ==> LED Groen (Lamp)

  • Veld1 =0 ==> Lamp UIT
  • Veld1 =1 ==> Lamp AAN

Stap 13:Arduino-code installeren en testen met actuatoren

Toen we gegevens naar het web stuurden, deden we SCHRIJVEN op een ThingSpeak-kanaal (kanaalstatus) om gegevens te "verzenden" (uploaden). Nu moeten we LEZEN van een ThingSpeak-kanaal (Actuator Channel) om gegevens te "ontvangen" (downloaden).

We zullen LEZEN van een ThingSpeak-kanaal en daarvoor moeten we een GET-string sturen. We doen het in 3 delen:

We sturen een "Start cmd":

AT+CIPSTART="TCP","184.106.153.149",80 

Volg de "lengte" van het commando:

AT+CIPSEND=36 

En de GET-string zelf, die leest uit veld 1 op elk van de Actuator Channel:

GET /channels/375598/fields/1/last 

We zullen lezen van ThingSpeak-kanalen met tussenpozen van 10 seconden. Nadat we het bovenstaande GET-commando hebben verzonden, dat de "LAST VALUE STORED ON FIELD 1" oproept, ontvangen we een antwoord van ThingSpeak dat "1" of "0" moet zijn op een specifieke positie van het antwoord. Als er iets anders is dan dat aangekomen, moeten we het negeren.

Het belangrijkste verschil tussen dit deel van de code en het vorige (om statusgegevens te verzenden), is de functie:

readThingSpeak(String channelID) 

De onderstaande code zal het werk voor ons doen en het bovenstaande PrintScreen toont het resultaat op Serial Monitor:

// Thingspeak String canalID1 ="375598"; //Actuator1String canalID2 ="375599"; //Actuator2#include SoftwareSerial EspSerial(6, 7); // Rx, Tx#define HARDWARE_RESET 8// Variabelen die moeten worden gebruikt met timerslong readTimingSeconds =10; // ==> Definieer de monstertijd in seconden voor het ontvangen van datalong startReadTiming =0;long elapsedReadTime =0;//Relays#define ACTUATOR1 10 // RODE LED ==> Pump#define ACTUATOR2 12 // GROENE LED ==> Lampboolean pump =0; booleaanse lamp =0; int spare =0;boolean error;void setup(){Serial.begin(9600); pinMode (ACTUATOR1, UITGANG); pinMode (ACTUATOR2, UITGANG); pinMode (HARDWARE_RESET, UITGANG); digitalWrite(ACTUATOR1, HOOG); //o módulo relé é ativo em LOW digitalWrite(ACTUATOR2, HIGH); //o módulo relé é ativo em LOW digitalWrite(HARDWARE_RESET, HIGH); EspSerial.begin(9600); // Comunicacao com Modulo WiFi EspHardwareReset(); // Reset Modulo WiFi startReadTiming =millis(); // starten van de "programmaklok"}void loop(){ start://label error=0; elapsedReadTime =millis()-startReadTiming; if (elapsedReadTime> (readTimingSeconds*1000)) {int command =readThingSpeak (canalID1); if (opdracht !=9) pomp =opdracht; vertraging (5000); commando =readThingSpeak(canalID2); if (opdracht !=9) lamp =opdracht; actie ondernemen(); startReadTiming =millis(); } if (error==1) //Opnieuw verzenden als verzending niet is voltooid {Serial.println(" <<<>>>"); vertraging (2000); ga beginnen; //ga naar label "start" }}/********* Onderneem acties op basis van ThingSpeak-commando's *************/void takeActions(void){ Serial.print( "Pomp:"); Serial.println(pomp); Serial.print("Lamp:"); Serial.println(lamp); if (pomp ==1) digitalWrite (ACTUATOR1, LAAG); anders digitalWrite (ACTUATOR1, HOOG); if (lamp ==1) digitalWrite (ACTUATOR2, LAAG); else digitalWrite(ACTUATOR2, HIGH);}/********** Lees het Actuators-commando van ThingSpeak ***********/int readThingSpeak(String channelID){ startThingSpeakCmd(); int commando; // preparacao da string GET String getStr ="GET /channels/"; getStr +=kanaal-ID; getStr +="/velden/1/laatste"; getStr +="\r\n"; String messageDown =sendThingSpeakGetCmd(getStr); if (messageDown[5] ==49) { command =messageDown[7]-48; Serial.print("Opdracht ontvangen:"); Serial.println(opdracht); } else-opdracht =9; return commando;}/********** Reset ESP ***********/void EspHardwareReset(void){ Serial.println("Resetten......." ); digitalWrite (HARDWARE_RESET, LAAG); vertraging (500); digitalWrite (HARDWARE_RESET, HOOG); delay(8000);//Tempo nodig om te komen tot een ler Serial.println("RESET"); }/********* Start de communicatie met ThingSpeak*************/void startThingSpeakCmd(void){ EspSerial.flush();//limpa o buffer antes de começar a gravar String cmd ="AT+CIPSTART=\"TCP\",\""; cmd +="184.106.153.149"; // Endereco IP van api.thingspeak.com cmd +="\",80"; EspSerial.println(cmd); Serial.print("enviado ==> Start cmd:"); Serieel.println(cmd); if(EspSerial.find("Fout")) { Serial.println("AT+CIPSTART fout"); opbrengst; }}/********* stuur een GET-cmd naar ThingSpeak *************/String sendThingSpeakGetCmd(String getStr){ String cmd ="AT+CIPSEND="; cmd +=String(getStr.length()); EspSerial.println(cmd); Serial.print("enviado ==> lengte cmd:"); Serieel.println(cmd); if(EspSerial.find((char *)">")) { EspSerial.print(getStr); Serial.print("enviado ==> getStr:"); Serial.println(getStr); delay(500);//tempo para processar o GET, sem este delay apresenta busy no proximo command String messageBody =""; while (EspSerial.available()) { String line =EspSerial.readStringUntil('\n'); if (line.length() ==1) {//werkelijke inhoud begint na een lege regel (die lengte heeft 1) messageBody =EspSerial.readStringUntil('\n'); } } Serial.print("MessageBody received:"); Serial.println(messageBody); return messageBody; } else { EspSerial.println("AT+CIPCLOSE"); // alert user Serial.println("ESP8266 CIPSEND ERROR:RESENDING"); //Resend... spare =spare + 1; error=1; return "error"; } } 

The code can be downloaded from my GITHUB:ReadingCommandTS_EXT.ino

Step 14:Sending Commands to Actuators

At this point, we have the actuators channels configured on ThingSpeak and changing the value of Field 1 on each channel, we must see the actuators changing accordingly. On our final project we will do this task, using the Android App, but for testing proposes we can also do it using a normal browser. Let's do it.

The commands are:

Turn ON Pump (RED LED):

https://api.thingspeak.com/update?api_key=ACT1_WRITE_KEY&field1=1 

Turn OFF Pump (RED LED):

https://api.thingspeak.com/update?api_key=ACT1_WRITE_KEY&field1=0 

Turn ON Lamp (GREEN LED):

https://api.thingspeak.com/update?api_key=ACT2_WRITE_KEY&field1=1 

Turn OFF Lamp (GREEN LED):

https://api.thingspeak.com/update?api_key=ACT2_WRITE_KEY&field1=0 

Above you can see a print screen of a command to TurnOn the Pump sent from a browser and how it will appear at Serial Monitor. Obviously, the LED Red and relay will be also be turned on.

Step 15:Completing the Android APP

Let's complete the APP. Previously we have developed a simple App that gets the status from ThingSpeak (READ from Staus Channel). Now we must WRITE on Actuator channels, so those commands could be read by Arduino and act on Pump and Lamp accordingly.

For a user to pass the commands to the App, we will use "buttons". A pair of buttons (ON and OFF) for each one of the Actuators.

When a button is pressed, the color of its text changes.

  • If ON ==> Blue
  • if OFF ==> Red

Above you can see the set of blocks for each one of the pairs of buttons.

Test the App, sending commands to turn ON and OFF the actuators. Check on Serial Monitor, the messages exchanged between ESP-01 and ThingSpeak.

The complete App code can be downloaded from my GITHUB:ArduFarmBot_V1_EXT.aia

Step 16:Putting All Together

Perfect! At this point, you have a full Android APP, a complete HW but you still do not have a code that will continuously read and write on ThingSpeak. Let's combine all that we have developed previously.

On the final code, you will find additional portions to verify for example if the ESP-01 is not freezing. We will do it, sending an AT command to it before any read or write. As we saw at the very beginning of this tutorial, sending an AT command should return from ESP-01 an OK. If this does not happen, we will proceed with an HW reset, commanded by SW (as we do once during setup phase).

The complete code for our project can be downloaded from my GITHUB:ArduFarmBot_Light_EXT.ino

Step 17:Conclusion

There is a lot to be explored in IoT arena with those great little devices, the Arduino Uno, and the ESP8266-01. We will return soon with new tutorials! Keep following MJRoBot tutorials!

As always, I hope this project can help others find their way in the exciting world of electronics, robotics, and IoT!

Please visit my GitHub for updated files:ArduFarmBot_Light

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

Saludos from the south of the world!

See you at my next tutorial!

Thank you,

Marcelo

Code

  • Codefragment #1
  • Code snippet #2
  • Codefragment #3
  • Code snippet #11
  • Code snippet #12
  • Code snippet #16
  • Code snippet #20
Codefragment #1Platte tekst
// DS18B20#include #include #define ONE_WIRE_BUS 5 // DS18B20 on pin D5 OneWire oneWire(ONE_WIRE_BUS);DallasTemperature DS18B20(&oneWire);int soilTemp =0;//DHT#include "DHT.h"#include int pinoDHT =11;int tipoDHT =DHT22;DHT dht(pinoDHT, tipoDHT); int airTemp =0;int airHum =0;// LDR (Light)#define ldrPIN 1int light =0;// Soil humidity#define soilHumPIN 0int soilHum =0;
Code snippet #2Plain text
void setup(){ Serial.begin(9600); DS18B20.begin(); dht.begin();}void loop(){ readSensors(); displaySensors(); delay (10000);}
Code snippet #3Plain text
/********* Read Sensors value *************/void readSensors(void){ airTemp =dht.readTemperature(); airHum =dht.readHumidity(); DS18B20.requestTemperatures(); soilTemp =DS18B20.getTempCByIndex(0); // Sensor 0 will capture Soil Temp in Celcius soilHum =map(analogRead(soilHumPIN), 1023, 0, 0, 100); light =map(analogRead(ldrPIN), 1023, 0, 0, 100); //LDRDark:0 ==> light 100% }/********* Display Sensors value *************/void displaySensors(void){ Serial.print ("airTemp (oC):"); Serial.println (airTemp); Serial.print ("airHum (%):"); Serial.println (airHum); Serial.print ("soilTemp (oC):"); Serial.println (soilTemp); Serial.print ("soilHum (%):"); Serial.println (soilHum); Serial.print ("light (%):"); Serial.println (light); Serial.println ("");}
Code snippet #11Plain text
#include  SoftwareSerial esp8266(6,7); //Rx ==> Pin 6; TX ==> Pin7 #define speed8266 9600 void setup() { esp8266.begin (speed8266); Serial.begin(speed8266); Serial.println("ESP8266 Setup test - use AT coomands");}void loop() { while(esp8266.available()) { Serial.write(esp8266.read()); } while(Serial.available()) { esp8266.write(Serial.read()); }}
Code snippet #12Plain text
* AT =====> ESP8266 returns OK* AT+RST =====> ESP8266 restart and returns OK* AT+GMR =====> ESP8266 returns AT Version; SDK version; id; OK* AT+CWMODE? => ESP8266 returns mode type* AT+CWLAP ===> ESP8266 returs close access points* AT+CIFSR ===> ESP8266 returs designided IP
Code snippet #16Plain text
// Thingspeak String statusChWriteKey ="6SRPQQKIE6AJVQE6"; // Status Channel id:385184#include SoftwareSerial EspSerial(6, 7); // Rx, Tx#define HARDWARE_RESET 8// DS18B20#include #include #define ONE_WIRE_BUS 5 // DS18B20 on pin D5 OneWire oneWire(ONE_WIRE_BUS);DallasTemperature DS18B20(&oneWire);int soilTemp =0;//DHT#include "DHT.h"#include int pinoDHT =11;int tipoDHT =DHT22;DHT dht(pinoDHT, tipoDHT); int airTemp =0;int airHum =0;// LDR (Light)#define ldrPIN 1int light =0;// Soil humidity#define soilHumPIN 0int soilHum =0;// Variables to be used with timerslong writeTimingSeconds =17; // ==> Define Sample time in seconds to send datalong startWriteTiming =0;long elapsedWriteTime =0;// Variables to be used with Actuatorsboolean pump =0; boolean lamp =0; int spare =0;boolean error;void setup(){ Serial.begin(9600); pinMode(HARDWARE_RESET,OUTPUT); digitalWrite(HARDWARE_RESET, HIGH); DS18B20.begin(); dht.begin(); EspSerial.begin(9600); // Comunicacao com Modulo WiFi EspHardwareReset(); //Reset do Modulo WiFi startWriteTiming =millis(); // starting the "program clock"}void loop(){ start://label error=0; elapsedWriteTime =millis()-startWriteTiming; if (elapsedWriteTime> (writeTimingSeconds*1000)) { readSensors(); writeThingSpeak(); startWriteTiming =millis(); } if (error==1) //Resend if transmission is not completed { Serial.println(" <<<>>>"); delay (2000); goto start; //go to label "start" }}/********* Read Sensors value *************/void readSensors(void){ airTemp =dht.readTemperature(); airHum =dht.readHumidity(); DS18B20.requestTemperatures(); soilTemp =DS18B20.getTempCByIndex(0); // Sensor 0 will capture Soil Temp in Celcius light =map(analogRead(ldrPIN), 1023, 0, 0, 100); //LDRDark:0 ==> light 100% soilHum =map(analogRead(soilHumPIN), 1023, 0, 0, 100); }/********* Conexao com TCP com Thingspeak *******/void writeThingSpeak(void){ startThingSpeakCmd(); // preparacao da string GET String getStr ="GET /update?api_key="; getStr +=statusChWriteKey; getStr +="&field1="; getStr +=String(pump); getStr +="&field2="; getStr +=String(lamp); getStr +="&field3="; getStr +=String(airTemp); getStr +="&field4="; getStr +=String(airHum); getStr +="&field5="; getStr +=String(soilTemp); getStr +="&field6="; getStr +=String(soilHum); getStr +="&field7="; getStr +=String(light); getStr +="&field8="; getStr +=String(spare); getStr +="\r\n\r\n"; sendThingSpeakGetCmd(getStr); }/********* Reset ESP *************/void EspHardwareReset(void){ Serial.println("Reseting......."); digitalWrite(HARDWARE_RESET, LOW); vertraging (500); digitalWrite(HARDWARE_RESET, HIGH); delay(8000);//Tempo necessário para começar a ler Serial.println("RESET"); }/********* Start communication with ThingSpeak*************/void startThingSpeakCmd(void){ EspSerial.flush();//limpa o buffer antes de começar a gravar String cmd ="AT+CIPSTART=\"TCP\",\""; cmd +="184.106.153.149"; // Endereco IP de api.thingspeak.com cmd +="\",80"; EspSerial.println(cmd); Serial.print("enviado ==> Start cmd:"); Serial.println(cmd); if(EspSerial.find("Error")) { Serial.println("AT+CIPSTART error"); opbrengst; }}/********* send a GET cmd to ThingSpeak *************/String sendThingSpeakGetCmd(String getStr){ String cmd ="AT+CIPSEND="; cmd +=String(getStr.length()); EspSerial.println(cmd); Serial.print("enviado ==> lenght cmd:"); Serial.println(cmd); if(EspSerial.find((char *)">")) { EspSerial.print(getStr); Serial.print("enviado ==> getStr:"); Serial.println(getStr); delay(500);//tempo para processar o GET, sem este delay apresenta busy no próximo comando String messageBody =""; while (EspSerial.available()) { String line =EspSerial.readStringUntil('\n'); if (line.length() ==1) { //actual content starts after empty line (that has length 1) messageBody =EspSerial.readStringUntil('\n'); } } Serial.print("MessageBody received:"); Serial.println(messageBody); return messageBody; } else { EspSerial.println("AT+CIPCLOSE"); // alert user Serial.println("ESP8266 CIPSEND ERROR:RESENDING"); //Resend... spare =spare + 1; error=1; return "error"; } }
Code snippet #20Plain text
// Thingspeak String canalID1 ="375598"; //Actuator1String canalID2 ="375599"; //Actuator2#include SoftwareSerial EspSerial(6, 7); // Rx, Tx#define HARDWARE_RESET 8// Variables to be used with timerslong readTimingSeconds =10; // ==> Define Sample time in seconds to receive datalong startReadTiming =0;long elapsedReadTime =0;//Relays#define ACTUATOR1 10 // RED LED ==> Pump#define ACTUATOR2 12 // GREEN LED ==> Lampboolean pump =0; boolean lamp =0; int spare =0;boolean error;void setup(){ Serial.begin(9600); pinMode(ACTUATOR1,OUTPUT); pinMode(ACTUATOR2,OUTPUT); pinMode(HARDWARE_RESET,OUTPUT); digitalWrite(ACTUATOR1, HIGH); //o módulo relé é ativo em LOW digitalWrite(ACTUATOR2, HIGH); //o módulo relé é ativo em LOW digitalWrite(HARDWARE_RESET, HIGH); EspSerial.begin(9600); // Comunicacao com Modulo WiFi EspHardwareReset(); //Reset do Modulo WiFi startReadTiming =millis(); // starting the "program clock"}void loop(){ start://label error=0; elapsedReadTime =millis()-startReadTiming; if (elapsedReadTime> (readTimingSeconds*1000)) { int command =readThingSpeak(canalID1); if (command !=9) pump =command; delay (5000); command =readThingSpeak(canalID2); if (command !=9) lamp =command; takeActions(); startReadTiming =millis(); } if (error==1) //Resend if transmission is not completed { Serial.println(" <<<>>>"); delay (2000); goto start; //go to label "start" }}/********* Take actions based on ThingSpeak Commands *************/void takeActions(void){ Serial.print("Pump:"); Serial.println(pump); Serial.print("Lamp:"); Serial.println(lamp); if (pump ==1) digitalWrite(ACTUATOR1, LOW); else digitalWrite(ACTUATOR1, HIGH); if (lamp ==1) digitalWrite(ACTUATOR2, LOW); else digitalWrite(ACTUATOR2, HIGH);}/********* Read Actuators command from ThingSpeak *************/int readThingSpeak(String channelID){ startThingSpeakCmd(); int command; // preparacao da string GET String getStr ="GET /channels/"; getStr +=channelID; getStr +="/fields/1/last"; getStr +="\r\n"; String messageDown =sendThingSpeakGetCmd(getStr); if (messageDown[5] ==49) { command =messageDown[7]-48; Serial.print("Command received:"); Serial.println(command); } else command =9; return command;}/********* Reset ESP *************/void EspHardwareReset(void){ Serial.println("Reseting......."); digitalWrite(HARDWARE_RESET, LOW); vertraging (500); digitalWrite(HARDWARE_RESET, HIGH); delay(8000);//Tempo necessário para começar a ler Serial.println("RESET"); }/********* Start communication with ThingSpeak*************/void startThingSpeakCmd(void){ EspSerial.flush();//limpa o buffer antes de começar a gravar String cmd ="AT+CIPSTART=\"TCP\",\""; cmd +="184.106.153.149"; // Endereco IP de api.thingspeak.com cmd +="\",80"; EspSerial.println(cmd); Serial.print("enviado ==> Start cmd:"); Serial.println(cmd); if(EspSerial.find("Error")) { Serial.println("AT+CIPSTART error"); opbrengst; }}/********* send a GET cmd to ThingSpeak *************/String sendThingSpeakGetCmd(String getStr){ String cmd ="AT+CIPSEND="; cmd +=String(getStr.length()); EspSerial.println(cmd); Serial.print("enviado ==> lenght cmd:"); Serial.println(cmd); if(EspSerial.find((char *)">")) { EspSerial.print(getStr); Serial.print("enviado ==> getStr:"); Serial.println(getStr); delay(500);//tempo para processar o GET, sem este delay apresenta busy no próximo comando String messageBody =""; while (EspSerial.available()) { String line =EspSerial.readStringUntil('\n'); if (line.length() ==1) { //actual content starts after empty line (that has length 1) messageBody =EspSerial.readStringUntil('\n'); } } Serial.print("MessageBody received:"); Serial.println(messageBody); return messageBody; } else { EspSerial.println("AT+CIPCLOSE"); // alert user Serial.println("ESP8266 CIPSEND ERROR:RESENDING"); //Resend... spare =spare + 1; error=1; return "error"; } }
Github
https://github.com/Mjrovai/ArduFarmBot_Light

Schema's

Electrical diagram
https://github.com/Mjrovai/ArduFarmBot_Light/blob/master/ArduFarmBot_Light/ArduFarmBot%20Light.fzz

Productieproces

  1. Parallel computergebruik op Raspberry Pi 4B+ IoT-borden gemakkelijk gemaakt
  2. Hartslagmeter met IoT
  3. WebServerBlink met Arduino Uno WiFi
  4. Eenvoudige UNO-rekenmachine
  5. Persistentie van visie
  6. Contactloze temperatuurbewakingspoort
  7. Arduino - Stuur temperatuur naar internet via serieel
  8. ThingSpeak Arduino-weerstation
  9. SMART temperatuurbewaking voor scholen
  10. Hoe gemakkelijk is het om een ​​thermistor te gebruiken?!
  11. Azure IoT-zwembad