Ora per Completare questa Serie un semplice economico Dispositivo sulla Base ESP8266 con uno o due DS18B20 Sensori di temperatura. Poiché l'Apparecchio ogni 5 Minuti per pochi Millisecondi è attivo, può essere molto bene con le Batterie. La Batteria in Figura è simbolico. Se il +5V e il Pin del D1-Mini usati per il built-in Regolatore di tensione a 3.3 V per sfruttare bisogno di almeno 3 Batterie con 1.5 V.
Attenzione! La orangfarbene Drahtverbindung serve per Svegliarsi dalla modalità Sospensione e deve Flashare essere rimosso.
Ora il Codice:
Per la Versione finale, con Batteria voglia di gestire, se il Flag di DEBUG essere impostata su false.
/* Wi-FI Sensore di temperatura ESP Now per MQTT Gateway Se non un Indirizzo MAC è stato determinato in cerca di un Sensore WIRELESS con SSID MQTTGateway Se l'AP ha trovato, si ricorda l'Indirizzo MAC fintanto che l'Alimentazione non è stata interrotta L'ESP Now Protocollo è molto veloce in modo che solo periodo di Tempo molto breve (us) maggiore Corrente che scorre. Il Sensore invia i dati di Temperatura e poi va per 5 Minuti in un sonno profondo in modo molto poco di Energia e il Sensore della batteria può essere. */ //Biblioteca per WiFi #include <ESP8266WiFi.h> /Librerie/per Sensore di temperatura DS18B20 #include <OneWire.h> #include <DallasTemperature.h> #include <CayenneLPP.h> //Biblioteca per ESP Now extern "C" { #include <espnow.h> } //SSID del Gateway #define GW_SSID "MQTTGateway" //Flag di Debug, se false tutti i Messaggi di Debug sopprime //inoltre, per risparmiare Corrente #define DEBUG true //Costanti per WiFi #define SEND_TIMEOUT 2000 // 2 Secondi di timeout //correlazione di canali #define CHANNEL_TEMPI 1 #define CHANNEL_TEMPE 2 //Pin per sonde di temperatura const byte bus_int = 2; //GPIO2 const byte bus_ext = 4; //GPIO4 //struttura dati per il Rtc Memory con Checksum per la Validità //per verificare ciò, l'Indirizzo MAC è salvato struct MEMORYDATA { uint32_t crc32; uint8_t mac[6]; uint32_t channel; }; //i dati Globali volatile bool callbackCalled; //Memoria per valori di Temperatura float temp_int = 0; float temp_ext = 0; boolean has_int = 0; boolean has_ext = 0; //Indirizzo MAC wi-fi GRATUITA e Canali MEMORYDATA statinfo; //buffer per i dati dalla LPP Formato CayenneLPP lpp(64); //Pullman e Sensori OneWire oneWire_int(bus_int); OneWire oneWire_ext(bus_ext); DallasTemperature sensoren_int(&oneWire_int); DallasTemperature sensoren_ext(&oneWire_ext); //Array per Sensoradressen per salvare DeviceAddress adressen_int; DeviceAddress adressen_ext; //Subroutine per il Calcolo del Checksum uint32_t calculateCRC32(const uint8_t *data, size_t length) { uint32_t crc = 0xffffffff; while (length--) { uint8_t c = *data++; for (uint32_t i = 0x80; i > 0; i >>= 1) { bool bit = crc & 0x80000000; if (c & i) { bit = !bit; } crc <<= 1; if (bit) { crc ^= 0x04c11db7; } } } return crc; } //Scrive la struttura di dati statinfo corretta Checksum il RTC Memoria void UpdateRtcMemory() { uint32_t crcOfData = calculateCRC32(((uint8_t*) &statinfo) + 4, sizeof(statinfo) - 4); statinfo.crc32 = crcOfData; ESP.rtcUserMemoryWrite(0,(uint32_t*) &statinfo, sizeof(statinfo)); } //cerca un adeguato punto di accesso void ScanForSlave() { bool slaveFound = 0; int8_t scanResults = WiFi.scanNetworks(); // reset on each scansione if (DEBUG) Serial.system.out.println("Scan done"); if (scanResults == 0) { if (DEBUG) Serial.system.out.println("No WiFi devices in AP Mode found"); } else { if (DEBUG) Serial.print("Found "); if (DEBUG) Serial.print(scanResults); if (DEBUG) Serial.system.out.println(" devices "); for (int i, = 0; i < scanResults; ++i) { // Print and SSID RSSI for each device found String SSID = WiFi.SSID(i); int32_t RSSI = WiFi.RSSI(i); int32_t chl = WiFi.channel(i); String BSSIDstr = WiFi.BSSIDstr(io); se (DEBUG) { Seriale.di stampa(i + 1); Serial.stampa(": "); Seriale.di stampa(SSID); Seriale.di stampa(" /"); Seriale.di stampa(chl); Seriale.di stampa(" ("); Seriale.di stampa(RSSI); Seriale.di stampa(")"); Seriale.println(""); } ritardo(10); // Verifica se il dispositivo corrente inizia con il `Termometro` se (SSID == GW_SSID) { // SSID di interesse se (il DEBUG) { Seriale.println("Trovato uno Schiavo."); Seriale.di stampa(i + 1); Serial.stampa(": "); Seriale.di stampa(SSID); Seriale.di stampa(" ["); Seriale.di stampa(BSSIDstr); Seriale.di stampa("]"); Seriale.di stampa(" ("); Seriale.di stampa(RSSI); Seriale.di stampa(")"); Seriale.println(""); } int mac[6]; // wir testa girevole morire MAC Adresse und speichern sie im Memoria RTC se ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) { per (int ii = 0; ii < 6; ++ii ) { statinfo.mac[ii] = (uint8_t) mac[ii]; } statinfo.canale = chl; UpdateRtcMemory(); } slaveFound = 1; //Nachdem der AP gefunden wurde können wir abbrechen pausa; } } } se (il DEBUG) { se (slaveFound) { di Serie.println("Slave Trovato, elaborazione.."); } il resto { di Serie.println("Slave Non Trovato, cercando di nuovo."); } } // RAM freigeben WiFi.scanDelete(); } // funzione um eine Sensoradresse zu drucken void printAddress(DeviceAddress utili) { per (uint8_t io = 0; io < 8; io++) { se (adressen[i] < 16) Serial.stampa("0"); Seriale.di stampa(adressen[ho], HEX); } } //Unterprogramm zum Initialisieren der DS18B20 Sensoren boolean initDS18B20(uint8_t pin, DallasTemperature sensore, DeviceAddress indirizzo ) { boolean trovato = 0; pinMode(pin,INPUT_PULLUP); sensoren_int.iniziare(); se (il DEBUG) { Serial.print(sensore.getDeviceCount(), DIC); Seriale.println(" Sensoren gefunden."); } //Nun prüfen wir ob einer der Induttivi sono Autobus ein Temperatura Sensore ist se (!il sensore.getAddress(indirizzo,0)) { se (il DEBUG) Seriale.println("Kein Temperatursensor vorhanden!"); } else { //adressen anzeigen se (il DEBUG) { Seriale.di stampa("Indirizzo: "); printAddress(indirizzo); di Serie.println(); } //Nun setzen wir noch die gewünschte Risoluzione (9, 10, 11 o 12 bit) sensore.setResolution(indirizzo,10); //Zur Kontrolle lesen wir den Wert wieder aus se (il DEBUG) { Seriale.di stampa("Risoluzione = "); Serial.print(sensore.getResolution(indirizzo), DIC); Seriale.println(); } //Temperaturmessung starten sensore.requestTemperatures(); // Commando um die Temperaturen auszulesen trovato = 1; } tornare trovato; } void setup() { uint8_t buf[70]; //sendebuffer se (il DEBUG) { Seriale.iniziare(115200); Seriale.println("Start"); } //eigene MAC Adresse testa girevole und als Geräte-Id im Sendespeicher ablegen Stringa strmac = WiFi.macAddress(); se (il DEBUG) { Seriale.di stampa("Meine MAC Adresse = "); Seriale.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] ); per (uint8_t ii = 0; ii<6; ii++) buf[ii]=imac[ii]; se (il DEBUG) { Seriale.println("Interne Sensoren"); } has_int = initDS18B20(bus_int,sensoren_int,adressen_int); se (il DEBUG) { Seriale.println("Externe Sensoren"); } has_ext = initDS18B20(bus_ext,sensoren_ext,adressen_ext); //Wir lesen aus dem RTC Memoria ESP.rtcUserMemoryRead(0, (uint32_t*) &statinfo, sizeof(statinfo)); se (il DEBUG) Seriale.println((RTC Fatto"); uint32_t crcOfData = calculateCRC32(((uint8_t*) &statinfo) + 4, sizeof(statinfo) - 4); WiFi.in modalità(WIFI_STA); // Stazione di modalità per esp-ora il nodo sensore se (il DEBUG) Seriale.println("WifiMode"); se (statinfo.crc32 != crcOfData) { //wir haben keine gültige MAC Adresse se (il DEBUG) Seriale.println("Scansione vor Slave"); ScanForSlave(); //for (uint8_t i = 0; i<6;i++) statinfo.mac[i] = gwmac[i]; if (DEBUG) { Seriale.printf("Questo mac: %s",, WiFi.macAddress().c_str()); di Serie.printf("mac di destinazione: %02x%02x%02x%02x%02x%02x", statinfo.mac[0], statinfo.mac[1], statinfo.mac[2], statinfo.mac[3], statinfo.mac[4], statinfo.mac[5]); Serial.printf(", canale: %i\n", statinfo.canale); } } se (esp_now_init() != 0) { se (il DEBUG) Seriale.println("*** ESP_Now init failed"); ESP.riavviare(); } //ESP Ora Controller WiFi.setAutoConnect(false); esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER); uint8_t ch = esp_now_get_peer_channel(statinfo.mac); Serial.printf("Channel = %i\r\n",, ch); //Peer Daten initialisieren int res = esp_now_add_peer(statinfo.mac, ESP_NOW_ROLE_CONTROLLER, 1, NULL, 0); se (res==0) Seriale.println("Erfolgreich gepaart"); //wir registrieren die Funktion, die nach dem Senden aufgerufen werden soll esp_now_register_send_cb([](uint8_t* mac, uint8_t sendStatus) { se (il DEBUG) { Seriale.di stampa("send_cb, status = "); Serial.stampa(sendStatus); Seriale.di stampa(", per mac: "); char macString[50] = {0}; sprintf(macString,"%02X:%02X:%02X:%02X:%02X:%02X", statinfo.mac[0], statinfo.mac[1], statinfo.mac[2], statinfo.mac[3], statinfo.mac[4], statinfo.mac[5]); Serial.println(macString); } callbackCalled = true; }); //Flag auf false setzen callbackCalled = false; //Temperaturmessung starten se (has_int) sensoren_int.requestTemperatures(); se (has_ext) sensoren_ext.requestTemperatures(); ritardo(750); //750 ms warten bis die Messung fertig ist //Temperaturwert holen und in Datenstruktur zum Senden speichern se (has_int) temp_int = sensoren_int.getTempC(adressen_int); se (has_ext) temp_ext = sensoren_ext.getTempC(adressen_ext); //Buffer löschen lpp.reset(); //Datenpakete in den Buffer schreiben se (has_int) lpp.addTemperature(CHANNEL_TEMPI, temp_int); se (has_ext) lpp.addTemperature(CHANNEL_TEMPE, temp_ext); uint8_t sz = lpp.getSize(); //Datenstruktur in den Sendebuffer kopieren memcpy(&buf[6], lpp.getBuffer(), sz); //Daten un Termometro senden esp_now_send(NULL, buf, sz+6); // NULL significa inviare a tutti i colleghi se (DEBUG) { Seriale.di stampa("Interne Temperatur: "); Serial.stampa(temp_int); di Serie.println("°C"); di Serie.stampa("Externe Temperatur: "); Seriale.stampa(temp_ext); di Serie.println("°C"); } } void loop() { //warten bis Daten inviati sono riprodotti se (callbackCalled || (millis() > SEND_TIMEOUT)) { se (il DEBUG) Seriale.println("Sonno"); di ritardo(100); //Für 300 Secondi in den Tiefschlafmodus //dann erfolgt ein Reset und der ESP8266 wird neu gestartet //Daten im Memoria RTC werden beim Reset nicht gelöscht. ESP.sonno profondo(300E6); } }
Nachdem Das Gerät gestartet wurde, wir sollten es auf der Web-Seite des Gateway sehen.
Wir können dem Gerät einen Namen geben und es registrieren.
Das Gerät hat die Gerätenummer 1 erhalten daher morire Kanäle 8 bis 15. Der Kanal 1 des Gerätes ist anche Kanal 9. Nach kurzer Zeit wir sollten im Cayenne Dashboard die beiden neuen Kanäle (oder nur einen nur wenn ein Temperatursensor angeschlossen wurde) sehen.
Nun kann man die beiden Widget für Canale 9 e Canale 10 aggiungi und nach Wunsch anpassen.
Viel Spaß beim Nachbau