Utilisation du tableau de bord Cayenne - dispositif de capteur de température ESP-Now (partie 7)

Maintenant, pour compléter cette série, un simple appareil peu coûteux basé ESP8266  avec un ou deux DS18B20  Capteurs de température. Étant donné que l'appareil n'est actif que pendant quelques millisecondes toutes les 5 minutes, il peut très bien fonctionner avec des piles. La batterie de l'image est symbolique. Si vous utilisez la broche + 5 V du D1-Mini pour utiliser le régulateur de tension intégré à 3,3 V, vous avez besoin d'au moins 3 batteries de 1,5 V chacune.

Attention! La connexion du fil orange sert à sortir du mode veille et doit être retirée pour clignoter.

Maintenant, le code:

Pour la version finale que vous souhaitez exécuter sur batterie, l'indicateur DEBUG doit être défini sur false.

 

/*
  Capteur de température WLAN
  ESP maintenant vers la passerelle MQTT
  Si aucune adresse MAC n'a encore été déterminée
  le capteur recherche un WLAN avec une passerelle SSID MQTT
  Lorsqu'il trouve l'AP, il se souvient de l'adresse MAC 
  tant que l'alimentation n'a pas été interrompue
  Le protocole ESP Now est très rapide, donc très peu de temps (nous)
  flux de courant plus élevés. Le capteur envoie des données de température puis entre dans le pendant 5 minutes 
  Sommeil profond pour que très peu d'énergie soit utilisée et que
  Le capteur peut donc fonctionner avec des piles. 
*/

// bibliothèque pour WiFi
#include <ESP8266WiFi.h>
// Bibliothèques pour capteur de température DS18B20
#include <OneWire.h>
#include <DallasTempérature.h>
#include <CayenneLPP.h>

// Bibliothèque pour ESP Now
externe "C" {   #include <espnow.h>
}

// SSID de la passerelle
#define GW_SSID "MQTTGateway"

// Indicateur de débogage si faux, tous les messages de débogage sont supprimés
// pour économiser de l'électricité supplémentaire
#define DEBUG vrai

// Constantes pour le WiFi
#define SEND_TIMEOUT 2000  // Délai d'attente de 2 secondes 

// attribution de canal
#define CHANNEL_TEMPI 1
#define CHANNEL_TEMPE 2

// Broches pour capteurs de température
const octet bus_int = 2; // GPIO2
const octet bus_ext = 4; // GPIO4

// Structure de données pour la mémoire Rtc avec somme de contrôle pour la validité
// vérifie que l'adresse MAC est enregistrée
struct MEMORYDATA {   uint32_t crc32;   uint8_t mac[6];   uint32_t canal;
};


// Données globales
volatile bool callbackCalled;


// mémoire pour les valeurs de température
flotter temp_int = 0;
flotter temp_ext = 0;
booléen has_int = 0;
booléen has_ext = 0;

// Adresse MAC et canal WiFi
MEMORYDATA statinfo;
// tampon pour les données au format LPP
CayenneLPP lpp(64);

// bus vers les capteurs
OneWire oneWire_int(bus_int);
OneWire oneWire_ext(bus_ext);

DallasTempérature capteurs_int(&oneWire_int);
DallasTempérature capteurs_ext(&oneWire_ext);

// tableau pour stocker les adresses des capteurs
DeviceAddress adresses_int;
DeviceAddress adresses_ext;

// Sous-programme de calcul de la somme de contrôle
uint32_t calculerCRC32(const uint8_t *les données, taille_t longueur)
{   uint32_t crc = 0xffffffff;   tout (longueur--) {     uint8_t c = *les données++;     pour (uint32_t je = 0x80; je > 0; je >>= 1) {       bool peu = crc & 0x80000000;       si (c & je) {         peu = !peu;       }       crc <<= 1;       si (peu) {         crc ^= 0x04c11db7;       }     }   }   retour crc;
}

// Ecrit la structure de données statinfo avec la somme de contrôle correcte dans la mémoire RTC
nul UpdateRtcMemory() {     uint32_t crcOfData = calculerCRC32(((uint8_t*) &statinfo) + 4, taille de(statinfo) - 4);     statinfo.crc32 = crcOfData;     ESP.rtcUserMemoryWrite(0,(uint32_t*) &statinfo, taille de(statinfo));
}

// recherche un point d'accès approprié
nul ScanForSlave() {   bool slaveFound = 0;      int8_t scanResults = WiFi.scanNetworks();   // réinitialiser à chaque scan   si (DEBUG) Série.println("Scan terminé");   si (scanResults == 0) {     si (DEBUG) Série.println("Aucun périphérique WiFi trouvé en mode AP");   } d'autre {     si (DEBUG) Série.imprimer("Trouvé");      si (DEBUG) Série.imprimer(scanResults);      si (DÉBOGUER) En série.println(" dispositifs ");     pour (int je = 0; je < scanResults; ++je) {       // Imprimer SSID et RSSI pour chaque appareil trouvé       Chaîne SSID = Wifi.SSID(je);       int32_t RSSI = Wifi.RSSI(je);       int32_t chl = Wifi.canal(je);       Chaîne BSSIDstr = Wifi.BSSIDstr(je);       si (DÉBOGUER) {         En série.impression(je + 1);         En série.impression(": ");         En série.impression(SSID);         En série.impression(" /");         En série.impression(chl);         En série.impression(" (");         En série.impression(RSSI);         En série.impression(")");         En série.println("");       }       retard(10);       // Vérifiez si l'appareil actuel commence par `Thermomètre`       si (SSID == GW_SSID) {         // SSID d'intérêt         si (DÉBOGUER) {           En série.println("Trouvé un esclave.");           En série.impression(je + 1); En série.impression(": "); En série.impression(SSID); En série.impression(" ["); En série.impression(BSSIDstr); En série.impression("]"); En série.impression(" ("); En série.impression(RSSI); En série.impression(")"); En série.println("");         }         int Mac[6];         // wir ermitteln die MAC Adresse und speichern sie im RTC Memory         si ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c",  &Mac[0], &Mac[1], &Mac[2], &Mac[3], &Mac[4], &Mac[5] ) ) {           pour (int ii = 0; ii < 6; ++ii ) {             statinfo.Mac[ii] = (uint8_t) Mac[ii];           }           statinfo.canal = chl;           UpdateRtcMemory();         }         slaveFound = 1;         // Nachdem der AP gefunden wurde können wir abbrechen         Pause;       }     }   }         si (DÉBOGUER) {     si (slaveFound) {       En série.println("Esclave trouvé, traitement ..");     } autre {       En série.println("Slave Not Found, réessayant.");     }   }   // RAM freigeben   Wifi.scanDelete();
}
// fonction um eine Sensoradresse zu drucken
néant printAddress(DeviceAddress adressen)
{   pour (uint8_t je = 0; je < 8; je++)   {     si (adressen[je] < 16) En série.impression("0");     En série.impression(adressen[je], HEX);   }
}

// Unterprogramm zum Initialisieren der DS18B20 Sensoren
booléen initDS18B20(uint8_t épingle, DallasTempérature capteur, DeviceAddress adresse ) {   booléen a trouvé = 0;   pinMode(épingle,INPUT_PULLUP);   sensoren_int.commencer();   si (DÉBOGUER) {     En série.impression(capteur.getDeviceCount(), DÉC);     En série.println("Sensoren gefunden.");   }   // Nun prüfen wir ob einer der Sensoren am Bus ein Temperatur Sensor ist   si (!capteur.getAddress(adresse,0)) {     si (DÉBOGUER) En série.println("Kein Temperatursensor vorhanden!");   } autre {      // adressen anzeigen     si (DÉBOGUER) {       En série.impression("Adresse:");       printAddress(adresse);       En série.println();     }     // Nun setzen wir noch die gewünschte Auflösung (9, 10, 11 ou 12 bits)     capteur.setResolution(adresse,10);     // Zur Kontrolle lesen wir den Wert wieder aus     si (DÉBOGUER) {       En série.impression("Auflösung =");       En série.impression(capteur.getResolution(adresse), DÉC);       En série.println();     }     // Temperaturmessung starten     capteur.requestTemperatures(); // Commando um die Temperaturen auszulesen     a trouvé = 1;   }   revenir a trouvé;
}

néant installer() {   uint8_t buf[70]; // sendebuffer   si (DÉBOGUER) {     En série.commencer(115200);      En série.println("Début");   }   // eigene MAC Adresse ermitteln und als Geräte-Id im Sendespeicher ablegen   Chaîne strmac = Wifi.Adresse Mac();   si (DÉBOGUER) {     En série.impression("Meine MAC Adresse =");     En série.println(strmac);   }   int imac[6];   sscanf(strmac.c_str(), "%x:%x:%x:%x:%x:%x%c",  &imac[0], &imac[1], &imac[2], &imac[3], &imac[4], &imac[5] );   pour (uint8_t ii = 0; ii<6; ii++) buf[ii]=imac[ii];   si (DÉBOGUER) {     En série.println("Interne Sensoren");   }   has_int = initDS18B20(bus_int,sensoren_int,adressen_int);   si (DÉBOGUER) {     En série.println("Externe Sensoren");   }   has_ext = initDS18B20(bus_ext,sensoren_ext,adressen_ext);   // Wir lesen aus dem RTC Memory   ESP.rtcUserMemoryRead(0, (uint32_t*) &statinfo, taille de(statinfo));   si (DÉBOGUER) En série.println("RTC terminé");   uint32_t crcOfData = calculerCRC32(((uint8_t*) &statinfo) + 4, taille de(statinfo) - 4);   Wifi.mode(WIFI_STA); // Mode station pour le nœud de capteur esp-now   si (DÉBOGUER) En série.println("WifiMode");   si (statinfo.crc32 != crcOfData) { // wir haben keine gültige MAC Adresse     si (DÉBOGAGE) série.println("Examen avant l'esclave");     ScanForSlave();     // for (uint8_t i = 0 ; i < 6 ; i + +) statinfo.mac [i] = gwmac [i] ;     if (DÉBOGAGE) {       série.printf("This mac: %s,", WiFi.macAddress().c_str());        série.printf("target mac: %02x%02x%02x%02x%02x%02x", info-statinfo.mac[0], info-statinfo.mac[1], info-statinfo.mac[2], info-statinfo.mac[3], info-statinfo.mac[4], info-statinfo.mac[5]);        série.printf(", channel: %i \n", info-statinfo.channel);      }   }   if (esp_now_init() != 0) {     if (DÉBOGAGE) série.println("*** ESP_Now init failed");     DE.restart();   }   // ESP Now Controller   WiFi.setAutoConnect(false);   esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);   uint8_t tou = esp_now_get_peer_channel(info-statinfo.mac);   série.printf("Canal = %i\r \n",tou);   // L'homologue initialise les données   int res = esp_now_add_peer(info-statinfo.mac, ESP_NOW_ROLE_CONTROLLER, 1, ZÉRO, 0);   if (res==0) série.println("Paquation réussie");   // nous enregistrons la fonction à appeler après l'envoi   esp_now_register_send_cb([](uint8_t* mac, uint8_t sendStatus) {     if (DÉBOGAGE) {       série.print("send_cb, status ="); série.print(sendStatus);        série.print(", to mac:");        char macString[50] = {0};       sprintf(macString,"%02X: %02X: %02X: %02X: %02X: %02X", info-statinfo.mac[0], info-statinfo.mac[1], info-statinfo.mac[2], info-statinfo.mac[3], info-statinfo.mac[4], info-statinfo.mac[5]);       série.println(macString);     }     callbackCalled = vrai;   });      // définir l'indicateur sur false   callbackCalled = false;   // Démarrer la mesure de température   if (has_int) sensoren_int.requestTtempures();   if (has_ext) texte_sensitif.requestTtempures();   Délay(750); // attendre 750 ms pour la mesure   // obtenir la valeur de température et l'enregistrer dans la structure de données à envoyer   if (has_int) temp_int = sensoren_int.getTempC(int-int);   if (has_ext) temp_ext = texte_sensitif.getTempC(texte_adresse);    // Supprimer la mémoire tampon   lpp.reset();   // Ecrire des paquets de données dans la mémoire tampon   if (has_int) lpp.addTemperature(CHANNEL_TEMPI, temp_int);   if (has_ext) lpp.addTemperature(CHANNEL_TEMPE, temp_ext);   uint8_t sz = lpp.getSize();   // Copier la structure de données dans le tampon d'envoi   memcpy(&buf[6], lpp.getBuffer(), sz);   // envoie les données aux thermomètres   esp_now_send(ZÉRO, buf, sz+6); // NULL means send to all peers   if (DÉBOGAGE) {     série.print("Température interne:"); série.print(temp_int); série.println("° C");     série.print("Température externe:"); série.print(temp_ext); série.println("° C");   }
}

void boucle() {   // attendent que les données soient envoyées   if (callbackCalled || (millièmes() > SEND_TIMEOUT)) {     if (DÉBOGAGE) série.println("Sleep");     Délay(100);     // Pour 300 secondes dans le mode plancher     // alors un reset et le ESP8266 seront redémarrés     // Les données de la mémoire RTC ne sont pas supprimées lors de la réinitialisation.     DE.deepSleep(300E6);   }
}

Une fois le périphérique démarré, nous devrions le voir sur le site web de la passerelle.

On peut donner un nom à l'appareil et l'enregistrer.

Le périphérique a donc le numéro 1, les canaux 8 à 15. Le canal 1 de l'appareil est donc le canal 9. Après un bref laps de temps, nous devrions voir les deux nouveaux canaux dans le tableau de bord de Cayenne (ou seulement un capteur de température connecté).

Vous pouvez maintenant ajouter les deux widgets pour le canal 9 et le canal 10, puis les personnaliser si vous le souhaitez.

Amusez-vous bien dans la nuit.

Esp-8266Projekte für fortgeschritteneSensoren

Laisser un commentaire

Tous les commentaires sont modérés avant d'être publiés