Welcome back, everyone! Due to popular demand, I’ve created a new project that showcases how to control multiple servo motors using an ESP8266 via a Wi-Fi Soft Access Point (AP) web server. This project is ideal for anyone looking to expand their knowledge in electronics, specifically with the use of ESP8266 and servo motors.
In this project, I will guide you through setting up a web server on the ESP8266 that allows you to control several servo motors simultaneously. By creating a web interface, you can adjust the angles of the servos using sliders and buttons from any device connected to the ESP8266’s network. This makes it a versatile project for applications in robotics, home automation, and other DIY electronics projects.
The ESP8266 is a powerful and affordable microcontroller with built-in Wi-Fi capabilities, making it perfect for IoT projects. By utilizing its Wi-Fi feature, we can create a web server that can be accessed through any web browser, eliminating the need for additional hardware or complicated setups. This makes the project more accessible and easier to implement for hobbyists and enthusiasts alike.
You can also adjust the code in the Arduino IDE according to your specific requirements. The flexibility of this project allows for various customizations, whether you need to control more servos, integrate additional sensors, or modify the web interface to better suit your needs. The Arduino IDE provides a user-friendly environment to write, compile, and upload code to the ESP8266, ensuring that even beginners can follow along and succeed.
Simply follow the steps outlined in my video, and you'll have your multi-servo controller up and running in no time. The video provides a detailed, step-by-step tutorial, covering everything from the initial setup to the final testing of your servo motors. Whether you're a seasoned maker or just starting out, this project is a great way to enhance your skills and explore the capabilities of the ESP8266.
Part Needed:-
1x ESP8266 NodeMCU
4x Servo Motor
1x NeoPixel LED Ring(This is option you can use or not depends on you)
Some Jumper Wires
5V 1 Amps Power Supply
Schematic:-
Follow this Schematic to make this make sure power is correct or checked properly. You can Build in breadboard or simply solder components on breadboard.
+5V Power Supply GND |
ESP8266 Module Pins |
Components |
|
Yes |
Yes |
Digital Pin 1 |
Servo Motor 1 |
Yes |
Yes |
Digital Pin 2 |
Servo Motor 2 |
Yes |
Yes |
Digital Pin 6 |
Servo Motor 3 |
Yes |
Yes |
Digital Pin 7 |
Servo Motor 4 |
Yes |
Yes |
Digital Pin 5 |
NeoPixel LED Input |
The Main Code:-
#include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include <Servo.h> #include <Adafruit_NeoPixel.h> // Include the HTML file #include "webpage.h" // Wi-Fi credentials const char* ssid = "ESP8266-Servo"; // You can Change the SSID here const char* password = "password"; // You can also change the Password here // NeoPixel configuration #define LED_PIN D5 #define NUM_LEDS 16 Adafruit_NeoPixel pixels(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800); // Create web server object ESP8266WebServer server(80); // Create servo objects Servo servo1, servo2, servo3, servo4; int pos1 = 90, pos2 = 90, pos3 = 90, pos4 = 90; // Initial positions for servos void setup() { // Initialize serial communication Serial.begin(115200); Serial.println("NeoPixel Loading Effect"); // Initialize NeoPixel pixels.begin(); pixels.show(); // Initialize all pixels to 'off' // Set up servos servo1.attach(D1); servo2.attach(D2); servo3.attach(D6); servo4.attach(D7); servo1.write(pos1); servo2.write(pos2); servo3.write(pos3); servo4.write(pos4); // Set up Wi-Fi WiFi.softAP(ssid, password); // Define web server routes server.on("/", handleRoot); server.on("/servo1", handleServo1); server.on("/servo2", handleServo2); server.on("/servo3", handleServo3); server.on("/servo4", handleServo4); server.onNotFound(handleNotFound); // Start web server server.begin(); Serial.println("HTTP server started"); // Start the NeoPixel loading effect startLoadingEffect(); } void loop() { // Handle client requests server.handleClient(); } void handleRoot() { String html = FPSTR(webpage); // Use the stored HTML page server.send(200, "text/html", html); } void handleServo1() { if (server.hasArg("pos")) { pos1 = server.arg("pos").toInt(); servo1.write(pos1); updateLoadingEffect(); } server.send(200, "text/plain", "OK"); } void handleServo2() { if (server.hasArg("pos")) { pos2 = server.arg("pos").toInt(); servo2.write(pos2); updateLoadingEffect(); } server.send(200, "text/plain", "OK"); } void handleServo3() { if (server.hasArg("pos")) { pos3 = server.arg("pos").toInt(); servo3.write(pos3); updateLoadingEffect(); } server.send(200, "text/plain", "OK"); } void handleServo4() { if (server.hasArg("pos")) { pos4 = server.arg("pos").toInt(); servo4.write(pos4); updateLoadingEffect(); } server.send(200, "text/plain", "OK"); } void handleNotFound() { server.send(404, "text/plain", "404: Not Found"); } void startLoadingEffect() { int delayTime = 50; // Adjust speed of loading effect (smaller value = faster) // Gradient filling effect for (int i = 0; i < NUM_LEDS; i++) { for (int hue = 0; hue <= 255; hue++) { // Calculate brightness based on current hue position uint8_t brightness = map(hue, 0, 255, 0, 255); // Set color with adjusted brightness pixels.setPixelColor(i, pixels.ColorHSV(hue, 255, brightness)); pixels.show(); delayMicroseconds(delayTime * 100); // Adjust speed more smoothly } delay(delayTime * 5); // Pause between each LED filling } Serial.println("Loading complete!"); } void updateLoadingEffect() { int position = (pos1 + pos2 + pos3 + pos4) / 4; // Calculate average position int hue = map(position, 0, 180, 0, 65535); // Map servo position to hue for (int i = 0; i < NUM_LEDS; i++) { pixels.setPixelColor(i, pixels.ColorHSV(hue, 255, 255)); } pixels.show(); }Now Open New tab by pressing (Crtl+Shift+N) and rename it this webpage.h and save and
then paste this Web code.
const char webpage[] PROGMEM = R"=====( <!DOCTYPE html> <html> <head> <meta name='viewport' content='width=device-width, initial-scale=1'/> <title>ESP8266 Servo Control</title> <style> body { font-family: Arial, sans-serif; text-align: center; background: linear-gradient(to right, #00c6ff, #0072ff); color: white; } h1 { color: #ffcc00; } .slider-container { margin: 20px auto; width: 80%; max-width: 600px; } .slider { width: 100%; margin: 10px 0; } .button { background-color: #6a1b9a; border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; border-radius: 8px; transition-duration: 0.4s; } .button:hover { background-color: white; color: black; border: 2px solid #6a1b9a; } </style> <script> function updateServo(servo, value) { fetch(`/${servo}?pos=${value}`); } </script> </head> <body> <h1>ESP8266 Servo Control</h1> <div class="slider-container"> <input type="range" min="0" max="180" value="90" class="slider" id="servo1" oninput="updateServo('servo1', this.value)"> <button class="button" onclick="updateServo('servo1', 0)">0°</button> <button class="button" onclick="updateServo('servo1', 45)">45°</button> <button class="button" onclick="updateServo('servo1', 90)">90°</button> <button class="button" onclick="updateServo('servo1', 180)">180°</button> </div> <div class="slider-container"> <input type="range" min="0" max="180" value="90" class="slider" id="servo2" oninput="updateServo('servo2', this.value)"> <button class="button" onclick="updateServo('servo2', 0)">0°</button> <button class="button" onclick="updateServo('servo2', 45)">45°</button> <button class="button" onclick="updateServo('servo2', 90)">90°</button> <button class="button" onclick="updateServo('servo2', 180)">180°</button> </div> <div class="slider-container"> <input type="range" min="0" max="180" value="90" class="slider" id="servo3" oninput="updateServo('servo3', this.value)"> <button class="button" onclick="updateServo('servo3', 0)">0°</button> <button class="button" onclick="updateServo('servo3', 45)">45°</button> <button class="button" onclick="updateServo('servo3', 90)">90°</button> <button class="button" onclick="updateServo('servo3', 180)">180°</button> </div> <div class="slider-container"> <input type="range" min="0" max="180" value="90" class="slider" id="servo4" oninput="updateServo('servo4', this.value)"> <button class="button" onclick="updateServo('servo4', 0)">0°</button> <button class="button" onclick="updateServo('servo4', 45)">45°</button> <button class="button" onclick="updateServo('servo4', 90)">90°</button> <button class="button" onclick="updateServo('servo4', 180)">180°</button> </div> </body> </html> )=====";
startLoadingEffect()
to visually represent the change:Now Fun
This project not only enhances
your skills in working with microcontrollers and IoT but also opens up numerous
possibilities for your own creative applications in robotics and home
automation.
Feel free to customize the code
and hardware setup to suit your specific needs and share your own modifications
and ideas in the comments below. Your feedback is invaluable and helps us
improve and bring more exciting projects to the community.
Thank you for following along
with this tutorial. Don't forget to check out my other projects and subscribe
to my YouTube channel for more in-depth guides and innovative ideas. Happy
building!
Comments
Post a Comment