In this activity we will look at how to command our robot via wifi.
function LEDon(){ //turn LED ON
var xhr = new XMLHttpRequest();
xhr.open("GET", "/button?value="+document.form1.a.value, true);
xhr.send();
console.log("Value = " + document.form1.a.value);
}
The beginning of the sketch looks pretty much like out basic web server. Some variables needed later are initialized.
The web page contains a Javascript with 2 functions. the LEDon function creates a new XMLHttpRequest object.
We could have replaced "document.form1.a.value" with the number 1.
Each function generates an XML send back to the server.
class led{ //create an LED object so that we can update it's state
int ledPin;
public:
led(int pin){
ledPin = pin;
pinMode(ledPin,OUTPUT);
}
void Update(int ledState)
{
digitalWrite(ledPin, ledState);
}
};
led led1(2);
We are going to create an LED object to control the onboard LED on the ESP32. The state variable does not get passed into loop().
The class variable is ledPin.
The constructor sets up an LED object called led1 connected to pin 2.
The update method sets the state of led1, ON or OFF.
// Send a GET request to <ESP_IP>/button?value=<inputMessage>
server.on("/button", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET input value on <ESP_IP>/button?value=<inputMessage>
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
state = inputMessage.toInt();
Serial.println(state);
}
else {
inputMessage = "No message sent";
}
request->send(200, "text/plain", "OK");
});
This section sets up the server using .on to listen for a request whenever a button is pushed.
It will take the data coming in and put it into inputMessage and cast it into an integer.
void loop() {
led1.Update(state);
}
All that is left is to update our led1 object.
HERE IS THE COMPLETE SKETCH.
/********
Adapted from Basic Web Server
Apr 29, 2021
https://sites.google.com/view/sparboticsesp32/web/esp32-web-server
*********/
// Import required libraries
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
const char* ssid = "*************************";
const char* password = "**********************"; // put your own SSID and password here
const char* PARAM_INPUT = "value";
int LEDpin = 2, state = 0; // Some variables we will need later on.
AsyncWebServer server(80); // Create AsyncWebServer object on port 80
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>
ESP32 LED Control
</title>
<style>
body {font-family: Arial, Helvetica, sans-serif; background-color: powderblue;}
p {color: gray}
</style>
</head>
<body>
<h1>Neat Oh Batman!</h1>
<script language="JavaScript">
function LEDon(){ //turn LED ON
var xhr = new XMLHttpRequest();
xhr.open("GET", "/button?value="+document.form1.a.value, true);
xhr.send();
console.log("Value = " + document.form1.a.value);
}
function LEDoff(){ //turn LED OFF
var xhr = new XMLHttpRequest();
xhr.open("GET", "/button?value="+document.form1.b.value, true);
xhr.send();
console.log("Value = " + document.form1.b.value);
}
</script>
<form action="" method="post" name="form1">
<button name="a" type="button" onclick="LEDon()" value=1>LED ON</button>
<button name="b" type="button" onclick="LEDoff()" value=0>LED OFF</button>
</form>
</body>
</html>
)rawliteral";
class led{ //create an LED object so that we can update it's state
int ledPin;
public:
led(int pin){
ledPin = pin;
pinMode(ledPin,OUTPUT);
}
void Update(int ledState)
{
digitalWrite(ledPin, ledState);
}
};
led led1(2);
void setup(){
Serial.begin(115200); // Serial port for debugging purposes
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP 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);
});
// Send a GET request to <ESP_IP>/button?value=<inputMessage>
server.on("/button", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
// GET input value on <ESP_IP>/button?value=<inputMessage>
if (request->hasParam(PARAM_INPUT)) {
inputMessage = request->getParam(PARAM_INPUT)->value();
state = inputMessage.toInt();
Serial.println(state);
}
else {
inputMessage = "No message sent";
}
request->send(200, "text/plain", "OK");
});
// Start server
server.begin();
}
void loop() {
led1.Update(state);
}