Control PWM motor with slider over wifi

Hi guys,

I would like to use a slider to increase or decrease the pwm for the motor,or i try with several conidtion and i din't find a solution.

Here the screen of the slider control

If someboy have a idea.
Many thanks

here the code for the esp32


#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ArduinoOTA.h>

// connections for drive Motors
int PWM_A = D1;
//int PWM_B = D2;
int DIR_A = D3;
//int DIR_B = D4;

const int buzPin = D5; // set digital pin D5 as buzzer pin (use active buzzer)
const int ledPin = D8; // set digital pin D8 as LED pin (use super bright LED)
const int wifiLedPin = D0; // set digital pin D0 as indication, the LED turn on if NodeMCU connected to WiFi as STA mode

String command; // String to store app command state.
int SPEED = 100; // 330 - 1023.
int speed_Coeff = 3;

ESP8266WebServer server(80); // Create a webserver object that listens for HTTP request on port 80

unsigned long previousMillis = 0;

String sta_ssid = "";
String sta_password = "";

void setup(){
Serial.begin(115200); // set up Serial library at 115200 bps
Serial.println("WiFi Train Control Mode");

pinMode(buzPin, OUTPUT); // sets the buzzer pin as an Output
pinMode(ledPin, OUTPUT); // sets the LED pin as an Output
pinMode(wifiLedPin, OUTPUT); // sets the Wifi LED pin as an Output
digitalWrite(buzPin, LOW);
digitalWrite(ledPin, LOW);
digitalWrite(wifiLedPin, HIGH);

// Set all the motor control pins to outputs
pinMode(PWM_A, OUTPUT);
//pinMode(PWM_B, OUTPUT);
pinMode(DIR_A, OUTPUT);
//pinMode(DIR_B, OUTPUT);

// Turn off motors - Initial state
digitalWrite(DIR_A, LOW);
// digitalWrite(DIR_B, LOW);
analogWrite(PWM_A, 0);
//analogWrite(PWM_B, 0);

// set NodeMCU Wifi hostname based on chip mac address
String hostname("Train-APP");
Serial.println("Hostname: "+hostname);

// first, set NodeMCU as STA mode to connect with a Wifi network
WiFi.begin(sta_ssid.c_str(), sta_password.c_str());
Serial.print("Connecting to: ");
//Serial.print("Password: ");

// try to connect with Wifi network about 10 seconds
unsigned long currentMillis = millis();
previousMillis = currentMillis;
while (WiFi.status() != WL_CONNECTED && currentMillis - previousMillis <= 10000) {
currentMillis = millis();

// if failed to connect with Wifi network set NodeMCU as AP mode
if (WiFi.status() == WL_CONNECTED) {
Serial.print("IP: ");
digitalWrite(wifiLedPin, LOW); // Wifi LED on when connected to Wifi as STA mode
} else {
IPAddress myIP = WiFi.softAPIP();
Serial.println("WiFi failed connected to " + sta_ssid);
Serial.print("AP IP address: ");
digitalWrite(wifiLedPin, HIGH); // Wifi LED off when status as AP mode

server.on ( "/", HTTP_handleRoot ); // call the 'handleRoot' function when a client requests URI "/"
server.onNotFound ( HTTP_handleRoot ); // when a client requests an unknown URI (i.e. something other than "/"), call function "handleNotFound"
server.begin(); // actually start the server

ArduinoOTA.begin(); // enable to receive update/uploade firmware via Wifi OTA

void loop() {
ArduinoOTA.handle(); // listen for update OTA request from clients
server.handleClient(); // listen for HTTP requests from clients

  command = server.arg("State");          // check HTPP request, if has arguments "State" then saved the value
  if (command == "F") Forward();          // check string then call a function or set a value
  else if (command == "B") Backward();
  else if (command == "R") TurnRight();
  else if (command == "L") TurnLeft();
  else if (command == "G") ForwardLeft();
  else if (command == "H") BackwardLeft();
  else if (command == "I") ForwardRight();
  else if (command == "J") BackwardRight();
  else if (command == "S") Stop();
  else if (command == "V") BeepHorn();
  else if (command == "W") TurnLightOn();
  else if (command == "Z") TurnLightOff();
  else if (command == "0") SPEED = 50;
  else if (command == "1") SPEED = 60;
  else if (command == "2") SPEED = 70;
  else if (command == "3") SPEED = 80;
  else if (command == "4") SPEED = 90;
  else if (command == "5") SPEED = 100;
  else if (command == "6") SPEED = 750;
  else if (command == "7") SPEED = 820;
  else if (command == "8") SPEED = 890;
  else if (command == "9") SPEED = 960;
  else if (command == "q") SPEED = 1023;


// function prototypes for HTTP handlers
void HTTP_handleRoot(void){
server.send ( 200, "text/html", "" ); // Send HTTP status 200 (Ok) and send some text to the browser/client

if( server.hasArg("State") ){

void handleNotFound(){
server.send(404, "text/plain", "404: Not found"); // Send HTTP status 404 (Not Found) when there's no handler for the URI in the request

// function to move forward
void Forward(){
digitalWrite(DIR_A, HIGH);
// digitalWrite(DIR_B, HIGH);
analogWrite(PWM_A, SPEED);
//analogWrite(PWM_B, SPEED);

// function to move backward
void Backward(){
digitalWrite(DIR_A, LOW);
//digitalWrite(DIR_B, LOW);
analogWrite(PWM_A, SPEED);
//analogWrite(PWM_B, SPEED);

// function to turn right
void TurnRight(){
digitalWrite(DIR_A, LOW);
//digitalWrite(DIR_B, HIGH);
analogWrite(PWM_A, SPEED);
//analogWrite(PWM_B, SPEED);

// function to turn left
void TurnLeft(){
digitalWrite(DIR_A, HIGH);
//digitalWrite(DIR_B, LOW);
analogWrite(PWM_A, SPEED);
//analogWrite(PWM_B, SPEED);

// function to move forward left
void ForwardLeft(){
digitalWrite(DIR_A, HIGH);
//digitalWrite(DIR_B, HIGH);
analogWrite(PWM_A, SPEED);
//analogWrite(PWM_B, SPEED/speed_Coeff);

// function to move backward left
void BackwardLeft(){
digitalWrite(DIR_A, LOW);
//digitalWrite(DIR_B, LOW);
analogWrite(PWM_A, SPEED);
//analogWrite(PWM_B, SPEED/speed_Coeff);

// function to move forward right
void ForwardRight(){
digitalWrite(DIR_A, HIGH);
//digitalWrite(DIR_B, HIGH);
analogWrite(PWM_A, SPEED/speed_Coeff);
//analogWrite(PWM_B, SPEED);

// function to move backward left
void BackwardRight(){
digitalWrite(DIR_A, LOW);
//digitalWrite(DIR_B, LOW);
analogWrite(PWM_A, SPEED/speed_Coeff);
//analogWrite(PWM_B, SPEED);

// function to stop motors
void Stop(){
digitalWrite(DIR_A, LOW);
//digitalWrite(DIR_B, LOW);
analogWrite(PWM_A, 0);
//analogWrite(PWM_B, 0);

// function to beep a buzzer
void BeepHorn(){
digitalWrite(buzPin, HIGH);
digitalWrite(buzPin, LOW);

// function to turn on LED
void TurnLightOn(){
digitalWrite(ledPin, HIGH);

// function to turn off LED
void TurnLightOff(){
digitalWrite(ledPin, LOW);

Where is the event block for that Web component that fires on completion of the Get, with its valuable diagnostic codes?

Same for the error event block for that component?

Well, those blocks are not necessary, at least for sending procedure.
First, I think the slash does not need between the IP and the questionmark.
should look like this: IP?State= or put an other namespace between the slash and the questionmaqrk.
Second, put the arg value in the server.send() function in the handleroot():
Third. The esp8266 sending argument have to be "text/plain" I think.

server.send ( 200, "text/plain", "" );
command = server.arg("State"); 


Thanks for your answer,it's works,but it' almost what i am looking for.
I will try to explain better:

1- i press move forward => the motor go forward
2-with the slider i increase or decrease the speed
3- if i press backward => the motor go backward
4 with the slider i increase or decrease the speed.

with your modification,the slider set the good value,but if i am in backward,the change for forward.

Is it more clear? becasuse on my head it is

Many thanks

PS:i add a second slide bar for manage the backward

It should not work like that if you did not change anything else. Is far as I see from your sketch it is work like:
1: If you push forwad, go forward,
2: if you push backward go backward,
but the speed only apply if you push forward or backward or any other direction. In your sketch there is no separate function for changing speed. Speed variable only
I hope i am clear. For example.
1 .If you move the slider first, nothing happens until you push a direction button.

yes your right.
I add that on the apps.

Do you have a better idea/solution?
Sorry for the question but i am a total newbie

The easier way to do it in your app, but the best way to do it in your ESP. I am too tired today, tomorrow i will create something.

This is the easiest and fastest way.
I also would store the IP in a tinyDB And recall it when needed instead of keep it in a label, textbox all the time. You can also store the direction and slider variables and if you close the app accidentally you get it back from the tinyDB on app open. Though I do not know what do you control with this app and the ESP32. From the labels i would suppose it is an RC car or something, but not sure, so I think it is not so important to store these variables. Also if it would be a continously running device i would store everything in the ESP and request it to the app on connection.

many thanks,your awesome!
Normally it was for a RC car,but i adapt the code for control a train,it's for the birthday of a friend.

I try it as soon as possible and i let you know but many thanks for you help and time

To be clear.
I left the web.get out of the buttons, but i think you know tha, but for better understanding.
The button blocks have to look like this:


Hi mate,

Sorry my late answer i was out of the country for work,i try that now and i give you a feed back.


I just try,it's not working well,when i am using the sliderthe state send by app are not split as you can see on the monitor of the arduino

Seems the 2 get request follow each other too fast. Multiple solution possible.
For example you can use a timer and wait a little until the second request..

Or, you can spice it up with waiting for the request completed state:

You may have to experiment with timings. I just set it randomly.
Or. You modify the whole thing and separate the slider and the direction command, but that requires to modify the ESP sketch too.

Or you can think other solution from my examples.

Edit: a little modification to the second solution to clear the responsecontent variable.