Externe temperatuursensor voor thermometer met ESP8266

Dit bericht is een aanvulling op het vorige bericht. Het beschrijft een temperatuursensor met ESP8266 die de huidige temperatuur om de vijf minuten naar de thermometer in het laatste artikel stuurt. In de pauze tussen twee metingen wordt de ESP8266 in de diepe slaapstand gezet waarin hij nauwelijks energie verbruikt. Om de gegevens te verzenden, wordt het ESP Now-protocol gebruikt, dat de gegevens rechtstreeks naar het MAC-adres van de thermometer verzendt zonder complexe verbindingsinstellingen.

Wij gebruiken dat ESP8266-E12-module met adapter, omdat dit in tegenstelling tot de ESP8266-01 module de wake pin GPIO-16 heeft opgeleverd en geen permanent brandende LED op de voedingsspanning heeft. We hebben de wake-pin nodig om uit een diepe slaap te ontwaken en de power-LED verbruikt alleen onnodig energie.

Circuit:

De oranje draad verbindt de wake pin met de reset-ingang en zorgt ervoor dat de module opnieuw wordt gestart aan het einde van de slaapstop. De sensor is verbonden met de GPIO2 (witte draad).

Om het programma te uploaden hebben we een FDTI-adapter nodig om de ESP8266 via de seriële interface te programmeren.

We verbinden de FDTI-adapter met de GND-connector en TX met RX en RX met TX. Bovendien moet de Flash Pin GPIO 0 worden verbonden met aarde (groene draad) zodat de ESP8266 in de programmeermodus gaat.

De groene draad moet na het programmeren worden verwijderd. Als DEBUG in de schets is ingesteld op true, kunnen de berichten van de module worden gevolgd via de seriële interface.

Waarschuwing:  Een voeding van de ESP8266 door de FDTI-kaart leidt tot crashes wanneer de scanNetwork-functie wordt aangeroepen omdat het huidige verbruik dan te hoog is.

Schets:

Om het bord samen te stellen

aanpassen !!

 

/*
  WLAN temperatuursensor
  ESP Nu met de thermometer
  Als er nog geen MAC-adres is bepaald
  de sensor is op zoek naar een WLAN met SSID-thermometer
  Wanneer hij het AP vindt, onthoudt hij het MAC-adres 
  zolang de stroomtoevoer niet is onderbroken
  Het ESP Now-protocol is erg snel, dus slechts een zeer korte tijd (us)
  hogere stroom vloeit. De sensor verzendt temperatuurgegevens en gaat vervolgens gedurende 5 minuten in 
  Diepe slaap zodat heel weinig energie wordt gebruikt en dat
  Sensor kan daarom op batterijen worden gebruikt. 
*/

// bibliotheek voor wifi
# opnemen <ESP8266WiFi.h>
// Bibliotheken voor temperatuursensor DS18B20
# opnemen <OneWire.h>

// Bibliotheek voor ESP nu
# opnemen <DallasTemperatuur.h>
extern "C" {   # opnemen <vooral.h>
}

// Debug vlag indien false alle debug berichten worden onderdrukt
// om extra elektriciteit te besparen
#define DEBUG waar

// Constanten voor wifi
#define WIFI_CHANNEL 1
#define SEND_TIMEOUT 2450  // Time-out van 245 milliseconden 

// Pinnen voor temperatuursensor
const byte bus = 2;// pin GPIO2

// Gegevensstructuur voor gegevensuitwisseling
struct DATA_STRUCTURE {     zweven temp = 0;
};

// Gegevensstructuur voor het Rtc-geheugen met controlesom voor geldigheid
// controleer of het MAC-adres is opgeslagen
struct MEMORYDATA {   uint32_t crc32;   uint8_t mac[6];
};

// Wereldwijde gegevens
vluchtig dwaas callbackCalled;

MEMORYDATA statinfo;

OneWire oneWire(bus);

DallasTemperatuur sensoren(&oneWire);

// array om sensoradressen op te slaan
DeviceAddress adressen;

// Subroutine voor het berekenen van de controlesom
uint32_t berekenCRC32(const uint8_t *gegevens, size_t lengte)
{   uint32_t crc = 0xffffffff;   terwijl (lengte--) {     uint8_t c = *gegevens++;     voor (uint32_t ik = 0x80; ik > 0; ik >>= 1) {       dwaas beetje = crc & 0x80000000;       als (c & ik) {         beetje = !beetje;       }       crc <<= 1;       als (beetje) {         crc ^= 0x04c11db7;       }     }   }   terug crc;
}

// Schrijft de statinfo-gegevensstructuur met de juiste controlesom naar het RTC-geheugen
nietig UpdateRtcMemory() {     uint32_t crcOfData = berekenCRC32(((uint8_t*) &statinfo) + 4, De grootte van(statinfo) - 4);     statinfo.crc32 = crcOfData;     ESP.rtcUserMemoryWrite(0,(uint32_t*) &statinfo, De grootte van(statinfo));
}

// sucht nach einem geeigneten AccessPoint
nietig ScanForSlave() {   dwaas slaveFound = 0;      int8_t scanresultaten = Wifi.scanNetworks();   // reset bij elke scan   als (DEBUG) Serie.println("Scan gereed");   als (scanresultaten == 0) {     als (DEBUG) Serie.println("Geen wifi-apparaten in AP-modus gevonden");   } anders {     als (DEBUG) Serie.afdrukken("Gevonden");      als (DEBUG) Serie.afdrukken(scanresultaten);      als (DEBUG) Serie.println("apparaten");     voor (int ik = 0; ik < scanresultaten; ++ik) {       // SSID en RSSI afdrukken voor elk gevonden apparaat       Draad SSID = Wifi.SSID(ik);       int32_t RSSI = Wifi.RSSI(ik);       Draad BSSIDstr = Wifi.BSSIDstr(ik);       als (DEBUG) {         Serie.afdrukken(ik + 1);         Serie.afdrukken(": ");         Serie.afdrukken(SSID);         Serie.afdrukken(" (");         Serie.afdrukken(RSSI);         Serie.afdrukken(")");         Serie.println("");       }       vertraging(10);       // Controleer of het huidige apparaat start met `Thermometer`       als (SSID.index van("Thermometer") == 0) {         // SSID van belang         als (DEBUG) {           Serie.println("Een slaaf gevonden.");           Serie.afdrukken(ik + 1); Serie.afdrukken(": "); Serie.afdrukken(SSID); Serie.afdrukken(" ["); Serie.afdrukken(BSSIDstr); Serie.afdrukken("]"); Serie.afdrukken(" ("); Serie.afdrukken(RSSI); Serie.afdrukken(")"); Serie.println("");         }         int Mac[6];         // wir ermitteln die MAC Adresse und speichern sie im RTC Memory         als ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c",  &Mac[0], &Mac[1], &Mac[2], &Mac[3], &Mac[4], &Mac[5] ) ) {           voor (int ii = 0; ii < 6; ++ii ) {             statinfo.Mac[ii] = (uint8_t) Mac[ii];           }           UpdateRtcMemory();         }         slaveFound = 1;         // Nachdem der AP gefunden wurde können wir abbrechen         breken;       }     }   }         als (DEBUG) {     als (slaveFound) {       Serie.println("Slave gevonden, bezig met verwerken ...");     } anders {       Serie.println("Slave Not Found, probeert het opnieuw.");     }   }   // RAM freigeben   Wifi.scanVerwijderen();
}
// functie um eine Sensoradresse zu drucken
nietig printAdres(DeviceAddress adressen)
{   voor (uint8_t ik = 0; ik < 8; ik++)   {     als (adressen[ik] < 16) Serie.afdrukken("0");     Serie.afdrukken(adressen[ik], HEX);   }
}

nietig opstelling() {   als (DEBUG) {     Serie.beginnen(115200);      Serie.println("Begin");   }   pinMode(bus,INPUT_PULLUP);   // Wir ermitteln die Anzah der Sensoren am Eindraht-Bus   sensoren.beginnen();   als (DEBUG) {     Serie.afdrukken(sensoren.getDeviceCount(), DEC);     Serie.println("Sensoren gefunden.");   }   // Geen druk op de sensor voor bus en temperatuursensor   als (!sensoren.getAddress(adressen,0)) {     als (DEBUG) Serie.println("Kein Temperatursensor vorhanden!");   }   // adressen anzeigen   als (DEBUG) {     Serie.afdrukken("Adresse:");     printAdres(adressen);     Serie.println();   }   // Nun setzen wir noch die gewünschte Auflösung (9, 10, 11 of 12 bit)   sensoren.setResolution(adressen,10);   // Zur Kontrolle lesen wir den Wert wieder aus   als (DEBUG) {     Serie.afdrukken("Auflösung =");     Serie.afdrukken(sensoren.getResolution(adressen), DEC);     Serie.println();   }   sensoren.requestTemperatures(); // Commando um die Temperaturen auszulesen   // Wir lesen aus dem RTC-geheugen   ESP.rtcUserMemoryRead(0, (uint32_t*) &statinfo, De grootte van(statinfo));   als (DEBUG) Serie.println("RTC gereed");   uint32_t crcOfData = berekenCRC32(((uint8_t*) &statinfo) + 4, De grootte van(statinfo) - 4);   Wifi.modus(WIFI_STA); // Station-modus voor esp-now sensorknooppunt   als (DEBUG) Serie.println("WifiMode");   als (statinfo.crc32 != crcOfData) { // wir haben keine gültige MAC Adresse     als (DEBUG) Serie.println("Scan vor Slave");     ScanForSlave();     als (DEBUG) {       Serie.printf("Deze mac:% s,", Wifi.Mac adres().c_str());        Serie.printf("target mac:% 02x% 02x% 02x% 02x% 02x% 02x", statinfo.Mac[0], statinfo.Mac[1], statinfo.Mac[2], statinfo.Mac[3], statinfo.Mac[4], statinfo.Mac[5]);        Serie.printf(", kanaal:% i \ n", WIFI_CHANNEL);      }   }   als (esp_now_init() != 0) {     als (DEBUG) Serie.println("*** ESP_Now init mislukt");     ESP.herstarten();   }   // ESP Now-controller   esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);   // Peer Daten initialisieren   esp_now_add_peer(statinfo.Mac, ESP_NOW_ROLE_SLAVE, WIFI_CHANNEL, NUL, 0);   // wir registrieren die Funktion, die nach dem Senden aufgerufen werden soll   esp_now_register_send_cb([](uint8_t* Mac, uint8_t sendStatus) {     als (DEBUG) {       Serie.afdrukken("send_cb, status ="); Serie.afdrukken(sendStatus);        Serie.afdrukken(", naar 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]);       Serie.println(macString);     }     callbackCalled = waar;   });      // Vlag van valse setzen   callbackCalled = fout;   // Temperaturmessung starten   sensoren.requestTemperatures();      vertraging(750); // 750 ms warten bis die Messung fertig ist   // Temperaturwert holen und in Satenstruktur zum Senden speichern   DATEN_STRUKTUR gegevens;   gegevens.temp = sensoren.getTempC(adressen);   uint8_t bs[De grootte van(gegevens)];   // Datenstruktur in den Sendebuffer kopieren   memcpy(bs, &gegevens, De grootte van(gegevens));   // Daten an Thermometer senden   esp_now_send(NUL, bs, De grootte van(gegevens)); // NULL betekent verzenden naar alle peers   als (DEBUG) {     Serie.afdrukken("Temperatur:"); Serie.afdrukken(gegevens.temp); Serie.println("° C");   }
}

nietig lus() {   // warten bis Daten gesendet wurden   als (callbackCalled || (millis() > SEND_TIMEOUT)) {     als (DEBUG) Serie.println("Slaap");     vertraging(100);     // Für 300 Sekunden in den Tiefschlafmodus     // dann erfolgt ein Reset und der ESP8266 wird neu gestartet     // Daten im RTC Memory werden beim Reset nicht gelöscht.     ESP.diepe slaap(300E6);   }
}




Testen:

Nachdem das Modul mit Strom versorgt wurde kennt es noch keine gültige MAC-adresse des thermometers. Es versucht ein offenes Netwerk met der SSID "Thermometer" zu finden. Da Thermometer en temperatuur Minuten na dem Start seine SSID versteckt, müssen wir einen Neustart des Thermometers auslösen. Geen sensor Sensormodule Temperatuur thermometer en alle temperatuur Minuten den aktuellen Temperaturwert übermitteln. Das Thermometer sollte abwechselnd die lokale Temperatur (Häuschen Symbol) und die Temperatur vom Sensor Modul (Baum Symbol) anzeigen.

Esp-8266Projekte für fortgeschritteneSensoren

2 Kommentare

Carsten Jürges

Carsten Jürges

Wenn kein “Thermometer” gefunden wird, landet irgendeine MAC-Adresse in statinfo und das war’s dann erstmal. Daher habe ich Funktion DeleteRtcMemory spendiert, den CRC-Wert “zerstört”. Diese Funktionen wird aufgerufen, wenn das Senden nicht erfolgreich (sendStatus) war …
Dann gibt es beim nächsten Start einen neuen Verbindungsversuch …

Jörg

Jörg

Super, genau so etwas habe ich gesucht.
Vielen Dank für die interessanten Projektvorstellungen.

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert

Aanbevolen blog berichten

  1. Installeer ESP32 nu van de raad van bestuur
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP Programmeren via Wi-Fi

Aanbevolen producten