A temperature, air humidity and air pressure sensor should be operated with a battery and send its measured values via WLAN every five minutes. The data should then be called up on a website.
concept
In order to solve this task, it is necessary to keep the energy requirement of the sensor as small as possible and a web server is required that collects the data and, if necessary, delivers as a HTML document. As a controller for the sensor, a D1 mini with ESP 8266 and a BME280 should be used as a sensor. Any other sensor can also be used by corresponding changes in the sketch. During the break between the measurements, the controller is to be put into deep sleep mode in order to reduce power consumption. D1 Mini Plus BME280 need 35 µA together in this state. The D1 Mini needs about 80 mA to send the data via WLAN. It is therefore necessary to keep the time to transfer the data as short as possible. The network protocols TCP or UDP are not so well suited for this, since a connection with the network must first be established after the deep sleep mode before the data can be sent. Such a connection can take up to ten seconds depending on the network. In a network, however, data packages that are provided with the recipient's MAC address can also be sent without existing connection. However, these packages can only be received in the same network. They cannot be transmitted to other networks via a router. The manufacturer of the ESP8266, the Espressif company, has developed its own protocol "ESP-NOW". If this protocol is used, the time is reduced to measure and transmit to 0.55 seconds. This means a measurement requires 0.55s x 77mA = 42.35mas. During the break between the measurements in deep sleep mode, 299.45s x 0.035ma = 10.48mas are required. A whole measuring cycle therefore needs 42.35mas + 10.48mas = 52.83mas. On one day, 288 measurements are carried out with a total energy requirement of 288 x 52.83mas = 15,215.04mas or 4.23 mAh. A battery owner is used for 4 AA-Mignon batteries or batteries. With low power consumption, the sensor can be operated for about a year.
An ESP32-D1-mini is used as a server, which is operated via a USB power supply. This server must always be accessible in the network. The sensor sends the measured values every five minutes via ESP-NOW to the server, which stores the measured values and provides HTTP page in the network on request. The server must therefore also have a TCP connection to the network. In order for ESP-NOW to be used together with WIFI, the WIFI network must use channel 1!
The structure can be carried out on a hole grid plate 4 x 6 cm, for example. The following figure shows the wiring. The spring strips enclosed by the module can be used as a base for the D1 mini. For the reset jumper you need a 2-pin pin strip plus jumper. A 4-pin spring strip for the BME280. You can solve the cables for the battery owner directly or use a two -pin screw clamp.
The figure shows the assembly and wiring on the underside
For the server, only the ESP32-D1 mini is used without any external circuit. The enclosed contact strips do not have to be equipped. Only a USB power supply is required.
software
In order for the sketch to be compiled, the Arduino IDE must be prepared accordingly. By default, Arduino IDE supports a large number of boards with different microcontrollers, but not the ESP8266 and not the ESP32. So that you can create and upload programs for these controllers, a software package for the support must therefore be installed.
Now choose the board management in the Arduino IDE under tool → board.
A window opens in which all available packages are listed. In order to narrow down the list, you enter in the search field "ESP". Then you only get an entry in the list. Install the packages "ESP32" and "ESP8266".
For the sensor BME280 you need a library that can be installed via the Arduino library management. This is the library "Bluedot BME280".
If all libraries are installed, the sketch can be compiled and uploaded to the hardware. Danger! The jumper between D0 and RST must be removed for uploading.
The sketch for the sensor
#include<Wire.H>#include<Bluedot_bme280.H>#include<ESP8266WIFI.H>#include<Arduinojson.H>// Library for ESP Now#include<Espnow.H>// ssid of the gateway#defineGW_SSID"Webhookgateway"// Series Resistor for Supply Voltage Measurement#defineResistor470// for battery = 470 for battery loader = 130// Switch debug messages on#defineDebug1#defineSend_timeout2000// 2 Seconds timeout#defineReconD5// pin for reconnect button// Instance for SensorBluedot_bme280BME;// Data Structure to Save Gateways Mac AddressstructMemorydata{uint32_tcrc32;// Checksumuint8_tMac[6];};// global variablesuint32_tMS;// TIMESTAMP to calculate process timeBoolcallback=false;// Flag for data SentMemorydatastatinfo;// memory for mac address// Callback function wants to be called if data has been sent to the gatewayvoidsenddata(uint8_t*SMAC,uint8_tbroad status){IF(Debug){Serial.print("Send_cb, status =");Serial.print(broad status);Serial.print(", Mac:");charMacString[50]={0};sprint(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.print(MacString);}callback=true;}// Function to calculate checksumuint32_tcalculatecrc32(constuint8_t*data,Size_Tlength){uint32_tCRC=0xffffffff;while(length--){uint8_tC=*data++;for(uint32_tI=0x80;I>0;I>>=1){Boolbit=CRC&0x80000000;IF(C&I){bit=!bit;}CRC<<=1;IF(bit){CRC^=0x04c11db7;}}}returnCRC;}// Save Gateways Mac Address and Checksum in RTC MemoryvoidUpdate(){uint32_tcrcofdata=calculatecrc32(((uint8_t*)&statinfo)+4,Sizeof(statinfo)-4);statinfo.crc32=crcofdata;ESP.Rtcuser memorywrite(0,(uint32_t*)&statinfo,Sizeof(statinfo));}// Search for Gateways Access PointBooleanScanforlave(){Boolslave found=false;int8_tscanresults=Wifi.scannetworks();IF(Debug)Serial.print("Scan Done");IF(scanresults==0){IF(Debug)Serial.print("No Accessspoint Found");}Else{IF(Debug){Serial.print("Found ");Serial.print(scanresults);Serial.print("Netze");}for(intimatelyI=0;I<scanresults;++I){StringSSID=Wifi.SSID(i);int32_tRSSI=WiFi.RSSI(i);int32_tchl=WiFi.channel(i);StringBSSIDstr=WiFi.BSSIDstr(i);if(DEBUG){// display what we foundSerial.print(i+1);Serial.print(": ");Serial.print(SSID);Serial.print(" /");Serial.print(chl);Serial.print(" (");Serial.print(RSSI);Serial.print(")");Serial.println("");}delay(10);// check if we have the gatewayif(SSID==GW_SSID){if(DEBUG){Serial.println("Network found");Serial.print(i+1);Serial.print(": ");Serial.print(SSID);Serial.print(" [");Serial.print(BSSIDstr);Serial.print("]");Serial.print(" (");Serial.print(RSSI);Serial.print(")");Serial.println("");}intmac[6];// Save gateways MAC addressif(6==sscanf(BSSIDstr.c_str(),"%x:%x:%x:%x:%x:%x%c",&mac[0],&mac[1],&mac[2],&mac[3],&mac[4],&mac[5])){for(intii=0;ii<6;++ii){statinfo.mac[ii]=(uint8_t)mac[ii];}UpdateRtcMemory();}slaveFound=true;//break scan if accesspoint was foundbreak;}}}if(DEBUG){if(slaveFound){Serial.println("Found accesspoint!");}else{Serial.println("Did not found the accesspoint! New try.");}}// release memoryWiFi.scanDelete();returnslaveFound;}voidsetup(){booleannetExists=true;ms=millis();//remember start timeSerial.begin(74880);pinMode(RECON,INPUT_PULLUP);//Start BME280bme.parameter.communication=0;//I2C communication for Sensorbme.parameter.I2CAddress=0x76;//I2C Address for Sensorbme.parameter.sensorMode=0b01;//forced mode a single measured is performedbme.parameter.IIRfilter=0b000;//factor 0 (filter off)bme.parameter.humidOversampling=0b001;//Humidity Oversampling factor 1bme.parameter.tempOversampling=0b001;//Temperature Oversampling factor 1bme.parameter.pressOversampling=0b001;//Pressure Oversampling factor 1if(bme.init()!=0x60){Serial.println("BME280 Sensor not found!");}delay(50);//wait 50 ms to complete the measurement//Read gateways MAC address from RTC memoryESP.rtcUserMemoryRead(0,(uint32_t*)&statinfo,sizeof(statinfo));if(DEBUG)Serial.println("RTC fertig");uint32_tcrcOfData=calculateCRC32(((uint8_t*)&statinfo)+4,sizeof(statinfo)-4);if((statinfo.crc32!=crcOfData)||(digitalRead(RECON)==0)){//if the checksum is wrong, the MAC address is invalid//we have to scan for gatewayif(DEBUG)Serial.println("Search for gateway");netExists=ScanForSlave();}if(DEBUG){Serial.print("Gateway MAC address: ");Serial.printf("%x-%x-%x-%x-%x-%x\n",statinfo.mac[0],statinfo.mac[1],statinfo.mac[2],statinfo.mac[3],statinfo.mac[4],statinfo.mac[5]);Serial.print("My MAC address: ");Serial.println(WiFi.macAddress());}if(netExists){//initialize ESP-NOWif(esp_now_init()!=0){if(DEBUG)Serial.println("*** ESP_Now INIT has failed");ESP.restart();}esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);//Initialize peerintres=esp_now_add_peer(statinfo.mac,ESP_NOW_ROLE_CONTROLLER,1,NULL,0);if((res==0)&&DEBUG)Serial.println("Erfolgreich gepaart");//register callback functionesp_now_register_send_cb(sendData);callbackCalled=false;//cleare flag//buffer for message (max 250 characters)charbuf[500];//Unique name from sensor name and MAC addressstrcpy(buf,"BME280-");Stringmc=WiFi.macAddress();mc.replace(":","");strcat(buf,mc.c_str());uint16_tlen=strlen(buf);//read valuesfloathumidity=bme.readHumidity();floattemperature=bme.readTempC();floatpressure=bme.readPressure();pinMode(A0,INPUT);uint16_traw=analogRead(A0);floatvolt=raw/1023.0;floatbattery=volt/100*(320+RESISTOR);charmbuf[200];Stringunit="°C";//first we create a full text message. //This will be used for web display and for Alexasprintf(mbuf,"&Die Temperatur ist %5.1fGrad Celsius\ndie Feuchtigkeit ist %5.0f%%\nder Luftdruck ist %7.1fhPa\ndie Batteriespannung ist %3.1fVolt&",temperature,humidity,pressure,battery);uint8_tn1=strlen(mbuf);//add data to the message bufferstrlcat(buf,mbuf,n1+len+1);//now we create another message with values JSON formatted for MQTTStaticJsonDocument<400>doc;//the JSON object will be filleddoc["t"]=temperature;//Valuedoc["tu"]=unit;//Unitdoc["h"]=humidity;//Valuedoc["hu"]="%";//Unitdoc["p"]=round(pressure);//Valuedoc["pu"]="hPa";//Unitdoc["b"]=battery;doc["bu"]="V";//create a JSON string from JSON objectuint16_tn=serializeJson(doc,mbuf);//add it to the message buffer//as a delimiter ampersand character will be usedstrlcat(buf,mbuf,n+n1+len+1);if(DEBUG)Serial.println(buf);//Send message buffer to gatewayesp_now_send(NULL,(uint8_t*)&buf,len+n1+n);}else{//No gatway was found, we go to sleep//and restart 5 minutes later to try it againESP.deepSleep(300E6);}}voidloop(){//wait untril data were sentif(callbackCalled||(millis()>5000)){if(DEBUG)Serial.println("Sleep");delay(100);//go to deep sleep and restart the controller after 5 minutes//sleep time is in micro secondsSerial.printf("Processing time %i ms\n",millis()-ms);//display processing timeESP.deepSleep(300E6);}}
Der Sketch im Downloadbereich enthält eine verbesserte Version.!
Hinweis: Der ESP32 verfügt über 8K statisches RAM, bekannt als Real Time Clock Random Access Memory (Static RTC RAM), der zum Speichern und Halten von Variablen während des Tiefschlafs verwendet werden kann.
Das Programm wird praktisch nur in der Setup-Funktion ausgeführt. Nachdem der Sensor initialisiert wurde, wird im Speicher der Echtzeituhr nachgeschaut, ob dort bereits die MAC Adresse des Gateways gespeichert ist. Ist das nicht der Fall wird ein Netzwerkscan durchgeführt, um das Gateway zu finden. Wurde das Gateway gefunden, wird die MAC Adresse im RTC Speicher für später gespeichert. Der RTC Speicher behält seine Informationen, solange der Chip mit Strom versorgt wird. Mit der MAC Adresse des Gateways wird dann eine Paarung durchgeführt, die Messwerte vom Sensor gelesen und an das Gateway gesendet. In der Funktion loop() wird darauf gewartet, dass die Datenübertragung fertig ist, dann wird der ESP8266 für fünf Minuten in den Tiefschlaf versetzt. Das Aufwecken besorgt ein interner Timer, der nach der programmierten Zeit einen Impuls auf dem Pin D0 ausgibt, der über den Jumper mit Reset verbunden ist und so einen Neustart auslöst.
Der Sketch für den Server
Für den Server benötigen Sie zwei Bibliotheken, die nicht über die Bibliotheksverwaltung installiert werden können. Diese müssen zuerst als ZIP Datei heruntergeladen werden. Der asynchrone Webserver von https://github.com/me-no-dev/ESPAsyncWebServer und Asynchron TCP von https://github.com/me-no-dev/AsyncTCP. Zum Herunterladen einfach auf den grünen Knopf Code klicken und „Download ZIP“ auswählen.
Um die heruntergeladenen ZIP-Dateien in der Arduino IDE zu installieren, rufen Sie im Menü Sketch -> Bibliothek einbinden -> .ZIP Bibliothek hinzufügen auf. Es erscheint ein Datei-Auswahl-Dialog, indem Sie die heruntergeladenen Dateien auswählen. Mehr ist nicht zu tun.
Schließlich wird noch eine weitere Bibliothek benötigt, die über die Arduino Bibliotheksverwaltung installiert werden kann. Das ist die Bibliothek „AsyncWebConfig“, die die Konfiguration über den Browser implementiert
The Server Sketch starts a web server that displays the measured values from the sensor and through which the configuration can be carried out. He also takes care of the ESP-Now protocol to display the data from the sensors. A real-time clock is displayed.
#include"WiFi.h"//WiFi support#include<ESPmDNS.h>//Dynamics name server#include<esp_now.h>//ESP NOW#include<SPIFFS.h>//Flash Filesystem#include<FS.h>//File streams#include"ESPASyncWebServer.h"//Asynchronous web server#include<AsyncWebConfig.h>//Configuration by asynchronous web server#defineACCESS POINT"WebhookGateway"//SSID of the access point#defineMAXDEVICES100//maximum number of devices#defineEMPTYMSG"No measured values are available yet"//message if no values exist#defineDEVICEFILE"/devices.csv"//filename to save devices in SPIFFS#defineTIMEZONETZ_Europe_Berlin//timezone constant//Define parameter for WebConfigStringparams="[""{""'name':'ssid',""'label':'WLAN name',""'type':"+String(INPUTTEXT)+",""'default':''""},""{""'name':'pwd',""'label':'WLAN Password',""'type':"+String(INPUT PASSWORD)+",""'default':''""},""{""'name':'ntp_server',""'label':'NTP Server',""'type':"+String(INPUTTEXT)+",""'default':'fritz.box'""}""]";//Templates for the web page//Start partconstcharHTML_START[]PROGRAMME="\n""\n"\n""\n""\n"\n"\n""
My Devices
\n""
%s
\n";//Template to show a deviceconstcharHTML_DEVICE[]PROGRAMME="
\n"
"\n""
\n";//Template for a single lineconstcharHTML_LINE[]PROGRAMME="
%s
\n";/Template for final closeconstcharHTML_END[]PROGRAMME="\n""
\n"
"
\n""\n";//Instance for web serverAsyncWebServerserver(80);//Instance for web configAsyncWebConfigconf;/structure to store a sensor devicetypedefstruct{charid[32];//unique idtime_tdateTime;http://timestampcharkeyword[32];/name of the devicecharmsg[256];//msg with valuescharjsone[150];//json formatted values}Device;//global variablesDevicedevices[MAXDEVICES];//currency listuint16_tcount;//number of registered devicesbooleanconnected=false;//true if we have a WiFi connectionuint16_tnextTry=0;//counter for reconnect/add a device to the device listvoidaddDevice(constchar*id,constchar*keyword="",constchar*msg=EMPTYMSG){if(count<MAXDEVICES){strcpy(devices[count].id,id);strcpy(devices[count].keyword,keyword);strcpy(devices[count].msg,msg);devices[count].dateTime=0;count++;}}//read device list from flash file systemvoidreadDevices(){uint16_tlen;count=0;if(SPIFFS.exists(DEVICEFILE)){Filef=SPIFFS.open(DEVICEFILE,"r");Serial.println("Lese Geräte");if(f){Stringdata;Stringid;Stringkeyword;Serial.println("Lese Geräte");uint16_tsize=f.size();while(f.position()<size){data=f.readStringUntil(10);Serial.println(data);uint8_tp=data.indexOf(",");id=data.substring(0,p).c_str();keyword=data.substring(p+1);if(id!=""){addDevice(id.c_str(),keyword.c_str());}}}}}//save device list into flash filesystemvoidsaveDevices(){Filef=SPIFFS.open(DEVICEFILE,"w");Serial.printf("Speichere Geräte auf %s \n",DEVICEFILE);if(f){for(uint8_ti=0;i<count;i++){f.printf("%s,%s\n",devices[i].id,devices[i].keyword);Serial.printf("%s,%s\n",devices[i].id,devices[i].keyword);}f.close();}else{Serial.printf("Kann file %s nicht öffnen",DEVICEFILE);}}//find a device with certain id return index or -1 if not foundint16_tfindId(constchar*id){int16_tix=count-1;while((ix>=0)&&(strcmp(devices[ix].id,id)!=0))ix--;returnix;}//find a device with certain name return index or -1 if not foundint16_tfindKeyword(constchar*keyword){int16_tix=count-1;while((ix>=0)&&(strcmp(devices[ix].keyword,keyword)!=0))ix--;returnix;}//delete the device with name keyword from device listvoiddeleteDevice(constchar*keyword){int16_tix=findKeyword(keyword);if(ix<0)return;count--;if(ix!=count){memcpy(&devices[ix],&devices[count],sizeof(Device));}}//delete the device with unique id from device listvoiddeleteDeviceId(constchar*id){int16_tix=findId(id);if(ix<0)return;count--;if(ix!=count){memcpy(&devices[ix],&devices[count],sizeof(Device));}}//set the name for device with unique idvoidsetKeyword(constchar*id,constchar*keyword){int16_tix=findId(id);if(ix>=0)strncpy(devices[ix].keyword,keyword,32);}//initialioze WiFi connectionbooleaninitWiFi(){booleanconnected=false;WiFi.mode(WIFI_AP_STA);WiFi.softAP(ACCESSPOINT,"",0,0);Serial.print("Verbindung zu ");Serial.print(conf.values[0]);Serial.println(" herstellen");//if we have a config we try to connectif(conf.values[0]!=""){WiFi.begin(conf.values[0].c_str(),conf.values[1].c_str());uint8_tcnt=0;while((WiFi.status()!=WL_CONNECTED)&&(cnt<20)){delay(500);Serial.print(".");cnt++;}Serial.println();if(WiFi.status()==WL_CONNECTED){Serial.print("IP-Adresse = ");Serial.println(WiFi.localIP());connected=true;boolflag=(esp_now_init()==ESP_OK);if(flag){Serial.println("ESP-NOW gestartet");}}}//if we have no connection /no config or wrong config)//we start an access point to allow configurationif(!connected){Serial.println("Keine Verbindung! \nStarte Access-Point.");WiFi.mode(WIFI_AP);WiFi.softAP(conf.getApName(),"",1);nextTry=0;}returnconnected;}//show configuration formvoidhandleConfig(AsyncWebServerRequest*request){conf.handleFormRequest(request);}//response to a root requestvoidhandleRoot(AsyncWebServerRequest*request){char*ptr;charbuf[256];structtm*timeinfo;Stringnam;Stringid;booleanconf=false;if(!connected){//if not connected show config pagehandleConfig(request);}else{uint8_targs=request->args();//we checkk the requests arguments for commandsfor(uint8_ti=0;i<args;i++){nam=request->argName(i);if(nam=="config")conf=true;if(nam.startsWith("edt-")){//an edit button was clickedid=nam.substring(4);Serial.printf("Change name for %s\n",id.c_str());if(request->hasArg(id.c_str()))setKeyword(id.c_str(),request->arg(id).c_str());saveDevices();}if(nam.startsWith("del-")){//a delete button was clickedid=nam.substring(4);Serial.printf("Delete device %s\n",id.c_str());deleteDeviceId(id.c_str());saveDevices();}}if(!conf){//build the eb page, show all devices and their valuesAsyncResponseStream*response=request->beginResponseStream("text/html");time_tnow=time(nullptr);timeinfo=localtime(&now);strftime(buf,256,"%d.%m.%Y %H:%M:%S",timeinfo);Serial.printf("we have %i devices\n",count);response->printf(HTML_START,buf);for(uint16_ti=0;i<count;i++){Serial.printf("Device [%s] name [%s]\n",devices[i].id,devices[i].keyword);response->print("
");}response->print(HTML_END);request->send(response);}else{handleConfig(request);}}}// callback for ESP NowvoidreadESPNow(constuint8_t*mac_addr,constuint8_t*r_data,intdata_len){charbuf[256];char*msg;char*json;char*id;if(data_len<256){memcpy(&buf,r_data,data_len);buf[data_len]=0;Serial.printf("Received from ESPNOW %x : %s\n",mac_addr,buf);//split the message in parts. Separator is "&"id=strtok(buf,"&");msg=strtok(NULL,"&");json=strtok(NULL,"&");int16_tindex=findId(id);if(index<0){//if device not exists, add itaddDevice(id,"",msg);saveDevices();}else{//if device exists, update valuesstrlcpy(devices[index].msg,msg,255);if(json)strlcpy(devices[index].json,json,149);devices[index].dateTime=time(nullptr);}}}//setup the gatewayvoidsetup(){Serial.begin(115200);Serial.println(params);//read configurationconf.setDescription(params);conf.readConfig();//init WiFi connectionconnected=initWiFi();//start ESP NOWesp_now_register_recv_cb(readESPNow);//prepare nameserver chardns[30];sprintf(dns,"%s.local",conf.getApName());if(MDNS.begin(dns)){Serial.println("MDNS responder gestartet");}//register request callbacksserver.on("/",handleRoot);server.on("/config",handleConfig);//start webserverserver.begin();//initialize real time clockif(connected){//if we have an internet connection//init the internal clockconfigTzTime("CET-1CEST,M3.5.0/03,M10.5.0/03",conf.getValue("ntp_server"));Serial.print(conf.getValue("ntp_server"));Serial.println(" Uhrzeit gesetzt!");}//read devivce listreadDevices();}voidloop(){//all happens asynchron, no actions required}
When the sketch was compiled and uploaded without errors, the program starts. Since there are no configuration data yet, an access point is started. The SSID is formed from the MAC address of the D1 minis. With a smartphone or other WiFi-enabled computer, a connection to this access point can now be established. Access is open, so no password is required. After the WLAN connection is established, the address 192.168.4.1 can be called up in the browser. The configuration page is shown.
The name of the access point is later used as a DNS name. The access data to the WLAN follow. The NTP server is used to synchronize the internal clock. For example, FRITZ.BOX could also be here if the FRITZ box is to be used as a time server. With the "Save" button, the configuration is saved in the flash files system of the D1 minis. The configuration is also saved with the "Restart" button and then the D1 mini restarted. The initial configuration should be ended with "remaining type", since the D1 mini should connect to the WLAN after the restart. If the connection is successful, no access point is started. It should now be possible to call up the homepage with the URL .local in the example shown, with gateway1.local. If your Router MDNS does not support, you must use the IP address that was output via the serial monitor.
If no connection with a sensor had yet occurred, the following homepage is shown.
With the button with the gear you can switch to the configuration page. After a sensor has been connected to the gateway, you get the following homepage.
In the input field you can see the clear identification of the sensor consisting of a sensor type and Mac address. Here you can enter a more meaningful name and permanently save it with the EDIT button. The device can be deleted from the list with the extinguishing button. Up to 100 sensors can be connected to the gateway.
A second part of this project will follow. In this second part, the gateway sends the measured values of the sensors to a MQTT broker and/or Alexa, so that a query about the voice assistant will be possible.
Have fun replica.
Addendum:
Since ESP-NOW does not work when an incorrect server MAC address is used, I created a new verion, the Sensor Sketch, where a network scan can be triggered via a button. The button must be switched between connection D5 and GND. If it is pressed during the reset, a network scan will be stared.
#include<Wire.H>#include<Bluedot_bme280.H>#include<ESP8266WIFI.H>#include<Arduinojson.H>// Library for ESP Now#include<Espnow.H>// ssid of the gateway#defineGW_SSID"Webhookgateway"// Series Resistor for Supply Voltage Measurement#defineResistor470// for battery = 470 for battery loader = 130// Switch debug messages on#defineDebug1#defineSend_timeout2000// 2 Seconds timeout#defineReconD5// pin for reconnect button// Instance for SensorBluedot_bme280BME;// Data Structure to Save Gateways Mac AddressstructMemorydata{uint32_tcrc32;// Checksumuint8_tMac[6];};// global variablesuint32_tMS;// TIMESTAMP to calculate process timeBoolcallback=false;// Flag for data SentMemorydatastatinfo;// memory for mac address// Callback function wants to be called if data has been sent to the gatewayvoidsenddata(uint8_t*SMAC,uint8_tbroad status){IF(Debug){Serial.print("Send_cb, status =");Serial.print(broad status);Serial.print(", Mac:");charMacString[50]={0};sprint(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.print(macString);}callbackCalled=true;}//function to calculate checksumuint32_tcalculateCRC32(constuint8_t*data,size_tlength){uint32_tcrc=0xffffffff;while(length--){uint8_tc=*data++;for(uint32_ti=0x80;i>0;i>>=1){boolbit=crc&0x80000000;if(c&i){bit=!bit;}crc<<=1;if(bit){crc^=0x04c11db7;}}}returncrc;}//Save gateways MAC address and checksum in RTC memoryvoidUpdateRtcMemory(){uint32_tcrcOfData=calculateCRC32(((uint8_t*)&statinfo)+4,sizeof(statinfo)-4);statinfo.crc32=crcOfData;ESP.rtcUserMemoryWrite(0,(uint32_t*)&statinfo,sizeof(statinfo));}//Search for gateways access pointbooleanScanForSlave(){boolslaveFound=false;int8_tscanResults=WiFi.scanNetworks();if(DEBUG)Serial.println("Scan done");if(scanResults==0){if(DEBUG)Serial.println("No accesspoint found");}else{if(DEBUG){Serial.print("Gefunden ");Serial.print(scanResults);Serial.println(" Netze ");}for(inti=0;i<scanResults;++i){StringSSID=WiFi.SSID(i);int32_tRSSI=WiFi.RSSI(i);int32_tchl=WiFi.channel(i);StringBSSIDstr=WiFi.BSSIDstr(i);if(DEBUG){// display what we foundSerial.print(i+1);Serial.print(": ");Serial.print(SSID);Serial.print(" /");Serial.print(chl);Serial.print(" (");Serial.print(RSSI);Serial.print(")");Serial.println("");}delay(10);// check if we have the gatewayif(SSID==GW_SSID){if(DEBUG){Serial.println("Network found");Serial.print(i+1);Serial.print(": ");Serial.print(SSID);Serial.print(" [");Serial.print(BSSIDstr);Serial.print("]");Serial.print(" (");Serial.print(RSSI);Serial.print(")");Serial.println("");}intmac[6];// Save gateways MAC addressif(6==sscanf(BSSIDstr.c_str(),"%x:%x:%x:%x:%x:%x%c",&mac[0],&mac[1],&mac[2],&mac[3],&mac[4],&mac[5])){for(intii=0;ii<6;++ii){statinfo.mac[ii]=(uint8_t)mac[ii];}UpdateRtcMemory();}slaveFound=true;//break scan if accesspoint was foundbreak;}}}if(DEBUG){if(slaveFound){Serial.println("Found accesspoint!");}else{Serial.println("Did not found the accesspoint! New try.");}}// release memoryWiFi.scanDelete();returnslaveFound;}voidsetup(){booleannetExists=true;ms=millis();//remember start timeSerial.begin(74880);pinMode(RECON,INPUT_PULLUP);//Start BME280bme.parameter.communication=0;//I2C communication for Sensorbme.parameter.I2CAddress=0x76;//I2C Address for Sensorbme.parameter.sensorMode=0b01;//forced mode a single measured is performedbme.parameter.IIRfilter=0b000;//factor 0 (filter off)bme.parameter.humidOversampling=0b001;//Humidity Oversampling factor 1bme.parameter.tempOversampling=0b001;//Temperature Oversampling factor 1bme.parameter.pressOversampling=0b001;//Pressure Oversampling factor 1if(bme.init()!=0x60){Serial.println("BME280 Sensor not found!");}delay(50);//wait 50 ms to complete the measurement//Read gateways MAC address from RTC memoryESP.rtcUserMemoryRead(0,(uint32_t*)&statinfo,sizeof(statinfo));if(DEBUG)Serial.println("RTC fertig");uint32_tcrcOfData=calculateCRC32(((uint8_t*)&statinfo)+4,sizeof(statinfo)-4);if((statinfo.crc32!=crcOfData)||(digitalRead(RECON)==0)){//if the checksum is wrong, the MAC address is invalid//we have to scan for gatewayif(DEBUG)Serial.println("Search for gateway");netExists=ScanForSlave();}if(DEBUG){Serial.print("Gateway MAC address: ");Serial.printf("%x-%x-%x-%x-%x-%x\n",statinfo.mac[0],statinfo.mac[1],statinfo.mac[2],statinfo.mac[3],statinfo.mac[4],statinfo.mac[5]);Serial.print("My MAC address:");Serial.println(WiFi.macAddress());}if(netExists){// initialize ESP-NOWif(esp_now_init()!=0){if(DEBUG)Serial.println("*** ESP_Now INIT has failed");ESP.restart();}esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);// Initialize peerintRes=esp_now_add_peer(statinfo.mac,ESP_NOW_ROLE_CONTROLLER,1,NULL,0);if((Res==0)&&DEBUG)Serial.println("Successfully paired");// register callback functionesp_now_register_send_cb(sendData);callbackCalled=false;// cleare flag// buffer for message (max 250 characters)charbuf[500];// Unique name from sensor name and MAC addressstrcpy(buf,"BME280-");Stringmc=WiFi.macAddress();mc.replace(":","");strcat(buf,mc.c_str());uint16_tI=strlen(buf);// read valuesfloathumidity=Bme.readHumidity();floattemperature=Bme.readTempC();floatpressure=Bme.readPressure();pinMode(A0,INPUT);uint16_traw=Analog Read(A0);floatvolt=raw/1023.0;floatbattery=volt/100*(320+RESISTOR);charmbuf[200];Stringunit="° C";// first we create a full text message. // This will be used for web display and for Alexasprintf(mbuf,"&The temperature is %5.1fGrad Celsius \n the humidity is %5.0f%%\n the air pressure is %7.1fhPa\n the battery voltage is %3.1fVolt &",temperature,humidity,pressure,battery);uint8_tn1=strlen(mbuf);// add data to the message bufferstrlcat(buf,mbuf,n1+I+1);// now we create another message with values JSON formatted for MQTTStaticJsonDocument<400>doc;// the JSON object will be filleddoc["t"]=temperature;// Valuedoc["tu"]=unit;// Unitdoc["h"]=humidity;// Valuedoc["hu"]="%";// Unitdoc["p"]=pressure;// Valuedoc["pu"]="hPa";// Unitdoc["b"]=battery;doc["bu"]="V";// create a JSON string from JSON objectuint16_tN=serializeJson(doc,mbuf);// add it to the message buffer// as a delimiter ampersand character will be usedstrlcat(buf,mbuf,N+n1+I+1);if(DEBUG)Serial.println(buf);// Send message buffer to gatewayesp_now_send(NULL,(uint8_t*)&buf,I+n1+N);}else{// No gatway was found, we go to sleep// and restart 5 minutes later to try it againESP.deepSleep(300E6);}}voidloop(){// wait untril data were sentif(callbackCalled||(millis()>5000)){if(DEBUG)Serial.println("Sleep");delay(100);// go to deep sleep and restart the controller after 5 minutes// sleep time is in micro secondsSerial.printf("Processing time %i ms \n",millis()-ms);// display processing timeESP.deepSleep(300E6);}}
The code extensions are marked in yellow. In the Gatway-Sketch you should also install the display of the two MAC addresses for station and access point.
Serial.print ("Station MAC address:"); Serial.println (WiFi.macAddress ()); Serial.print ("Accesspoint MAC address:"); Serial.println (WiFi.softAPmacAddress ());
Then you can check if the sensor finds the correct MAC address. He has to use dim MAC address of the accessory.
The download sketches have now installed the extensions.
@Max: Der Analog-Eingang des ESP8266 ist für eine maximale Spannung von 1V ausgelegt. Da der Anschluss-Pin A0 maximal 3.3 V vertragen soll ist am D1-Mini ein Spannungsteiler mit 220kOhm zwischen A0 und AnalogEingang und 100kOhm zwischen Analogeingang und Masse. Das ergibt bei 3.3V an A0 3.3 /320 * 100 = 1,03V am Analogeingang. Im Falle des Batteriepakets kann die Spannung bis zu 6V betragen. Deshalb wird der 470kOhm Widerstand zwischen Batterie und A0 geschaltet. Das ergibt
6 /(470 + 220 +100) * 100 = 0.76V am Analogeingang. Also sicher unterhalb von 1V.
Im Sketch wird dann der gemessene Wert wieder in Volt umgerechnet
uint16_t raw = analogRead(A0);
float volt = raw/1023.0;
float battery = volt/100 * (320 + RESISTOR);
Max
Moin,
können Sie mir erklären wie Sie beim Widerstand auf 470 kOhm kommen?
Gruß
Gerald Lechner
@Andreas: Es steht zwar nirgends explizit, aber ich habe es auch experimentell überprüft. ESP-NOW und gleichzeitig eine Routerverbindung funktioniert nur, wenn ESP-NOW den gleichen Kanal wie der Router benutzt und wenn es Kanal 1 ist. Ich habe es mit anderen Kanälen versucht bin aber immer gescheitert. Eine technische Erklärung, warum es nur mit Kanal 1 funktioniert habe ich nicht gefunden. Aber vielleicht habe ich bei den Tests etwas falsch gemacht. Einen Versuch wäre es auf alle Fälle wert.
Andreas
Hallo Herr Lechner, tolles Projekt, hier kann man viel lernen! Dank dafür. Ich betreibe das System seit einem halben Jahr und musste erst vor wenigen Tagen den Batteriesatz für den Sensor-ESP erneuern.
In Ihrer Beschreibung steht (unmittelbar vor der HW-Liste):
“…Damit ESP-NOW zusammen mit WiFi genutzt werden kann, muss das WiFi Netzwerk den Kanal 1 benutzen!”
Mein Problem: neuerdings meldet mir meine FritzBox, dass Kanal 1 und teilweise auch Kanal 2 gestört sind. Die Fritzbox schaltet dann automatisch und unmerklich auf einen anderen Kanal um, dann funktioniert aber die ESP-NOW-Verbindung nicht mehr.
Können Sie mir bitte Hinweise geben, warum es Kanal 1 sein muss und wie ich da Abhilfe schaffen kann? Wäre da z.B. der Aufruf “esp_now_set_peer_channel(u8 *mac_addr, u8 channel)” hilfreich? LG Andreas
Wolfgang Kübler
Zum Strombedarf von ESP8266-Modulen im DeepSleep Mode gibt es im Netz zahlreiche Beiträge. Ich habe keinen verifizierten Beitrag gesehen, der an die Datenblattwerte heranreicht.
Für mein aktuelles Projekt von Batteriebetriebenen ESP8266 (ESP03) zur periodischen Übermittlung (ESPNow) von BME280 Daten an einen ESP-Server habe ich daher eine Schaltung gebaut, die mich unabhängig von DeepSleep macht.
Zunächst zur aktiven Zeit:
der ESP braucht zum Hochfahren, also bis er nach PowerUp den ersten Befehl ausführt ca. 130ms. Messung und Übertragung (BME280) dauern ca. 40ms. Die Torwächterschaltung läßt nach frühestens 180ms zu, dass der ESP das Abschalten veranlassen kann. Sie ist eigentlich nur dann notwendig, wenn der Controller nicht garantiert, dass seine GPIOs beim Hochfahren und bis zum ersten Setzen auf einen definierten Pegel nicht zappeln und somit ein ungewolltes Abschalten veranlassen. Da ich aber mit verschiedenen Modulen arbeite (ESP8266/32/..), ist sie in meinem Layout eben vorgesehen.
Die inaktive Zeit wird von einem Widerstand bestimmt und beträgt maximal zwei Stunden.
Der Strombedarf (ESP03) aktiv, also über die 180ms, liegt bei ca. 70-80mA. Inaktiv braucht es ca. 3uA (in Worten: drei Microampere).
Schaltung und Software sind aufgebaut und getestet. Die 4 ICs kosten ca. 4€.
Ein Bild davon liegt unter: https://magentacloud.de/s/MGfgFz3nj9eXk3S
Andreas Wolter
@Michael: Da die Sensoren per I2C angeschlossen werden, kann man diese nicht einfach in Räumen verteilen und dann mit dem Mikrocontroller verkabeln. I2C lässt nur sehr kurze Kabellängen zu. Das heißt, es wird für jeden Sensor auch noch je ein weiterer Mikrocontroller benötigt. Man könnte den Aufbau aus diesem Projekt fünf mal zusammenbauen, um fünf Sensoren zu betreiben. Die Daten müssten dann an einer Stelle gesammelt werden. Eventuell einen der fünf MCs als Mutterschiff, an das die Daten gesendet werden. Dann könnte man die Daten dort gesammelt in einer Tabelle anzeigen lassen. Das wäre eine Idee.
Grüße,
Andreas Wolter
AZ-Delivery Blog
michael
Hallo, mich würde es interessieren, wie man sagen wir mal 5 Stück Sensoren in verschiedenen Zimmern hat und diese dann abfragen könnte, sodas die Daten untereinander in einer Tabelle dargestellt werden. Also auch Tempreatur, Luftfeuchte, Luftdruck und Batteriespannung.
Christian Magg
Hallo Herr Lechner,
es macht außerordentlich Spaß, die vorgeschlagenen Projekt nachzubauen und, und genau darauf kommt es auch an, etwas zu modifizieren. Da hätte ich noch so einige Idee, aber derzeit kämpfe ich mit der Laufzeit über die Batterien. Es gelingt mir einfach nicht auf einen Ruhestrom im DeepSleep Modus unter 5mA zu kommen. Ich bin damit mit weit über den von Ihren angegebenen 0,035mA oder den 0,3 mA, wie in Ihrer Antwort geschrieben entfernt. Ich habe 3 Stück dieser D1 Minis vorliegen und alle drei liegen im ähnlichen Bereich. Der Aufbau ist so wie von Ihnen beschrieben. Wichtig!!! Es funktioniert alles super gut, aber wie gesagt bei einem Faktor von etwas mehr wie 15 sind es dann keine 190 Tage sondern nur noch 12 Tage, und das ist dann schon etwas wenig. Ich habe jetzt die Messung auf eine Zyklus von 30 Minuten eingestellt, aber ich sehe jeden Tag wie die Spannung 0,02 V sinkt.
Freue mich sehr von Ihnen zu lesen!
Schöne Grüße
Christian Magg
Tobias Bast
Hallo Herr Lechner,
vielen Dank für die ausführliche Beschreibung des Projekts! Ich habe es mittlerweile geschafft den Webserver aufzusetzen und einen D1 Mini mit dem Gateway zu verbinden. Leider habe beim zweiten D1 Mini das Problem, dass dieser das Gateway, und nur das Gateway, partout nicht finden kann/will ;)
Hier der Auszug der Logs von dem “guten” und dem “schlechten” D1 Mini, beides kurz hintereinander:
Beim Durchlauf des zweiten D1 Minis war das Gateway mit dem Namen “TempGateway” definitiv noch im Netz vorhanden, ich habe darauf per Browser zugegriffen. Da ich am Anfang nicht wusste, ob es mit der WLAN-Konnektivität allgemein Probleme gibt, habe ich versuchsweise meinen normalen WLAN-Namen beim zweiten D1 Mini eingetragen, das Verbinden hat sofort geklappt. Danach habe ich den Namen wieder zurückgeändert und das Sketch mit der Option “All Flash Settings” geschrieben um die gespeicherte MAC-Adresse des WLANs wieder loszuwerden. Trotzdem wird genau das TempGateway-Netzwerk beim Scan nicht erkannt. Woran kann das liegen, haben Sie da eine Idee? Ich bin nämlich mittlerweile ratlos.
Gerald Lechner
Im Blog wird der ESP32 für den Web-Server und der ESP8266 für den Sensor verwendet. Der ESP8266 ist sehr wohl Tiefschlaffähig und verbraucht, nach Datenblatt, etwa 0.01 mA in diesem Modus. Allerdings verbrauchen andere Bauelemente auf der D1-Mini Platine und am Sensormodul auch Strom, sodass sich, wie schon in einem vorangegangenen Kommentar erwähnt, ein Ruhestrom von 0.3 mA ergibt.
Rainer
@gerald lechner:
Im Kommentar und auch an anderen Stellen wird vom " ESP8266" gesprochen. Im Blog ist aber der Rede vom ESP32.
Ich denke dass nicht der ES8266 D1 Mini, sondern grundsätzlich der ESP32 D1 mini gemeint ist, denn nach meiner Meinung ist nur des ESP32 richtig tiefschlaffähig.
Gerald Lechner
Es ist richtig, der Ruhestrom ist etwa 0.3 mA. Eine Untersuchung der Schaltung des D1-Minis ergab, etwa 0.1mA entfallen auf den ESP8266 + Flash-Speicher, 0.1mA auf den CH340 un 0.1mA auf den Spannungsregler. Wenn man mit diesen geänderten Daten, also 0.3mA statt 0.035mA die Berechnungen durchführt ergibt sich ein Bedarf von 132mAs pro Messung somit 38000 mAs pro Tag oder 10.5 mAh pro Tag. Bei einer Akku-Kapazität von 2000mAh sind das immerhin 190 Tage. Also denke ich, dass der Batteriebetrieb trotz des höheren Ruhestroms funktioniert.
Ben Gabel
Im Prinzip funktioniert alles mit dem oben verlinkten D1 mini von AZ-Delivery. Leider ist aber der Strom im DeepSleep-Modus nicht 0,038 sondern ca. 0,3 mA, auch wenn ich den Temperatursensor ganz entferne.
Damit funktioniert der Batteriebetrieb nicht!
ben
Gerald Lechner
Ich habe nochmals nachgemessen und dabei folgendes festgestellt. Es scheint so, dass die Stromaufnahme im Tiefschlafmodus sehr schwankt. Zudem wenn die Batteriespannung unter 4V absinkt steigt die Stromaufnahme stark an, das dürfte am 3.3V Spannungsregler liegen, der natürlich auch noch ein wenig Spannungsabfall für sich benötigt. Teilweise schafft dann der ESP8266 keinen Neustart. In diesem Zustand kann der Strom auf über 100mA steigen und erf geht nie in den Schlafmodus. Ich werde das Verehalten weiter untersuchen und die Erkenntnisse hier posten.
Hike
Hallo Herr Lechner,
schönes Projekt.
Ich habe das Gateway und den Sensor (mehrfach) nachgebaut und inzwischen funktioniert es.
Probleme: Es schein ein Problem mit einer Fritzbox 4040 als Router zu geben, wenn diese im Mesh-Modus betrieben wird. Wenn sich das Gateway mit der Fritzbox verbindet, stellt sich das Gateway auf den aktuellen Kanal der 4040 ein. Dann ist die Übertagung per ESPNow nur zufällig möglich. Das erkennt man auch daran, das nur ab und zu die Anwort von Gateway zum Sensor (sendStatus == 0) ist
Ich habe einen zusätzlichen alten TP-Link Router benutzt, den ich fest auf Kanal 1 eingestellt habe. Seitdem läuft alles stabil.
Mein Problem ist, dass meine ESP8266 D1 minis von AZ-Delivery sehr viel mehr Strom verbrauchen.
In der vorgestellten Konfiguration mit 4 Batterien an VIn ist der Verbrauch auch während des Deep-Sleep > 7,6 mA.
Selbst mit 2 AAA Batterien, also 3V an 3,3V angeschlossen habe ich immer noch 3,5mA was um Größenordnungen mehr ist als die 35 microA aus ihrer Beschreibung.
Witzgerweise steigt hierbei der Verbrauch auf 5,5 mA, wenn man lediglich ein nicht verbundenes USB-Kabel einsteckt.
Gerald Lechner
Wenn das Gateway keine Geräte findet, liegt das am Sensor, wenn der keine Daten sendet. Das kann verschiedene Ursachen haben. Wenn die Nachricht zu lange ist also mehr als 250 Zeichen, werden keine Daten übertragen. Auch wenn der ESP8266 nicht in einem definierten Anfangszustand ist, kann es vorkommen, dass keine Daten gesendet werden. Für den ersten Fall habe ich die Länge der Meldung verkürtzt, für den zweiten Fall habe ich am Anfang der Setup Funktion WiFi Kommandos eingebaut die einen definierten Zustand sicherstellen. Ein neuer Sketch mit all den Änderungen kann vom Downloadbereich heruntergeladen werden. Den Link findet man im Blog Beitrag nach dem Listing des Sensor Sketchs. Der geänderte Sketch liefert jetzt auch eine Fehlermeldung und die Länge der Nachricht, wenn das Senden nicht erfolgreich ist.
@Klaus: Danke für den Hinweis, ich habe den Link zu AsyncTCP korrigiert. Die Installation von AsyncWebConfig ist im Blogbeitrag beschrieben.
@Burkhard: Der AP muss weiterhin bestehen, damit ESP-NOW Daten senden kann. Leider kann nicht verhindert werden, dass man über dieses WLan auch den Webserver des Gateways erreichen kann. Damit ist ein Zugriff auf die Nachrichten der Sensoren aber auch auf die Konfiguration des Gateways möglich. Ich würde daher empfehlen den AccessPoint über ein Passwort zu sichern. Die Funktion von ESP-NOW wird dadurch nicht beeinflusst. Das setzen eines Passworts ist ganz einfach. Im Gateway Sketch, in der Funktion initWiFi() muss die Zeile zum Starten des AP
WiFi.softAP(ACCESSPOINT,“meinPasswort”,0,0); lauten. Das Passwort muss mindestens 8 Zeichen haben. Der Klick auf das Zahnrad oben führt immer zur Konfiguration, damit man die Konfiguration auch ändern kann.
Burkhard
Hallo Herr Lechner.
Leider funktioniert das nicht wie erwartet. Ich habe die neuen Sketche installiert. Der Webserver startet und nach Eingabe meines WiFi verbindet er sich auch mit meinem WLAN. Allerdings existiert ja nach einem Reboot ja weiterhin ein AP “WebookGateway”. Damit kann sich auch jeder problemlos verbinden. Wenn man allerdings die Adresse 192.168.4.1 aufruft, landet man immer auf dem Webserver, so dass jeder, der sich mit dem AP verbindet meine WLAN-Daten ändern kann. Das dürfte doch nicht sein.
Weiterhin findet er keine Sensordevices. Die Serverseite sieht folgendermaßen aus:
Read configuration
apName=Gateway1
ssid=XXXXXX
pwd=*************
ntp_server=fritz.box
Verbindung zu XXXXX herstellen
..
IP-Adresse = 192.168.X.X
ESP-NOW gestartet
MDNS responder gestartet
Station MAC address: XX:XX:XX:XX:XX:C0
Accesspoint MAC address: XX:XX:XX:XX:XX:C1
fritz.box Uhrzeit gesetzt!
we have 0 devices
Die Sensorseite so:
Gateway MAC address: XX-XX-XX-XX-XX-c1
My MAC address: YY:YY:YY:YY:YY:00
Erfolgreich gepaart
BME280-YYYYYYYYYY00&Die Temperatur ist 25.3Grad Celsius
die Feuchtigkeit ist 38%
der Luftdruck ist 1016.4hPa
Meines Erachtens nach ist das alles korrekt. Wenn ich aber auf der Webseite des Servers das Zahnrädchen klicke, erscheint wieder die Konfigurationsseite des WLANs.
Was passiert hier? Haben Sie eine Idee?
Klaus
Hallo, bitte meinen Beitrag vom 13.Mai löschen. Ich habe die fehlende Datei auf github unter Hrn. Lechners repositories gefunden. Funktionieren tut es aber trotzdem nicht.:-(
Freundliche Grüße
Klaus
Klaus
Hallo Herr Lechner, versuche wieder mal, eines Ihrer Projekte nachzubauen. Jetzt kommt die Fehlermeldung, dass das Programm “AsyncWebConfig.h” nicht gefunden wird. Es befindet sich nicht in den von Ihnen angegebenen Bibliotheken. Fehlt mir da noch irgendwas?
BTW, die angeblich im Beitrag korrigierte URL für die AsyncTCP Bibliothek führt immer noch auf die falsche Webseite.
LG Klaus
Gerald Lechner
Der offene HotSpot stellt keine Gefahr dar. Der Treiber im ESP 32 implementiert einen Protokollstack mit dem er WLAN Datenpakete die an seine MAC Adresse gesendet werden empfangen kann OSI-Modell Schicht 2). Diese Daten können dann weiterverarbeitet werden, dafür sind Dienste notwendig, die in ein Programm eingebunden und gestartet werden müssen. Im Fall dieses Beitrags ist das der Dienst ESP-Now der die empfangenen Daten aus dem Netzwer-Frame extrahiert und über eine Callback-Funktion dem Sketch zur Verfügung stellt. Mehr macht auch dieser Dienst nicht. Es ist also ohne zusätzliche Software am ESP32 nicht möglich über den Access-Point eine Verbindung zum zweiten Protokoll-Stack, der im Station Mode mit dem lokalen WLAN verbunden ist, herzustellen.
AnsgarFleichhut
Moin,
danke für die Anleitung. Ich habe eine Frage hierzu:
WiFi.mode(WIFI_AP_STA);
WiFi.softAP(ACCESSPOINT,"",0,0);
Kann es eine Sicherheitslücke darstellen, wenn der ESP immer einen offenen Hotspot aktiv hat? Könnte jemand sich mit dem offenen Wlan verbinden und dann eine Verbindung zu meinem Heimnetz herstellen?
Schöne Grüße
Gerald Lechner
Einige hatten beim Nachbau dieses Projekts das Problem, dass keine Daten übermittelt wurden. Der Grund dafür war, dass die neueste Version von Arduino JSON bei Fließkommazahlen die Anzahl der Nachkommastellen erhöht hat und dadurch die Nachricht zu lang wurde. ESP NOW kann nur 250 Bytes in einem Paket Übertragen. Um das Problem zu lösen, müssen Sie zwei kleine Änderungen vornehmen:
Die Zeile für die Erzeugung des Strings muss geändert werden
sprintf(mbuf,“&Die Temperatur ist 5.1fGrad Celsius\ndie Feuchtigkeit ist %5.0f%\nder Luftdruck ist %7.1fhPa\ndie Batteriespannung ist %3.1fVolt&”,temperature,humidity,pressure,battery);
Also die unnötigen Zwischenräume nach dem Zeilenvorschub entfernen und statt “Luftfeuchtigkeit” nur “Feuchtigkeit”
Die zweite Änderung betrifft den Luftdruck. Hier macht es keinen Sinn Nachkommastellen zu nutzen, daher wird der Luftdruck bei der Zuweisung zum JSON Dokument gerundet.
doc[“p”]=round(pressure); //Value
Mit diesen Änderungen funktioniert die Übertragung.
Der Sketch zum Herunterladen enthält bereits die Änderungen.
Gerald Lechner
Wenn ESP-Now nicht funktioniert, also das Gateway keine Daten empfängt, muss überprüft werden ob der Sensor die richtige MAC-Adresse benutzt. Um diese Prüfung zu erleichtern, habe ich den Sketch für den Sensor erweitert. Siehe Abschnitt Nachtrag am Ende des Beitrags. Ebenso hab ich die Ausgabe der Station-MAC-Adresse und der Accesspoint MAC Adresse im Sketch für das Gateway eingebaut. Die geänderten Sketchs können von Google-Drive heruntergeladen werden.
Gerald Lechner
ACHTUNG WICHTIGER HINWEIS!
Im Beitrag war eine falsche URL für die AsyncTCP Bibliothek. Die URL ist nicht https://github.com/me-no-dev/ESPAsyncTCP sondern https://github.com/me-no-dev/AsyncTCP.
Die URL ist jetzt auch im Beitrag korrigiert.
Knut Hansen
Hallo Herr Lechner,
ich habe das gleiche Problem wie Herr Wiegand.
Meine Ausgaben am seriellen Port sind fast identisch.
Als Server verwende ich auch einen ESP32 und keinen D1 mini.
Beim Neustart wird das Gateway gefunden und auch die Mac-Adresse.
Der Webserver zeigt keine Geräte an.
auf dem Serial Monitor wird die Nachricht:
we have 0 devices ausgegeben.
Können Sie mir helfen?
Mit freundlichen Grüßen
Knut Hansen
Burkhard
Hallo, beim Compilieren des Webservers bekomme ich immer die Fehlermeldung:
Alternatives for interrupts.h: []
/home/burkhard/Arduino/libraries/ESPAsyncTCP-master/src/SyncClient.cpp:25:24: fatal error: interrupts.h: No such file or directory
ResolveLibrary(interrupts.h)
→ candidates: []
compilation terminated.
…
exit status 1
Fehler beim Kompilieren für das Board ESP32 Dev Module.
Wo bekomme ich interrupts.h her?
VG
Burkhard
Gerald Lechner
ESP-NOW ist ein sehr einfaches Protokoll, wenn die MAC-Adresse des Empfängers bekannt ist, werden die Daten an diese MAC-Adresse gesendet ohne irgendwelche Überprüfungen. Kommt das Datenpaket bei keinem Empfänger an, kann der Sender das nicht feststellen. Der Sensor im Beitrag ist ESP-NOW Sender. Wenn er noch keine MAC-Adresse des Servers hat, wird ein Netzwerk-Scan durchgeführt um diese Adresse zu erhalten und für die Zukunft zu speichern. Wird die Stromversorgung nicht unterbrochen, so sendet der Sensor die Daten an die gespeicherte MAC-Adresse, egal ob das die Adresse des Servers ist oder nicht. Um sicherzustellen, dass die richtige MAC-Adresse gespeichert wird, sollte der Sensor von der Stromversorgung getrennt werden, damit er irgendwelche falsche MAC-Adressen vergisst. Dann sollte der Server gestartet werden und erst danach der Sensor wieder mit der Stromversorgung verbunden werden. Im seriellen Monitor beim Sender wird ausgegeben, dass ein Netzwerkscan ausgeführt wird.
Fritz Wiegand
Hallo Herr Lechner,
sehr schönes Projekt. Erst mal vielen Dank für die Mühe…
Leider funktioniert es nicht so wie es soll…
Als Gateway habe ich einen ESP 32 und der Client ist ein D1 mini ESP8266.
Nach aufspielen der Sketche konnte ich den Server wie beschrieben konfigurieren.
Fritz Box Kanal 1 (in der Beschreibung Kanl 0 den gibt es nicht).
Server connectet sich problemslos mit FritzBox WiFi….
Client bekommt auch Verbimdung zum Gateway….
Aber leider werden keine Daten übertragen..
Eine Idee WARUM ???
Hier ein Auszug des logs…..Gateway
:11:27.122 → rst:0×1 (POWERON_RESET),boot:0×13 (SPI_FAST_FLASH_BOOT)
18:11:27.122 → configsip: 0, SPIWP:0xee
18:11:27.122 → clk_drv:0×00,q_drv:0×00,d_drv:0×00,cs0_drv:0×00,hd_drv:0×00,wp_drv:0×00
18:11:27.122 → mode:DIO, clock div:1
18:11:27.122 → load:0×3fff0018,len:4
18:11:27.122 → load:0×3fff001c,len:1100
18:11:27.122 → load:0×40078000,len:9232
18:11:27.122 → load:0×40080400,len:6400
18:11:27.122 → entry 0×400806a8
18:11:27.427 → [{’name’:‘ssid’,‘label’:‘Name des WLAN’,‘type’:0,‘default’:‘’},{’name’:‘pwd’,‘label’:‘WLAN Passwort’,‘type’:1,‘default’:‘’},{’name’:‘ntp_server’,‘label’:‘NTP Server’,‘type’:0,‘default’:‘fritz.box’}]
18:11:27.529 → Read configuration
18:11:27.529 → apName=WebhookGateway
18:11:27.529 → ssid=FRITZ!Box Fon WLAN 7270
18:11:27.563 → pwd=*************
18:11:27.563 → ntp_server=fritz.box
18:11:27.631 → Verbindung zu FRITZ!Box Fon WLAN 7270 herstellen
18:11:28.209 → ..
18:11:28.685 → IP-Adresse = 192.168.1.123
18:11:28.685 → ESP-NOW gestartet
18:11:28.719 → MDNS responder gestartet
18:11:28.719 → fritz.box Uhrzeit gesetzt!
18:11:52.062 → dhcps: send_offer>>udp_sendto result 0
18:11:52.062 → dhcps: send_nak>>udp_sendto result 0
18:11:55.561 → dhcps: send_nak>>udp_sendto result 0
18:11:55.561 → dhcps: send_offer>>udp_sendto result 0
18:11:55.561 → dhcps: send_nak>>udp_sendto result 0
18:16:15.674 → dhcps: send_offer>>udp_sendto result 0
18:16:17.506 → dhcps: send_offer>>udp_sendto result 0
und hier Client
18:02:23.912 → ets Jan 8 2013,rst cause:2, boot mode:(3,6)
18:02:23.946 →
18:02:23.946 → load 0×4010f000, len 3460, room 16
18:02:23.946 → tail 4
18:02:23.946 → chksum 0xcc
18:02:23.946 → load 0×3fff20b8, len 40, room 4
18:02:23.946 → tail 4
18:02:23.946 → chksum 0xc9
18:02:23.946 → csum 0xc9
18:02:23.946 → v00048000
18:02:23.946 → ~ld
18:02:24.082 → RTC fertig
18:02:24.082 → Erfolgreich gepaart
18:02:24.116 → BME280-B4E62D697FD0&Die Temperatur ist 25.1Grad Celsius
18:02:24.116 → die Luftfeuchtigkeit ist 34%
18:02:24.116 → der Luftdruck ist 989.7hPa
18:02:24.116 → die Batteriespannung ist 4.8Volt&{"t":25.09000015,“tu”:“°C”,h,“hu”:“%”,p,“pu”:“hPa”,b,“bu”:"V"}
18:02:28.968 → Sleep
18:02:29.070 → Processing time 5030 ms
Lutz Ti
Hilferuf …
Versuche schon seit ein paar Tagen den Nachbau, scheitere aber in beiden Scripten bei Compilieren, offensichtlich fehlen ( mir ) da noch Bibliotheken:
WebhookGateway:
ESPAsyncWebServer.h: No such file or directory
und beim Client:
ESP8266WiFi.h: No such file or directory
In beiden Fällen bricht der Compiler ab …
Welchen ( Anfänger ? ) Fehler mache ich? Wo finde ich die zusätzlichen Biblioheken ?
Danke für eine rettende Idee …
ti
Andreas Wolter
@Äd Franzis: mit RTC ist in diesem Fall nicht gemeint, dass eine Real Time Clock verwendet wird. Wir haben einen zusätzlichen Hinweis eingefügt. Der ESP32 hat 8Kbyte Speicher, der RTC RAM genannt wird. Damit können Variablen während des Deep Sleep gehalten werden.
Grüße,
Andreas Wolter
AZ-Delivery Blog
Äd Franzis
Sehr schöner Artikel, vielen Dank.
Allerdings habe ich nicht verstanden, dass in der SW und im Text auf den Speicher der RTC Bezug genommen wird, wobei ich aber im Anschlußplan und der Stückliste kein Uhrenmodul sehe.
LG
Äd
Gerald Lechner
Vielen Dank für den Hinweis. Habe den Code geändert. Der Fehler war aber nicht tragisch, da die Funktion scanForSlave nur einmal ausgeführt wird. Der Sensor erhält nach dem Tiefschlaf einen Reset und da werden ohnehin alle Speicherstrukturen neu initialisiert.
Ulrich Klaas
In “scanForSlave” steht ein WiFi.scanDelete(); nach einem return. Wird also nie ausgeführt.
Blijf op de hoogte
Verzeker je nu van een 15% kortingscode! Kom direct te weten wanneer we een nieuw spannend project presenteren of onverslaanbare aanbiedingen hebben!
100% gratis, kan op elk moment worden geannuleerd!
33 Reacties
Gerald Lechner
@Max: Der Analog-Eingang des ESP8266 ist für eine maximale Spannung von 1V ausgelegt. Da der Anschluss-Pin A0 maximal 3.3 V vertragen soll ist am D1-Mini ein Spannungsteiler mit 220kOhm zwischen A0 und AnalogEingang und 100kOhm zwischen Analogeingang und Masse. Das ergibt bei 3.3V an A0 3.3 /320 * 100 = 1,03V am Analogeingang. Im Falle des Batteriepakets kann die Spannung bis zu 6V betragen. Deshalb wird der 470kOhm Widerstand zwischen Batterie und A0 geschaltet. Das ergibt
6 /(470 + 220 +100) * 100 = 0.76V am Analogeingang. Also sicher unterhalb von 1V.
Im Sketch wird dann der gemessene Wert wieder in Volt umgerechnet
uint16_t raw = analogRead(A0);
float volt = raw/1023.0;
float battery = volt/100 * (320 + RESISTOR);
Max
Moin,
können Sie mir erklären wie Sie beim Widerstand auf 470 kOhm kommen?
Gruß
Gerald Lechner
@Andreas: Es steht zwar nirgends explizit, aber ich habe es auch experimentell überprüft. ESP-NOW und gleichzeitig eine Routerverbindung funktioniert nur, wenn ESP-NOW den gleichen Kanal wie der Router benutzt und wenn es Kanal 1 ist. Ich habe es mit anderen Kanälen versucht bin aber immer gescheitert. Eine technische Erklärung, warum es nur mit Kanal 1 funktioniert habe ich nicht gefunden. Aber vielleicht habe ich bei den Tests etwas falsch gemacht. Einen Versuch wäre es auf alle Fälle wert.
Andreas
Hallo Herr Lechner, tolles Projekt, hier kann man viel lernen! Dank dafür. Ich betreibe das System seit einem halben Jahr und musste erst vor wenigen Tagen den Batteriesatz für den Sensor-ESP erneuern.
In Ihrer Beschreibung steht (unmittelbar vor der HW-Liste):
“…Damit ESP-NOW zusammen mit WiFi genutzt werden kann, muss das WiFi Netzwerk den Kanal 1 benutzen!”
Mein Problem: neuerdings meldet mir meine FritzBox, dass Kanal 1 und teilweise auch Kanal 2 gestört sind. Die Fritzbox schaltet dann automatisch und unmerklich auf einen anderen Kanal um, dann funktioniert aber die ESP-NOW-Verbindung nicht mehr.
Können Sie mir bitte Hinweise geben, warum es Kanal 1 sein muss und wie ich da Abhilfe schaffen kann? Wäre da z.B. der Aufruf “esp_now_set_peer_channel(u8 *mac_addr, u8 channel)” hilfreich? LG Andreas
Wolfgang Kübler
Zum Strombedarf von ESP8266-Modulen im DeepSleep Mode gibt es im Netz zahlreiche Beiträge. Ich habe keinen verifizierten Beitrag gesehen, der an die Datenblattwerte heranreicht.
Für mein aktuelles Projekt von Batteriebetriebenen ESP8266 (ESP03) zur periodischen Übermittlung (ESPNow) von BME280 Daten an einen ESP-Server habe ich daher eine Schaltung gebaut, die mich unabhängig von DeepSleep macht.
Zunächst zur aktiven Zeit:
der ESP braucht zum Hochfahren, also bis er nach PowerUp den ersten Befehl ausführt ca. 130ms. Messung und Übertragung (BME280) dauern ca. 40ms. Die Torwächterschaltung läßt nach frühestens 180ms zu, dass der ESP das Abschalten veranlassen kann. Sie ist eigentlich nur dann notwendig, wenn der Controller nicht garantiert, dass seine GPIOs beim Hochfahren und bis zum ersten Setzen auf einen definierten Pegel nicht zappeln und somit ein ungewolltes Abschalten veranlassen. Da ich aber mit verschiedenen Modulen arbeite (ESP8266/32/..), ist sie in meinem Layout eben vorgesehen.
Die inaktive Zeit wird von einem Widerstand bestimmt und beträgt maximal zwei Stunden.
Der Strombedarf (ESP03) aktiv, also über die 180ms, liegt bei ca. 70-80mA. Inaktiv braucht es ca. 3uA (in Worten: drei Microampere).
Schaltung und Software sind aufgebaut und getestet. Die 4 ICs kosten ca. 4€.
Ein Bild davon liegt unter: https://magentacloud.de/s/MGfgFz3nj9eXk3S
Andreas Wolter
@Michael: Da die Sensoren per I2C angeschlossen werden, kann man diese nicht einfach in Räumen verteilen und dann mit dem Mikrocontroller verkabeln. I2C lässt nur sehr kurze Kabellängen zu. Das heißt, es wird für jeden Sensor auch noch je ein weiterer Mikrocontroller benötigt. Man könnte den Aufbau aus diesem Projekt fünf mal zusammenbauen, um fünf Sensoren zu betreiben. Die Daten müssten dann an einer Stelle gesammelt werden. Eventuell einen der fünf MCs als Mutterschiff, an das die Daten gesendet werden. Dann könnte man die Daten dort gesammelt in einer Tabelle anzeigen lassen. Das wäre eine Idee.
Grüße,
Andreas Wolter
AZ-Delivery Blog
michael
Hallo, mich würde es interessieren, wie man sagen wir mal 5 Stück Sensoren in verschiedenen Zimmern hat und diese dann abfragen könnte, sodas die Daten untereinander in einer Tabelle dargestellt werden. Also auch Tempreatur, Luftfeuchte, Luftdruck und Batteriespannung.
Christian Magg
Hallo Herr Lechner,
es macht außerordentlich Spaß, die vorgeschlagenen Projekt nachzubauen und, und genau darauf kommt es auch an, etwas zu modifizieren. Da hätte ich noch so einige Idee, aber derzeit kämpfe ich mit der Laufzeit über die Batterien. Es gelingt mir einfach nicht auf einen Ruhestrom im DeepSleep Modus unter 5mA zu kommen. Ich bin damit mit weit über den von Ihren angegebenen 0,035mA oder den 0,3 mA, wie in Ihrer Antwort geschrieben entfernt. Ich habe 3 Stück dieser D1 Minis vorliegen und alle drei liegen im ähnlichen Bereich. Der Aufbau ist so wie von Ihnen beschrieben. Wichtig!!! Es funktioniert alles super gut, aber wie gesagt bei einem Faktor von etwas mehr wie 15 sind es dann keine 190 Tage sondern nur noch 12 Tage, und das ist dann schon etwas wenig. Ich habe jetzt die Messung auf eine Zyklus von 30 Minuten eingestellt, aber ich sehe jeden Tag wie die Spannung 0,02 V sinkt.
Freue mich sehr von Ihnen zu lesen!
Schöne Grüße
Christian Magg
Tobias Bast
Hallo Herr Lechner,
vielen Dank für die ausführliche Beschreibung des Projekts! Ich habe es mittlerweile geschafft den Webserver aufzusetzen und einen D1 Mini mit dem Gateway zu verbinden. Leider habe beim zweiten D1 Mini das Problem, dass dieser das Gateway, und nur das Gateway, partout nicht finden kann/will ;)
Hier der Auszug der Logs von dem “guten” und dem “schlechten” D1 Mini, beides kurz hintereinander:
15:16:02.802 → Scan done
15:16:02.802 → Gefunden 11 Netze
15:16:02.802 → 1: UPC2639615 /1 (-69)
15:16:02.837 → 2: TempGateway /1 (-58)
15:16:02.837 → Network found
15:16:02.837 → 2: TempGateway [XX:XX:XX:XX:XX:XX] (-58)
15:16:02.837 → Found accesspoint!
15:16:02.837 → Gateway MAC address: XX-XX-XX-XX-XX-XX
15:16:02.837 → My MAC address: YY:YY:YY:YY:YY:YY
15:16:02.837 → Erfolgreich gepaart
15:16:55.043 → Scan done
15:16:55.043 → Gefunden 12 Netze
15:16:55.043 → 1: UPC2639615 /1 (-81)
15:16:55.043 → 2: Luftinternet_Fiber 2,4 Ghz /1 (-75)
15:16:55.043 → 3: Biwe /1 (-84)
15:16:55.078 → 4: Biwe-Gast /1 (-82)
15:16:55.078 → 5: MagentaWLAN-3RZ5 /6 (-83)
15:16:55.078 → 6: PAGMBH /6 (-85)
15:16:55.112 → 7: Biwe-Gast /6 (-91)
15:16:55.112 → 8: Biwe /6 (-92)
15:16:55.112 → 9: FRITZ!Box 7590 TL /11 (-78)
15:16:55.146 → 10: FRITZ!Box 7590 TL /11 (-77)
15:16:55.146 → 11: ZYXEL-288 /11 (-91)
15:16:55.146 → 12: MVZ Gast /1 (-87)
15:16:55.146 → Did not found the accesspoint! New try.
15:16:55.181 → Gateway MAC address: Z-ZZ-ZZ-ZZ-ZZ-ZZ
15:16:55.181 → My MAC address: YY:YY:YY:YY:YY:YY
Beim Durchlauf des zweiten D1 Minis war das Gateway mit dem Namen “TempGateway” definitiv noch im Netz vorhanden, ich habe darauf per Browser zugegriffen. Da ich am Anfang nicht wusste, ob es mit der WLAN-Konnektivität allgemein Probleme gibt, habe ich versuchsweise meinen normalen WLAN-Namen beim zweiten D1 Mini eingetragen, das Verbinden hat sofort geklappt. Danach habe ich den Namen wieder zurückgeändert und das Sketch mit der Option “All Flash Settings” geschrieben um die gespeicherte MAC-Adresse des WLANs wieder loszuwerden. Trotzdem wird genau das TempGateway-Netzwerk beim Scan nicht erkannt. Woran kann das liegen, haben Sie da eine Idee? Ich bin nämlich mittlerweile ratlos.
Gerald Lechner
Im Blog wird der ESP32 für den Web-Server und der ESP8266 für den Sensor verwendet. Der ESP8266 ist sehr wohl Tiefschlaffähig und verbraucht, nach Datenblatt, etwa 0.01 mA in diesem Modus. Allerdings verbrauchen andere Bauelemente auf der D1-Mini Platine und am Sensormodul auch Strom, sodass sich, wie schon in einem vorangegangenen Kommentar erwähnt, ein Ruhestrom von 0.3 mA ergibt.
Rainer
@gerald lechner:
Im Kommentar und auch an anderen Stellen wird vom " ESP8266" gesprochen. Im Blog ist aber der Rede vom ESP32.
Ich denke dass nicht der ES8266 D1 Mini, sondern grundsätzlich der ESP32 D1 mini gemeint ist, denn nach meiner Meinung ist nur des ESP32 richtig tiefschlaffähig.
Gerald Lechner
Es ist richtig, der Ruhestrom ist etwa 0.3 mA. Eine Untersuchung der Schaltung des D1-Minis ergab, etwa 0.1mA entfallen auf den ESP8266 + Flash-Speicher, 0.1mA auf den CH340 un 0.1mA auf den Spannungsregler. Wenn man mit diesen geänderten Daten, also 0.3mA statt 0.035mA die Berechnungen durchführt ergibt sich ein Bedarf von 132mAs pro Messung somit 38000 mAs pro Tag oder 10.5 mAh pro Tag. Bei einer Akku-Kapazität von 2000mAh sind das immerhin 190 Tage. Also denke ich, dass der Batteriebetrieb trotz des höheren Ruhestroms funktioniert.
Ben Gabel
Im Prinzip funktioniert alles mit dem oben verlinkten D1 mini von AZ-Delivery. Leider ist aber der Strom im DeepSleep-Modus nicht 0,038 sondern ca. 0,3 mA, auch wenn ich den Temperatursensor ganz entferne.
Damit funktioniert der Batteriebetrieb nicht!
ben
Gerald Lechner
Ich habe nochmals nachgemessen und dabei folgendes festgestellt. Es scheint so, dass die Stromaufnahme im Tiefschlafmodus sehr schwankt. Zudem wenn die Batteriespannung unter 4V absinkt steigt die Stromaufnahme stark an, das dürfte am 3.3V Spannungsregler liegen, der natürlich auch noch ein wenig Spannungsabfall für sich benötigt. Teilweise schafft dann der ESP8266 keinen Neustart. In diesem Zustand kann der Strom auf über 100mA steigen und erf geht nie in den Schlafmodus. Ich werde das Verehalten weiter untersuchen und die Erkenntnisse hier posten.
Hike
Hallo Herr Lechner,
schönes Projekt.
Ich habe das Gateway und den Sensor (mehrfach) nachgebaut und inzwischen funktioniert es.
Probleme: Es schein ein Problem mit einer Fritzbox 4040 als Router zu geben, wenn diese im Mesh-Modus betrieben wird. Wenn sich das Gateway mit der Fritzbox verbindet, stellt sich das Gateway auf den aktuellen Kanal der 4040 ein. Dann ist die Übertagung per ESPNow nur zufällig möglich. Das erkennt man auch daran, das nur ab und zu die Anwort von Gateway zum Sensor (sendStatus == 0) ist
Ich habe einen zusätzlichen alten TP-Link Router benutzt, den ich fest auf Kanal 1 eingestellt habe. Seitdem läuft alles stabil.
Mein Problem ist, dass meine ESP8266 D1 minis von AZ-Delivery sehr viel mehr Strom verbrauchen.
In der vorgestellten Konfiguration mit 4 Batterien an VIn ist der Verbrauch auch während des Deep-Sleep > 7,6 mA.
Selbst mit 2 AAA Batterien, also 3V an 3,3V angeschlossen habe ich immer noch 3,5mA was um Größenordnungen mehr ist als die 35 microA aus ihrer Beschreibung.
Witzgerweise steigt hierbei der Verbrauch auf 5,5 mA, wenn man lediglich ein nicht verbundenes USB-Kabel einsteckt.
Gerald Lechner
Wenn das Gateway keine Geräte findet, liegt das am Sensor, wenn der keine Daten sendet. Das kann verschiedene Ursachen haben. Wenn die Nachricht zu lange ist also mehr als 250 Zeichen, werden keine Daten übertragen. Auch wenn der ESP8266 nicht in einem definierten Anfangszustand ist, kann es vorkommen, dass keine Daten gesendet werden. Für den ersten Fall habe ich die Länge der Meldung verkürtzt, für den zweiten Fall habe ich am Anfang der Setup Funktion WiFi Kommandos eingebaut die einen definierten Zustand sicherstellen. Ein neuer Sketch mit all den Änderungen kann vom Downloadbereich heruntergeladen werden. Den Link findet man im Blog Beitrag nach dem Listing des Sensor Sketchs. Der geänderte Sketch liefert jetzt auch eine Fehlermeldung und die Länge der Nachricht, wenn das Senden nicht erfolgreich ist.
@Klaus: Danke für den Hinweis, ich habe den Link zu AsyncTCP korrigiert. Die Installation von AsyncWebConfig ist im Blogbeitrag beschrieben.
@Burkhard: Der AP muss weiterhin bestehen, damit ESP-NOW Daten senden kann. Leider kann nicht verhindert werden, dass man über dieses WLan auch den Webserver des Gateways erreichen kann. Damit ist ein Zugriff auf die Nachrichten der Sensoren aber auch auf die Konfiguration des Gateways möglich. Ich würde daher empfehlen den AccessPoint über ein Passwort zu sichern. Die Funktion von ESP-NOW wird dadurch nicht beeinflusst. Das setzen eines Passworts ist ganz einfach. Im Gateway Sketch, in der Funktion initWiFi() muss die Zeile zum Starten des AP
WiFi.softAP(ACCESSPOINT,“meinPasswort”,0,0); lauten. Das Passwort muss mindestens 8 Zeichen haben. Der Klick auf das Zahnrad oben führt immer zur Konfiguration, damit man die Konfiguration auch ändern kann.
Burkhard
Hallo Herr Lechner.
Leider funktioniert das nicht wie erwartet. Ich habe die neuen Sketche installiert. Der Webserver startet und nach Eingabe meines WiFi verbindet er sich auch mit meinem WLAN. Allerdings existiert ja nach einem Reboot ja weiterhin ein AP “WebookGateway”. Damit kann sich auch jeder problemlos verbinden. Wenn man allerdings die Adresse 192.168.4.1 aufruft, landet man immer auf dem Webserver, so dass jeder, der sich mit dem AP verbindet meine WLAN-Daten ändern kann. Das dürfte doch nicht sein.
Weiterhin findet er keine Sensordevices. Die Serverseite sieht folgendermaßen aus:
Read configuration
apName=Gateway1
ssid=XXXXXX
pwd=*************
ntp_server=fritz.box
Verbindung zu XXXXX herstellen
..
IP-Adresse = 192.168.X.X
ESP-NOW gestartet
MDNS responder gestartet
Station MAC address: XX:XX:XX:XX:XX:C0
Accesspoint MAC address: XX:XX:XX:XX:XX:C1
fritz.box Uhrzeit gesetzt!
we have 0 devices
Die Sensorseite so:
Gateway MAC address: XX-XX-XX-XX-XX-c1
My MAC address: YY:YY:YY:YY:YY:00
Erfolgreich gepaart
BME280-YYYYYYYYYY00&Die Temperatur ist 25.3Grad Celsius
die Feuchtigkeit ist 38%
der Luftdruck ist 1016.4hPa
Meines Erachtens nach ist das alles korrekt. Wenn ich aber auf der Webseite des Servers das Zahnrädchen klicke, erscheint wieder die Konfigurationsseite des WLANs.
Was passiert hier? Haben Sie eine Idee?
Klaus
Hallo, bitte meinen Beitrag vom 13.Mai löschen. Ich habe die fehlende Datei auf github unter Hrn. Lechners repositories gefunden. Funktionieren tut es aber trotzdem nicht.:-(
Freundliche Grüße
Klaus
Klaus
Hallo Herr Lechner, versuche wieder mal, eines Ihrer Projekte nachzubauen. Jetzt kommt die Fehlermeldung, dass das Programm “AsyncWebConfig.h” nicht gefunden wird. Es befindet sich nicht in den von Ihnen angegebenen Bibliotheken. Fehlt mir da noch irgendwas?
BTW, die angeblich im Beitrag korrigierte URL für die AsyncTCP Bibliothek führt immer noch auf die falsche Webseite.
LG Klaus
Gerald Lechner
Der offene HotSpot stellt keine Gefahr dar. Der Treiber im ESP 32 implementiert einen Protokollstack mit dem er WLAN Datenpakete die an seine MAC Adresse gesendet werden empfangen kann OSI-Modell Schicht 2). Diese Daten können dann weiterverarbeitet werden, dafür sind Dienste notwendig, die in ein Programm eingebunden und gestartet werden müssen. Im Fall dieses Beitrags ist das der Dienst ESP-Now der die empfangenen Daten aus dem Netzwer-Frame extrahiert und über eine Callback-Funktion dem Sketch zur Verfügung stellt. Mehr macht auch dieser Dienst nicht. Es ist also ohne zusätzliche Software am ESP32 nicht möglich über den Access-Point eine Verbindung zum zweiten Protokoll-Stack, der im Station Mode mit dem lokalen WLAN verbunden ist, herzustellen.
AnsgarFleichhut
Moin,
danke für die Anleitung. Ich habe eine Frage hierzu:
WiFi.mode(WIFI_AP_STA);
WiFi.softAP(ACCESSPOINT,"",0,0);
Kann es eine Sicherheitslücke darstellen, wenn der ESP immer einen offenen Hotspot aktiv hat? Könnte jemand sich mit dem offenen Wlan verbinden und dann eine Verbindung zu meinem Heimnetz herstellen?
Schöne Grüße
Gerald Lechner
Einige hatten beim Nachbau dieses Projekts das Problem, dass keine Daten übermittelt wurden. Der Grund dafür war, dass die neueste Version von Arduino JSON bei Fließkommazahlen die Anzahl der Nachkommastellen erhöht hat und dadurch die Nachricht zu lang wurde. ESP NOW kann nur 250 Bytes in einem Paket Übertragen. Um das Problem zu lösen, müssen Sie zwei kleine Änderungen vornehmen:
Die Zeile für die Erzeugung des Strings muss geändert werden
sprintf(mbuf,“&Die Temperatur ist 5.1fGrad Celsius\ndie Feuchtigkeit ist %5.0f%\nder Luftdruck ist %7.1fhPa\ndie Batteriespannung ist %3.1fVolt&”,temperature,humidity,pressure,battery);
Also die unnötigen Zwischenräume nach dem Zeilenvorschub entfernen und statt “Luftfeuchtigkeit” nur “Feuchtigkeit”
Die zweite Änderung betrifft den Luftdruck. Hier macht es keinen Sinn Nachkommastellen zu nutzen, daher wird der Luftdruck bei der Zuweisung zum JSON Dokument gerundet.
doc[“p”]=round(pressure); //Value
Mit diesen Änderungen funktioniert die Übertragung.
Der Sketch zum Herunterladen enthält bereits die Änderungen.
Gerald Lechner
Wenn ESP-Now nicht funktioniert, also das Gateway keine Daten empfängt, muss überprüft werden ob der Sensor die richtige MAC-Adresse benutzt. Um diese Prüfung zu erleichtern, habe ich den Sketch für den Sensor erweitert. Siehe Abschnitt Nachtrag am Ende des Beitrags. Ebenso hab ich die Ausgabe der Station-MAC-Adresse und der Accesspoint MAC Adresse im Sketch für das Gateway eingebaut. Die geänderten Sketchs können von Google-Drive heruntergeladen werden.
Gerald Lechner
ACHTUNG WICHTIGER HINWEIS!
Im Beitrag war eine falsche URL für die AsyncTCP Bibliothek. Die URL ist nicht https://github.com/me-no-dev/ESPAsyncTCP sondern https://github.com/me-no-dev/AsyncTCP.
Die URL ist jetzt auch im Beitrag korrigiert.
Knut Hansen
Hallo Herr Lechner,
ich habe das gleiche Problem wie Herr Wiegand.
Meine Ausgaben am seriellen Port sind fast identisch.
Als Server verwende ich auch einen ESP32 und keinen D1 mini.
Beim Neustart wird das Gateway gefunden und auch die Mac-Adresse.
Der Webserver zeigt keine Geräte an.
auf dem Serial Monitor wird die Nachricht:
we have 0 devices ausgegeben.
Können Sie mir helfen?
Mit freundlichen Grüßen
Knut Hansen
Burkhard
Hallo, beim Compilieren des Webservers bekomme ich immer die Fehlermeldung:
Alternatives for interrupts.h: []
/home/burkhard/Arduino/libraries/ESPAsyncTCP-master/src/SyncClient.cpp:25:24: fatal error: interrupts.h: No such file or directory
ResolveLibrary(interrupts.h)
→ candidates: []
compilation terminated.
…
exit status 1
Fehler beim Kompilieren für das Board ESP32 Dev Module.
Wo bekomme ich interrupts.h her?
VG
Burkhard
Gerald Lechner
ESP-NOW ist ein sehr einfaches Protokoll, wenn die MAC-Adresse des Empfängers bekannt ist, werden die Daten an diese MAC-Adresse gesendet ohne irgendwelche Überprüfungen. Kommt das Datenpaket bei keinem Empfänger an, kann der Sender das nicht feststellen. Der Sensor im Beitrag ist ESP-NOW Sender. Wenn er noch keine MAC-Adresse des Servers hat, wird ein Netzwerk-Scan durchgeführt um diese Adresse zu erhalten und für die Zukunft zu speichern. Wird die Stromversorgung nicht unterbrochen, so sendet der Sensor die Daten an die gespeicherte MAC-Adresse, egal ob das die Adresse des Servers ist oder nicht. Um sicherzustellen, dass die richtige MAC-Adresse gespeichert wird, sollte der Sensor von der Stromversorgung getrennt werden, damit er irgendwelche falsche MAC-Adressen vergisst. Dann sollte der Server gestartet werden und erst danach der Sensor wieder mit der Stromversorgung verbunden werden. Im seriellen Monitor beim Sender wird ausgegeben, dass ein Netzwerkscan ausgeführt wird.
Fritz Wiegand
Hallo Herr Lechner,
sehr schönes Projekt. Erst mal vielen Dank für die Mühe…
Leider funktioniert es nicht so wie es soll…
Als Gateway habe ich einen ESP 32 und der Client ist ein D1 mini ESP8266.
Nach aufspielen der Sketche konnte ich den Server wie beschrieben konfigurieren.
Fritz Box Kanal 1 (in der Beschreibung Kanl 0 den gibt es nicht).
Server connectet sich problemslos mit FritzBox WiFi….
Client bekommt auch Verbimdung zum Gateway….
Aber leider werden keine Daten übertragen..
Eine Idee WARUM ???
Hier ein Auszug des logs…..Gateway
:11:27.122 → rst:0×1 (POWERON_RESET),boot:0×13 (SPI_FAST_FLASH_BOOT)
18:11:27.122 → configsip: 0, SPIWP:0xee
18:11:27.122 → clk_drv:0×00,q_drv:0×00,d_drv:0×00,cs0_drv:0×00,hd_drv:0×00,wp_drv:0×00
18:11:27.122 → mode:DIO, clock div:1
18:11:27.122 → load:0×3fff0018,len:4
18:11:27.122 → load:0×3fff001c,len:1100
18:11:27.122 → load:0×40078000,len:9232
18:11:27.122 → load:0×40080400,len:6400
18:11:27.122 → entry 0×400806a8
18:11:27.427 → [{’name’:‘ssid’,‘label’:‘Name des WLAN’,‘type’:0,‘default’:‘’},{’name’:‘pwd’,‘label’:‘WLAN Passwort’,‘type’:1,‘default’:‘’},{’name’:‘ntp_server’,‘label’:‘NTP Server’,‘type’:0,‘default’:‘fritz.box’}]
18:11:27.529 → Read configuration
18:11:27.529 → apName=WebhookGateway
18:11:27.529 → ssid=FRITZ!Box Fon WLAN 7270
18:11:27.563 → pwd=*************
18:11:27.563 → ntp_server=fritz.box
18:11:27.631 → Verbindung zu FRITZ!Box Fon WLAN 7270 herstellen
18:11:28.209 → ..
18:11:28.685 → IP-Adresse = 192.168.1.123
18:11:28.685 → ESP-NOW gestartet
18:11:28.719 → MDNS responder gestartet
18:11:28.719 → fritz.box Uhrzeit gesetzt!
18:11:52.062 → dhcps: send_offer>>udp_sendto result 0
18:11:52.062 → dhcps: send_nak>>udp_sendto result 0
18:11:55.561 → dhcps: send_nak>>udp_sendto result 0
18:11:55.561 → dhcps: send_offer>>udp_sendto result 0
18:11:55.561 → dhcps: send_nak>>udp_sendto result 0
18:16:15.674 → dhcps: send_offer>>udp_sendto result 0
18:16:17.506 → dhcps: send_offer>>udp_sendto result 0
und hier Client
18:02:23.912 → ets Jan 8 2013,rst cause:2, boot mode:(3,6)
18:02:23.946 →
18:02:23.946 → load 0×4010f000, len 3460, room 16
18:02:23.946 → tail 4
18:02:23.946 → chksum 0xcc
18:02:23.946 → load 0×3fff20b8, len 40, room 4
18:02:23.946 → tail 4
18:02:23.946 → chksum 0xc9
18:02:23.946 → csum 0xc9
18:02:23.946 → v00048000
18:02:23.946 → ~ld
18:02:24.082 → RTC fertig
18:02:24.082 → Erfolgreich gepaart
18:02:24.116 → BME280-B4E62D697FD0&Die Temperatur ist 25.1Grad Celsius
18:02:24.116 → die Luftfeuchtigkeit ist 34%
18:02:24.116 → der Luftdruck ist 989.7hPa
18:02:24.116 → die Batteriespannung ist 4.8Volt&{"t":25.09000015,“tu”:“°C”,h,“hu”:“%”,p,“pu”:“hPa”,b,“bu”:"V"}
18:02:28.968 → Sleep
18:02:29.070 → Processing time 5030 ms
Lutz Ti
Hilferuf …
Versuche schon seit ein paar Tagen den Nachbau, scheitere aber in beiden Scripten bei Compilieren, offensichtlich fehlen ( mir ) da noch Bibliotheken:
WebhookGateway:
ESPAsyncWebServer.h: No such file or directory
und beim Client:
ESP8266WiFi.h: No such file or directory
In beiden Fällen bricht der Compiler ab …
Welchen ( Anfänger ? ) Fehler mache ich? Wo finde ich die zusätzlichen Biblioheken ?
Danke für eine rettende Idee …
ti
Andreas Wolter
@Äd Franzis: mit RTC ist in diesem Fall nicht gemeint, dass eine Real Time Clock verwendet wird. Wir haben einen zusätzlichen Hinweis eingefügt. Der ESP32 hat 8Kbyte Speicher, der RTC RAM genannt wird. Damit können Variablen während des Deep Sleep gehalten werden.
Grüße,
Andreas Wolter
AZ-Delivery Blog
Äd Franzis
Sehr schöner Artikel, vielen Dank.
Allerdings habe ich nicht verstanden, dass in der SW und im Text auf den Speicher der RTC Bezug genommen wird, wobei ich aber im Anschlußplan und der Stückliste kein Uhrenmodul sehe.
LG
Äd
Gerald Lechner
Vielen Dank für den Hinweis. Habe den Code geändert. Der Fehler war aber nicht tragisch, da die Funktion scanForSlave nur einmal ausgeführt wird. Der Sensor erhält nach dem Tiefschlaf einen Reset und da werden ohnehin alle Speicherstrukturen neu initialisiert.
Ulrich Klaas
In “scanForSlave” steht ein WiFi.scanDelete(); nach einem return. Wird also nie ausgeführt.