Fabrication d’un capteur connecté à base de ESP8266 et son code serveur

Aujourd’hui on va apprendre à créer une un capteur connecté a base de esp8266 ainsi que le site web pour les données du capteur.
On va pour ça s’aider de ChatGPT pour nous donner les bon tips pour coder ce capteur et voir si il se trompe ou non.

Capteur Connecte Circuit

 
#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
}

 

En matériel il nous faut :
– un esp8266
– un capteur dht11 ou dht22 (ou capteur nécessaire, je conseille de dht22 monté sur pcb plus précis)
– un hébergement web php mysql

Pour le câblage rien de compliqué , le + du capteur sur le 3.3V , le – sur le Gnd et le pin des données sur le pin D4 de l’esp8266.

Si vous ne l’avez pas fait dans votre logiciel arduino, aller dans préférence, gestionnaire de carte supplémentaire et ajouter : http://arduino.esp8266.com/stable/package_esp8266com_index.json

Lors du téléversement du programme n’oubliez pas de choisir la bonne carte pour transférer le code correctement.

Pour faire ce code on a demandé à chatGPT de nous aider https://chat.openai.com/chat
Et il nous a pas mal aidé et nous a aussi fait perdre du temps en modifiant le nom de nos variables.

On commence avec la partie code microcontrôleur esp !
Ce que j’ai prévu :
– me connecter sur un point wifi
– récupérer la date et l’heure française sur un serveur
– récupérer des mesures du capteur et les stocker
– envoyer les données sur un serveur

On utilise des bibliothèque ou librairies dans notre programme il nous faut
– NTPClient de Fabrice Weinberg
– arduino-timer de Michael Contreras
– esp826611 de AMD16 ( pour le capteur dht, librairie DHT.h )
– les différentes autres librairies sont inclues en ayant ajouté le package esp8266 ( sinon cherche sur google tu trouveras tes librairies manquantes 😀 )

Passons au code rapidement pour comprendre comment il fonctionne.
Tout ce qui est NTP sert a récuperer la date et l’heure par rapport aux parametres que l’on aura mis dans les variables ntpServer, gmtOffset_sec,DaylightOffset_sec.
Ici c’est paramétré pour l’heure de la France (Paris).
Le capteur DHT11 est sur le pin 4

On a une partie qui va s’occuper du timer, auto timer pour créer un timer.

Puis la fonction miseAJourTimeWeb qui sert à appeler le serveur pour récupérer la date et heure exacte sur un serveur web.

Ainsi qu’une fonction pour reset la carte tous les 4 jours resetESP8266() 

Ensuite je passe a mon setup, initialisation du serial pour communiquer, Wifi.begin avec le nom du wifi SSID et PASSWORD le mot de passe du wifi.
On devra remplir le fichier de configuration config.h et mettre le bon nom et mot de passe de wifi pour que cela fonctionne.

On reviendra sur le fichier de config.h pour configurer le wifi et le site web sur lequel on va enregistrer les données.

Apres avoir crée la connexion wifi , on active le capteur dht ( dht.begin ), on active timeClient (timeClient.begin) pour aller récupérer la date et heure au serveur.
On appelle la fonction miseAJourTimeWeb pour récuperer ce coup ci la date et heure au serveur.
Puis on va creer plusieurs timer.
Le premier timer.every(3600000, miseAJourTimeWeb) tourne toute les heures pour récupérer la date heure au serveur, on peut aisément augmenter la fréquence ( 3600000 milli secondes = 1 h ) car l’esp se débrouille bien une fois la date établie.
Le deuxième timer.every(300000, mesuresCapteur) s’execute toutes les 5 minutes et appelle mesuresCapteur; comme son nom l’indique la fonction sert a mesurer des données.
La troisieme timer.every(301000, envoieServeur) s’execute toutes les 5 minutes et 1 secondes et appelle envoieServeur, et encore come son nom l’indique la fonction envoie au serveur.

Maintenant passons à l’explication du fonctionnement de la fonction mesuresCapteur.
On recupere les valeurs du capteur dht et on les affectes a des variables.
C’est la ou tu vas pouvoir mettre ton ton propre capteur si tu utilise un autre capteur que le dht.
La boucle while ensuite sert seulement a controler si j’ai bien récupéré la donnée de mon capteur dht et je reboucle si il y a une erreur ou si les 2 valeurs sont a 0.
Puis c’est la ou c’est important et la ou tu vas devoir modifier des données c’est que j’enregistre dans un tableau avec la fonction recordSensorData(1,h) ici la mesure du capteur h ( humidité ) et le 1 correspond au numero de capteur que je veux affecter sur mon site web.
Donc ce numero doit etre different si j’ai beaucoup de capteur.
imaginons que j’ai fabriqué 2 esp8266 avec chacun un capteur dht qui mesurent des données a 2 endroits differents. La par exemple je mettrai:
recordSensorData(1,h);
recordSensorData(2,t);
Pour mon premier esp et pour le second:
recordSensorData(5,h);
recordSensorData(6,t);

Donc je vais envoyée des données pour le capteur 1,2,5,6.
C’est la ou tu interviens et tu choisi le bon numéro de capteur ( plus loin dans le tuto “creation capteur partie web”).
On a fini avec cette fonction, pour info le return true  permet au timer de reboucler.

Maintenant regardons de plus près la fonction sendData, qui s’occupe seulement de faire un appel sur l’url fourni en paramètre. Il ne s’occupe que de cette fonction , se reconnecte si besoin, appelle l’url et retourne true si ça a fonctionné, sinon il retournera false.
Je ne vais pas m’attarder dessus cette fonction.

J’ai ensuite la structure de donnée SensorData qui contient , l’id du capteur, la donnée ( un float ici ) et la date heure.
Puis on definit sensorData comme une structure SensorData avec un tableau de donnée de  100 (SensorData sensorData[100] ).

Enchainons avec la fonction recordSensorData, elle sert a enregistrer les données capteur temporairement dans un tableau de donnée. Il enregistre les données envoyés en paramètre et ajoute la date et heure du moment avec dateNow(). Il n’y a rien à toucher ici.

Fonction dateNow() recupere le temps local et retourne la date sous le format que j’ai demandé ici exemple: “2023-02-25_14:55:42”.

Retrouver le loop avec simplement timer.tick() qui sert a faire tourner les timer pour s’executer au bon moment.

Puis la fonction envoieServeur dont le but est d’envoyer les données du tableau des données enregistrés des capteurs. On parcourt avec une boucle for le tableau de donnée. Ensuite on crée l’url a appeler. HOST est la variable dans config.h qui doit etre parametre vers ton “site” web qui va heberger la page reception.php que j’ai crée. Si le nom de la page est modifiée, modifier ici le nom de la page.
Ensuite on appelle la fonction sendData avec en parametre l’url que l’on a cree juste avant. Url qui contient l’id du capteur, la donnée du capteur et la date.
On boucle sur tous les les enregistrements et on retire la donnée du tableau si l’envoie est réussi.

Ci dessous je met le code config.h que nous appelons dans le programme.
SSID pour le nom du wifi
PASWORD pour le mot de passe du wifi
KEY c’est pour securiser un peu les données envoyées, on choisit la clé que l’on veut, on devra mettre la même sur le serveur web.
HOST et l’adresse de ton site web ou je vais trouver la page de réception, copier l’url après https://

//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 avoir un hébergement web php mysql ( soit en local soit sur le web). Envoyer sur votre serveur par ftp le contenu du repertoire en lien a la fin du blog ou sur le github exepté le dossier Arduino qui lui contient le code arduino.

Utiliser filezilla ou winscp pour transferer vos fichier avec les données de connexion.

Pour la configuration modifier les données de connexion dans le fichier config.php

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 etre la même sur l esp

define(‘ADMIN_PASS’, ‘motdepasseadminbackoffice’); // mot de passe admin

Lancer votre site web et aller sur la page install.php avec https://lenomdemonsite.fr/install.php

Puis aller sur la page https://lenomdemonsite.fr/capteur.php ou https://lenomdemonsite.fr/login.php

Se connecter avec le mot de passe du fichier config.php (ADMIN_PASS)

Cree son capteur, puis l’éditer et choisir son nom, zone, couleur et modifier

Votre capteur est ajouté, il a un identifiant maintenant

Retourner sur adruino
Dans la fonction bool mesuresCapteur(void *)
Vous retrouvez ce qu’il faut modifier “recordSensorData(1,h);” , ici le 1 est l’identifiant du capteur, vous devez mettre le votre et adapter dans cette fonction a votre capteur.

Ici j’ai utilisé le capteur DHT et j’ai récupéré juste avant la temperature et l’humidité.
Imaginons que je veux seulement recuperer la valeur de la luminosité avec un capteur fait pour ça; je récupère la valeur de luminosité et je l’insere dans “recordSensorData(8,luminosite);”
J’aurai seulement un seul recordSensorData dans la fonction vu que j’ai un seul capteur.

Normalement si votre arduino est bien connecté a votre wifi et qu’il pointe bien vers votre site web vous devriez commencer à voir des données dans la page https://lenomdemonsite.fr/view.php

Voici les liens pour télécharger les différents codes Télécharger capteur connecté ou sur github.

N’hésitez pas à poser vos questions sur les réseaux sociaux de la chaîne instagramtwitter , facebook ,youtube , discord; si vous ne comprenez pas certaines parties du tutoriel n’hésitez pas , me dire ce que vous aimeriez que je crée pour en faire des vidéos tutoriel  et à partager les projets que vous aimeriez créer etc…

Comme toujours allez sur la page de C’est quoi Retro et Geek pour connaître tout ce que je recherche à faire sur la chaîne.

Merci les RetroGeeker et RetroGeekeuse