• Skip to main content
  • Skip to primary sidebar

RNTLab.com

The Ultimate Shortcut to Learn Electronics and Programming with Open Source Hardware and Software

  • Courses
  • Forum
    • Forum
    • Ask Question
  • Shop
  • Account
  • Blog
  • Login

ESP 32 cam robot add a slider

Q&A Forum › ESP 32 cam robot add a slider
0 Vote Up Vote Down
Austin asked 6 years ago
17 Answers
0 Vote Up Vote Down
Austin answered 6 years ago

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("");
}
}
0 Vote Up Vote Down
DK answered 6 years ago

Hi
Slider examples
https://randomnerdtutorials.com/esp32-servo-motor-web-server-arduino-ide/

0 Vote Up Vote Down
Austin answered 6 years ago

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);

0 Vote Up Vote Down
DK answered 6 years ago

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/

0 Vote Up Vote Down
Sara Santos Staff answered 6 years ago

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

0 Vote Up Vote Down
Austin answered 6 years ago

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. 

0 Vote Up Vote Down
Austin answered 6 years ago

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("");
}
}
0 Vote Up Vote Down
Austin answered 6 years ago

ugh I cant even get the code tags to work ……..

0 Vote Up Vote Down
Sara Santos Staff answered 6 years ago

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

0 Vote Up Vote Down
Austin answered 6 years ago

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. 

0 Vote Up Vote Down
Sara Santos Staff answered 6 years ago

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
 

0 Vote Up Vote Down
Austin answered 6 years ago

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);
}}}
0 Vote Up Vote Down
Sara Santos Staff answered 6 years ago

Ok.
Then let me know how it went.

0 Vote Up Vote Down
Austin answered 6 years ago

On your example that streams video as an access point for the esp32 cam where could I add buttons? Is it possible? 

0 Vote Up Vote Down
Sara Santos Staff answered 6 years ago

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

0 Vote Up Vote Down
Austin answered 6 years ago

Awesome thanks. I look forward to it. currently using two esp32-cam boards for the tank project. one to drive one cam 

0 Vote Up Vote Down
Sara Santos Staff answered 6 years ago

That’s also another alternative and easier (at the moment).
Regards.
Sara

Primary Sidebar

Login to Ask or Answer Questions

This Forum is private and it’s only available for members enrolled in our Courses.

Login »

Latest Course Updates

  • [New Edition] Build ESP32-CAM Projects eBook – 2nd Edition April 16, 2025
  • [eBook Updated] Learn ESP32 with Arduino IDE eBook – Version 3.2 April 16, 2025

You must be logged in to view this content.

Contact Support - Refunds - Privacy - Terms - MakerAdvisor.com - Member Login

Copyright © 2013-2025 · RandomNerdTutorials.com · All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.