Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

ArduFarmBot Partie 2 : Construction d'une Station de Contrôle IoT à Distance

Composants et Fournitures

Composant Description Quantité
Arduino Nano R3 Microcontrôleur principal 1
Espressif ESP8266 ESP-01 Module WiFi pour connectivité IoT 1
Capteur Température/Humidité DHT22 Mesure air ambiant 1
Module Photoreflecteur KY-018 Capteur luminosité 1
Capteur Humidité Sol (Hydrometer) Mesure humidité du sol 1
Relais (générique) Contrôle pompe et lampe 2
Écran LCD 4x20 (I2C) Affichage données 1
Bouton Poussoir 12mm SparkFun Clavier membrane 4 touches 3
LED (générique) Indicateurs d'état 3

Applications et Services en Ligne

Service Description
ThingSpeak API Plateforme cloud pour stockage et visualisation données IoT

À Propos de ce Projet

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Ce tutoriel est la continuation de ArduFarmBot : Contrôle d'une Ferme Tomate Maison avec Arduino et IoT.

Dans la première partie, nous avons créé une station de contrôle locale, capturant les informations d'une plantation de tomates : température, humidité relative de l'air, luminosité et humidité du sol. Sur la base de ces données, l'ArduFarmBot décidait automatiquement la bonne quantité (et le moment) d'arrosage et de chauffage. La station locale de la Partie 1 permettait aussi une intervention manuelle d'un opérateur pour contrôler la pompe à eau et la lampe électrique. Dans cette Partie 2, nous implémentons une approche IoT où cette "intervention manuelle" sera également possible à distance via Internet. Le diagramme de blocs montre comment nous procéderons.

Notez que les données capturées seront envoyées vers un "service de stockage Cloud" (dans notre cas ThinkSpeak.com). Un site web dédié, la "Page de Contrôle à Distance", surveillera et affichera ces données en quasi temps réel. Cette page web permettra aussi l'activation à distance de la pompe et de la lampe.

Étape 1 : Liste du Matériel (Bill of Material)

Étape 2 : Compléter le Matériel

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

En partant de la Station Locale développée dans la Partie 1, le seul matériel supplémentaire nécessaire est l'ESP8266. Le diagramme de blocs ci-dessus montre toutes les connexions des broches Arduino et composants principaux. La seule précaution concerne le niveau de tension : l'ESP8266 fonctionne en 3,3V, donc la broche Rx ne doit pas être connectée directement à la broche Tx du Nano (D3). Un diviseur de tension doit être utilisé comme convertisseur de niveau. Les schémas ci-dessus montrent en détail comment connecter l'ESP8266. Pour en savoir plus sur l'ESP8266, consultez mes tutoriels :

Note : nous utilisons l'ESP8266 connecté aux broches Nano 2 (Tx) et 3 (Rx) via la bibliothèque SoftSerial. Pour "libérer" ces broches numériques, vous pouvez alternativement utiliser les broches série natives 0 et 1 du Nano. N'oubliez pas de les déconnecter lors du téléversement du code.

NOTE : Si vous voulez connecter le BUZZER, faites-le sur la broche D17 (identique à A3). C'est bien d'avoir un son en cas d'erreur de communication. Je l'ai utilisé pendant la phase de test, puis retiré au projet final (le matériel, mais le code le prévoit). À vous de voir.

Vous pouvez utiliser le code ci-dessous pour tester et/ou configurer votre ESP8266 :

FC9DBPKIT682FY7.ino

Étape 3 : Connexion de l'ESP8266

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Pour connecter l'ArduFarmBot à Internet, nous utilisons l'ESP8266, un module simple, bon marché et facile à programmer pour projets IoT. Une fois le module installé, la première chose à faire est d'appliquer un "Reset" sur sa broche CH-PD :

/***************************************************
 * Fonction Reset pour accepter la communication
 ****************************************************/
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 ");
}

Après le reset, connectons-le à votre réseau local avec vos identifiants (dans le code, remplacez : USERNAME et PASSWORD) et initialisons le module en mode "STA: Station Mode" (CWMODE = 1) :

/***************************************************
 * Connexion WiFi
 ****************************************************/
void connectWiFi(void) {
  sendData("AT+RST\r\n", 2000, DEBUG); // reset
  sendData("AT+CWJAP=\"USERNAME\",\"PASSWORD\"\r\n", 2000, DEBUG); // Connexion réseau
  delay(3000);
  sendData("AT+CWMODE=1\r\n", 1000, DEBUG);
  sendData("AT+CIFSR\r\n", 1000, DEBUG); // Afficher adresse IP
  lcd.clear();
  lcd.print("8266 Connected");
  Serial.println("8266 Connected");
}

Pour envoyer des données à l'ESP8266, on utilise la fonction sendData() :

/***************************************************
 * Envoi commandes AT au 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;
}

Ces fonctions seront appelées pendant la "Phase Setup" de notre code. Si tout est correct, vous devriez voir des messages similaires au Moniteur Série.

Étape 4 : Stockage Cloud des Données : ThinkSpeak.com

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Toutes les données capturées par l'ArduFarmBot seront envoyées dans le cloud via le service gratuit de ThinkSpeak.com.

Dans la fonction Loop() (après avoir capturé les données avec readSensors()), nous appellerons une fonction spécifique pour envoyer les données : updateDataThingSpeak();

/***************************************************
 * Transmission données vers thingspeak.com
 ****************************************************/
void updateDataThingSpeak(void) {
  startThingSpeakCmd ();
  cmd = msg ;
  cmd += "&field1="; // field 1 pour température DHT
  cmd += tempDHT;
  cmd += "&field2="; // field 2 pour humidité DHT
  cmd += humDHT;
  cmd += "&field3="; // field 3 pour luminosité LDR
  cmd += lumen;
  cmd += "&field4="; // field 4 pour humidité sol
  cmd += soilMoist;
  cmd += "&field5="; // field 5 pour statut POMPE
  cmd += pumpStatus;
  cmd += "&field6="; // field 6 pour statut LAMPE
  cmd += lampStatus;
  cmd += "\r\n";
  sendThingSpeakCmd();
}

Pour envoyer ces données, il faut d'abord démarrer la communication avec ThingSpeak via la fonction startThingSpeakCmd (); :

/***************************************************
 * Démarrage communication ThingSpeak.com
 ****************************************************/
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 ="";
}

Une fois le canal ouvert avec ThingSpeak et la chaîne "cmd" assemblée avec les données, il est temps de tout envoyer sur le canal correspondant via la fonction sendThingSpeakCmd(); :

/***************************************************
 * Mise à jour canal ThingSpeak.com
 ****************************************************/
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) {
        // contenu réel commence après ligne vide (longueur 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");
    // Renvoi...
    error=1;
    return "error";
  }
}

Ces fonctions sont basées sur un excellent tutoriel détaillé de Michalis Vasilakis. Pour plus de détails, voir son tutoriel : Arduino IOT: Temperature and Humidity (with ESP8266 WiFi).

Étape 5 : Commander les Actionneurs depuis le Web

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

À ce stade, nous envoyons toutes les données collectées et les stockons dans le cloud. C'est très bien pour la surveillance à distance, mais que se passe-t-il si, basé sur ces données, nous voulons aussi allumer la Pompe ou la Lampe, indépendamment du programme automatique local ? Pour cela, nous devons aussi "Télécharger" des données du Cloud et commander le contrôleur d'agir selon ces commandes.

Nous créerons des champs spécifiques sur notre canal ThinkSpeak pour commander les actionneurs :

Champ 7 :

Champ 8 :

Comment configurer ces champs directement sur ThingSpeak ? On peut le faire en écrivant un "PlugIn" directement sur ThinkSpeak, ou en utilisant un site web externe (notre choix). Dans les deux cas, on utilise une commande comme :

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

Avec cette commande (et votre clé d'écriture), vous écrirez "1" au champ 7, ce qui signifie que la POMPE doit s'allumer. Testez facilement en entrant la commande dans votre navigateur – le champ correspondant de votre canal changera. En retour, le navigateur affiche une page blanche avec un seul chiffre en haut à gauche, correspondant à l'entrée séquentielle dans votre canal.

50 % du travail est fait. Maintenant, il faut lire cette "commande" (donnée du champ) sur la station ArduFarmBot locale.

La commande pour lire la dernière donnée écrite sur un champ spécifique :

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

Même principe : testez dans votre navigateur. Il affichera la donnée de ce champ. Voir la photo ci-dessus.

Retour sur terre, écrivons une fonction qui lit ce "dernier champ" :

/***************************************************
 * Lecture données field7 de 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;
}

Cette fonction retourne la donnée du champ 7 ("1" ou "0"). Une fonction similaire pour le Champ 8.

Une fois le contenu des deux champs récupéré, on l'utilise dans une fonction qui commande les actionneurs comme on le faisait pour la "fonction commande manuelle" :

/***************************************************
 * Réception Commandes depuis 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);
}

Dès maintenant, vous pouvez utiliser la ligne de commande dans votre navigateur pour Allumer/Éteindre la Pompe et la Lampe à distance. La photo ci-dessus montre comment la commande reçue apparaît sur votre Moniteur Série.

Autre point important : la "coordination" entre commande locale et distante. Nous devons modifier la fonction readLocalCmd() pour aussi mettre à jour les champs ThingSpeak 7 et 8 respectivement avec le statut Pompe et Lampe (dans leur "IF statement" respectif – voir le code complet à la fin) :

field7Data = pumpStatus;
field8Data = lampStatus;

Maintenant "field7Data" et "field8Data" sont synchronisés avec les commandes de la page web et aussi avec les actions locales quand vous appuyez sur un bouton. Mettons à jour la fonction aplyCmd(), responsable d'allumer/éteindre les actionneurs :

/***************************************************
 * Réception Commandes et action sur actionneurs
 ****************************************************/
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);
}

Quand vous commencez vos tests, vous verrez que toute commande manuelle (locale ou web) sera écrasée par les actions automatiques définies par autoControlPlantation(). À ce stade, il faut décider qui sera le "chef", ayant le dernier mot ! Dans notre cas :

Vous pouvez changer cette logique comme vous voulez. C'est l'avantage d'utiliser un processeur programmable !

Deux temporisateurs seront utilisés : un pour le polling des commandes distantes, un autre pour la lecture des capteurs (le même qu'avant) :

long sampleTimingSeconds = 75; // Temps échantillonnage en secondes pour lecture capteurs
int reverseElapsedTimeSeconds = 0;
long startTiming = 0;
long elapsedTime = 0;
long poolingRemoteCmdSeconds = 20; // Temps polling en secondes pour nouvelles commandes ThingSpeak
long startRemoteCmdTiming = 0;
long elapsedRemoteCmdTime = 0;

La fonction loop() doit maintenant être réécrite ainsi :

void loop() {
  elapsedRemoteCmdTime = millis()-startRemoteCmdTiming; // Timer polling commandes distantes
  elapsedTime = millis()-startTiming; // Timer mesures
  reverseElapsedTimeSeconds = round (sampleTimingSeconds - elapsedTime/1000);
  readLocalCmd(); // Lecture statut boutons locaux
  showDataLCD();
  if (elapsedRemoteCmdTime > (poolingRemoteCmdSeconds*1000)) {
    receiveCommands();
    updateDataThingSpeak();
    startRemoteCmdTiming = millis();
  }
  if (elapsedTime > (sampleTimingSeconds*1000)) {
    readSensors();
    autoControlPlantation();
    updateDataThingSpeak();
    startTiming = millis();
  }
}

Étape 6 : Implémentation d'une Page Web Dédiée

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

L'ArduFarmBot est opérationnel et contrôlable depuis le web. Vous pouvez surveiller les données sur ThingSpeak et envoyer des commandes via navigateur, mais ce n'est pas une solution "élégante" ! La meilleure façon d'implémenter une solution IoT complète est de développer une page web complète qui affiche toutes les données et propose des boutons pour actionner les actionneurs.

J'ai choisi Byethost, un hébergeur web gratuit, très simple pour gérer vos pages. J'ai aussi profité de l'occasion pour appliquer ce que j'ai appris dans une excellente spécialisation en ligne sur Coursera/Université du Michigan : Learn to Design and Create Websites (Construire un portfolio web responsive et accessible avec HTML5, CSS3 et JavaScript).

Je ne détaillerai pas le développement de cette page (ce n'est pas le but de ce tutoriel), mais j'inclus ici les codes sources HTML, CSS et JavaScript. Si quelqu'un s'intéresse à la méthode, on peut en discuter dans les commentaires.

Il est important de noter que cette page n'interagit pas directement avec la Station de Contrôle Locale ArduFarmBot. Elle interagit avec le canal ThingSpeak comme suit :

Le point 4 n'est pas crucial mais fournit des données additionnelles pour d'éventuelles actions à distance indépendantes de la plantation locale. Vous pourriez par exemple stocker ces données sur un autre canal ThingSpeak et les télécharger vers votre Arduino pour afficher la météo sur l'écran LCD local (j'ai fait ça sur un autre projet sympa qui marchait bien ! Je le laisse comme suggestion).

FQOK9ENIT653YX5.zip

Étape 7 : Retour au Cerveau. Approche Matrice Capteur-Actionneur

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Dans la première partie, nous avions défini des considérations préliminaires sur comment les actionneurs devaient agir selon les lectures des capteurs. Nous n'avions fait que des choix simples, mais que se passe-t-il dans des situations plus complexes ? Plusieurs conditions différentes ? Nous allons développer une "approche Matrice Capteur-Actionneur".

Dans une Matrice, on définit pour chaque capteur sa condition et comment doit être la sortie des actionneurs. Le résultat est visible dans le fichier Excel joint ci-dessous. Il y a deux onglets : un tableau avec filtre et une version où vous pouvez sélectionner plusieurs conditions de capteurs et voir comment les actionneurs réagiront.

Une fois la Matrice définie, il faut la traduire en code. Un tableau de 18 lignes et 10 colonnes a été créé pour "copier" les conditions de la Matrice Capteur-Actionneur :

// +---SOIL----+-LIGHT-+---TEMP---+---ACTUAT----+
// SL SM SH LL LH TL TM TH Pump 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 },
};

Pour travailler avec la Matrice, nous créons une fonction defSensorStatus (). Cette fonction teste pour chaque ligne si la condition des 8 premières colonnes est VRAIE. Si oui, la condition des 2 dernières colonnes est exécutée.

Par exemple :

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

Et ainsi de suite.

À l'intérieur de cette fonction, un autre tableau est créé avec le statut de chaque lecture de capteur :

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

Ce tableau servira aussi pour le registre LOG.

F2HWXBYITA8WIN1.xlsx

Étape 8 : Optimisation du Code

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Pendant le développement de l'ArduFarmBot, nous avons réalisé que certains changements par rapport à la spécification originale étaient nécessaires :

Affichage :

L'écran LCD doit être ÉTEINT par défaut. À chaque fois qu'une lecture de capteurs est nécessaire, on peut l'allumer manuellement. Cette condition a été implémentée dans le code : le bouton "Lecture Capteurs" fonctionne en mode "toggle" pour Allumer/Éteindre le LCD à tout moment. Allumer ou éteindre l'affichage mettra à jour les lectures pour l'affichage, mais ne sera pas utilisé par l'ArduFarmBot dans ses fonctions régulières.

Configuration Initiale :

Au démarrage (ou reset) de l'ArduFarmBot, le LCD affiche la "Configuration Initiale". Pour lancer le programme, il faut appuyer sur le bouton "Capteurs". Les informations initiales affichées (voir photo) :

Registre LOG :

Pour des raisons d'audit, nous avons créé un LOG avec les lectures et actions de notre ArduFarmBot. À chaque cycle de lecture, la fonction storeDataLogEEPROM() est exécutée.

/***************************************************
 * Stockage données Log dans EEPROM Arduino
 ****************************************************/
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++;
}

Comme mentionné à l'étape précédente, ce qui est stocké dans l'EEPROM Arduino est le contenu, bit par bit, du tableau snsSts[] plus le statut Pompe et Lampe. Vous pouvez voir le LOG sur le Moniteur Série.

Tout le code ArduFarmBot a été divisé en différents fichiers pour être plus facile à comprendre. Notez que 2 nouveaux fichiers ont été ajoutés dans cette deuxième partie :

Enfin, une fois le code arrivé à une taille raisonnable, nous avons décidé de stocker les données constantes en mémoire flash (programme) au lieu de la SRAM. Pour cela, on utilise le mot-clé PROGMEM qui est un modificateur de variable. Par exemple, au lieu de :

#define DHTPIN 5

Nous avons utilisé :

const PROGMEM byte DHTPIN = 5;

Le mot-clé PROGMEM dit au compilateur "mets cette info en mémoire flash", au lieu de la SRAM où elle irait normalement. Vous devez aussi inclure la bibliothèque avr/pgmspace.h dans le fichier principal.

Une autre bonne pratique pour réduire l'usage de la SRAM : commenter (ou supprimer) toutes les lignes Serial.Print() utilisées pour le débogage pendant le développement. Vous verrez que le code pour afficher le LOG sur le Moniteur Série sera commenté dans les fichiers ci-dessous.

Ci-dessous, le code complet de l'ArduFarmBot Arduino. N'oubliez pas de changer les données factices dans credentials.h avec votre ID Canal et Clé d'écriture. Aussi dans communication.ino, utilisez vos vrais identifiants pour connecter l'ESP8266 à Internet.

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

Étape 9 : La Ferme Maison MJRovai

Les photos ci-dessous montrent l'évolution séquentielle de l'ArduFarmBot contrôlant ma première plantation de tomates.

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

La séquence photo ci-dessous montre l'évolution de ma 2e plantation, du semis jusqu'à la sélection des meilleurs plants (environ 45 jours) et la transplantation des 6 meilleurs.

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Étape 10 : Conclusion

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance
ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

C'est tout pour l'instant !

Comme toujours, j'espère que ce projet aidera d'autres à trouver leur voie dans le monde passionnant de l'électronique, de l'IoT et de la robotique !

Bientôt, nous publierons probablement la troisième et dernière partie de notre projet qui, je l'espère, sera une excellente recette de pâtes à la sauce tomate bio.

Au passage, sur la photo ci-dessus, on voit les premiers signes de vie sur la plantation de Mauricio ! Et avant de partir, jetez un œil au nouveau ArduFarmBot, le livre !, où je regroupe tout le projet dans un format plus convivial :

ArduFarmBot, le Livre !

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

"ArduFarmBot, le livre" est aussi sur Amazon.com ! Vous pouvez l'obtenir en cliquant ici. Le livre utilise le contrôleur électronique ArduFarmBot comme base pour enseigner comment travailler à la fois en HW et SW avec :

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Toutes les étapes clés du projet sont documentées en détail via textes explicatifs, diagrammes de blocs, photos haute résolution en couleur, schémas électriques avec Fritzing, codes complets sur GitHub et vidéos YouTube.

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Deux versions du contrôleur électronique ArduFarmBot sont développées en détail. À partir de la capture de données d'un jardin (température air/sol, humidité relative, humidité sol, luminosité), l'ArduFarmBot aide à contrôler quand une culture doit recevoir chaleur et eau. Le contrôle se fait automatiquement, localement et à distance via Internet. Le livre est en 3 parties. Dans la première, l'Arduino Nano est le point de départ pour développer une version locale de l'ArduFarmBot, contrôlable manuellement et automatiquement.

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Dans la deuxième partie, le livre plonge dans la conception d'automatisation, introduisant le contrôle à distance via la création d'une page web. L'ESP8266-01 est utilisé pour la connexion Wi-Fi, l'envoi de données vers un service web majeur de l'IoT, ThingSpeak.com.

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Dans la troisième partie, une deuxième version de l'ArduFarmBot est développée, introduisant le NodeMCU ESP8266-12E, un dispositif IoT puissant et polyvalent, qui remplace à la fois l'Arduino Nano et l'ESP8266-01 utilisés dans les parties précédentes.

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Dans cette dernière partie, une nouvelle plateforme de service de l'univers IoT, Blynk, est aussi explorée.

ArduFarmBot Partie 2 : Construction d une Station de Contrôle IoT à Distance

Téléchargez le livre, donnez un avis et utilisez le forum ici pour tout commentaire, suggestion ou critique !

Pour plus de projets, visitez mon blog : MJRoBot.org

Saludos du sud du monde !

À mon prochain projet !

Merci

Marcelo

Code (Extraits)

Le code complet est divisé en plusieurs fichiers. Voici les extraits principaux :

Extrait #1 : Reset ESP8266

/***************************************************
 * Fonction Reset pour accepter la communication
 ****************************************************/
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 ");
}

Extrait #2 : Connexion WiFi

/***************************************************
 * Connexion 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");
}

Extrait #3 : Envoi Commandes AT

/***************************************************
 * Envoi commandes AT au 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;
}

Extrait #4 : Envoi Données ThingSpeak

/***************************************************
 * Transmission données vers 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();
}

Extrait #5 : Démarrage Communication ThingSpeak

/***************************************************
 * Start communication with ThingSpeak.com
 ****************************************************/
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 ="";
}

Extrait #6 : Mise à jour Canal ThingSpeak

/***************************************************
 * Update channel ThingSpeak.com
 ****************************************************/
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";
  }
}

Extrait #9 : Lecture Champ 7 ThingSpeak

/***************************************************
 * 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;
}

Extrait #10 : Réception Commandes ThingSpeak

/***************************************************
 * 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);
}

Extrait #11 : Application Commandes Actionneurs

/***************************************************
 * 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);
}

Extrait #12 : Configuration Temporisateurs

long sampleTimingSeconds = 75; // Sample time in seconds to read sensors
int reverseElapsedTimeSeconds = 0;
long startTiming = 0;
long elapsedTime = 0;
long poolingRemoteCmdSeconds = 20; // Pooling time in seconds for new ThingSpeak commands
long startRemoteCmdTiming = 0;
long elapsedRemoteCmdTime = 0;

Extrait #13 : Boucle Principale loop()

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();
  }
}

Extrait #14 : Matrice Capteur-Actionneur

// +---SOIL----+-LIGHT-+---TEMP---+---ACTUAT----+
// SL SM SH LL LH TL TM TH Pump 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 },
};

Extrait #15 : Stockage LOG EEPROM

/***************************************************
 * 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

Schémas

ardufarmbot_qpNcBDX6Jr.fzz

Processus de fabrication

  1. Tendances émergentes dans l'implémentation IoT : Insights et stratégies
  2. Station de Mixage Automatique 6-Shooter Pilotée par Arduino – Construisez Votre Propre Robot Barman
  3. Système de Capteur de Température Multi-Position pour Intégration Domotique
  4. MotionSense : Détection d'intrusion intelligente avec Arduino et ESP8266
  5. Prévention incendie imprimante 3D : Système de sécurité à capteur intelligent
  6. Créer une jauge IoT connectée au Web avec Arduino, Yaler et IFTTT
  7. Lévitation magnétique répulsive avec Arduino : circuit simple et guide DIY
  8. Robot préhenseur télécommandé avancé pour manipulation de précision
  9. CoroFence : Détecteur Thermique Avancé PIR + Capteur Grid-EYE & IoT