Last active
May 12, 2024 18:16
-
-
Save mikbuch/a5c7492fc6c29956c5755683ea23d35b to your computer and use it in GitHub Desktop.
ESP8266 web server receiving GET requests and sending POST request, also sending information as a JSON to the serial port
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This script is avilable as a gist: | |
// https://gist.github.com/mikbuch/a5c7492fc6c29956c5755683ea23d35b | |
// ESP8266 web server receiving GET requests and sending POST request, | |
// but also sending information as a JSON to the serial port | |
// For a different example, focused on network communication, see: | |
// * "ESP8266_WebServerAndClient.ino" (https://gist.github.com/mikbuch/59753429f721f4a93d9592b9f21484c9) | |
/* Requirements: | |
* I. "esp8266" board installed. | |
* II. "arduino-timer" by Michael Contreras installed (https://github.com/contrem/arduino-timer, https://www.arduino.cc/reference/en/libraries/arduino-timer/) | |
* | |
* I. Installing WeMos ESP Board: | |
* 1. File -> Preferences | |
* 2. In "Additional Board Manager URLs" (at the bottom), paste the following link: | |
* http://arduino.esp8266.com/stable/package_esp8266com_index.json | |
* 3. Tools -> Board -> Board Managers | |
* 4. Type in the search: "esp" | |
* 5. Install the community package "esp8266" (It also includes "Wemos" boards; "LOLIN") | |
* | |
* Then you set the board as: | |
* * Tools -> Boards -> ESP8266 Boards -> WEMOS D1 R1 mini | |
* | |
* Source, with screenshots (in Polish): https://blog.elektroweb.pl/jak-programowac-wemos-d1-w-srodowisku-arduino-ide/ | |
*/ | |
/* Connection status codes ("WiFi.status()"): | |
* 0 : WL_IDLE_STATUS when Wi-Fi is in process of changing between statuses | |
* 1 : WL_NO_SSID_AVAILin case configured SSID cannot be reached | |
* 3 : WL_CONNECTED after successful connection is established | |
* 4 : WL_CONNECT_FAILED if connection failed | |
* 6 : WL_CONNECT_WRONG_PASSWORD if password is incorrect | |
* 7 : WL_DISCONNECTED if module is not configured in station mode | |
* | |
* Source: https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/readme.html#diagnostics | |
*/ | |
/* | |
* Receiving GET requests: | |
* * / (root) -- basic information | |
* * /status -- is the LED diode turned on or off | |
* * /switch -- turn the LED on or off (switch its state) | |
* | |
* Sending POST requests, with plain text JSON in its body. | |
* | |
* Caution: to see your POST requests in the browser go to: | |
* -> http://ptsv3.com/t/tdi0k-1641503634/ | |
* | |
* Alternatively you can look this page up in the following way: | |
* -> Go to: http://ptsv3.com/ | |
* -> Copy-paste the following string in the input field: "tdi0k-1641503634" | |
* -> Click "Look up*" | |
* | |
* See also this StackOverflow answer: https://stackoverflow.com/a/7194919 | |
* | |
* Sources & references (on the client): | |
* - https://randomnerdtutorials.com/esp8266-nodemcu-http-get-post-arduino/#http-get-2 | |
* - https://techtutorialsx.com/2016/07/21/esp8266-post-requests/ | |
* | |
*/ | |
/* Instructon on how to use this example on the client side. | |
* | |
* The client side means that you will be sending requests | |
* to the server hosted at ESP8266, and you will be receiving | |
* requests. | |
* | |
* Use a root request (e.g., http://192.168.0.22/), or either of | |
* the two endpoints: | |
* (1) /switch (to switch diode), or | |
* (2) /status (to get the info about diode status: on or off). | |
* For example: http://192.168.0.22/status | |
* ---------------------------------------------------------------------- | |
* | |
*/ | |
#include <ESP8266WiFi.h> | |
#include <ESP8266WiFiMulti.h> | |
#include <WiFiClient.h> | |
#include <ESP8266HTTPClient.h> | |
#include <ESP8266WebServer.h> | |
#include <ESP8266mDNS.h> | |
#include <arduino-timer.h> | |
/* SSID is the name of your WiFi network, e.g.: "linksys", or "ab8402932". | |
* You have to set the variable STASSID below. | |
* -- | |
* STAPSK is the password you your WiFi (WLAN) network, i.e., the password | |
* to your router. This variable has to be set as well. | |
* | |
* To sum up, the 4 lines below this block comment should look shomehow | |
* like that: | |
* | |
* #ifndef STASSID | |
* #define STASSID "linksys" | |
* #define STAPSK "@sdjj2325k^#asd" | |
* #endif | |
*/ | |
#ifndef STASSID | |
#define STASSID "<your_WiFi_SSID>" | |
#define STAPSK "<your_WiFi_password>" | |
#endif | |
/* URL to send POST requests, with plain text JSON in its body. | |
* Caution: create your own POST URL here: http://ptsv3.com/ | |
* -> "New random toilet" | |
* See also: https://stackoverflow.com/a/7194919 | |
*/ | |
const char* url = "http://ptsv3.com/t/tdi0k-1641503634/post/"; | |
const char* ssid = STASSID; | |
const char* password = STAPSK; | |
ESP8266WebServer server(80); | |
ESP8266WiFiMulti WiFiMulti; | |
int led_status = 0; | |
// Create a request timer with default settings. | |
// It will be configured in the "setup", and run | |
// <<ticked>> in the "loop" section. | |
auto requestTimer = timer_create_default(); | |
/**************************** | |
* Functions definition * | |
****************************/ | |
void handleRoot() { | |
Serial.println("Received a root (`/`) request."); | |
Serial.println("LED status is: " + String(led_status)); | |
Serial.println("----------------------------"); | |
// Server response | |
String message = "Use either of the two endpoints:\n"; | |
message += " (1) /switch (to switch diode)\n"; | |
message += " (2) /status (to get the info about diode status: on or off)\n"; | |
message += "For example: 192.168.0.22/status\n"; | |
message += "----------------------------\n"; | |
message += "LED status is now: " + String(led_status) + "\n"; | |
message += "----------------------------"; | |
server.send(200, "text/plain", message); | |
} | |
void handleLedSwitch() { | |
Serial.println("Received a `switch` request."); | |
if (led_status == 0) { | |
digitalWrite(LED_BUILTIN, LOW); | |
led_status = 1; | |
} else { | |
digitalWrite(LED_BUILTIN, HIGH); | |
led_status = 0; | |
} | |
Serial.println("LED status is: " + String(led_status)); | |
// Send a JSON message to the Serial output | |
Serial.println("{'channel1':'" + String(led_status) +"'}"); | |
Serial.println("----------------------------"); | |
// Server response | |
String message = "Switched LED!\n\n"; | |
message += "Now status of the diode is: "; | |
message += String(led_status); | |
server.send(200, "text/plain", message); | |
} | |
void handleLedStatus() { | |
Serial.println("Received a `status` request."); | |
Serial.println("LED status is: " + String(led_status)); | |
Serial.println("----------------------------"); | |
// Server response | |
String message = "Status of the LED is: "; | |
message += String(led_status); | |
server.send(200, "text/plain", message); | |
} | |
void handleNotFound() { | |
digitalWrite(LED_BUILTIN, LOW); | |
String message = "File Not Found\n\n"; | |
message += "URI: "; | |
message += server.uri(); | |
message += "\nMethod: "; | |
message += (server.method() == HTTP_GET) ? "GET" : "POST"; | |
message += "\nArguments: "; | |
message += server.args(); | |
message += "\n"; | |
for (uint8_t i = 0; i < server.args(); i++) { | |
message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; | |
} | |
server.send(404, "text/plain", message); | |
digitalWrite(LED_BUILTIN, HIGH); | |
} | |
/******************************* | |
* * | |
* WiFi Client * | |
* * | |
* Sending a periodic report * | |
* * | |
*******************************/ | |
// Timers has to be "bool" type: | |
// if "true" is returned it means: "keep the timer alive" | |
bool sendRequest(void *) { | |
// Run only when there is a WiFi connection. | |
if ((WiFiMulti.run() == WL_CONNECTED)) { | |
WiFiClient client; | |
HTTPClient http; | |
Serial.print("\n\n\n"); | |
Serial.print("============================\n"); | |
// Display local IP address of the board, in case the initial | |
// information (during connecting to the WiFi) was missed. | |
Serial.print("IP address: "); | |
Serial.println(WiFi.localIP()); | |
Serial.print("[HTTP] begin...\n"); | |
// HTTP request start | |
if (http.begin(client, url)) { | |
//Specify content-type header | |
http.addHeader("Content-Type", "text/plain"); | |
Serial.print("[HTTP] POST...\n"); | |
// Start connection and send HTTP header | |
int httpCode = http.POST("{'temp1':'50', 'temp2':'53'}"); | |
// httpCode will be negative on error | |
if (httpCode > 0) { | |
// HTTP header has been send and Server response header has been handled | |
Serial.printf("[HTTP] POST... code: %d\n", httpCode); | |
// file found at server | |
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { | |
String payload = http.getString(); | |
Serial.println(payload); | |
} | |
} else { | |
Serial.printf("[HTTP] POST... failed, error: %s\n", http.errorToString(httpCode).c_str()); | |
} | |
http.end(); | |
} else { | |
Serial.printf("[HTTP] Unable to connect\n"); | |
} | |
Serial.print("============================\n"); | |
} | |
// Keep timer active? true | |
return true; | |
} | |
/* ======================================= | |
* | |
* SETUP | |
* | |
* ======================================= | |
*/ | |
void setup(void) { | |
// Reset the serial monitor at the beginning. | |
Serial.flush(); | |
// Initial variables and setup | |
pinMode(LED_BUILTIN, OUTPUT); | |
digitalWrite(LED_BUILTIN, HIGH); | |
Serial.begin(115200); | |
WiFi.mode(WIFI_STA); | |
WiFi.begin(ssid, password); | |
Serial.println(""); | |
/* Wait for the connection | |
* | |
* Connection status codes: | |
* 0 : WL_IDLE_STATUS when Wi-Fi is in process of changing between statuses | |
* 1 : WL_NO_SSID_AVAILin case configured SSID cannot be reached | |
* 3 : WL_CONNECTED after successful connection is established | |
* 4 : WL_CONNECT_FAILED if connection failed | |
* 6 : WL_CONNECT_WRONG_PASSWORD if password is incorrect | |
* 7 : WL_DISCONNECTED if module is not configured in station mode | |
* Source: https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/readme.html#diagnostics | |
*/ | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
Serial.print(WiFi.status()); | |
} | |
Serial.println(""); | |
Serial.println("----------------------------"); | |
Serial.print("Connected to "); | |
Serial.println(ssid); | |
Serial.print("IP address: "); | |
Serial.println(WiFi.localIP()); | |
if (MDNS.begin("esp8266")) { | |
Serial.println("MDNS responder started"); | |
} | |
server.on("/", handleRoot); | |
server.on("/switch", handleLedSwitch); | |
server.on("/status", handleLedStatus); | |
server.onNotFound(handleNotFound); | |
server.begin(); | |
Serial.println("HTTP server started"); | |
Serial.println("----------------------------"); | |
// Call the sendRequest function every 5000 millisecond (5 second) | |
requestTimer.every(5000, sendRequest); | |
} | |
void loop(void) { | |
server.handleClient(); | |
MDNS.update(); | |
// Send the request periodically | |
requestTimer.tick(); | |
} |
Thank you, I appreciate your kind words. Hope the code will be helpful to you
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
better code than I could ever write in C++