I need help with a webserver project...



  • @rop I've just tried what you said but with no luck at all (it seems to be worst than before)... It must be something related to M5Stack, 'cause if I set another Arduino with the IP of M5Stack it gets a request every minute and it works as intended to. I'l try to setup a program without M5ez and see if it works that way, maybe there's something wrong with interactions between it and the webserver part...
    Thank you for all your help!



  • @rop I found where the error was! I was streaming my GET request string to the client with multiple prints and while it is OK for connecting to a web site I send data to and to my MySQL database, it was not OK for the M5Stack.
    I set up a buffer string, printed all my data in it and then use it to send data to my client object and now it work flawless! I got my stream of data sent every minute!





  • Could you please help me with this backtrace I got few moments ago?

    PC: 0x400853e3: esp_log_write at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/log/log.c line 214
    EXCVADDR: 0x00000000
    
    Decoding stack results
    0x400853e3: esp_log_write at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/log/log.c line 214
    0x400f54d2: __assert_func at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/bootloader_support/src/bootloader_init.c line 537
    0x4008de99: vTaskEnterCritical at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/portmux_impl.inc.h line 106
    0x4008fd4b: multi_heap_internal_lock at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap.c line 372
    0x400903d3: multi_heap_malloc at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap_poisoning.c line 190
    0x400856b5: heap_caps_malloc at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/heap_caps.c line 110
    0x400857b9: heap_caps_realloc at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/heap_caps.c line 275
    0x4008586e: heap_caps_realloc_default at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/heap_caps.c line 162
    0x40087799: _realloc_r at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/newlib/syscalls.c line 47
    0x400ead7a: String::changeBuffer(unsigned int) at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\cores\esp32\WString.cpp line 170
    0x400eadc8: String::reserve(unsigned int) at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\cores\esp32\WString.cpp line 158
    0x400eade9: String::copy(char const*, unsigned int) at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\cores\esp32\WString.cpp line 195
    0x400eae23: String::String(char const*) at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\cores\esp32\WString.cpp line 39
    0x400d8dfa: Timezone::dateTime(long, ezLocalOrUTC_t, String) at C:\Arduino-1.8.7\portable\sketchbook\libraries\ezTime\src\ezTime.cpp line 1164
    0x400d9622: Timezone::dateTime(long, String) at C:\Arduino-1.8.7\portable\sketchbook\libraries\ezTime\src\ezTime.cpp line 1154
    0x400d9801: Timezone::dateTime(String) at C:\Arduino-1.8.7\portable\sketchbook\libraries\ezTime\src\ezTime.cpp line 1150
    0x400e1eb3: ezClock::draw(unsigned short, unsigned short) at C:\Arduino-1.8.7\portable\sketchbook\libraries\M5ez\src\M5ez.cpp line 973
    0x400de59d: ezHeader::show(String) at C:\Arduino-1.8.7\portable\sketchbook\libraries\M5ez\src\M5ez.cpp line 184
    0x400d2307: remDisplayPage1() at Z:\_PVControl\M5remDisplay/M5remDisplay.ino line 164
    0x400d26ba: remDisplay() at Z:\_PVControl\M5remDisplay/M5remDisplay.ino line 152
    0x400d2c13: handleRoot() at Z:\_PVControl\M5remDisplay/M5remDisplay.ino line 103
    0x4017b6c1: std::_Function_handler ::_M_invoke(std::_Any_data const&) at c:\arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\tools\xtensa-esp32-elf\xtensa-esp32-elf\include\c++\5.2.0/functional line 1871
    0x400d5ee2: std::function ::operator()() const at c:\arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\tools\xtensa-esp32-elf\xtensa-esp32-elf\include\c++\5.2.0/functional line 2271
    0x400e9bdd: FunctionRequestHandler::handle(WebServer&, HTTPMethod, String) at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\libraries\WebServer\src\detail/RequestHandlersImpl.h line 42
    0x400e9c2a: WebServer::_handleRequest() at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\libraries\WebServer\src\WebServer.cpp line 617
    0x400e9d86: WebServer::handleClient() at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\libraries\WebServer\src\WebServer.cpp line 320
    0x400d3a44: serveClients() at Z:\_PVControl\M5remDisplay/M5remDisplay.ino line 64
    0x400dbb68: M5ez::yield() at C:\Arduino-1.8.7\portable\sketchbook\libraries\M5ez\src\M5ez.cpp line 1736
    0x400dbbb4: ezButtons::poll() at C:\Arduino-1.8.7\portable\sketchbook\libraries\M5ez\src\M5ez.cpp line 612
    0x400d26c2: remDisplay() at Z:\_PVControl\M5remDisplay/M5remDisplay.ino line 154
    0x400d2c13: handleRoot() at Z:\_PVControl\M5remDisplay/M5remDisplay.ino line 103
    0x4017b6c1: std::_Function_handler ::_M_invoke(std::_Any_data const&) at c:\arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\tools\xtensa-esp32-elf\xtensa-esp32-elf\include\c++\5.2.0/functional line 1871
    0x400d5ee2: std::function ::operator()() const at c:\arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\tools\xtensa-esp32-elf\xtensa-esp32-elf\include\c++\5.2.0/functional line 2271
    0x400e9bdd: FunctionRequestHandler::handle(WebServer&, HTTPMethod, String) at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\libraries\WebServer\src\detail/RequestHandlersImpl.h line 42
    0x400e9c2a: WebServer::_handleRequest() at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\libraries\WebServer\src\WebServer.cpp line 617
    0x400e9d86: WebServer::handleClient() at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\libraries\WebServer\src\WebServer.cpp line 320
    0x400d3a44: serveClients() at Z:\_PVControl\M5remDisplay/M5remDisplay.ino line 64
    0x400dbb68: M5ez::yield() at C:\Arduino-1.8.7\portable\sketchbook\libraries\M5ez\src\M5ez.cpp line 1736
    0x400dbbb4: ezButtons::poll() at C:\Arduino-1.8.7\portable\sketchbook\libraries\M5ez\src\M5ez.cpp line 612
    0x400d26c2: remDisplay() at Z:\_PVControl\M5remDisplay/M5remDisplay.ino line 154
    0x400d2c13: handleRoot() at Z:\_PVControl\M5remDisplay/M5remDisplay.ino line 103
    0x4017b6c1: std::_Function_handler ::_M_invoke(std::_Any_data const&) at c:\arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\tools\xtensa-esp32-elf\xtensa-esp32-elf\include\c++\5.2.0/functional line 1871
    0x400d5ee2: std::function ::operator()() const at c:\arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\tools\xtensa-esp32-elf\xtensa-esp32-elf\include\c++\5.2.0/functional line 2271
    0x400e9bdd: FunctionRequestHandler::handle(WebServer&, HTTPMethod, String) at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\libraries\WebServer\src\detail/RequestHandlersImpl.h line 42
    0x400e9c2a: WebServer::_handleRequest() at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\libraries\WebServer\src\WebServer.cpp line 617
    0x400e9d86: WebServer::handleClient() at C:\Arduino-1.8.7\portable\sketchbook\hardware\espressif\esp32\libraries\WebServer\src\WebServer.cpp line 320
    0x400d3a44: serveClients() at Z:\_PVControl\M5remDisplay/M5remDisplay.ino line 64
    0x400dbb68: M5ez::yield() at C:\Arduino-1.8.7\portable\sketchbook\libraries\M5ez\src\M5ez.cpp line 1736
    0x400dbbb4: ezButtons::poll() at C:\Arduino-1.8.7\portable\sketchbook\libraries\M5ez\src\M5ez.cpp line 612
    0x400d26c2: remDisplay() at Z:\_PVControl\M5remDisplay/M5remDisplay.ino line 154
    


  • @crazyhorse80 Looks like it somehow crashed while M5ez was printing the on-screen clock, but no clue why. Try turning off the on-screen clock... Shouldn't do this no matter what though.



  • I need the clock... :( I have that same error every 5 / 7 minutes, it restarts and works for a few minutes again and so on...
    Maybe I can do some test without the clock to see if it is the cause of the problem...



  • @crazyhorse80 Maybe show the whole code you're running now?



  • @rop Here's what my full code looks like at the moment:

    #include <M5Stack.h>
    #include <ezTime.h>
    #include <M5ez.h>
    
    #include <WiFi.h>
    #include <WiFiClient.h>
    #include <WebServer.h>
    #include <ESPmDNS.h>
    
    #include "images.h"
    
    #define MAIN_DECLARED
    
    WebServer rDserver(1980);
    
    byte   remYear = 0;           // Current PVControl server Year
    byte   remMonth = 0;          // Current PVControl server Month
    byte   remDay = 0;            // Current PVControl server Day
    byte   remHour = 0;           // Current PVControl server Hour
    byte   remMinute = 0;         // Current PVControl server Minute
    float  GenE = 0;              // Last Generated Energy
    float  UseE = 0;              // Last Consumed Energy
    float  TtGE = 0;              // Last to the Grid Energy
    float  FtGE = 0;              // Last from the Grid Energy
    int    GenP = 0;              // Last Generated Power
    int    UseP = 0;              // Last Consumed Power
    int    NetP = 0;              // Last Net Power
    
    void setup() {
      #include <themes/default.h>
      #include <themes/dark.h>
      ezt::setDebug(NONE);
      ez.begin();
      if (ez.wifi.indexForSSID("xxx") == -1) {
        ez.wifi.add("xxx", "xxx");
        ez.wifi.writeFlash();
      }
    
      MDNS.begin("remdisplay1");
    
      rDserver.on("/", handleRoot);
      rDserver.onNotFound(handleNotFound);
      rDserver.begin();
      
      dacWrite(25,0); // Speaker mute
    
      ez.addEvent(serveClients, 3000);
    
      ezMenu mainmenu("remDisplay");
      //  mainmenu.txtSmall();
      mainmenu.addItem("PVControl", remDisplay);
      mainmenu.addItem("Settings", mainmenu_image);
      //  mainmenu.addItem("Updates via https", mainmenu_ota);
      mainmenu.upOnFirst("last|up");
      mainmenu.downOnLast("first|down");
      mainmenu.run();
    }
    
    void loop() {
      
    }
    
    uint16_t serveClients() {
      rDserver.handleClient();
      return 50;
    }
    
    void handleRoot() {
      for (uint8_t i = 0; i < rDserver.headers(); i++) { //debug only
        Serial.print(" ");
        Serial.print(rDserver.headerName(i));
        Serial.print(": ");
        Serial.println(rDserver.header(i));
      }
      for (uint8_t i = 0; i < rDserver.args(); i++) { //debug only
        Serial.print(" ");
        Serial.print(rDserver.argName(i));
        Serial.print(": ");
        Serial.println(rDserver.arg(i));
      }
    
      if(rDserver.args() == 7) {
          if((rDserver.argName(0) != "r") || (rDserver.argName(1) != "da")
            || (rDserver.argName(2) != "ti") || (rDserver.argName(3) != "v1")
              || (rDserver.argName(4) != "v2") || (rDserver.argName(5) != "v3")
                || (rDserver.argName(6) != "v4")) {
            rDserver.send(400, "text/plain", " Bad Request");
            return;
          }
          else {
            rDserver.send(200, "text/plain", " OK");
    
            remYear = atoi(rDserver.arg(1).substring(0,3).c_str());
            remMonth = atoi(rDserver.arg(1).substring(4,5).c_str());
            remDay = atoi(rDserver.arg(1).substring(6,7).c_str());
            remHour = atoi(rDserver.arg(2).substring(0,1).c_str());
            remMinute = atoi(rDserver.arg(2).substring(2,3).c_str());
            GenE = atoi(rDserver.arg(3).c_str());
            GenP = atoi(rDserver.arg(4).c_str());
            UseE = atoi(rDserver.arg(5).c_str());
            UseP = atoi(rDserver.arg(6).c_str());
            NetP = GenP - UseP;    // Last Net Power
            remDisplay();
          }
      }
      else {
        rDserver.send(400, "text/plain", " Bad Request");
        return;
      }
    }
    
    void handleNotFound() {
      String message = "File Not Found\n\n";
      message += "URI: ";
      message += rDserver.uri();
      message += "\nMethod: ";
      message += (rDserver.method() == HTTP_GET) ? "GET" : "POST";
      message += "\nArguments: ";
      message += rDserver.args();
      message += "\n";
      for (uint8_t i = 0; i < rDserver.args(); i++) {
        message += " " + rDserver.argName(i) + ": " + rDserver.arg(i) + "\n";
      }
      rDserver.send(404, "text/plain", message);
    }
    
    void mainmenu_image() {
      ezMenu images;
      images.imgBackground(TFT_BLACK);
      images.imgFromTop(40);
      images.imgCaptionColor(TFT_WHITE);
      images.addItem(sysinfo_jpg, "System Information", sysInfo);
      images.addItem(wifi_jpg, "Built-in wifi & other settings", ez.settings.menu);
      images.addItem(wifi_jpg, "WiFi Settings", ez.wifi.menu);
      images.addItem(about_jpg, "About remDisplay", about);
      images.addItem(sleep_jpg, "Power Off", powerOff);
      images.addItem(return_jpg, "Back");
      images.run();
    }
    
    void powerOff() {
      m5.powerOFF();
    }
    
    void about() {
      ez.msgBox("About remDisplay", "");
    }
    
    String exit_buttonrD = "Exit";
    
    void remDisplay() {
      remDisplayPage1();
      while (true) {
        String btn = ez.buttons.poll();
        if (btn == "up") remDisplayPage1();
        if (btn == "down") remDisplayPage2();
        if (btn == "Exit") break;
      }
    }
    
    void remDisplayPage1() {
      const byte tab = 120;
      ez.screen.clear();
      ez.header.show("PVControl  (1/2)");
      ez.buttons.show("#" + exit_buttonrD + "#down");
      ez.canvas.font(&FreeSans9pt7b);
      ez.canvas.lmargin(10);
      ez.canvas.println("");
      ez.canvas.print("Produzione:");
      ez.canvas.x(tab);ez.canvas.print(GenP); ez.canvas.println(" W");
      ez.canvas.x(tab); ez.canvas.print(GenE / 1000); ez.canvas.println(" kWh");
      ez.canvas.print("Consumo:");
      ez.canvas.x(tab); ez.canvas.print(UseP); ez.canvas.println(" W");
      ez.canvas.x(tab); ez.canvas.print(UseE / 1000); ez.canvas.println(" kWh");
      ez.canvas.print("Immissione:");
      ez.canvas.x(tab);
      if(NetP > 0)
        ez.canvas.print(NetP);
      else
        ez.canvas.print("0");
      ez.canvas.println(" W");
      ez.canvas.x(tab); ez.canvas.println(" kWh");
      ez.canvas.print("Prelievo:");
      ez.canvas.x(tab);
      if(NetP < 0)
        ez.canvas.print(abs(NetP));
      else
        ez.canvas.print("0");
      ez.canvas.println(" W");
      ez.canvas.x(tab); ez.canvas.println(" kWh");
    }
    
    void remDisplayPage2() {
      const byte tab = 140;
      ez.screen.clear();
      ez.header.show("PVControl  (2/2)");
      ez.buttons.show("up#" + exit_buttonrD + "#");
      ez.canvas.font(&FreeSans9pt7b);
      ez.canvas.lmargin(10);
      ez.canvas.println("");
      ez.canvas.print("Free RAM:");  ez.canvas.x(tab);  ez.canvas.println(String((long)ESP.getFreeHeap()) + " bytes");
      ez.canvas.print("Min. free seen:");  ez.canvas.x(tab); ez.canvas.println(String((long)esp_get_minimum_free_heap_size()) + " bytes");
    }
    

    It's only a part of what I want to achieve and here I'll try to explain what my project should do when it'll be complete:
    every minute my M5Stack will receive from another Arduino board an HTTP GET request with data and it stores them in global variables and eventually does some operation with them;
    it should have a multi-page view to show data received and stored in variables (one displays data in numeric form, another will display them in graphs, another one will only change screen background color and make some noise based on data received, and maybe some more);
    it also should have access to the menus to change wi-fi and screen preferences and some more options related to my program (sound volume, default page to display on startup and so on).
    I'd also like to have some more widgets:
    one will have to show me if data received is older than one minute (it means I've lost connection with the Arduino board);
    another one will have to show the current energy billing band based on what time and day of week it is.
    The problem with M5ez, and ESP32 in general, is that I've no clue of where to put my code: do I have to do all in loop() function? Or should I register various functions with ez.addEvent()? Or should I do it some other way? I'm a bit confused... Can you show me a proof of concept application using M5ez (even if not related to my needs, so I could understand how it works)?



  • @crazyhorse80I need help with a webserver project... 中说:

    It's only a part of what I want to achieve and here I'll try to explain what my project should do when it'll be complete:

    • every minute my M5Stack will receive from another Arduino board an HTTP GET request with data and it stores them in global variables and eventually does some operation with them;
    • it should have a multi-page view to show data received and stored in variables (one displays data in numeric form, another will display them in graphs, another one will only change screen background color and make some noise based on data received, and maybe some more);
    • it also should have access to the menus to change wi-fi and screen preferences and some more options related to my program (sound volume, default page to display on startup and so on).
      I'd also like to have some more widgets:
    • one will have to show me if data received is older than one minute (it means I've lost connection with the Arduino board);
      another one will have to show the current energy billing band based on what time and day of week it is.

    The problem with M5ez, and ESP32 in general, is that I've no clue of where to put my code: do I have to do all in loop() function? Or should I register various functions with ez.addEvent()? Or should I do it some other way? I'm a bit confused... Can you show me a proof of concept application using M5ez (even if not related to my needs, so I could understand how it works)?

    Zooming out and looking at your propject:

    • Have you considered using mqtt ? I'm no expert, but it seems built for jobs that involve getting values from A to B, figuring out if the sending side is still there, etc etc. All sorts of Arduino libraries for sending and receiving end.

    • How to switch between functionality that runs concurrently is always an issue, and there are often more ways to accomplish the same thing. So don't worry too much if it seems hard now. It gets easier to wrap one's head around the program flow with experience, and it sucks in the beginning.

    Specifically for this project:

    • To make widgets, after reading the user manual it's probably best to study the clock-related code in M5ez.cpp to see how it does its widget things.

    • All web handling is done by the webserver code which you have placed in M5ez's main loop with ez.addEvent. The difference between placing code there and placing it in your sketch's loop() function is that loop() is not called when M5ez is waiting for input (like in menus, msgBox, etc etc).

    • There is a way to add your own items to the M5ez settings menu. It's in the manual, but again: also look at how it's done inside M5ez.cpp, for example with the clock code.

     

    Good luck!



  • Thanks for your help, I'll try to follow your directions in the following days.


登录后回复
 

与 M5Stack Community 的连接断开,我们正在尝试重连,请耐心等待