![]() |
arduino IDEArduino
|
|
![]() |
Visual Studio Code |
Dual DC Motor and Servo Motor control via Web Server - ESP8266 DRV8848 Motor Driver Board
In this project you will see how to build a web server with ESP that controls dual DC motor directions and one servo motor position using four buttons and a slider. I will use the my last design ESP8266 based DRV8848 Motor Driver Development Board, but the source codes of the project are compatible for motor drivers such as L298N and L293D.
If you need an ESP8266 WiFi development board that can drive Dual DC motors, you can order this PCB from PCBWay with high-quality and low-price. You can reach the features of this board, all stages such as soldering and assembly from the link
Let's take a look at the source codes that allow to control DC motor directions and Servo motor position via Web Server.
Added the necessary WiFi and Servo libraries to use the Arduino IDE.
#include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <Servo.h>
A Servo object named “My Servo” has been created.
Servo myServo;
GPIO pins to which servo and DC motors are connected are defined.
// GPIO the servo is attached to static const int servoPin = 0; // GPIO the motors are attached to static const int M1forwardPin = 14; static const int M1backwardPin = 12; static const int M2forwardPin = 5; static const int M2backwardPin = 4; static const int sleepPin = 16;
If your drive doesn't include a "sleep" pin, change the "sleep mode" lines to comment lines.
//static const int sleepPin = 16;
Motor speeds are defined and can be changed according to demand.
#define M1SPEED 200 #define M2SPEED 200
Replace your network details with these lines.
const char* ssid = "REPLACE_WITH_YOUR_SSID"; const char* password = "REPLACE_WITH_YOUR_PASSWORD";
A variable was created to store the header of the HTTP request.
String header;
Then a few more variables were created to be used to extract the slider position from the HTTP request.
String valueString = String(5); int pos1 = 0; int pos2 = 0;
In the "Setup" section, serial communication is started and the modes of the connected pins are specified. If "sleep pin" is not used, you can remove the line.
Serial.begin(115200); pinMode(M1forwardPin, OUTPUT); pinMode(M1backwardPin, OUTPUT); pinMode(M2forwardPin, OUTPUT); pinMode(M2backwardPin, OUTPUT); pinMode(sleepPin, OUTPUT); myServo.attach(servoPin); digitalWrite(sleepPin, HIGH);
Then the Wi-Fi connection is started and the IP address is printed on the serial monitor.
Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } // Print local IP address and start web server Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); server.begin();
Finally before moving on to the loop part, functions were created for the move and direction of the motors.
void forward() { analogWrite(M1forwardPin, M1SPEED); analogWrite(M2forwardPin, M2SPEED); analogWrite(M1backwardPin, 0); analogWrite(M2backwardPin, 0); } void backward() { analogWrite(M1backwardPin, M1SPEED); analogWrite(M2backwardPin, M2SPEED); analogWrite(M1forwardPin, 0); analogWrite(M2forwardPin, 0); } void turnLeft() { analogWrite(M1backwardPin, M1SPEED); analogWrite(M2forwardPin, M2SPEED); analogWrite(M1forwardPin, 0); analogWrite(M2backwardPin, 0); } void turnRight() { analogWrite(M1forwardPin, M1SPEED); analogWrite(M2backwardPin, M2SPEED); analogWrite(M1backwardPin, 0); analogWrite(M2forwardPin, 0); } void stopMotors() { analogWrite(M1forwardPin, 0); analogWrite(M2forwardPin, 0); analogWrite(M1backwardPin, 0); analogWrite(M2backwardPin, 0); }
In the loop part, it was defined what happens when a new client first establishes a connection with the web server. When a request is received from a client, the incoming data is saved. The while loop that follows will be running as long as the client stays connected.
WiFiClient client = server.available(); if (client) { currentTime = millis(); previousTime = currentTime; Serial.println("New Client."); String currentLine = ""; while (client.connected() && currentTime - previousTime <= timeoutTime) { currentTime = millis(); if (client.available()) { char c = client.read(); Serial.write(c); header += c; if (c == '\n') { if (currentLine.length() == 0) {
Then the web server is generated and some HTML text is sent to display the web page. The web page is sent to the client using the "client print" function. You must enter what you want to send to the client as an argument.
client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println(); // Display the HTML web page client.println("<!DOCTYPE html><html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); // Style section for buttons and slider. You can change customizations such as color and so on. client.println("<style>"); client.println(".container {font: caption; display: block; flex-direction: column; align-items: center;}"); client.println(".slider {width: 275px; accent-color: #ede100; cursor: pointer;}"); client.println(".button-container {display: flex; flex-direction: column; align-items: center;}"); client.println(".row-container {display: flex; flex-direction: row; justify-content: center; align-items: center;}"); client.println(".button {width: 135px; border: 0; background-color: #ede100; box-shadow: inset 2px 2px 3px #b2b2b2, inset -2px -2px 3px #000; padding: 10px 25px; text-align: center; display: inline-block; border-radius: 5px; font-size: 16px; margin: 10px 25px; cursor: pointer;}"); client.println(".button:hover {background-color: #fff200;}"); client.println(".button:active{box-shadow: inset 2px 2px 3px #000, inset -2px -2px 3px #b2b2b2;}"); client.println("footer {text-align: center; margin: 50px; width: 400px; background-color: #ede100;}"); client.println("</style><script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script></head>"); // Body section. Contains functions of buttons and slider. client.println("<body>"); client.println("<div class=\"container\">"); client.println("<div class=\"row-container\"><h2>ESP8266 Motor Control Panel</h2></div>"); client.println("<div><div class=\"button-container\">"); client.println("<div class=\"row-container\"><button class=\"button\" id=\"forward-btn\" onmousedown=\"btnVal('forward')\" onmouseup=\"btnVal('stop')\">Forward</button></div>"); client.println("<div class=\"row-container\"><button class=\"button\" id=\"left-btn\" onmousedown=\"btnVal('left')\" onmouseup=\"btnVal('stop')\">Left</button>"); client.println("<button class=\"button\" id=\"right-btn\" onmousedown=\"btnVal('right')\" onmouseup=\"btnVal('stop')\">Right</button></div>"); client.println("<div class=\"row-container\"><button class=\"button\" id=\"backward-btn\" onmousedown=\"btnVal('backward')\" onmouseup=\"btnVal('stop')\">Backward</button></div></div>"); client.println("</div>"); client.println("<div class=\"row-container\"><p>Servo Position: <span id=\"servoPos\"></span></p></div>"); client.println("<div class=\"row-container\"><input type=\"range\" min=\"0\" max=\"180\" class=\"slider\" id=\"servoSlider\" onchange=\"servo(this.value)\" value="+valueString+"/></div>"); client.println("<div class=\"row-container\"><footer><p>@Maker101io</p></footer></div></div>"); // Script section. Get the button and slider values and executes functions. client.println("<script>"); client.println("var slider = document.getElementById(\"servoSlider\");"); client.println("var servoP = document.getElementById(\"servoPos\"); servoP.innerHTML = slider.value;"); client.println("slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value; }"); client.println("$.ajaxSetup({timeout:1000});"); client.println("function btnVal(dir) { $.get(\"/?btnVal=\" + dir, true);}"); client.println("function servo(pos) { $.get(\"/?value=\" + pos + \"&\");}"); client.println("{Connection: close};</script>"); client.println("</body></html>");
Let's take a look at the HTML codes that the ESP sends to the browser. The web page has some CSS for the buttons and slider. If you are sure of what you are doing, you can change some properties defined in this section, such as colors and sizes.
If you want to make changes on the web page, I will share these HTML codes together with the source codes. Remember, you must update the HTML lines you make changes to the HTML lines found in the shared source code for the Arduino IDE. The point you should pay attention to when making changes is that you need to add the "Backslash" symbol before the "double quotes" symbols in the HTML code.
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Style section for buttons and slider. You can change customizations such as color and so on. -->
<style>
.container {font: caption; display: block; flex-direction: column; align-items: center;}
.slider {width: 275px; accent-color: #ede100; cursor: pointer;}
.button-container {display: flex; flex-direction: column; align-items: center;}
.row-container {display: flex; flex-direction: row; justify-content: center; align-items: center;}
.button {width: 135px; border: 0; background-color: #ede100; box-shadow: inset 2px 2px 3px #b2b2b2, inset -2px -2px 3px #000; padding: 10px 25px; text-align: center; display: inline-block; border-radius: 5px; font-size: 16px; margin: 10px 25px; cursor: pointer;}
.button:hover {background-color: #fff200;}
.button:active{box-shadow: inset 2px 2px 3px #000, inset -2px -2px 3px #b2b2b2;}
footer {text-align: center; margin: 50px; width: 400px; background-color: #ede100;}
</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script></head>
Four button classes were added and motor directions were defined for each button. As long as the button is kept pressed, the "direction" value of the button will be taken and when the button is released, the "stop" value will be taken. Then a slider is added, minimum and maximum range is defined to the slider. Created a "value string" variable to hold the slider value.
<!-- Body section. Contains functions of buttons and slider. -->
<body>
<div class="container">
<div class="row-container"><h2>ESP8266 Motor Control Panel</h2></div>
<div><div class="button-container">
<div class="row-container"><button class="button" id="forward-btn" onmousedown="btnVal('forward')" onmouseup="btnVal('stop')">Forward</button></div>
<div class="row-container"><button class="button" id="left-btn" onmousedown="btnVal('left')" onmouseup="btnVal('stop')">Left</button>
<button class="button" id="right-btn" onmousedown="btnVal('right')" onmouseup="btnVal('stop')">Right</button></div>
<div class="row-container"><button class="button" id="backward-btn" onmousedown="btnVal('backward')" onmouseup="btnVal('stop')">Backward</button></div></div>
</div>
<div class="row-container"><p>Servo Position: <span id="servoPos"></span></p></div>
<div class="row-container"><input type="range" min="0" max="180" class="slider" id="servoSlider" onchange="servo(this.value)" value="+valueString+"/></div>
<div class="row-container"><footer><p>@Maker101io</p></footer></div></div>
Finally, you make an HTTP GET request to get the values. Two functions are executed that process the button direction values and the slider value.
<!-- Script section. Get the button and slider values and executes functions. -->
<script>
var slider = document.getElementById("servoSlider");
var servoP = document.getElementById("servoPos");
servoP.innerHTML = slider.value;
slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value;}
$.ajaxSetup({timeout:1000});
function btnVal(dir) { $.get("/?btnVal=" + dir);}
function servo(pos) { $.get("/?value=" + pos + "&");}
{Connection: close};
</script></body></html>
Let's load the source code and test the functions. After uploading the code, open Serial Monitor. Copy the IP address that appears on the Serial Monitor. Open your browser, paste the IP address and you will see the previously created web page. Press and hold the motor direction buttons and release. In the Serial Monitor you can see the HTTP requests you are sending to the ESP.
The “If” and “Else” statements are a condition. It controls which button is pressed and runs the function determined according to the received data. This data contains the variables defined for the buttons. When you move the slider, the slider position between the two symbol is taken and stored in the "value string" variable. Then this string value is converted to an integer value. This converted value is written to the servo motor position. The servo motor moves to this position value.
if(header.indexOf("GET /?value=")>=0) {
pos1 = header.indexOf('=');
pos2 = header.indexOf('&');
valueString = header.substring(pos1+1, pos2);
myServo.write(valueString.toInt()); // Rotate the servo
Serial.println(valueString);
} else if (header.indexOf("GET /?btnVal=forward")!= -1) {
Serial.println("FORWARD");
forward(); // Turn forward
} else if (header.indexOf("GET /?btnVal=left")!= -1) {
Serial.println("LEFT");
turnLeft(); // Turn left
} else if (header.indexOf("GET /?btnVal=right")!= -1) {
Serial.println("RIGHT");
turnRight(); // Turn right
} else if (header.indexOf("GET /?btnVal=backward")!= -1) {
Serial.println("BACK");
backward(); // Turn backward
} else if (header.indexOf("GET /?btnVal=stop")!= -1) {
Serial.println("STOP");
stopMotors(); // Stopped
}
// 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("");
}
}
Thanks for your interest and reading. If you have any questions or suggestions, please let me know in the comments.
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Style section for buttons and slider. You can change customizations such as color and so on. -->
<style>
.container {font: caption; display: block; flex-direction: column; align-items: center;}
.slider {width: 275px; accent-color: #ede100; cursor: pointer;}
.button-container {display: flex; flex-direction: column; align-items: center;}
.row-container {display: flex; flex-direction: row; justify-content: center; align-items: center;}
.button {width: 135px; border: 0; background-color: #ede100; box-shadow: inset 2px 2px 3px #b2b2b2, inset -2px -2px 3px #000; padding: 10px 25px; text-align: center; display: inline-block; border-radius: 5px; font-size: 16px; margin: 10px 25px; cursor: pointer;}
.button:hover {background-color: #fff200;}
.button:active{box-shadow: inset 2px 2px 3px #000, inset -2px -2px 3px #b2b2b2;}
footer {text-align: center; margin: 50px; width: 400px; background-color: #ede100;}
</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script></head>
<!-- Body section. Contains functions of buttons and slider. -->
<body>
<div class="container">
<div class="row-container"><h2>ESP8266 Motor Control Panel</h2></div>
<div><div class="button-container">
<div class="row-container"><button class="button" id="forward-btn" onmousedown="btnVal('forward')" onmouseup="btnVal('stop')">Forward</button></div>
<div class="row-container"><button class="button" id="left-btn" onmousedown="btnVal('left')" onmouseup="btnVal('stop')">Left</button>
<button class="button" id="right-btn" onmousedown="btnVal('right')" onmouseup="btnVal('stop')">Right</button></div>
<div class="row-container"><button class="button" id="backward-btn" onmousedown="btnVal('backward')" onmouseup="btnVal('stop')">Backward</button></div></div>
</div>
<div class="row-container"><p>Servo Position: <span id="servoPos"></span></p></div>
<div class="row-container"><input type="range" min="0" max="180" class="slider" id="servoSlider" onchange="servo(this.value)" value="+valueString+"/></div>
<div class="row-container"><footer><p>@Maker101io</p></footer></div></div>
<!-- Script section. Get the button and slider values and executes functions. -->
<script>
var slider = document.getElementById("servoSlider");
var servoP = document.getElementById("servoPos");
servoP.innerHTML = slider.value;
slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value;}
$.ajaxSetup({timeout:1000});
function btnVal(dir) { $.get("/?btnVal=" + dir);}
function servo(pos) { $.get("/?value=" + pos + "&");}
{Connection: close};
</script></body></html>
Dual DC Motor and Servo Motor control via Web Server - ESP8266 DRV8848 Motor Driver Board
*PCBWay community is a shared platform and we are not responsible for any design issues.
- Comments(0)
- Likes(2)
-
Engineer May 05,2023
-
MERT KILIC May 03,2023
- 0 USER VOTES
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
More by MERT KILIC
-
Robot Sumo Board Robot-sumo, or pepe-sumo, is a sport in which two robots attempt to push each other out of a circle ...
-
ESP32 Mecanum Wheels Robot and Bluetooth Gamepad Controller In this project we will see how to make an ESP32 Mecanum Wheels Robot which is capable of moving in ...
-
DIY Motorized WiFi Roller Blind - ESP8266 & Blynk In this project we will see how to control a roller blind via a smartphone application. The reason w...
-
Pet Feeder Controlled Via WiFi - ESP8266 How It Works?As you can see, a 3D design was used for the pet feeder. ESP8266-based Wemos D1 Mini bo...
-
ESP8266 Two Wheel Robot (NodeMCU and Stepper Motor) Generally, robot cars are built on a chassis with 2 DC motor wheels and a bovine wheel. While surfin...
-
3D Printed Rotating Table Board with Arduino Nano and 28BYJ-48 Stepper Motor This project shows how to make a 3D printed Rotating Table using Arduino and a hobby stepper motor. ...
-
Hand Gesture Controller for Robotic Hand Gesture Controller for RoboticThe hand gesture controller makes it possible to control applicat...
-
How To Make DIY Remote Control Hoverboat at Home In this video, I showed you how to make your own hoverboat from materials available at home and chea...
-
How to Make DIY Arduino Gesture Control Robot at Home Parts Required for Receiver (Tank):1) Robot Tank Chassis - https://bit.ly/3j8y2Q52) Arduino Nano V3 ...
-
DIY Circuit Activty Board with Paperclips | MAKER | STEM You can be creative and design your own circuit and add different sensors (other LEDs...). The idea ...
-
ATtiny85 Wearable Activity Tracking Watch How to make the wearable activity tracking watch? This is a wearable gadget designed to vibrate when...
-
Build a Self Watering System (Soil Moisture Sensor - Water Pump - Water Level Sensor - MOSFET - Circuit - Code) This project shows how to build a self-watering system whose values can be monitored through an app....
-
DIY ESP32 Bluetooth GamePad for Android, PlayStation and PC In this project, we will first see how to build a breadboard gamepad circuit, and how you can commun...
-
One and Multiple Servo Motor Control With ESP32 Development Board (DOIT ESP32 DEVKIT V1) IThis article covers controlling a Servo motor using the ESP32 development board. Also, this article...
-
Dual DC Motor and Servo Motor control via Web Server - ESP8266 DRV8848 Motor Driver Board In this project you will see how to build a web server with ESP that controls dual DC motor directio...
-
ESP8266 ESP-12F DRV8848 Motor Driver Development Board Line Following - Obstacle Avoiding - Drawing Robot (ESP8266 Dual DC Motor Controller Board)Hi everyo...
-
Modules for Educational Programming Board Gerber page of modules belonging to the open source ESP8266 Education Programming BoardVisit this li...
-
Open Source Educational Programming Board and Modules (Coded by ChatGPT) In this project, I will show you the assembly and use of the educational programming board and modul...
-
Pipistrelle BatWalk auto scanning / time-expanding bat detector
326 0 1 -
Commodore AMIGA PSU USB-C Power Sink Delivery Supply High Efficiency Triple Output 5V ±12V OLED ATARI ST
521 3 5 -
Ultrasonic distance meter without microcontroller
305 0 1 -
-