samedi 7 septembre 2019

ESP32: utilisation du capteur à effet Hall intégré

Les concepteurs de l'ESP32 ont jugé utile de le munir d'un capteur à effet Hall intégré grâce auquel il est possible de détecter le champ magnétique d'un aimant placé à proximité du module.

Ce capteur se situe à l'intérieur de la partie de la carte qui est recouverte par un bouclier métallique, à peu près au centre du rectangle; il mesure la composante du champ magnétique orientée perpendiculairement à la carte.

L'exemple "HallSensor", accessible dans l'IDE Arduino par les menus "Fichier - Exemples - ESP32 - HallSensor" constitue une façon simple et rapide de vérifier le bon fonctionnement du capteur à effet Hall (au besoin, vous pouvez vous référer à ce précédent billet pour apprendre comment programmer l'ESP32 au moyen de l'IDE Arduino).


Prenez soin de ne pas brancher quoi que ce soit aux broches GPIO36 et GPIO39, car leur ADC est utilisé lors de l'utilisation du capteur à effet Hall.

En ce qui concerne la programmation dans l'IDE Arduino, la lecture du champ magnétique au moyen du capteur à effet Hall intégré se limite à l'utilisation de la fonction "hallRead()", qui retourne un entier.

Voici ce que j'ai obtenu en avec l'exemple "HallSensor", lorsqu'aucun aimant n'était placé à proximité du module ESP32: les valeurs affichées varient entre 32 et 40.


J'ai ensuite placé un petit aimant tout proche du centre du bouclier métallique du module ESP32 (j'avais collé l'aimant à l'extrémité d'un petit support en carton afin de faciliter les manipulations).


Les valeurs mesurées dépendent du pôle de l'aimant qui fait face au module ESP32. Pour un sens, les valeurs diminuent (elles peuvent même devenir négatives).



...alors qu'en plaçant l'aimant dans l'autre sens, les valeurs augmentent aux environs de 100.


D'après mes observations, il est difficile de mesurer quoi que ce soit si l'aimant est situé à plus de quelques millimètres du centre du bouclier métallique. Pour une mesure plus précise du champ magnétique, des capteurs externes me semblent plus appropriés (voir par exemple le HMC5883L ou le A1302).

Pour détecter la présence d'un aimant tout près de l'ESP32, par contre, il n'y a pas de doute: le module à effet Hall intégré fonctionne très bien.

Détecter l'ouverture d'une porte 

On pourrait penser à une application où l'ESP32 est fixé à un cadre de porte. Lorsque la porte est fermée, un aimant est appuyé contre l'ESP32, et cet aimant s'éloigne de l'ESP32 lorsqu'on ouvre la porte. Grâce aux mesures effectuées par le capteur à effet Hall intégré, l'ESP32 sait quand la porte est ouverte ou non. Et puisqu'il s'agit d'un ESP32, pourquoi ne pas afficher les résultats dans une page web?

C'est ce que fait le sketch ci-dessous: il s'agit d'un serveur web qui affiche la date et l'heure des 10 plus récentes ouvertures de la porte.

/**************************************************************
Détecteur d'ouverture de porte ESP32
L'ouverture d'une porte est détectée grâce au capteur à effet
Hall intégré de l'ESP32. Une page web affiche la date et l'heure
des 10 plus récentes ouvertures de portes.
Plus d'infos:
https://electroniqueamateur.blogspot.com/2019/09/esp32-utilisation-du-capteur-effet-hall.html
*****************************************************************/
// pour la communication WiFi
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
// pour l'affichage de la date et de l'heure
#include <time.h>
const char* ssid = "**********";
const char* password = "**********";
const int stockage_max = 10; //nombre maximal de données stockées dans UID et dateHeure
const int decalage = -5; // la valeur dépend de votre fuseau horaire. Essayez 2 pour la France.
time_t date_et_heure[stockage_max]; // tableau contenant le moment des plus récentes ouvertures de porte
int nb_de_donnees = 0; // nombre de données déjà stockées dans dateHeure
int etat = 0; // 0 quand la porte est fermée, 1 quand elle est ouverte
const int Hallnormal = 36; //valeur retournée par le capteur à effet Hall en absence d'aimant
const int tolerance = 20; // ecart toléré par rapport à la valeur moyenne
WebServer serveur(80);
// Construction de la page web
void handle_root() {
struct tm * timeinfo;
String contenu; // les informations concernant les scans de tags RFID
for (int i = 0; i < stockage_max; i++) {
if (date_et_heure[i] != 0)
{
timeinfo = localtime(&date_et_heure[i]);
contenu.concat( "<p> Date et heure: " + String(timeinfo->tm_mday) + "-" + String(timeinfo->tm_mon + 1) + "-" + String(timeinfo->tm_year + 1900) + " " + String(timeinfo->tm_hour) + ":" + String(timeinfo->tm_min) + ":" + String(timeinfo->tm_sec) + "</p>");
}
}
serveur.send(200, "html", "<head> <title>Detecteur d'ouverture de porte ESP32</title> <meta http-equiv=Refresh content=10></head> "
"<body><H1>" + String(stockage_max) + " plus r&eacute;cents &eacute;v&eacute;nements</H1>"
"<p>" + contenu + "<p>"
"<p>Visitez <a href=http://electroniqueamateur.blogspot.ca/>&Eacute;lectronique en Amateur</a>!</p></body>");
delay(100);
}
// Initialisation du WiFi. Les progrès s'affichent dans le moniteur série
// pour faciliter le débogage, et pour connaître l'adresse IP de l'ESP32.
void setup()
{
Serial.begin(9600);
Serial.println();
WiFi.begin(ssid, password);
Serial.print("Connexion au reseau WiFi");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.print("Nom du reseau WiFi: ");
Serial.println(ssid);
Serial.print("Adresse IP de la page web: ");
Serial.println(WiFi.localIP());
serveur.on("/", handle_root);
serveur.begin();
Serial.println("Le serveur web est en fonction.");
configTime(decalage * 3600, 0, "ca.pool.ntp.org"); //serveurs canadiens
// en Europe, essayez europe.pool.ntp.org ou fr.pool.ntp.org
Serial.print("Attente date et heure");
while (time(nullptr) <= 100000) {
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.println("Pret.");
}
void loop()
{
// on fait la moyenne de trois lectures consécutives du champ magnétique
// la moyenne permet d'atténuer les occasionnelles lectures aberrantes.
int valeur1 = hallRead();
delay(100);
int valeur2 = hallRead();
delay(100);
int valeur3 = hallRead();
int moyenne = (valeur1 + valeur2 + valeur3)/3;
if (abs(moyenne - Hallnormal) < tolerance ) // pas d'aimant à proximité: la porte est ouverte
{
if (etat == 0) // lors de la dernière vérification, la porte était fermée!
{
Serial.println("Porte ouverte!");
if (nb_de_donnees < stockage_max) { // il y a des lignes vides dans le tableau
time(&date_et_heure[nb_de_donnees]); // quelle heure est-il?
nb_de_donnees++;
}
else // le tableau est plein
{
for (int i = 0; i < stockage_max - 1; i++) { // on décale toutes les infos d'une ligne
date_et_heure[i] = date_et_heure[i + 1];
}
time(&date_et_heure[stockage_max - 1]); // quelle heure est-il?
}
delay (1000); // pour éviter les "rebonds"
}
etat = 1;
}
else { // la porte est fermée
if (etat == 1) {
Serial.println("Porte refermee.");
}
etat = 0;
}
serveur.handleClient();
}


Au démarrage, du programme, le moniteur série nous indique l'adresse IP du serveur web.


En tapant cette adresse IP dans un navigateur, on accède à la page web qui indique la date et l'heure des plus récentes ouvertures de la porte.


Si vous désirez utiliser vous-mêmes le sketch, vous devez évidemment assigner aux constantes ssid et password les valeurs correspondant à votre réseau WiFi, mais également vérifier que la valeur de la constante Hallnormal correspond à ce qu'affiche votre capteur en absence de l'aimant, et régler la constante decalage afin que l'heure affichée corresponde bien au pays dans lequel vous vous trouvez,


Yves Pelletier   (TwitterFacebook)

2 commentaires:

  1. Bonjour,
    Ce prog est très intéressant mais le capteur hall de l'ESP32 donne des résultats trop fantaisistes . Le serveur web n'affiche pas les 10 valeurs mais seulement le titre pour 10 valeurs ?
    Je pense qu'un vrai capteur hall serait plus indiqué que celui incorporé à lESP32 . Dommage !
    Merci pour ce projet intéressant

    RépondreSupprimer
  2. Force à toi tu t'es pris un vent

    RépondreSupprimer