diff --git a/esp32cam-demo.ino b/esp32cam-demo.ino index 6a575e1..c4668d6 100644 --- a/esp32cam-demo.ino +++ b/esp32cam-demo.ino @@ -84,7 +84,7 @@ void readRGBImage(); bool getNTPtime(int sec); void handleStream(); - String requestWebPage(String ip, String page, int port, int maxChars, String cuttoffText); + int requestWebPage(String*, String*, int); void handleTest(); void brightLed(byte ledBrightness); void MessageRGB(WiFiClient &client, String theText); @@ -95,7 +95,7 @@ // --------------------------------------------------------------- const char* stitle = "ESP32Cam-demo"; // title of this sketch - const char* sversion = "21Nov21"; // Sketch version + const char* sversion = "29dec21"; // Sketch version bool sendRGBfile = 0; // if set '/rgb' will send the rgb data as a file rather than display some on a HTML page @@ -1157,88 +1157,420 @@ void handleStream(){ // ---------------------------------------------------------------- -// request a web page +// +// +// ESP32 / ESp8266 very basic web server demo - 29Dec21 +// for Arduino IDE or PlatformIO +// +// shows use of AJAX to show updating info on the web page +// +// https://github.com/alanesq/BasicWebserver/blob/master/misc/VeryBasicWebserver.ino +// +// // ---------------------------------------------------------------- -// @param ip ip address -// @param page web page to request -// @param port ip port to use (usually 80) -// @param maxChars maximum number of chars to receive -// @param cuttoffText ignore all in reply before this text -// @return the reply as a string -// Example usage: requestWebPage("192.168.1.166", "/log", 80, 600, ""); -String requestWebPage(String ip, String page, int port, int maxChars, String cuttoffText = ""){ - uint32_t maxWaitTime = 3000; // max time to wait for reply (ms) +// --------------------------------------------------------------------------------------------------------- - char received[maxChars + 1]; // temp store for incoming character data - int received_counter = 0; // counter of number of characters which have been received +// Wifi Settings - if (!page.startsWith("/")) page = "/" + page; // make sure page begins with "/" +#include // delete this line, un-comment the below two lines and enter your wifi details - if (serialDebug) { - Serial.print("requesting web page: "); - Serial.print(ip); - Serial.println(page); - } +//const char *SSID = "your_wifi_ssid"; - WiFiClient client; +//const char *PWD = "your_wifi_pwd"; - // Connect to the site - if (!client.connect(ip.c_str() , port)) { - if (serialDebug) Serial.println("Web client connection failed"); - return "web client connection failed"; - } - if (serialDebug) Serial.println("Connected to host - sending request..."); - // send request - A basic request looks something like: "GET /index.html HTTP/1.1\r\nHost: 192.168.0.4:8085\r\n\r\n" - client.println("GET " + page + " HTTP/1.1 "); - client.println("Host: " + ip ); - client.println("User-Agent: arduino-ethernet"); - client.println("Connection: close"); - client.println(); // needed to end HTTP header +// --------------------------------------------------------------------------------------------------------- - if (serialDebug) Serial.println("Request sent - waiting for reply..."); - // Wait for a response - uint32_t ttimer = millis(); - while ( client.connected() && !client.available() && (uint32_t)(millis() - ttimer) < maxWaitTime ) { - delay(10); - } - if ( ((uint32_t)(millis() - ttimer) > maxWaitTime ) && serialDebug) Serial.println("-Timed out"); +#include // required by platformIO +bool serialDebug = 1; // enable debugging info on serial port - // read the response - while ( client.connected() && client.available() && received_counter < maxChars ) { - delay(4); - received[received_counter] = char(client.read()); // read one character - received_counter+=1; - } - received[received_counter] = '\0'; // end of string marker - if (serialDebug) { - Serial.println("--------received web page-----------"); - Serial.println(received); - Serial.println("------------------------------------"); - Serial.flush(); // wait for serial data to finish sending +// forward declarations (required by PlatformIO) + //String requestWebPage(String ip, String page, int port, int maxChars, String cuttoffText = ""); + void handleRoot(); + void handleTest(); + void handleButton(); + void handleAJAX(); + void handleSendData(); + void handleLED(); + void handleNotFound(); + int requestWebPage(String*, String*, int); + + +// ---------------------------------------------------------------- + + +//#include // required by platformio? + +#if defined ESP32 + // esp32 + byte LEDpin = 2; + #include + #include + #include + WebServer server(80); +#elif defined ESP8266 + //Esp8266 + byte LEDpin = D4; + #include + #include + #include "ESP8266HTTPClient.h" + ESP8266WebServer server(80); +#else + #error "This sketch only works with the ESP8266 or ESP32" +#endif + + +// ---------------------------------------------------------------- + + +// this section runs once at startup + + +void setup() { + + Serial.begin(115200); // start serial comms at speed 115200 + delay(200); + Serial.println("\n\nWebserver demo sketch"); + //Serial.println("- Reset reason: " + ESP.getResetReason()); + + // onboard LEDs + pinMode(LEDpin, OUTPUT); + digitalWrite(LEDpin, HIGH); + + // Connect to Wifi + Serial.print("Connecting to "); + Serial.println(SSID); + WiFi.begin(SSID, PWD); + while (WiFi.status() != WL_CONNECTED) { + Serial.print("."); + delay(500); + } + Serial.print("\nConnected - IP: "); + Serial.println(WiFi.localIP()); + + // set up web server pages to serve + server.on("/", handleRoot); // root web page (i.e. when root page is requested run procedure 'handleroot') + server.on("/test", handleTest); // test web page + server.on("/button", handleButton); // demo simple use of buttons + server.on("/ajax", handleAJAX); // demo using AJAX to update information on the page (also javascript buttons) + server.on("/senddata", handleSendData); // requested by the AJAX web page to request current millis value + server.on("/setLED", handleLED); // action when a button is clicked on the AJAX page + server.onNotFound(handleNotFound); // if invalid url is requested + + // start web server + server.begin(); + + // stop the wifi being turned off if not used for a while + #if defined ESP32 + WiFi.setSleep(false); + #else + WiFi.setSleepMode(WIFI_NONE_SLEEP); + #endif + + WiFi.mode(WIFI_STA); // turn off access point - options are WIFI_AP, WIFI_STA, WIFI_AP_STA or WIFI_OFF + +} // setup + + + +// ---------------------------------------------------------------- + + +// this section runs repeatedly in a loop + + +void loop() { + + server.handleClient(); // service any web page requests + + //// flash onboard LED + //digitalWrite(LEDpin, !digitalRead(LEDpin)); // invert onboard LED status + //delay(200); // wait 200 milliseconds + + #if defined(ESP8266) + yield(); // allow esp8266 to carry out wifi tasks (may restart randomly without this) + #endif + +} // loop + + + +// ---------------------------------------------------------------- +// -test web page requested i.e. http://x.x.x.x/ +// ---------------------------------------------------------------- +// demonstrate sending a plain text reply + +void handleRoot(){ + + if (serialDebug) Serial.println("Root page requested"); + + String message = "root web page"; + + server.send(404, "text/plain", message); // send reply as plain text + +} // handleRoot + + + +// ---------------------------------------------------------------- +// -test web page requested i.e. http://x.x.x.x/test +// ---------------------------------------------------------------- +// demonstrate sending html reply + +void handleTest(){ + + if (serialDebug) Serial.println("Test page requested"); + + WiFiClient client = server.client(); // open link with client + + // html header + client.print(" Web Demo \n"); // basic html header + + // html body + client.print("

Test Page

\n"); + + // end html + client.print("\n"); + delay(3); + client.stop(); + +} // handleTest + + + +// ---------------------------------------------------------------- +// -button web page requested i.e. http://x.x.x.x/button +// ---------------------------------------------------------------- +// demonstrate simple use of a html buttons without using Javascript + +void handleButton(){ + + if (serialDebug) Serial.println("Button page requested"); + + // check if button1 has been pressed + if (server.hasArg("button1")) { + Serial.println("Button 1 was pressed"); } - client.stop(); // close connection - if (serialDebug) Serial.println("Connection closed"); + // check if button2 has been pressed + if (server.hasArg("button2")) { + Serial.println("Button 2 was pressed"); + } - // if cuttoffText was supplied then only return the text following this - if (cuttoffText != "") { - char* locus = strstr(received,cuttoffText.c_str()); // locus = pointer to the found text - if (locus) { // if text was found - if (serialDebug) Serial.println("The text '" + cuttoffText + "' was found in reply"); - return locus; // return the reply text following 'cuttoffText' - } else if (serialDebug) Serial.println("The text '" + cuttoffText + "' WAS NOT found in reply"); - } - return received; // return the full reply text + // send reply to client + + WiFiClient client = server.client(); // open link with client + + // html header + client.print(" Web Demo \n"); // basic html header + client.print("
\n"); // used by the buttons in the html (action = the web page to send it to + + // html body + client.print("

Button demo page

\n"); + if (server.hasArg("button1")) client.print("Button 1 has been pressed!"); + if (server.hasArg("button2")) client.print("Button 2 has been pressed!"); + client.print("

\n"); + client.print("

\n"); + + // end html + client.print("\n"); + delay(3); + client.stop(); + +} // handleButton + + +// ---------------------------------------------------------------- +// -ajax web page requested i.e. http://x.x.x.x/ajax +// ---------------------------------------------------------------- +// demonstrate use of AJAX to refresh info. on web page +// see: https://circuits4you.com/2018/02/04/esp8266-ajax-update-part-of-web-page-without-refreshing/ +// to store html in program memory to save ram use command: const char index_html[] PROGMEM = R"rawliteral( )rawliteral"; + +void handleAJAX() { + + WiFiClient client = server.client(); // open link with client + + // log page request including clients IP address + IPAddress cip = client.remoteIP(); + Serial.println("Ajax page requested from: " + String(cip[0]) +"." + String(cip[1]) + "." + String(cip[2]) + "." + String(cip[3]) ); + + + // ---------------------- html ---------------------- + + client.print (R"=====( + + + + + AJAX Demo + + + +
+

Update web page using AJAX

+ +
+
+
+ Current Millis : 0
+ Received text : NA
+ LED State is : NA
+
+ + )====="); + + // ------------------- JavaScript ------------------- + + client.print (R"=====()====="); + // -------------------------------------------------- + + // close html page + client.print("\n"); // close HTML + delay(3); + client.stop(); + +} // handleAJAX + + +// send data to AJAX web page +// it replies with two items comma separated: the value in millis and some text +void handleSendData() { + String reply = String(millis()); // item 1 + reply += ","; + reply += "This text sent by handleSendtime()"; // item 2 + server.send(200, "text/plane", reply); //Send millis value only to client ajax request +} + + +// handle button clicks on AJAX web page +// it sets the onboard LED status and replies with it's status as plain text +void handleLED() { + String ledState = "OFF"; + String t_state = server.arg("LEDstate"); //Refer xhttp.open("GET", "setLED?LEDstate="+led, true); + Serial.println(t_state); + if(t_state == "1") { + digitalWrite(LEDpin,LOW); //LED ON + ledState = "ON"; //Feedback parameter + } else { + digitalWrite(LEDpin,HIGH); //LED OFF + ledState = "OFF"; //Feedback parameter + } + server.send(200, "text/plane", ledState); //Send web page +} + + +// ---------------------------------------------------------------- +// -invalid web page requested +// ---------------------------------------------------------------- +// send this reply to any invalid url requested + +void handleNotFound() { + + if (serialDebug) Serial.println("Invalid page requested"); + + String tReply; + + tReply = "File Not Found\n\n"; + tReply += "URI: "; + tReply += server.uri(); + tReply += "\nMethod: "; + tReply += ( server.method() == HTTP_GET ) ? "GET" : "POST"; + tReply += "\nArguments: "; + tReply += server.args(); + tReply += "\n"; + + for ( uint8_t i = 0; i < server.args(); i++ ) { + tReply += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n"; + } + + server.send ( 404, "text/plain", tReply ); + tReply = ""; // clear variable + +} // handleNotFound + + + +// ---------------------------------------------------------------------------------------------------------------- + + +// Not used in this sketch but provided as an example of how to request an external web page and receive the reply as a string + + +// ---------------------------------------------------------------- +// request a web page +// ---------------------------------------------------------------- +// @param page web page to request +// @param received String to store response in +// @param maxWaitTime maximum time to wait for reply (ms) +// @returns http code +// see: https://randomnerdtutorials.com/esp32-http-get-post-arduino/#http-get-1 +// to do: limit size of reply + +int requestWebPage(String* page, String* received, int maxWaitTime=5000){ + + if (serialDebug) Serial.println("requesting web page: " + *page); + + WiFiClient client; + HTTPClient http; // see: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266HTTPClient + http.setTimeout(maxWaitTime); + http.begin(client, *page); // for https requires (client, *page, thumbprint) e.g.String thumbprint="08:3B:71:72:02:43:6E:CA:ED:42:86:93:BA:7E:DF:81:C4:BC:62:30"; + int httpCode = http.GET(); // http codes: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes + if (serialDebug) Serial.println("http code: " + String(httpCode)); + + if (httpCode > 0) { + *received = http.getString(); + } else { + *received = "error:" + String(httpCode); + } + if (serialDebug) Serial.println(*received); + + http.end(); //Close connection + if (serialDebug) Serial.println("Web connection closed"); + + return httpCode; } // requestWebPage +// ---------------------------------------------------------------- +// end + + + // ******************************************************************************************************************