XAN77 Postat Ianuarie 1, 2022 Partajează Postat Ianuarie 1, 2022 La mulți ani dragi colegi Am o problemă care mă enervează deja la 3 proiecte ce le am în uz prin casă. Sunt niște web servere cu esp8266 cu date de la senzori. Am preluat inițial un cod de pe siteul randomnerdtutorial ce era un exemplu de webserver cu un singur senzor și am duplicat tot ce am crezut eu de cuviință pentru a avea 2 senzori. Problema este că în browser, atât pe pc cât și pe telefon, datele primului senzor cel din codul original, se actualizează singure la câteva secunde până în 10, dar datele senzorului adăugat de mine nu se actualizează decât dacă dau eu refresh în browser. Nu înțeleg ce nu am modificat bine sau ce trebuie să fac ca să se actualizeze toți senzorii la fel. /********* Rui Santos Complete project details at https://RandomNerdTutorials.com *********/ // Import required libraries #ifdef ESP32 #include <WiFi.h> #include <ESPAsyncWebServer.h> #else #include <Arduino.h> #include <ESP8266WiFi.h> #include <Hash.h> #include <ESPAsyncTCP.h> #include <ESPAsyncWebServer.h> #include <AsyncElegantOTA.h> #endif #include <OneWire.h> #include <DallasTemperature.h> // Data wire is connected to GPIO 4 #define ONE_WIRE_BUS 2 // Setup a oneWire instance to communicate with any OneWire devices OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature sensor DallasTemperature sensors(&oneWire); // Variables to store temperature values String temperatureF = ""; String temperatureC = ""; String temperatureF2 = ""; String temperatureC2 = ""; // Timer variables unsigned long lastTime = 0; unsigned long timerDelay = 2000; // Replace with your network credentials const char* ssid = "........"; const char* password = "........."; // Create AsyncWebServer object on port 80 AsyncWebServer server(80); String readDSTemperatureC() { // Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus sensors.requestTemperatures(); float tempC = sensors.getTempCByIndex(0); if(tempC == -127.00) { Serial.println("Failed to read from DS18B20 sensor"); return "--"; } else { Serial.print("Temperature Celsius: "); Serial.println(tempC); } return String(tempC); } String readDSTemperatureF() { // Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus sensors.requestTemperatures(); float tempF = sensors.getTempFByIndex(0); if(int(tempF) == -196){ Serial.println("Failed to read from DS18B20 sensor"); return "--"; } else { Serial.print("Temperature Fahrenheit: "); Serial.println(tempF); } return String(tempF); } String readDSTemperatureC2() { // Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus sensors.requestTemperatures(); float tempC2 = sensors.getTempCByIndex(1); if(tempC2 == -127.00) { Serial.println("Failed to read from DS18B20 sensor"); return "--"; } else { Serial.print("Temperature Celsius: "); Serial.println(tempC2); } return String(tempC2); } String readDSTemperatureF2() { // Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus sensors.requestTemperatures(); float tempF2 = sensors.getTempFByIndex(1); if(int(tempF2) == -196){ Serial.println("Failed to read from DS18B20 sensor"); return "--"; } else { Serial.print("Temperature Fahrenheit: "); Serial.println(tempF2); } return String(tempF2); } const char index_html[] PROGMEM = R"rawliteral( <!DOCTYPE HTML><html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous"> <style> html { font-family: Arial; display: inline-block; margin: 0px auto; text-align: center; } h2 { font-size: 3.0rem; } p { font-size: 3.0rem; } .units { font-size: 1.2rem; } .ds-labels{ font-size: 1.5rem; vertical-align:middle; padding-bottom: 15px; } </style> </head> <body> <h2>ESP DS18B20 Server</h2> <p> <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> <span class="ds-labels">Temperature Celsius</span> <span id="temperaturec">%TEMPERATUREC%</span> <sup class="units">°C</sup> </p> <p> <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> <span class="ds-labels">Temperature Fahrenheit</span> <span id="temperaturef">%TEMPERATUREF%</span> <sup class="units">°F</sup> </p> <p> <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> <span class="ds-labels">Temperature Celsius2</span> <span id="temperaturec2">%TEMPERATUREC2%</span> <sup class="units">°C</sup> </p> <p> <i class="fas fa-thermometer-half" style="color:#059e8a;"></i> <span class="ds-labels">Temperature Fahrenheit2</span> <span id="temperaturef2">%TEMPERATUREF2%</span> <sup class="units">°F</sup> </p> </body> <script> setInterval(function ( ) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("temperaturec").innerHTML = this.responseText; } }; xhttp.open("GET", "/temperaturec", true); xhttp.send(); }, 2000) ; setInterval(function ( ) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("temperaturef").innerHTML = this.responseText; } }; xhttp.open("GET", "/temperaturef", true); xhttp.send(); }, 2000) ; setInterval(function ( ) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("temperaturec2").innerHTML = this.responseText; } }; xhttp.open("GET", "/temperaturec2", true); xhttp.send(); }, 2000) ; setInterval(function ( ) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("temperaturef2").innerHTML = this.responseText; } }; xhttp.open("GET", "/temperaturef2", true); xhttp.send(); }, 2000) ; </script> </html>)rawliteral"; // Replaces placeholder with DS18B20 values String processor(const String& var){ //Serial.println(var); if(var == "TEMPERATUREC"){ return temperatureC; } else if(var == "TEMPERATUREF"){ return temperatureF; } else if(var == "TEMPERATUREC2"){ return temperatureC2; } else if(var == "TEMPERATUREF2"){ return temperatureF2; } return String(); } void setup(){ // Serial port for debugging purposes Serial.begin(115200); Serial.println(); // Start up the DS18B20 library sensors.begin(); temperatureC = readDSTemperatureC(); temperatureF = readDSTemperatureF(); temperatureC2 = readDSTemperatureC2(); temperatureF2 = readDSTemperatureF2(); // Connect to Wi-Fi WiFi.begin(ssid, password); Serial.println("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); // Print ESP Local IP Address Serial.println(WiFi.localIP()); // Route for root / web page server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", index_html, processor); }); server.on("/temperaturec", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", temperatureC.c_str()); }); server.on("/temperaturef", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", temperatureF.c_str()); }); server.on("/temperaturec", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", temperatureC2.c_str()); }); server.on("/temperaturef", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", temperatureF2.c_str()); }); AsyncElegantOTA.begin(&server); // Start ElegantOTA server.begin(); // Start server } void loop(){ if ((millis() - lastTime) > timerDelay) { temperatureC = readDSTemperatureC(); temperatureF = readDSTemperatureF(); temperatureC2 = readDSTemperatureC2(); temperatureF2 = readDSTemperatureF2(); lastTime = millis(); } } codul original se găsește aici, e o pagină cu 3 exemple de cod, aceste de webserver este al treilea. Link spre comentariu
Vizitator Postat Ianuarie 1, 2022 Partajează Postat Ianuarie 1, 2022 Acum 1 oră, x_dadu a spus: xhttp.open("GET", "/temperaturec2", true); Acum 1 oră, x_dadu a spus: server.on("/temperaturec", trebuie sa modifici si aici "temperaturec2" si "...f2" Link spre comentariu
Liviu M Postat Ianuarie 1, 2022 Partajează Postat Ianuarie 1, 2022 Conform obiceiului, pentru ca ai primit deja raspunsul la intrebare, vin si eu cu despicatul firului. Eu n-as fi facut cate doua functii de citire a temperaturii, ci as fi adaugat un parametru pentru selectia senzorului in functiile existente. Ar fi mai usor de intretinut, daca vrei sa modifici ceva, o faci o singura data, nu de doua ori. Pentru temperatura in °C functia s-ar transforma in: String readDSTemperatureC(uint8_t uiSensor) { // Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus sensors.requestTemperatures(); float tempC = sensors.getTempCByIndex(uiSensor); if(tempC == -127.00) { Serial.println("Failed to read from DS18B20 sensor"); return "--"; } else { Serial.print("Temperature Celsius: "); Serial.println(tempC); } return String(tempC); } si va fi folosita in setup si loop: temperatureC = readDSTemperatureC(0); temperatureC2 = readDSTemperatureC(1); Probabil se poate gasi o varianta "comuna" si pentru cele doua "grade", desi cred ca cel mai "cinstit" ar fi cu o functie care sa citeasca senzorii o singura data (sensors.requestTemperatures();) si sa "genereze" toate cele 4 valori de care ai nevoie. Asa cum e acum, pentru cele 4 valori afisate tu citesti de 4 ori ambii senzori. Si pentru ca sunt bata la partea de html, daca as avea hardul necesar as incerca sa vad ce se intampla daca "comasez" cele 4 setInterval() intr-unul singur. setInterval(function ( ) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("temperaturec").innerHTML = this.responseText; document.getElementById("temperaturef").innerHTML = this.responseText; document.getElementById("temperaturec2").innerHTML = this.responseText; document.getElementById("temperaturef2").innerHTML = this.responseText; } }; xhttp.open("GET", "/temperaturec", true); xhttp.send(); xhttp.open("GET", "/temperaturef", true); xhttp.send(); xhttp.open("GET", "/temperaturec2", true); xhttp.send(); xhttp.open("GET", "/temperaturef2", true); xhttp.send(); }, 2000) ; Link spre comentariu
XAN77 Postat Ianuarie 1, 2022 Autor Partajează Postat Ianuarie 1, 2022 (editat) Vă mulțumesc pentru răspunsuri, întradevăr după ce am modificat acele 2 linii de la server.on .... a mers. Acest cod l-am pregătit special pentru postare, ca să fie cât mai asemănător cu cel original, că proiectele de care mă plâng eu sunt mult mai modificate. Am vrut să evidiențez numai problema respectivă. Oricum când am făcut acest cod azi am sesizat și corectat și alte greșeli ce le făceam dar am omis acele modificări. Va trebui să-mi modific proiectele acum. Normal eu splituiesc proiectul în mai multe fișiere cu declarațiile și definirea variabilelor întrun tab/file.h, codul siteului html într-altul, funcția setup altul etc Da @Liviu M e mai optimizat cum zici, am preferat așa doar pentru această postare. ce este acel 2000 (inițial era 10000) de la finele funcției setInternal ( function() {}, 2000 ) ? E cumva timpul de autorefresh ? Că am văzut că acel timp e oarecum variabil. Am încercat varianta cu comasarea setInterval. Dar la primu autorefresh toate cele 4 valori devin identice și anume F2. dacă dau refresh manual, valorile apar corecte dar în câteva secunde la autoupdate iar sunt toate valoarea lui F2 Editat Ianuarie 1, 2022 de x_dadu Link spre comentariu
Vizitator Postat Ianuarie 1, 2022 Partajează Postat Ianuarie 1, 2022 (editat) Acum 34 minute, Liviu M a spus: Si pentru ca sunt bata la partea de html, daca as avea hardul necesar as incerca sa vad ce se intampla daca "comasez" cele 4 setInterval() intr-unul singur. setInterval(function ( ) { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("temperaturec").innerHTML = this.responseText; document.getElementById("temperaturef").innerHTML = this.responseText; document.getElementById("temperaturec2").innerHTML = this.responseText; document.getElementById("temperaturef2").innerHTML = this.responseText; } }; xhttp.open("GET", "/temperaturec", true); xhttp.send(); xhttp.open("GET", "/temperaturef", true); xhttp.send(); xhttp.open("GET", "/temperaturec2", true); xhttp.send(); xhttp.open("GET", "/temperaturef2", true); xhttp.send(); }, 2000) ; Nu cred ca merge asa ca mai sus. La cine face referire "this" in acest caz ? Poate prin folosirea de mai multe obiecte XMLHttpRequest: xhttp1, xhttp2... Si definirea de events separate de tip onreadystatechange pentru fiecare. Dar eu zic ca se complica inutil. Editat Ianuarie 1, 2022 de Vizitator Link spre comentariu
XAN77 Postat Ianuarie 1, 2022 Autor Partajează Postat Ianuarie 1, 2022 M-am apucat să mdific proiectele mele ca să facă autoupdate la toate valorile din pagină, 2 le-am rezolvat deja la al treilea am mai mult de lucru că e diferită partea de web și vreau s-o fac în același stil. Acum modificând acele proiecte am constatat că eroarea mea principală era că nu duplicam corespunzător acea secvență cu setInterval. De, bizon. Link spre comentariu
Liviu M Postat Ianuarie 1, 2022 Partajează Postat Ianuarie 1, 2022 Acum 16 minute, Liviu.Mihaiu a spus: Nu cred ca merge asa ca mai sus. La cine face referire "this" in acest caz ? Speram ca fiecare sa se refere la documentul care le foloseste document.getElementById("temperaturec") da' se pare ca nu. Cum ziceam, la html mai am mult de studiat. Acum 35 minute, x_dadu a spus: ce este acel 2000 (inițial era 10000) de la finele funcției setInternal ( function() {}, 2000 ) ? E cumva timpul de autorefresh ? Da, asa cum ii zice numele, seteaza un interval. In cazul tau de refresh. Link spre comentariu
Postări Recomandate
Creează un cont sau autentifică-te pentru a adăuga comentariu
Trebuie să fi un membru pentru a putea lăsa un comentariu.
Creează un cont
Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!
Înregistrează un nou contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum