Fabrication d'un capteur connecté avec ESP8266 et code serveur

image principale Fabrication d'un capteur connecté avec ESP8266 et code serveur

Difficulté:

Aujourd'hui, nous allons découvrir comment fabriquer un capteur connecté basé sur l'ESP8266 et développer un site web pour visualiser les données du capteur. Nous serons accompagnés de ChatGPT, qui nous fournira des conseils précieux pour la programmation du capteur, en veillant à éviter toute erreur.

Matériel :

Budget : Non défini

  • 1 Hébergeur Php Mysql
  • 1 DHT22
  • 1 Esp8266 ou autre

Etape 1 :

Etape 2 : Le code esp

#include <WiFiUdp.h> 
#include <ESP8266WiFi.h> 
#include <NTPClient.h> 
#include <ESP8266HTTPClient.h> 
#include <DHT.h> 
#include <WiFiClient.h> 
#include <arduino-timer.h> 
#include "config.h" 
// parametre NTP pour le serveur et parametre de l'heure
const char *ntpServer = "europe.pool.ntp.org";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;

#define DHTPIN 4 //pin pour le DHT
DHT dht(DHTPIN, DHT11);
 // parametrage NTP date et heure WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, ntpServer, gmtOffset_sec, daylightOffset_sec);
 // timer
auto timer = timer_create_default();
 // recuperation du temps et heure sur le serveur
bool miseAJourTimeWeb(void *){
timeClient.update();
Serial.print("TempsWeb");
Serial.println(timeClient.getFormattedTime());
return true; // repeter
}
 // Fonction de réinitialisation de la carte ESP8266
bool resetESP8266(void *) {
ESP.reset();
delay(5000); // Attendre 5 secondes pour la réinitialisation
return true; // repeter
}
void setup() {
Serial.begin(115200);
//connexion au wifi
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
 //activation dht
dht.begin();
//activation timerClient
timeClient.begin();
// recuperation date et heure
miseAJourTimeWeb(NULL);
 // creation d'un timer de recuperation date et heure
timer.every(3600000, miseAJourTimeWeb);
// creation d'un timer de recuperation capteur
timer.every(300000, mesuresCapteur);
// creation d'un timer d'envoie serveur
timer.every(301000, envoieServeur);
 // Création d'un timer pour la réinitialisation tous les 4 jours (4 jours = 345600000 millisecondes)
timer.every(345600000, resetESP8266);
} 
//fonction de mesure de capteur
bool mesuresCapteur(void *){
// recuperation valeur dht
float h = dht.readHumidity();
float t = dht.readTemperature();
 // si valeurs pas ok alors on relance
while (isnan(h) || isnan(t) || ( h < 0.1 && t < 0.1)) {
Serial.println("Failed to read valid data from DHT sensor. Retrying...");
delay(1000); // attendre une seconde avant la prochaine tentative
h = dht.readHumidity();
t = dht.readTemperature();
}
// envoie des données dans un tableau de stockage (1,h) correspond au capteur 1 de notre serveur // (2,t) correspond au capteur 2 de notre serveur
recordSensorData(1,h);
recordSensorData(2,t);
 Serial.print((float)t); Serial.print(" *C, "); Serial.print((float)h); Serial.println(" H"); return true; // repeter }
 // fonction pour envoyer les données sur le serveur
bool sendData(String url) {
 // pour debug //Serial.println(url); 
WiFiClient client; HTTPClient http; if (!client.connect(HOST, 80)) { Serial.println("Wifi absent ou site web ko"); // fonction pour relancer le wifi quand il est ko if (WiFi.status() != WL_CONNECTED) { Serial.println("WiFi absent. Reconnexion..."); WiFi.disconnect(); WiFi.reconnect(); }
return false; }
 String serverPath = url; // Your Domain name with URL path or IP address with path http.begin(client, serverPath.c_str()); 
// Send HTTP GET request int httpResponseCode = http.GET(); 
if (httpResponseCode>0) { Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); String payload = http.getString(); Serial.println(payload); 
if(httpResponseCode != 200){ http.end(); return false; }
} else { Serial.print("Error code: "); Serial.println(httpResponseCode); http.end(); return false; }
// Free resources http.end(); 
return true; }
 // structure des données capteur
struct SensorData {
int capteur_id;
float data;
String date;
};

SensorData sensorData[100]; // tableau pour enregistrer les données du capteur int sensorDataIndex = 0; // index pour enregistrer les données dans le tableau 
//fonction pour enregistrer les donnes capteur
void recordSensorData(int capteur_id, float data) {
if (sensorDataIndex < 100) {
// enregistrer les données du capteur
sensorData[sensorDataIndex].capteur_id = capteur_id;
sensorData[sensorDataIndex].data = data;
sensorData[sensorDataIndex].date = String(dateNow());
sensorDataIndex++;
}
}
 // retourne la date formatée
String dateNow(){
time_t epochTime = timeClient.getEpochTime();
struct tm *ptm = localtime((const time_t *)&epochTime);
char buffer[20];
strftime(buffer, 20, "%Y-%m-%d_%H:%M:%S", ptm);
return buffer;
}
 void loop() { 
// pour faire tourner le timer
timer.tick();
 }
 // fonction d'envoie au serveur
bool envoieServeur(void *){
for (int i = 0; i < sensorDataIndex; i++) {
SensorData data = sensorData[i]; // envoie sur HOST ( a completer dans config ) page reception.php
String url = String("http://") + String(HOST) + String("/reception.php?capteur_id=") + String(data.capteur_id) + String("&data=") + String(data.data) + String("&date=") + data.date+ String("&key=") + String(KEY);

if (!sendData(url)) {
// l'envoi a échoué, ne retirez pas l'enregistrement et sortez de la fonction return true; } else {
// l'envoi a réussi, retirez l'enregistrement de SensorData
for (int j = i; j < sensorDataIndex - 1; j++) {
sensorData[j] = sensorData[j + 1];
}
sensorDataIndex--;
i--;
}
} return true; // repeter }
Etape 3 :

Pour le matériel, vous aurez besoin des éléments suivants :
  • Un module ESP8266
  • Un capteur DHT11 ou DHT22 (le DHT22 est recommandé pour sa précision et doit être monté sur un circuit imprimé)
  • Un hébergement web avec support PHP et MySQL
En ce qui concerne le câblage, il est assez simple. Connectez le fil positif du capteur au 3,3V, le fil négatif au GND et le fil de données à la broche D4 de l'ESP8266.
Si vous n'avez pas déjà effectué cette étape dans votre logiciel Arduino, suivez ces étapes :
  1. Accédez aux Préférences.
  2. Ajoutez l'URL suivante dans le Gestionnaire de cartes supplémentaires : http://arduino.esp8266.com/stable/package_esp8266com_index.json
  3. Ensuite, allez dans Outils > Type de carte > Gestionnaire de cartes.
  4. Recherchez "ESP8266" et installez le package.
  5. Lors du téléversement du code, assurez-vous de sélectionner la carte ESP8266 appropriée pour transférer le code correctement.
Pour créer le code, nous avons utilisé l'aide de ChatGPT via https://chat.openai.com/chat. Il nous a été d'une grande aide, même s'il a modifié le nom de certaines de nos variables, ce qui nous a fait perdre du temps.
Passons maintenant à la partie du code concernant le microcontrôleur ESP. Voici les fonctionnalités prévues :
  • Se connecter à un point d'accès WiFi.
  • Récupérer la date et l'heure françaises à partir d'un serveur.
  • Collecter les mesures du capteur et les stocker.
  • Envoyer les données vers un serveur.
Nous utilisons différentes bibliothèques dans notre programme, notamment :
  • NTPClient de Fabrice Weinberg.
  • Arduino-timer de Michael Contreras.
  • ESP8266WiFi de AMD16 (pour le capteur DHT, la bibliothèque DHT.h est utilisée).
  • Les autres bibliothèques nécessaires sont incluses dans le package ESP8266. Si elles sont manquantes, vous pouvez les trouver facilement en effectuant une recherche sur Google.
Passons maintenant rapidement au code pour comprendre son fonctionnement.
La partie NTP permet de récupérer la date et l'heure en fonction des paramètres que nous avons définis dans les variables ntpServer, gmtOffset_sec et DaylightOffset_sec. Dans notre cas, ces paramètres sont configurés pour l'heure de la France (Paris).
Le capteur DHT11 est connecté à la broche 4.
Nous avons également une section qui gère le timer et crée un timer automatique.
La fonction "miseAJourTimeWeb" est utilisée pour interroger un serveur et récupérer la date et l'heure exactes à partir d'un site web.
Nous avons également une fonction "resetESP8266" qui réinitialise la carte tous les 4 jours.
Passons maintenant à la partie "setup". Nous initialisons la communication série (Serial) pour la communication, puis nous appelons "WiFi.begin" avec le SSID (nom du réseau WiFi) et le PASSWORD (mot de passe WiFi). Assurez-vous de remplir le fichier de configuration "config.h" avec les bonnes informations de connexion WiFi pour que cela fonctionne.
Ensuite, nous configurons le capteur DHT (dht.begin) et initialisons timeClient (timeClient.begin) pour récupérer la date et l'heure à partir du serveur.
Nous appelons la fonction "miseAJourTimeWeb" pour récupérer la date et l'heure à partir du serveur.
Ensuite, nous créons plusieurs timers :
  • Le premier timer.every(3600000, miseAJourTimeWeb) s'exécute toutes les heures pour récupérer la date et l'heure à partir du serveur. Vous pouvez ajuster la fréquence selon vos besoins. (3600000 millisecondes = 1 heure).
  • Le deuxième timer.every(300000, mesuresCapteur) s'exécute toutes les 5 minutes et appelle la fonction "mesuresCapteur" pour effectuer les mesures.
  • Le troisième timer.every(301000, envoieServeur) s'exécute toutes les 5 minutes et 1 seconde et appelle la fonction "envoieServeur" pour envoyer les données au serveur.
Maintenant, expliquons le fonctionnement de la fonction "mesuresCapteur". Nous récupérons les valeurs du capteur DHT et les stockons dans des variables. Vous pouvez modifier cette partie si vous utilisez un autre capteur que le DHT.
La boucle "while" permet simplement de vérifier si les données du capteur DHT ont été récupérées correctement. Si une erreur se produit ou si les deux valeurs sont à zéro, la boucle est relancée.
Ensuite, nous enregistrons les données dans un tableau à l'aide de la fonction "recordSensorData(1, h)". Ici, la mesure de l'humidité (h) est enregistrée pour le capteur numéro 1. Vous devez modifier ce numéro si vous avez plusieurs capteurs. Par exemple, si vous avez deux ESP8266 avec chacun un capteur DHT mesurant des données à deux endroits différents, vous pouvez utiliser les configurations suivantes :
  • Pour le premier ESP8266 : recordSensorData(1, h); recordSensorData(2, t);
  • Pour le second ESP8266 : recordSensorData(5, h); recordSensorData(6, t); Dans cet exemple, les données sont envoyées pour les capteurs 1, 2, 5 et 6. Vous devez choisir le bon numéro de capteur en fonction de vos besoins (nous aborderons la création de capteurs dans la partie Web du tutoriel).
Nous avons maintenant terminé avec cette fonction. À noter que le "return true" permet au timer de reboucler.
Passons maintenant à la fonction "sendData", qui se charge simplement d'appeler l'URL fournie en paramètre.
Elle ne s'occupe que de cette tâche, se reconnecte si nécessaire, appelle l'URL et renvoie "true" si tout s'est bien passé, sinon elle renverra "false".
Nous ne nous attarderons pas sur cette fonction.
Ensuite, nous avons la structure de données "SensorData" qui contient l'ID du capteur, la donnée (un nombre décimal ici) et la date-heure.
Nous définissons ensuite "sensorData" comme une structure "SensorData" avec un tableau de données de taille 100 (SensorData sensorData[100]).
Passons à la fonction "recordSensorData", qui sert à enregistrer temporairement les données du capteur dans un tableau. Elle enregistre les données fournies en paramètre et ajoute la date et l'heure actuelles à l'aide de "dateNow()". Vous n'avez rien à modifier ici.
La fonction "dateNow()" récupère l'heure locale et renvoie la date au format demandé, par exemple : "2023-02-25_14:55:42".
Revenons ensuite à la boucle "loop" où nous appelons simplement "timer.tick()" pour faire avancer les timers et les exécuter au bon moment.
Enfin, nous avons la fonction "envoieServeur" dont le but est d'envoyer les données du tableau de données enregistrées par les capteurs. Nous parcourons le tableau de données avec une boucle "for".
Ensuite, nous créons l'URL à appeler. "HOST" est une variable définie dans "config.h" et doit être paramétrée avec l'adresse de votre site web qui hébergera la page "reception.php" que j'ai créée.
Si le nom de la page est modifié, vous devrez également modifier son nom ici.
Ensuite, nous appelons la fonction "sendData" en lui fournissant l'URL que nous avons créée précédemment. L'URL contient l'ID du capteur, la donnée du capteur et la date.
Nous parcourons tous les enregistrements et retirons les données du tableau si l'envoi réussit.

Voici le contenu du fichier "config.h" que nous utilisons dans le programme :
// fichier config.h
#define SSID "NomDeMonWifi"
#define PASSWORD "MotDePasseWifi"
#define KEY "Cle_Url_Php"
#define HOST "monsiteweb.fr"

Pour l'installation de la partie site web, vous devez disposer d'un hébergement web PHP MySQL, que ce soit en local ou sur le web. Envoyez le contenu du répertoire (à l'exception du dossier "Arduino" qui contient le code ESP8266 ) sur votre serveur via FTP. Utilisez FileZilla ou WinSCP pour transférer vos fichiers en utilisant les informations de connexion.
Pour la configuration, modifiez les informations de connexion dans le fichier "config.php" comme suit :

define('DB_HOST', 'adresseDeLaBaseDeDonnee'); // l'adresse de l'hôte de la base de données
define('DB_USER', 'nomUtilisateurBasededonnee'); // le nom d'utilisateur pour se connecter à la base de données
define('DB_PASS', 'MotDepasseBaseDeDonnee'); // le mot de passe pour se connecter à la base de données
define('DB_NAME', 'nombasededonnee'); // le nom de la base de données
define('KEY', 'CleDonneeEsp'); // clé données ESP, doit être la même sur l'ESP
define('ADMIN_PASS', 'motdepasseadminbackoffice'); // mot de passe admin

Lancez votre site web et accédez à la page "install.php" via "https://lenomdemonsite.fr/install.php". 
Connectez-vous avec le mot de passe du fichier "config.php" (ADMIN_PASS). 
Créez votre capteur, puis éditez-le en choisissant son nom, sa zone et sa couleur. Modifiez les paramètres selon vos besoins.
Votre capteur est désormais ajouté et possède un identifiant. 
Revenons à l'ESP.
Dans la fonction "bool mesuresCapteur(void *)", vous trouverez l'instruction à modifier : "recordSensorData(1, h);". 
Ici, le "1" représente l'identifiant du capteur. 
Vous devez le remplacer par le vôtre et l'adapter à votre capteur dans cette fonction.
Si vous souhaitez uniquement récupérer la valeur de luminosité avec un capteur dédié, par exemple, vous devez récupérer la valeur de luminosité et l'insérer dans "recordSensorData(8, luminosite);". 
Vous n'aurez qu'un seul "recordSensorData" dans la fonction car vous n'avez qu'un seul capteur.
Si votre Arduino est correctement connecté à votre réseau Wi-Fi et pointe vers votre site web, vous devriez commencer à voir des données sur la page "https://lenomdemonsite.fr/view.php".

Télécharger capteur connecté ou sur github.

Vous retrouvez le contenu du tuto aussi sur mon blog ainsi que d'autres tuto.
https://retroetgeek.com/arduino/fabrication-dun-capteur-connecte-a-base-de-esp8266-et-son-code-serveur/
Et le lien de ma chaine youtube et twitch
https://www.youtube.com/@RetroEtGeek
https://www.twitch.tv/retroetgeek

Sources :


Ces tutoriels devraient vous plaire

vignette Arduino Uno - Capteur d'humidité au sol.
Arduino Uno - Capteur d'humidité au sol.
vignette Arduino et Porte automatique de poulailler
Arduino et Porte automatique de poulailler
vignette Écran Tactile et Raspberry Pi
Écran Tactile et Raspberry Pi

Découvrez tous les tutoriels partagés sur Oui Are Makers

Powered by Oui Are Makers