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.