I need help with a webserver project...
-
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)? -
@crazyhorse80 在 I 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'sloop()
function is thatloop()
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.