Sari la conținut
ELFORUM - Forumul electronistilor

ESP8266 rescriere sketch OTA


XAN77

Postări Recomandate

Am încercat să implementez programarea Over The Air de aici https://randomnerdtutorials.com/esp8266-nodemcu-ota-over-the-air-arduino/

ESP-ul se accesează local cu 192.168.1.5 (în cazul meu) iar încărcarea viitoarelor programe prin pagina disponibilă la 192.168.1.5/update

Îmi funcționează bine cu unele softuri, ceea ce este mișto fiind o chestie foarte utilă, însă nu cu toate programele merge ok.

De exemplu cu codul de aici de control relee am o problemă https://randomnerdtutorials.com/esp32-esp8266-relay-web-server/ .

Respectiv, după trimiterea over the air a acelui program de control relee, nu se mai încarcă pagina de update pentru a putea rescrie alte programe. Când accesez 192.168.1.5/update îmi apare o pagină goală albă pe care scrie mic în colțul din stânga sus ”OK”

Nu prea am avut ce greși pentru că adăugarea funcției OTA la progrmele existente (ca să se asigure posibilitatea rescriereii viitoare via OTA) constă în adăugarea a 3 linii, una la sus la includeri de librării, una chiar înainte de server.begin() și una în funcția loop. Cum spuneam cu alt program îmi funcționează bine și pot rescrie de mai multe ori acel program.

S-a mai jucat cineva cu aceste funcții ?

Așa arată în mod normal pagina de update:

Capture.jpg

Link spre comentariu
  • Răspunsuri 11
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Zile populare

Top autori în acest subiect

Ca simpla banuiala, ai inlocuit serverul web care asculta pe portul 80 si-ti trimitea pagina de update cu alt server web care asculta pe acelasi port si care are alta functionalitate pt. path-u` /update.... Instantiaza/acceseaza serverul web pt. comanda releelor pe alt port decat 80 si vezi daca asa-ti merge.

Link spre comentariu

Nu știu dacă am înțeles exact. 

Acesta este codul ce-l scriu inițial prin portul serial:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.h>

const char* ssid = "DIGI_cd7d50";
const char* password = "989d3282";

AsyncWebServer server(80);

void setup(void) {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(200, "text/plain", "Hi! I am ESP8266.");
  });

  AsyncElegantOTA.begin(&server);    // Start ElegantOTA
  server.begin();
  Serial.println("HTTP server started");
}

void loop(void) {
  AsyncElegantOTA.loop();
}

și acesta este codul cu relee, unde era portul 80 și eu am pus acum 8080 dar am aceeași problemă:

#include "ESP8266WiFi.h"
#include "ESPAsyncWebServer.h"
#include <AsyncElegantOTA.h>

// Set to true to define Relay as Normally Open (NO)
#define RELAY_NO    true

// Set number of relays
#define NUM_RELAYS  3

// Assign each GPIO to a relay
int relayGPIOs[NUM_RELAYS] = {3, 1, 0};

// Replace with your network credentials
const char* ssid = "DIGI_cd7d50";
const char* password = "989d3282";

const char* PARAM_INPUT_1 = "relay";  
const char* PARAM_INPUT_2 = "state";

// Create AsyncWebServer object on port 80
AsyncWebServer server(8080);

#include "2_saitu.h"

// Replaces placeholder with button section in your web page
String processor(const String& var){
  //Serial.println(var);
  if(var == "BUTTONPLACEHOLDER"){
    String buttons ="";
    for(int i=1; i<=NUM_RELAYS; i++){
      String relayStateValue = relayState(i);
      buttons+= "<h4>Relay #" + String(i) + " - GPIO " + relayGPIOs[i-1] + "</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"" + String(i) + "\" "+ relayStateValue +"><span class=\"slider\"></span></label>";
    }
    return buttons;
  }
  return String();
}

String relayState(int numRelay){
  if(RELAY_NO){
    if(digitalRead(relayGPIOs[numRelay-1])){
      return "";
    }
    else {
      return "checked";
    }
  }
  else {
    if(digitalRead(relayGPIOs[numRelay-1])){
      return "checked";
    }
    else {
      return "";
    }
  }
  return "";
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

  // Set all relays to off when the program starts - if set to Normally Open (NO), the relay is off when you set the relay to HIGH
  for(int i=1; i<=NUM_RELAYS; i++){
    pinMode(relayGPIOs[i-1], OUTPUT);
    if(RELAY_NO){
      digitalWrite(relayGPIOs[i-1], HIGH);
    }
    else{
      digitalWrite(relayGPIOs[i-1], LOW);
    }
  }
  
  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP8266 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);
  });

  // Send a GET request to <ESP_IP>/update?relay=<inputMessage>&state=<inputMessage2>
  server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    String inputParam;
    String inputMessage2;
    String inputParam2;
    // GET input1 value on <ESP_IP>/update?relay=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1) & request->hasParam(PARAM_INPUT_2)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
      inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
      inputParam2 = PARAM_INPUT_2;
      if(RELAY_NO){
        Serial.print("NO ");
        digitalWrite(relayGPIOs[inputMessage.toInt()-1], !inputMessage2.toInt());
      }
      else{
        Serial.print("NC ");
        digitalWrite(relayGPIOs[inputMessage.toInt()-1], inputMessage2.toInt());
      }
    }
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    Serial.println(inputMessage + inputMessage2);
    request->send(200, "text/plain", "OK");
  });
  AsyncElegantOTA.begin(&server);    // Start ElegantOTA
  // Start server
  server.begin();
}
  
void loop() {
AsyncElegantOTA.loop();
}

 

Link spre comentariu

Pagina de upload OTA este servita de un server web ce ruleaza pe ESP-ul tau si care asculta pe portul standard pt. HTTP (80).

Calea este 192.168.1.5/update.

 

Pe de alta parte tu uploadezi un alt server web instantiat aici:
 

AsyncWebServer server(80);

si care mai mult, foloseste o functie asociata cu ACEEASI cale, adica aici:
 

 server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
.........

 

Nu pot merge simultan doua servere web care asculta pe acelasi port si folosesc aceeasi cale. :) 
OK-ul pe care-l primesti este de la serverul din soft-ul ce deserveste releele si anume de aici:

 

    request->send(200, "text/plain", "OK");

 

Ce as incerca ar fi sa pornesc al 2-lea server web sa asculte pe un alt port... adica:

AsyncWebServer server(8080);

Sa nu uiti sa-l specifici in browser, ca altfel merge tot pe 80.
 

Link spre comentariu

păi după cum se vede în codul pus de mine, cel pentru relee, am pus portul 8080, inițial fiind 80, și l-am accesat evident cu :8080 dar am primit același OK

 

chestia e că alte softuri, care folosesc tot 80, merg ok, adică rămâne activa pagina de la .../update

Editat de x_dadu
Link spre comentariu

Pai mi se pare normal sa primesti OK de la serverul pt. relee daca l-ai accesat pe el pe 8080... aia ii facut sa trimita.
Intrebarea e ce primesti daca accesezi acel IP pe portul 80... tot OK? :)

 

L.E.

M-am uitat un pic peste cod... se pare ca nu sunt totusi 2 servere... schimba calea pt. update relee, sa fie la altceva decat "/update"...

Editat de informer
Link spre comentariu

ce observ diferit (că nu pricep preamult din aceste coduri) față de programele care merg ok cu această funcșie OTA, este tocmai acel ”/update” care cumva coincide cu calea spre pagina de update firmware. Dacă înlocuiesc cu altceva, gen ”/relay” sau altceva, merge bine pagina de update dar nu mai merg releele nu se mai activează.

Link spre comentariu

deci codul cu comanda releelor este:

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp8266-relay-module-ac-web-server/
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

// Import required libraries
#include "ESP8266WiFi.h"
#include "ESPAsyncWebServer.h"
#include <AsyncElegantOTA.h>

// Set to true to define Relay as Normally Open (NO)
#define RELAY_NO    true

// Set number of relays
#define NUM_RELAYS  3

// Assign each GPIO to a relay
int relayGPIOs[NUM_RELAYS] = {3, 1, 0};

// Replace with your network credentials
const char* ssid = "DIGI_cd7d50";
const char* password = "989d3282";

const char* PARAM_INPUT_1 = "relay";  
const char* PARAM_INPUT_2 = "state";

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

#include "2_saitu.h"

// Replaces placeholder with button section in your web page
String processor(const String& var){
  //Serial.println(var);
  if(var == "BUTTONPLACEHOLDER"){
    String buttons ="";
    for(int i=1; i<=NUM_RELAYS; i++){
      String relayStateValue = relayState(i);
      buttons+= "<h4>Relay #" + String(i) + " - GPIO " + relayGPIOs[i-1] + "</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"" + String(i) + "\" "+ relayStateValue +"><span class=\"slider\"></span></label>";
    }
    return buttons;
  }
  return String();
}

String relayState(int numRelay){
  if(RELAY_NO){
    if(digitalRead(relayGPIOs[numRelay-1])){
      return "";
    }
    else {
      return "checked";
    }
  }
  else {
    if(digitalRead(relayGPIOs[numRelay-1])){
      return "checked";
    }
    else {
      return "";
    }
  }
  return "";
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

  // Set all relays to off when the program starts - if set to Normally Open (NO), the relay is off when you set the relay to HIGH
  for(int i=1; i<=NUM_RELAYS; i++){
    pinMode(relayGPIOs[i-1], OUTPUT);
    if(RELAY_NO){
      digitalWrite(relayGPIOs[i-1], HIGH);
    }
    else{
      digitalWrite(relayGPIOs[i-1], LOW);
    }
  }
  
  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP8266 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);
  });

  // Send a GET request to <ESP_IP>/update?relay=<inputMessage>&state=<inputMessage2>
  server.on("/relay", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    String inputParam;
    String inputMessage2;
    String inputParam2;
    // GET input1 value on <ESP_IP>/update?relay=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1) & request->hasParam(PARAM_INPUT_2)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
      inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
      inputParam2 = PARAM_INPUT_2;
      if(RELAY_NO){
        Serial.print("NO ");
        digitalWrite(relayGPIOs[inputMessage.toInt()-1], !inputMessage2.toInt());
      }
      else{
        Serial.print("NC ");
        digitalWrite(relayGPIOs[inputMessage.toInt()-1], inputMessage2.toInt());
      }
    }
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    Serial.println(inputMessage + inputMessage2);
    request->send(200, "text/plain", "OK I am still here");
  });
  AsyncElegantOTA.begin(&server);    // Start ElegantOTA  
  // Start server
  server.begin();
}
  
void loop() {
AsyncElegantOTA.loop();
}

pagina releelor o accesez cu 192.168.1.5 doar că în acest caz (cu /relay în loc de /update) pagina apare ok dar acționarea butoanelor nu mai activează pinii respectivi de la ESP

pagina OTA o accesez cu 192.168.1.5/update

Link spre comentariu

Pai nu prea mi-ai dat tot codul... :)

Pagina pe care o trimite serverul are o sectiune javascript:

 

... 
if(element.checked){ xhr.open("GET", "/update?relay="+element.id+"&state=1", true); }
  else { xhr.open("GET", "/update?relay="+element.id+"&state=0", true); }
...

 

Daca ai schimbat "/update" in codul C trebuie sa schimbi si in JS.

Link spre comentariu

îmi cer scuze, amobiceiul să splitez codul în mai multe fișiere/tab-uri și am uitat că și în acest program aveam site-ul eparat. am modificat acum ce credeam eu, dar tot nu se activează releele:

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    html {font-family: Arial; display: inline-block; text-align: center;}
    h2 {font-size: 3.0rem;}
    p {font-size: 3.0rem;}
    body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}
    .switch {position: relative; display: inline-block; width: 120px; height: 68px} 
    .switch input {display: none}
    .slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 34px}
    .slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px}
    input:checked+.slider {background-color: #2196F3}
    input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
  </style>
</head>
<body>
  <h2>ESP Web Server</h2>
  %BUTTONPLACEHOLDER%
<script>function toggleCheckbox(element) {
  var xhr = new XMLHttpRequest();
  if(element.checked){ xhr.open("GET", "/relay?relay="+element.id+"&state=1", true); }
  else { xhr.open("GET", "/relay?relay="+element.id+"&state=0", true); }
  xhr.send();
}</script>
</body>
</html>
)rawliteral";

 

 

l.e. hmm, culmea, după ce am pus acest post am macționat iar unu din relee (la gpio1 că esp01 are led onboard acolo) și a mers. Nu îmi dau seama de ce nu a mers imediat după programare.

Văd că merge, clar asta era problema.

Mulțumesc @informer

Editat de x_dadu
Link spre comentariu
Acum 16 minute, x_dadu a spus:

l.e. hmm, culmea, după ce am pus acest post am macționat iar unu din relee (la gpio1 că esp01 are led onboard acolo) și a mers. Nu îmi dau seama de ce nu a mers imediat după programare.

Daca modifici JS-ul trebuie sa dai refresh la pagina... pana nu faci asta ruleaza tot cel vechi.

Link spre comentariu

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 cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări