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 Deel 2: Een Extern IoT-besturingsstation Bouwen

Onderdelen en benodigdheden

Arduino Nano R3 Aantal: 1
Espressif ESP8266 ESP-01 Aantal: 1
DHT22 Temperatuur/vochtigheidssensor Aantal: 1
KY-018 Fotoweerstand module Aantal: 1
Bodemvochtigheidssensor (hydrometer) Aantal: 1
Relais (algemeen) Aantal: 2
LCD 4×20 (I2C) Aantal: 1
SparkFun Drukknop 12mm Aantal: 3
LED (algemeen) Aantal: 3

Apps en online diensten

ThingSpeak API

Over dit project

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Deze tutorial is een vervolg op ArduFarmBot: Een Tomaten-Hometuin Besturen met Arduino en IoT (Deel 1).

In Deel 1 maakten we een lokaal besturingsstation dat gegevens verzamelde van een tomatenteelt: temperatuur, relatieve luchtvochtigheid, lichtintensiteit en bodemvochtigheid. Op basis hiervan besloot de ArduFarmBot automatisch hoeveel en wanneer water en warmte nodig was. Handmatige bediening van de waterpomp en de lamp was ook mogelijk.

In Deel 2 implementeren we een IoT-aanpak: de "handmatige interventie" wordt ook op afstand via internet mogelijk. Het blokdiagram toont de architectuur.

Gemeten data wordt naar een cloud-opslagdienst gestuurd (in ons geval ThingSpeak.com). Een speciale website, de Remote Control Page, monitoren en toont deze data in near real-time en stelt remote activering van pomp en lamp in.

Stap 1: Stuklijst (Bill of Materials)

  • Arduino Nano – ($7,50)
  • DHT22 of DHT11 Temperatuur/vochtigheidssensor – ($3,66)
  • Lichtsensor – AD-018 Fotoweerstand module of equivalent – ($0,71)
  • 2× Bodemvochtigheidssensor – ($1,99) (Optioneel, zelfbouw mogelijk)
  • LCD I2C 20×4 – ($13,99)
  • LED (1×) – ($0,20)
  • ESP8266 ESP-01 WiFi-module – ($5,96)
  • Actieve buzzer – KY-012 of equivalent – ($0,60)
  • 2× 5V Relaismodule – ($11,60)
  • Jumperdrade – ($1,00)
  • Weerstanden: 10kΩ, 2,2kΩ, 1kΩ, 220Ω
  • Arduino Nano Shield ("Funduino") – ($7,28)
  • Membraantoetsenbord (4 toetsen) – ($6,65)
  • Plastic behuizing

Stap 2: Hardware completeren

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Vanaf het lokale station uit Deel 1 is de enige extra hardware de ESP8266. Het blokdiagram toont alle Arduino- en component-pinverbindingen.

Let op spanningsniveaus! De ESP8266 werkt op 3,3V. De Rx-pin mag niet direct aan de Nano Tx-pin (D3) worden aangesloten. Een spanningsdeler (level shifter) is vereist. In de schema's wordt gedetailleerd getoond hoe de ESP8266 te verbinden.

Meer over ESP8266 in mijn tutorials:

We gebruiken ESP8266 op Nano pin 2 (Tx) en pin 3 (Rx) met de SoftwareSerial-bibliotheek. Alternatief: hardware seriële pinnen 0 en 1 (moeten los bij uploaden).

Opmerking: De buzzer kan op pin D17 (A3) aangesloten worden voor foutgeluid. Ik gebruikte hem tijdens testen, niet in het finale project (hardware, maar code is ervoor klaar).

Testcode voor ESP8266 setup: FC9DBPKIT682FY7.ino

Stap 3: De ESP8266-verbinding

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Om de ArduFarmBot met internet te verbinden gebruiken we de ESP8266: goedkoop, eenvoudig te programmeren IoT-module.

Eerst een reset op de CH-PD-pin:

/***************************************************
 * Reset functie voor communicatie
 ***************************************************/
void reset8266(void) {
  pinMode(CH_PD, OUTPUT);
  digitalWrite(CH_PD, LOW);
  delay(300);
  digitalWrite(CH_PD, HIGH);
  Serial.print("8266 reset OK");
  lcd.clear();
  lcd.println("8266 reset OK ");
}

Vervolgens verbinden met je lokale netwerk (vervang USERNAME/PASSWORD in code) en instellen als STA (Station Mode, CWMODE=1):

/***************************************************
 * WiFi verbinden
 ***************************************************/
void connectWiFi(void) {
  sendData("AT+RST\r\n", 2000, DEBUG); // Reset
  sendData("AT+CWJAP=\"USERNAME\",\"PASSWORD\"\r\n", 2000, DEBUG); // Netwerk
  delay(3000);
  sendData("AT+CWMODE=1\r\n", 1000, DEBUG); // Station mode
  sendData("AT+CIFSR\r\n", 1000, DEBUG); // IP-adres tonen
  lcd.clear(); lcd.print("8266 Connected");
  Serial.println("8266 Connected");
}

Functie sendData() voor AT-commando's:

/***************************************************
 * AT-commando's sturen naar 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()) {
      char c = esp8266.read();
      response += c;
    }
  }
  if (debug) Serial.print(response);
  return response;
}

Deze functies worden in setup() aangeroepen. Bij succes zie je vergelijkbare berichten in de Seriële Monitor.

Stap 4: Cloud-opslag: ThingSpeak.com

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Alle data wordt geüpload naar de gratis service van ThingSpeak.com.

In loop() (na readSensors()) roepen we updateDataThingSpeak() aan:

/***************************************************
 * Data naar ThingSpeak sturen
 ***************************************************/
void updateDataThingSpeak(void) {
  startThingSpeakCmd();
  cmd = msg;
  cmd += "&field1="; cmd += tempDHT;      // Veld 1: DHT temperatuur
  cmd += "&field2="; cmd += humDHT;       // Veld 2: DHT vochtigheid
  cmd += "&field3="; cmd += lumen;        // Veld 3: LDR licht
  cmd += "&field4="; cmd += soilMoist;    // Veld 4: Bodemvochtigheid
  cmd += "&field5="; cmd += pumpStatus;   // Veld 5: POMP status
  cmd += "&field6="; cmd += lampStatus;   // Veld 6: LAMP status
  cmd += "\r\n";
  sendThingSpeakCmd();
}

Communicatie starten met startThingSpeakCmd():

/***************************************************
 * Communicatie met ThingSpeak starten
 ***************************************************/
void startThingSpeakCmd(void) {
  cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += IP;
  cmd += "\",80";
  esp8266.println(cmd);
  delay(2000);
  if (esp8266.find("Error")) {
    Serial.println("ESP8266 START ERROR");
    return;
  }
  Serial.println("Thinkspeak Comm Started");
  cmd = "";
}

Data uploaden met sendThingSpeakCmd():

/***************************************************
 * ThingSpeak kanaal updaten
 ***************************************************/
String sendThingSpeakCmd(void) {
  esp8266.print("AT+CIPSEND=");
  esp8266.println(cmd.length());
  if (esp8266.find(">")) {
    esp8266.print(cmd);
    Serial.println(""); Serial.println(""); Serial.println(cmd);
    delay(500);
    String messageBody = "";
    while (esp8266.available()) {
      String line = esp8266.readStringUntil('\n');
      if (line.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");
    error = 1; return "error";
  }
}

Bovenstaande functies gebaseerd op tutorial van Michalis Vasilakis: Arduino IOT: Temperature and Humidity (with ESP8266 WiFi).

Stap 5: Actuatoren besturen vanaf het web

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Data uploaden is goed voor monitoring, maar we willen ook op afstand pomp/lamp aansturen. We maken specifieke velden op ThingSpeak voor commando's:

  • Veld 7: 1 = POMP AAN, 0 = POMP UIT
  • Veld 8: 1 = LAMP AAN, 0 = LAMP UIT

Om een veld in te stellen via browser (met jouw Write Key):

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

Om de laatste waarde van een veld op te halen:

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

Functie om veld 7 te lezen:

/***************************************************
 * Laatste data uit veld 7 lezen (ThingSpeak)
 ***************************************************/
int readLastDataField7() {
  startThingSpeakCmd();
  cmd = msgReadLastDataField7;
  cmd += "\r\n";
  String messageDown = sendThingSpeakCmd();
  Serial.print("Command received: "); Serial.println(messageDown[7]);
  int command = messageDown[7] - 48; // ASCII naar int
  return command;
}

Vergelijkbare functie voor veld 8. Vervolgens commando's uitvoeren op actuatoren:

/***************************************************
 * Commando's van ThingSpeak ontvangen en uitvoeren
 ***************************************************/
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);
}

Nu kun je via browser-regel pomp en lamp remote aan/uit zetten. De ontvangen commando's verschijnen in de Seriële Monitor.

Coördinatie lokaal vs remote: We passen readLocalCmd() aan om ook ThingSpeak velden 7/8 te updaten met pomp/lamp-status (in de respectievelijke IF-statements). Zie complete code aan het eind.

field7Data = pumpStatus;
field8Data = lampStatus;

Nu zijn velden 7/8 gesynchroniseerd met zowel web-commando's als lokale knopacties. Update aplyCmd() die de actuatoren aanstuurt:

/***************************************************
 * Commando's ontvangen en op actuatoren toepassen
 ***************************************************/
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);
}

Prioriteitsregels: Elke luscyclus checken we lokale knoppen. Elke ~20 seconden polen we ThingSpeak voor remote commando's. Elke ~75 seconden lezen we sensoren, updaten ThingSpeak en voeren automatische acties uit (deze hebben "het laatste woord"). Je kunt dit aanpassen naar wens.

Twee timers:

long sampleTimingSeconds = 75;        // Sensor leesinterval (seconden)
long poolingRemoteCmdSeconds = 20;    // Remote command polling interval (seconden)

Herschreven loop():

void loop() {
  elapsedRemoteCmdTime = millis() - startRemoteCmdTiming;
  elapsedTime = millis() - startTiming;
  reverseElapsedTimeSeconds = round(sampleTimingSeconds - elapsedTime/1000);
  
  readLocalCmd();      // Lokale knoppen
  showDataLCD();       // Display updaten
  
  if (elapsedRemoteCmdTime > (poolingRemoteCmdSeconds * 1000)) {
    receiveCommands();         // Remote commando's ophalen
    updateDataThingSpeak();    // Status terugsturen
    startRemoteCmdTiming = millis();
  }
  
  if (elapsedTime > (sampleTimingSeconds * 1000)) {
    readSensors();             // Sensoren lezen
    autoControlPlantation();   // Automatische besturing
    updateDataThingSpeak();    // Data uploaden
    startTiming = millis();
  }
}

Stap 6: Toegewezen Webpagina Implementeren

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

De browser-oplossing is functioneel maar niet elegant. Een speciale webpage is beter: data tonen + knoppen voor actuatoren.

Ik gebruikte Byethost (gratis webhosting) en kennis uit de Coursera/University of Michigan specialisatie Learn to Design and Create Websites (HTML5, CSS3, JavaScript).

De pagina communiceert niet direct met de ArduFarmBot, maar met ThingSpeak:

  • Sensordata lezen uit velden 1, 2, 3, 4
  • Actuatorstatus lezen uit velden 5, 6
  • Commando's schrijven naar velden 7, 8
  • Lokaal weerdata ophalen via Yahoo-services (optioneel)

Broncode (HTML, CSS, JS) is bijgevoegd: FQOK9ENIT653YX5.zip

Stap 7: Terug naar de "hersenen" – Sensor-Actuator Matrix

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

In Deel 1 definieerden we simpele regels. Voor complexere situaties gebruiken we een Sensor-Actuator Matrix. In Excel (bijgevoegd) zijn alle sensorcondities en actuatoruitgangen in een matrix vastgelegd.

Vertaald naar code: een array van 18 regels × 10 kolommen:

// +---BODEM---+--LICHT--+--TEMP---+--ACTUAT--+
// SL SM SH LL LH TL TM TH Pomp Lamp
boolean 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}
};

Functie defSensorStatus() test per regel of de eerste 8 kolommen (sensorcondities) TRUE zijn. Zo ja, voer de actuatoracties uit (laatste 2 kolommen).

if (1 && 0 && 0 && 0 && 1 && 0 && 0 && 1) { pumpStatus=1; lampStatus=0; }
else if (1 && 0 && 0 && 0 && 1 && 0 && 1 && 0) { pumpStatus=1; lampStatus=0; }
// enzovoort...

Interne array snsSts[8] houdt sensorstatussen bij (ook voor logging).

Excel-bestand: F2HWXBYITA8WIN1.xlsx

Stap 8: Code-optimalisatie

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Display: LCD standaard UIT. Knop "Sensors Read" werkt als toggle om display aan/uit te zetten (update sensoren voor display, niet voor reguliere functies).

Initiële setup: Bij opstart/reset toont LCD "Initial Set-up". Druk "Sensors" om te starten. Instellingen: Koude temp (12°C), Droge bodem (30%), Natte bodem (60%), Donker licht (40%), Pomp AAN-tijd (10s), Scan-tijd (600s), SW-versie (4.1).

Log registratie: Elke meetcyclus voert storeDataLogEEPROM() uit. Er wordt bit-gepakt opgeslagen: sensorstatussen (8 bits) + pomp-status + lamp-status in EEPROM.

/***************************************************
 * Logdata opslaan in 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++;
}

Code opgesplitst in meerdere bestanden voor overzichtelijkheid. Nieuwe bestanden in Deel 2:

  • communication.ino (ThingSpeak & ESP8266 functies)
  • stationCredentials.h (ThingSpeak Channel ID & Write Keys)

Geheugenoptimalisatie: Constante data in flash (programma) geheugen via PROGMEM ipv SRAM. Bijv. const PROGMEM byte DHTPIN = 5; + #include <avr/pgmspace.h>. Debug Serial.print() regels uitcommentariëren bespaart ook SRAM.

Complete codebestanden (vervang dummy-gegevens in credentials.h met jouw Channel ID/Write Key, en in communication.ino jouw WiFi-gegevens):

Stap 9: De MJRovai Hometuin

Onderstaande foto's tonen de evolutie van mijn eerste tomatenteelt onder controle van ArduFarmBot.

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Tweede teelt: van zaailing tot selectie beste 6 planten (~45 dagen) en verplanting.

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Stap 10: Conclusie

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Dat is het voor nu! Ik hoop dat dit project anderen helpt in de spannende wereld van electronica, IoT en robotica!

Binnenkort waarschijnlijk Deel 3: een recept voor biologische tomatensaus pasta. Op de foto hierboven zie je de eerste levenstekens van Mauricios teelt!

Bekijk ook het nieuwe ArduFarmBot, het boek! waar het hele project in een vriendelijk formaat is gebundeld:

ArduFarmBot, het Boek!

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Ook verkrijgbaar op Amazon.com. Het boek gebruikt de ArduFarmBot-controller als basis om te leren werken met:

  • LCD en OLED displays
  • LEDs en knoppen
  • Activering van pompen en lampen via relais
  • Sensoren: DHT22 (lucht temp/vocht), DS18B20 (bodemtemp), YL69 (bodemvocht), LDR (licht)
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Alle fas gedocumenteerd met uitleg, blokdiagrammen, kleurenfoto's, Fritzing-schema's, complete code op GitHub en YouTube-video's.

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Twee versies van ArduFarmBot uitgewerkt. Deel 1: Arduino Nano als lokaal station (handmatig/automatisch). Deel 2: Remote operatie via webpage, ESP8266-01 voor WiFi, ThingSpeak.com. Deel 3: NodeMCU ESP8266-12E vervangt zowel Nano als ESP-01, plus Blynk-platform.

ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen
ArduFarmBot Deel 2: Een Extern IoT-besturingsstation Bouwen

Download het boek, geef een review en gebruik het berichtenbord voor commentaar, suggesties of kritiek!

Meer projecten op mijn blog: MJRoBot.org

Groetjes uit het zuiden van de wereld!

Tot de volgende keer!

Dank je wel

Marcelo

Code

Alle code-snippets en volledige bestanden zijn in de bovenstaande stappen verwerkt. De complete projectcode is te vinden op GitHub:

https://github.com/Mjrovai/ArduFarmBot

Schema

Fritzing-schema (ardufarmbot_qpNcBDX6Jr.fzz)

Productieproces

  1. Arduino-gestuurde 6-Shooter Drank Mixstation – Bouw je eigen Cocktail Automaat
  2. Meerpositie-temperatuursensorsysteem voor slimme thuisintegratie
  3. MotionSense: Slimme inbraakdetectie met Arduino en ESP8266
  4. 3D-Printer Brandpreventie: Slimme Sensor Veiligheidssysteem
  5. Web-IoT Meter Bouwen met Arduino, Yaler en IFTTT
  6. Arduino-gebaseerde Afstotende Magnetische Levitatie: Eenvoudige Schakeling & DIY Handleiding
  7. Geavanceerde Remote-gecontrolleerde Gripper Robot voor Precisiehantering
  8. High-Performance Arduino Weerballon Datalogger
  9. Bouw een $10 Draagbare Arduino Weerstation (AWS) – Eenvoudige DIY met Nano, DHT22, BMP180 & LCD
  10. CoroFence Thermische Detector: Geavanceerde PIR-sensor & IoT-integratie
  11. Opkomende Trends in IoT-implementatie: Inzichten & Strategieën