I am trying to figure out how to add a slider to this program. I am not following the web page programming. I modified the program from its original because of hardware. I want to use the speed slider and add a sider for time delay. so I can adjust the time delay between turning and stop, to increase the angle it turns.
/********* Rui Santos Complete project details at http://randomnerdtutorials.com *********/ // Load Wi-Fi library #include <WiFi.h> // You can customize the SSID name and change the password const char* ssid = "ESP32-Robot"; const char* password = "123456789"; // Set web server port number to 80 WiFiServer server(80); // Variable to store the HTTP request String header; // Motor 1 int motor1Pin1 = 13; //Ain int motor1Pin2 = 14; //Ain int enable1Pin = 2; // Motor 2 int motor2Pin1 = 15; //Bin int motor2Pin2 = 12; //Bin int enable2Pin = 32; // Setting PWM properties const int freq = 30000; const int pwmChannel0 = 0; const int pwmChannel1 = 1; const int pwmChannel2 = 2; const int pwmChannel3 = 3; const int resolution = 8; int dutyCycle = 0; // Decode HTTP GET value String valueString = "0"; int pos1 = 0; int pos2 = 0; void setup() { Serial.begin(115200); /* // Set the Motor pins as outputs pinMode(motor1Pin1, OUTPUT); pinMode(motor1Pin2, OUTPUT); pinMode(motor2Pin1, OUTPUT); pinMode(motor2Pin2, OUTPUT);*/ // Configure PWM channel functionalitites ledcSetup(pwmChannel0, freq, resolution); ledcSetup(pwmChannel1, freq, resolution); ledcSetup(pwmChannel2, freq, resolution); ledcSetup(pwmChannel3, freq, resolution); // Attach the PWM channel 0 to the enable pins which are the GPIOs to be controlled // ledcAttachPin(enable1Pin, pwmChannel); // ledcAttachPin(enable2Pin, pwmChannel); ledcAttachPin(motor1Pin1, pwmChannel0); ledcAttachPin(motor1Pin2, pwmChannel1); ledcAttachPin(motor2Pin1, pwmChannel2); ledcAttachPin(motor2Pin2, pwmChannel3); // Produce a PWM signal to both enable pins with a duty cycle 0 ledcWrite(pwmChannel0, dutyCycle); ledcWrite(pwmChannel1, dutyCycle); ledcWrite(pwmChannel2, dutyCycle); ledcWrite(pwmChannel3, dutyCycle); // Connect to Wi-Fi network with SSID and password Serial.print("Setting AP (Access Point)..."); // Remove the password parameter, if you want the AP (Access Point) to be open WiFi.softAP(ssid, password); IPAddress IP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(IP); server.begin(); } void loop(){ WiFiClient client = server.available(); // Listen for incoming clients if (client) { // If a new client connects, Serial.println("New Client."); // print a message out in the serial port String currentLine = ""; // make a String to hold incoming data from the client while (client.connected()) { // loop while the client's connected if (client.available()) { // if there's bytes to read from the client, char c = client.read(); // read a byte, then Serial.write(c); // print it out the serial monitor header += c; if (c == '\n') { // if the byte is a newline character // if the current line is blank, you got two newline characters in a row. // that's the end of the client HTTP request, so send a response: if (currentLine.length() == 0) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println(); // turns the GPIOs on and off if (header.indexOf("GET /forward") >= 0) { Serial.println("Forward"); ledcWrite(pwmChannel0 ,0); //(forward low) //digitalWrite(motor1Pin1, LOW); ledcWrite(pwmChannel1 ,dutyCycle); //attach motor1pin1 (forward high) //digitalWrite(motor1Pin2, HIGH); ledcWrite(pwmChannel2 ,0); //(forward low) //digitalWrite(motor2Pin1, LOW); ledcWrite(pwmChannel3,dutyCycle); //attach motor1pin1 // digitalWrite(motor2Pin2, HIGH); } else if (header.indexOf("GET /left") >= 0) { Serial.println("Left"); ledcWrite(pwmChannel0 ,0); ledcWrite(pwmChannel1 ,dutyCycle); ledcWrite(pwmChannel2 ,dutyCycle); ledcWrite(pwmChannel3 ,0); delay(220); ledcWrite(pwmChannel0 ,0); ledcWrite(pwmChannel1 ,0); ledcWrite(pwmChannel2 ,0); ledcWrite(pwmChannel3 ,0); } else if (header.indexOf("GET /stop") >= 0) { Serial.println("Stop"); ledcWrite(pwmChannel0 ,0); //digitalWrite(motor1Pin1, LOW); ledcWrite(pwmChannel1 ,0); //digitalWrite(motor1Pin2, LOW); ledcWrite(pwmChannel2 ,0); //digitalWrite(motor2Pin1, LOW); ledcWrite(pwmChannel3 ,0); //digitalWrite(motor2Pin2, LOW); } else if (header.indexOf("GET /right") >= 0) { Serial.println("Right"); ledcWrite(pwmChannel0 ,dutyCycle); ledcWrite(pwmChannel1 ,0); ledcWrite(pwmChannel2 ,0); ledcWrite(pwmChannel3 ,dutyCycle); delay(220); ledcWrite(pwmChannel0 ,0); ledcWrite(pwmChannel1 ,0); ledcWrite(pwmChannel2 ,0); ledcWrite(pwmChannel3 ,0); } else if (header.indexOf("GET /reverse") >= 0) { Serial.println("Reverse"); ledcWrite(pwmChannel0 ,dutyCycle); //digitalWrite(motor1Pin1, HIGH); ledcWrite(pwmChannel1 ,0); //digitalWrite(motor1Pin2, LOW); ledcWrite(pwmChannel2 ,dutyCycle); //digitalWrite(motor2Pin1, HIGH); ledcWrite(pwmChannel3 ,0); //digitalWrite(motor2Pin2, LOW); } // Display the HTML web page client.println("<!DOCTYPE HTML><html>"); client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<link rel=\"icon\" href=\"data:,\">"); // CSS to style the buttons // Feel free to change the background-color and font-size attributes to fit your preferences client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}"); client.println(".button { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: #4CAF50;"); client.println("border: none; color: white; padding: 12px 28px; text-decoration: none; font-size: 26px; margin: 1px; cursor: pointer;}"); client.println(".button2 {background-color: #555555;}</style></head>"); // Web Page client.println("<p><a href=\"/forward\"><button class=\"button\" onclick=\"moveForward()\">FORWARD</button></a></p>"); client.println("<div style=\"clear: both;\"><p><a href=\"/left\"><button class=\"button\" onclick=\"moveLeft()\">LEFT </button></a>"); client.println("<a href=\"/stop\"><button class=\"button button2\" onclick=\"stopRobot()\">STOP</button></a>"); client.println("<a href=\"/right\"><button class=\"button\" onclick=\"moveRight()\">RIGHT</button></a></p></div>"); client.println("<p><a href=\"/reverse\"><button class=\"button\" onclick=\"moveReverse()\">REVERSE</button></a></p>"); client.println("<input type=\"range\" min=\"0\" max=\"100\" step=\"25\" id=\"motorSlider\" onchange=\"motorSpeed(this.value)\" value=\"" + valueString + "\"/>"); client.println("<script> function motorSpeed(pos) { "); client.println("var xhr = new XMLHttpRequest();"); client.println("xhr.open('GET', \"/?value=\" + pos + \"&\", true);"); client.println("xhr.send(); } </script>"); client.println("</html>"); //Request example: GET /?value=100& HTTP/1.1 - sets PWM duty cycle to 100 if(header.indexOf("GET /?value=")>=0) { pos1 = header.indexOf('='); pos2 = header.indexOf('&'); valueString = header.substring(pos1+1, pos2); //Set motor speed value if (valueString == "0") { //ledcWrite(pwmChannel0, 0); // ledcWrite(pwmChannel1, 0); // ledcWrite(pwmChannel2, 0); // ledcWrite(pwmChannel3, 0); digitalWrite(motor1Pin1, LOW); digitalWrite(motor1Pin2, LOW); digitalWrite(motor2Pin1, LOW); digitalWrite(motor2Pin2, LOW); } else { dutyCycle = map(valueString.toInt(), 25, 100, 200, 255); Serial.println(valueString); } } // The HTTP response ends with another blank line client.println(); // Break out of the while loop break; } else { // if you got a newline, then clear currentLine currentLine = ""; } } else if (c != '\r') { // if you got anything else but a carriage return character, currentLine += c; // add it to the end of the currentLine } } } // Clear the header variable header = ""; // Close the connection client.stop(); Serial.println("Client disconnected."); Serial.println(""); } }
Hi
Slider examples
https://randomnerdtutorials.com/esp32-servo-motor-web-server-arduino-ide/
Thank you for the reply DK. I have already read those. I would like to do it using the library I already have installed. I suppose if I could find an example that has two sliders I could figure something out. maybe I can find something that explains all the parts of the code in more depth. how do I get a value without getting the same value? if(header.indexOf(“GET /?value=”)>=0) {
pos1 = header.indexOf(‘=’);
pos2 = header.indexOf(‘&’);
valueString = header.substring(pos1+1, pos2);
Hi try
use Ajax to obtain current values in esp32 code
if(header.indexOf(“GET /?value=”)>=0) is the same as
server.on(“/?value=”, getSliderPosValue);
//Ajax function getSliderPosValue() { //get current value of slider }
examples
servo as example use what you wish instead
its also above (near the bottom of page) inpart
https://randomnerdtutorials.com/esp32-servo-motor-web-server-arduino-ide/
Hi Austin.
I’m sorry for the delay in my response.
Do you still need help with this project, or have you figured it out already?
Regards,
Sara
Still working on it. I’m not sure how the insert code works on this page. I see start code here but no end. I would like to send updated program.
Hello. I managed to get two sliders, but I need to re name something. the program is reading both sliders. or at least the second slider is changing the variable the first slider has. the first slider motor speed is suppose to changes valuestring and dutyCycle. the second is suppose to change valueString1 and driveDelay.
/*********
Rui Santos
Complete project details at http://randomnerdtutorials.com
*********/ // Load Wi-Fi library
#include <WiFi.h> // You can customize the SSID name and change the password
const char* ssid = "ESP32-Robot";
const char* password = "123456789"; // Set web server port number to 80
WiFiServer server(80); // Variable to store the HTTP request
String header; // Motor 1
int motor1Pin1 = 13; //Ain
int motor1Pin2 = 14; //Ain // Motor 2
int motor2Pin1 = 15; //Bin
int motor2Pin2 = 12; //Bin //light
int lightPin = 2; // LED light kit // Setting PWM properties
const int freq = 30000;
const int pwmChannel0 = 0;
const int pwmChannel1 = 1;
const int pwmChannel2 = 2;
const int pwmChannel3 = 3;
const int resolution = 8;
int dutyCycle = 0; //slider for speed
int driveDelay = 1500; //add slider for delay time // Decode HTTP GET value
String valueString = "0"; //do I need another one of these?
int pos1 = 0;
int pos2 = 0; String valueString1 = "0"; //like this
int pos3 = 0;
int pos4 = 0; void setup() {
Serial.begin(115200); pinMode (lightPin, OUTPUT); // Configure PWM channel functionalitites
ledcSetup(pwmChannel0, freq, resolution);
ledcSetup(pwmChannel1, freq, resolution);
ledcSetup(pwmChannel2, freq, resolution);
ledcSetup(pwmChannel3, freq, resolution); // Attach the PWM channel 0 to the enable pins which are the GPIOs to be controlled ledcAttachPin(motor1Pin1, pwmChannel0); //control the channel not the pin
ledcAttachPin(motor1Pin2, pwmChannel1);
ledcAttachPin(motor2Pin1, pwmChannel2);
ledcAttachPin(motor2Pin2, pwmChannel3); // Produce a PWM signal to both enable pins with a duty cycle 0
ledcWrite(pwmChannel0, dutyCycle); //use dutyCycle to control the channel
ledcWrite(pwmChannel1, dutyCycle);
ledcWrite(pwmChannel2, dutyCycle);
ledcWrite(pwmChannel3, dutyCycle); // Connect to Wi-Fi network with SSID and password
Serial.print("Setting AP (Access Point)...");
// Remove the password parameter, if you want the AP (Access Point) to be open
WiFi.softAP(ssid, password); IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP); server.begin();
} void loop(){
WiFiClient client = server.available(); // Listen for incoming clients if (client) { // If a new client connects,
Serial.println("New Client."); // print a message out in the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println(); // turns the GPIOs on and off
if (header.indexOf("GET /forward") >= 0) {
Serial.println("Forward"); ledcWrite(pwmChannel0 ,0); //(forward low)
ledcWrite(pwmChannel1 ,dutyCycle); //(forward high)
ledcWrite(pwmChannel2 ,0); //(forward low)
ledcWrite(pwmChannel3,dutyCycle); //(forward high) delay(driveDelay); //add slider to control delay //stop after delay ledcWrite(pwmChannel0 ,0);
ledcWrite(pwmChannel1 ,0);
ledcWrite(pwmChannel2 ,0);
ledcWrite(pwmChannel3 ,0); } else if (header.indexOf("GET /left") >= 0) {
Serial.println("Left");
ledcWrite(pwmChannel0 ,0);
ledcWrite(pwmChannel1 ,dutyCycle);
ledcWrite(pwmChannel2 ,dutyCycle);
ledcWrite(pwmChannel3 ,0); delay(220); // add slider to control delay
//stop after delay
ledcWrite(pwmChannel0 ,0);
ledcWrite(pwmChannel1 ,0);
ledcWrite(pwmChannel2 ,0);
ledcWrite(pwmChannel3 ,0); } else if (header.indexOf("GET /stop") >= 0) {
Serial.println("Stop");
ledcWrite(pwmChannel0 ,0);
ledcWrite(pwmChannel1 ,0);
ledcWrite(pwmChannel2 ,0);
ledcWrite(pwmChannel3 ,0);
digitalWrite (lightPin,LOW); } else if (header.indexOf("GET /right") >= 0) {
Serial.println("Right"); ledcWrite(pwmChannel0 ,dutyCycle);
ledcWrite(pwmChannel1 ,0);
ledcWrite(pwmChannel2 ,0);
ledcWrite(pwmChannel3 ,dutyCycle); delay(220); ledcWrite(pwmChannel0 ,0);
ledcWrite(pwmChannel1 ,0);
ledcWrite(pwmChannel2 ,0);
ledcWrite(pwmChannel3 ,0); } else if (header.indexOf("GET /reverse") >= 0) {
Serial.println("Reverse"); ledcWrite(pwmChannel0 ,dutyCycle);
ledcWrite(pwmChannel1 ,0);
ledcWrite(pwmChannel2 ,dutyCycle);
ledcWrite(pwmChannel3 ,0); delay(driveDelay); //add slider to control delay //stop after delay ledcWrite(pwmChannel0 ,0);
ledcWrite(pwmChannel1 ,0);
ledcWrite(pwmChannel2 ,0);
ledcWrite(pwmChannel3 ,0); } else if (header.indexOf("GET /light") >= 0) {
Serial.println("light");
digitalWrite (lightPin,HIGH);} // Display the HTML web page
client.println("<!DOCTYPE HTML><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// CSS to style the buttons
// Feel free to change the background-color and font-size attributes to fit your preferences
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: #4CAF50;");
client.println("border: none; color: white; padding: 12px 28px; text-decoration: none; font-size: 26px; margin: 1px; cursor: pointer;}");
client.println(".button2 {background-color: #FF0000;}"); //button2 red
client.println(".button3 {background-color: #0000FF;}</style></head>"); //buton 3 blue // Web Page
client.println("<p><a href=\"/forward\"><button class=\"button\" onclick=\"moveForward()\">FORWARD</button></a></p>");
client.println("<div style=\"clear: both;\"><p><a href=\"/left\"><button class=\"button\" onclick=\"moveLeft()\">LEFT </button></a>");
client.println("<a href=\"/stop\"><button class=\"button button2\" onclick=\"stopRobot()\">STOP</button></a>");
client.println("<a href=\"/right\"><button class=\"button\" onclick=\"moveRight()\">RIGHT</button></a></p></div>");
client.println("<p><a href=\"/reverse\"><button class=\"button\" onclick=\"moveReverse()\">REVERSE</button></a>");
client.println("<a href=\"/light\"><button class=\"button button3\" onclick=\"moveRight()\">Light</button></a></p>"); //attempt to add
client.println("<p>Motor Speed<p>");
client.println("<input type=\"range\" min=\"0\" max=\"100\" step=\"25\" id=\"motorSlider\" onchange=\"motorSpeed(this.value)\" value=\"" + valueString + "\"/>");
client.println("<p>Drive Time<p>");
client.println("<p><input type=\"range\" min=\"0\" max=\"100\" step=\"25\" id=\"delaySlider\" onchange=\"delayTime(this.value)\" value=\"" + valueString1 + "\"/></p>"); client.println("<script> function motorSpeed(pos) { ");
client.println("var xhr = new XMLHttpRequest();");
client.println("xhr.open('GET', \"/?value=\" + pos + \"&\", true);");
client.println("xhr.send(); } </script>"); client.println("<script> function delayTime(pos) { ");
client.println("var xhr1 = new XMLHttpRequest();");
client.println("xhr1.open('GET', \"/?value=\" + pos + \"&\", true);"); //get1?
client.println("xhr1.send(); } </script>"); client.println("</html>"); //Request example: GET /?value=100& HTTP/1.1 - sets PWM duty cycle to 100
if(header.indexOf("GET /?value=")>=0) {
pos1 = header.indexOf('=');
pos2 = header.indexOf('&');
valueString = header.substring(pos1+1, pos2); //Set motor speed value
if (valueString == "0") {
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin1, LOW);
digitalWrite(motor2Pin2, LOW);
}
else {
dutyCycle = map(valueString.toInt(), 25, 100, 200, 255);
Serial.print("dutyCycle ");
Serial.println(dutyCycle);
Serial.print("valueString ");
Serial.println(valueString);
}
} if(header.indexOf("GET /?value=")>=0) { //second slider attempt
pos3 = header.indexOf('=');
pos4 = header.indexOf('&');
valueString1 = header.substring(pos3+1, pos4); //Set motor speed value
if (valueString1 == "0") {
driveDelay = 0;
}
else {
driveDelay = map(valueString1.toInt(), 0, 250, 100, 10000); Serial.print("driveDelay ");
Serial.println(driveDelay);
Serial.print("valueString1 ");
Serial.println(valueString1);
}
} // The HTTP response ends with another blank line
client.println();
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
Hi Austin.
Yes, using the tags for the code here can be a bit tricky.
I’ve taken a look at your code, and at lines 205 to 208 you have the following:
client.println("<p>Motor Speed<p>"); client.println("<input type=\"range\" min=\"0\" max=\"100\" step=\"25\" id=\"motorSlider\" onchange=\"motorSpeed(this.value)\" value=\"" + valueString + "\"/>"); client.println("<p>Drive Time<p>"); client.println("<p><input type=\"range\" min=\"0\" max=\"100\" step=\"25\" id=\"delaySlider\" onchange=\"delayTime(this.value)\" value=\"" + valueString1 + "\"/></p>");
Your mistake is that you’re making a request on the same /value URL wether you’re moving the motorSlider or the delaySlider. You need to make a request on a different URL, for example: /value1 as follows:
client.println("<p>Motor Speed<p>"); client.println("<input type=\"range\" min=\"0\" max=\"100\" step=\"25\" id=\"motorSlider\" onchange=\"motorSpeed(this.value)\" value=\"" + valueString + "\"/>"); client.println("<p>Drive Time<p>"); client.println("<p><input type=\"range\" min=\"0\" max=\"100\" step=\"25\" id=\"delaySlider\" onchange=\"delayTime(this.value)\" value1=\"" + valueString1 + "\"/></p>");
Then, you need to use that URL to get the value for the second slider, for example in lines 248 to 251, you need to have as follows:
if(header.indexOf("GET /?value1=")>=0) { //second slider attempt pos3 = header.indexOf('='); pos4 = header.indexOf('&'); valueString1 = header.substring(pos3+1, pos4);
I hope this helps.
Regards,
Sara
Thank you for your reply. I made the changes and it seems to work. For some reason my delay timer slider “2nd slider” keeps going to 50% when the page refreshes. It starts at 50% when I first open the page as well. After moving the slider and hitting forward there is a long pause as the page loads. I’m thinking that has to do with using (delay) in the program instead of (mills) or is there something in the http code? I appreciate your help. Thank you.
Hi Austin.
Yes, it may be caused by the delay.
It is preferably to use millis instead.
Can you try it and see if it solves the issue?
Regards,
Sara
I got the delays removed and the code is running better. The delay slider keeps going to the center when the page refreshes, but seems to be working. I plan on running this for a bit to see how it works, then trying to get it to work on WIFI instead of as an AP. Thanks
/********* Rui Santos Complete project details at http://randomnerdtutorials.com *********/ // Load Wi-Fi library #include <WiFi.h> // You can customize the SSID name and change the password const char* ssid = "ESP32-Robot"; const char* password = "123456789"; // Set web server port number to 80 WiFiServer server(80); // Variable to store the HTTP request String header; // motor enable SLP int motorEnable = 14; // Motor 1 int motor1Pin1 = 2; //Ain int motor1Pin2 = 4; //Ain // Motor 2 int motor2Pin1 = 15; //Bin int motor2Pin2 = 13; //Bin //light int lightPin = 2; // LED light kit // Setting PWM properties const int freq = 30000; const int pwmChannel0 = 0; const int pwmChannel1 = 1; const int pwmChannel2 = 2; const int pwmChannel3 = 3; const int resolution = 8; int dutyCycle = 0; //slider for speed int driveDelay = 1550; //add slider for delay time int turningDelay = 250; //increase for bigger turning angle 250 is about 45* depending on speed // Decode HTTP GET value String valueString = "0"; //do I need another one of these? int pos1 = 0; int pos2 = 0; String valueString1 = "0"; //like this int pos3 = 0; int pos4 = 0; //timmer stuff bool forwardFlag = 0; bool reverseFlag = 0; bool rightFlag = 0; bool leftFlag = 0; long driveMillis = 0; //drive millis set to slider for distance travled between button pushes //long turningMillis = 250; //make bigger for more turn angle long previousMillis = 0; void setup() { Serial.begin(115200); pinMode (lightPin, OUTPUT); pinMode (motorEnable, OUTPUT); digitalWrite (motorEnable , HIGH); // Configure PWM channel functionalitites ledcSetup(pwmChannel0, freq, resolution); ledcSetup(pwmChannel1, freq, resolution); ledcSetup(pwmChannel2, freq, resolution); ledcSetup(pwmChannel3, freq, resolution); // Attach the PWM channel 0 to the enable pins which are the GPIOs to be controlled ledcAttachPin(motor1Pin1, pwmChannel0); //control the channel not the pin ledcAttachPin(motor1Pin2, pwmChannel1); ledcAttachPin(motor2Pin1, pwmChannel2); ledcAttachPin(motor2Pin2, pwmChannel3); // Produce a PWM signal to both enable pins with a duty cycle 0 ledcWrite(pwmChannel0, dutyCycle); //use dutyCycle to control the channel ledcWrite(pwmChannel1, dutyCycle); ledcWrite(pwmChannel2, dutyCycle); ledcWrite(pwmChannel3, dutyCycle); // Connect to Wi-Fi network with SSID and password Serial.print("Setting AP (Access Point)..."); // Remove the password parameter, if you want the AP (Access Point) to be open WiFi.softAP(ssid, password); IPAddress IP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(IP); server.begin(); } void loop(){ WiFiClient client = server.available(); // Listen for incoming clients if (client) { // If a new client connects, Serial.println("New Client."); // print a message out in the serial port String currentLine = ""; // make a String to hold incoming data from the client while (client.connected()) { // loop while the client's connected if (client.available()) { // if there's bytes to read from the client, char c = client.read(); // read a byte, then Serial.write(c); // print it out the serial monitor header += c; if (c == '\n') { // if the byte is a newline character // if the current line is blank, you got two newline characters in a row. // that's the end of the client HTTP request, so send a response: if (currentLine.length() == 0) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println(); // turns the GPIOs on and off if (header.indexOf("GET /forward") >= 0) { Serial.println("Forward"); forwardFlag = HIGH; for (int x = 0; x < 1; x++){ previousMillis = millis(); // Serial.println("got millis P"); // Serial.println(forwardFlag); // Serial.println(previousMillis); } } else if (header.indexOf("GET /left") >= 0) { Serial.println("Left"); leftFlag = HIGH; for (int x = 0; x < 1; x++){ previousMillis = millis(); // Serial.println("got millis P"); // Serial.println(leftFlag); // Serial.println(previousMillis); } } else if (header.indexOf("GET /stop") >= 0) { Serial.println("Stop"); ledcWrite(pwmChannel0 ,0); ledcWrite(pwmChannel1 ,0); ledcWrite(pwmChannel2 ,0); ledcWrite(pwmChannel3 ,0); digitalWrite (lightPin,LOW); } else if (header.indexOf("GET /right") >= 0) { Serial.println("Right"); rightFlag = HIGH; for (int x = 0; x < 1; x++){ previousMillis = millis(); // Serial.println("got millis P"); // Serial.println(rightFlag); // Serial.println(previousMillis); } } else if (header.indexOf("GET /reverse") >= 0) { Serial.println("Reverse"); reverseFlag = HIGH; for (int x = 0; x < 1; x++){ previousMillis = millis(); // Serial.println("got millis P for reverse"); // Serial.println(reverseFlag); // Serial.println(previousMillis); } } else if (header.indexOf("GET /light") >= 0) { Serial.println("light"); digitalWrite (lightPin,HIGH);} // Display the HTML web page client.println("<!DOCTYPE HTML><html>"); client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<link rel=\"icon\" href=\"data:,\">"); // CSS to style the buttons // Feel free to change the background-color and font-size attributes to fit your preferences client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}"); client.println(".button { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: #4CAF50;"); client.println("border: none; color: white; padding: 12px 28px; text-decoration: none; font-size: 26px; margin: 1px; cursor: pointer;}"); client.println(".button2 {background-color: #FF0000;}"); //button2 red client.println(".button3 {background-color: #0000FF;}</style></head>"); //buton 3 blue // Web Page client.println("<p><a href=\"/forward\"><button class=\"button\" onclick=\"moveForward()\">FORWARD</button></a></p>"); client.println("<div style=\"clear: both;\"><p><a href=\"/left\"><button class=\"button\" onclick=\"moveLeft()\">LEFT </button></a>"); client.println("<a href=\"/stop\"><button class=\"button button2\" onclick=\"stopRobot()\">STOP</button></a>"); client.println("<a href=\"/right\"><button class=\"button\" onclick=\"moveRight()\">RIGHT</button></a></p></div>"); client.println("<p><a href=\"/reverse\"><button class=\"button\" onclick=\"moveReverse()\">REVERSE</button></a>"); client.println("<a href=\"/light\"><button class=\"button button3\" onclick=\"moveRight()\">Light</button></a></p>"); //attempt to add client.println("<p>Motor Speed<p>"); client.println("<input type=\"range\" min=\"0\" max=\"100\" step=\"25\" id=\"motorSlider\" onchange=\"motorSpeed(this.value)\" value=\"" + valueString + "\"/>"); client.println("<p>Drive Time<p>"); client.println("<p><input type=\"range\" min=\"0\" max=\"100\" step=\"25\" id=\"delaySlider\" onchange=\"delayTime(this.value)\" value1=\"" + valueString1 + "\"/></p>"); //first slider motor speed client.println("<script> function motorSpeed(pos) { "); client.println("var xhr = new XMLHttpRequest();"); client.println("xhr.open('GET', \"/?value=\" + pos + \"&\", true);"); client.println("xhr.send(); } </script>"); //second slider delay time client.println("<script> function delayTime(pos) { "); client.println("var xhr1 = new XMLHttpRequest();"); client.println("xhr1.open('GET', \"/?value1=\" + pos + \"&\", true);"); //value1? client.println("xhr1.send(); } </script>"); client.println("</html>"); //first slider motor speed //Request example: GET /?value=100& HTTP/1.1 - sets PWM duty cycle to 100 if(header.indexOf("GET /?value=")>=0) { pos1 = header.indexOf('='); pos2 = header.indexOf('&'); valueString = header.substring(pos1+1, pos2); //Set motor speed value if (valueString == "0") { digitalWrite(motor1Pin1, LOW); digitalWrite(motor1Pin2, LOW); digitalWrite(motor2Pin1, LOW); digitalWrite(motor2Pin2, LOW); }else { dutyCycle = map(valueString.toInt(), 25, 100, 200, 255); Serial.print("dutyCycle "); Serial.println(dutyCycle); Serial.print("valueString "); Serial.println(valueString); } } client.println("</html>"); //second slider delay time if(header.indexOf("GET /?value1=")>=0) { //second slider attempt changed value1 pos3 = header.indexOf('='); pos4 = header.indexOf('&'); valueString1 = header.substring(pos3+1, pos4); //Set delay time value if (valueString1 == "0") { driveDelay = 500; } else { driveDelay = map(valueString1.toInt(), 25, 100, 800, 3000); Serial.print("driveDelay "); Serial.println(driveDelay); Serial.print("valueString1 "); Serial.println(valueString1); } } // The HTTP response ends with another blank line client.println(); // Break out of the while loop break; } else { // if you got a newline, then clear currentLine currentLine = ""; } } else if (c != '\r') { // if you got anything else but a carriage return character, currentLine += c; // add it to the end of the currentLine } } } // Clear the header variable header = ""; // Close the connection client.stop(); Serial.println("Client disconnected."); Serial.println(""); } //Forward if (forwardFlag == HIGH){ driveMillis = millis(); // Serial.println("current millis"); // Serial.println(currentMillis); if (driveMillis - previousMillis <= driveDelay){ // Serial.println("moving"); ledcWrite(pwmChannel0 ,0); //(forward low) ledcWrite(pwmChannel1 ,dutyCycle); //(forward high) ledcWrite(pwmChannel2 ,0); //(forward low) ledcWrite(pwmChannel3,dutyCycle); //(forward high) }else{ //stop after delay // Serial.println("stop"); ledcWrite(pwmChannel0 ,0); ledcWrite(pwmChannel1 ,0); ledcWrite(pwmChannel2 ,0); ledcWrite(pwmChannel3 ,0); forwardFlag = LOW ; // Serial.println("forwardFlag"); // Serial.println(forwardFlag); }} //reverse if (reverseFlag == HIGH){ driveMillis = millis(); // Serial.println("current millis"); // Serial.println(currentMillis); if (driveMillis - previousMillis <= driveDelay){ // Serial.println("moving reverse"); ledcWrite(pwmChannel0 ,dutyCycle); //(forward low) ledcWrite(pwmChannel1 ,0); //(forward high) ledcWrite(pwmChannel2 ,dutyCycle); //(forward low) ledcWrite(pwmChannel3,0); //(forward high) }else{ //stop after delay // Serial.println("stop"); ledcWrite(pwmChannel0 ,0); ledcWrite(pwmChannel1 ,0); ledcWrite(pwmChannel2 ,0); ledcWrite(pwmChannel3 ,0); reverseFlag = LOW ; // Serial.println("reverseFlag"); // Serial.println(reverseFlag); }} //right turn if (rightFlag == HIGH){ driveMillis = millis(); // Serial.println("turning millis"); // Serial.println(turningMillis); if (driveMillis - previousMillis <= turningDelay){ // Serial.println("moving right"); ledcWrite(pwmChannel0 ,dutyCycle); //(right high) ledcWrite(pwmChannel1 ,0); //(right low) ledcWrite(pwmChannel2 ,0); //(right low) ledcWrite(pwmChannel3,dutyCycle); //(right high) }else{ //stop after delay // Serial.println("stop"); ledcWrite(pwmChannel0 ,0); ledcWrite(pwmChannel1 ,0); ledcWrite(pwmChannel2 ,0); ledcWrite(pwmChannel3 ,0); rightFlag = LOW ; // Serial.println("rightFlag"); // Serial.println(rightFlag); }} //left turn if (leftFlag == HIGH){ driveMillis = millis(); // Serial.println("current millis"); // Serial.println(driveMillis); if (driveMillis - previousMillis <= turningDelay){ // Serial.println("moving left"); ledcWrite(pwmChannel0 ,0); //(left low) ledcWrite(pwmChannel1 ,dutyCycle); //(left high) ledcWrite(pwmChannel2 ,dutyCycle); //(left high) ledcWrite(pwmChannel3,0); //(left low) }else{ //stop after delay // Serial.println("stop"); ledcWrite(pwmChannel0 ,0); ledcWrite(pwmChannel1 ,0); ledcWrite(pwmChannel2 ,0); ledcWrite(pwmChannel3 ,0); leftFlag = LOW ; // Serial.println("leftFlag"); // Serial.println(leftFlag); }}}
On your example that streams video as an access point for the esp32 cam where could I add buttons? Is it possible?
Hi.
Yes, it is possible. But with the examples that we have, it is not easy to implement and we don’t have any sample code for that.
We’ll be working on something like that soon. So, in a month or so, we should release something with the ESP32-CAM and buttons to control a servo (for pan and tilt) or a robot.
Thank you for the suggestion and I’m sorry that I can’t help much.
Regards,
Sara
Awesome thanks. I look forward to it. currently using two esp32-cam boards for the tank project. one to drive one cam