ESP8266 Servo Motor Control

In this tutorial ESP8266 we will see How to control Servo motor using NodeMCU web server? where the position of the Servo Motor can be controlled through a Web Page (within the same WiFi Network).

Servo motor control using NodeMCU

Introduction

Servo Motors are one of the most commonly used motors in both industries and DIY Projects.

I’ll be creating a simple Web Page (HTML) with a circular knob. When this web page is accessed from a laptop or mobile phone that is connected to the same WiFi Network as the ESP8266, you can control the position of the Servo Motor by adjusting the knob.

Web Controlled Servo using ESP8266

Normally, in order to control a Servo Motor with Arduino (for example), all you need is a Servo Motor, Arduino and a Potentiometer. Depending on the position of the POT, the PWM value of the Servo Motor input changes and consequently the position of the Servo Motor’s shaft changes.

In case of a Web Controlled Servo Motor using ESP8266, ESP8266 drives the Servo Motor but the input isn’t from a POT but a Web Page we created with AJAX.

The slider in the web page sends the angle values and is received by the NodeMCU, which acts as a Web Server. The NodeMCU, upon receiving the value, transmits corresponding PWM to servo, which then changes the position of the Servo Motor according to the value.

One important thing to remember here is that both the Server and client should be on the same network i.e. the ESP8266, which acts as the Server, and the Laptop (or a Mobile Phone), which is the client, must be connected to the same WiFi network.

Circuit Diagram

The circuit diagram for Web Controlled Servo using ESP8266 WiFi Module is given in the image below.

interfacing servo motor with NodeMCU

Components Required

  1. ESP8266 based Board (NodeMCU)
  2. Servo Motor
  3. Jumper Wires
  4. Laptop

Working of the Circuit

The main program responsible for everything i.e. connecting ESP8266 to WiFi, getting information from Web and finally controlling the Servo.

Pin D5 of NodeMCU will provide the necessary PWM signal to the Servo (Orange). Its other pins are power supply pins and are connected to 5V and GND (Red and Brown).

ESP8266 Servo Arduino Code

The Arduino IDE Code for the Web Controlled Servo using ESP8266 tutorial is given below.

Program is divided in tow parts Web Page (index.h) and Main Hardware Code ESPservo.ino

ESPservo.ino

before uploading code make changes in SSID and Password as per your wifi

/*
 * ESP8266 Servo Motor Control With Web Server 
 * https://circuits4you.com
 */

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

#include "index.h";

#define LED 2
#define ServoPin 14   //D5 is GPIO14

//WiFi Connection configuration
const char *ssid = "your-ssid";
const char *password = "your-password";


Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

ESP8266WebServer server(80);

//================================================
void handleServo(){
  String POS = server.arg("servoPOS");
  int pos = POS.toInt();
  myservo.write(pos);   // tell servo to go to position
  delay(15);
  Serial.print("Servo Angle:");
  Serial.println(pos);
  digitalWrite(LED,!(digitalRead(LED))); //Toggle LED
  server.send(200, "text/plane","");
}

void handleRoot() {
 String s = MAIN_page; //Read HTML contents
 server.send(200, "text/html", s); //Send web page
}

//================================================
//            Setup
//================================================
void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println();

  pinMode(LED,OUTPUT);
  myservo.attach(ServoPin); // attaches the servo on GIO2 to the servo object
  
  //Connect to wifi Network
  WiFi.begin(ssid, password);     //Connect to your WiFi router
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  //If connection successful show IP address in serial monitor
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  //IP address assigned to your ESP

  //Initialize Webserver
  server.on("/",handleRoot);
  server.on("/setPOS",handleServo); //Sets servo position from Web request
  server.begin();  
}

//================================================
//     LOOP
//================================================
void loop() {
 server.handleClient();
}
//================================================
index.h

Press Ctrl+Shift+N give name index.h and copy paste below code.

const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>ESP8266 Servo | Circuits4you.com</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<style>
.angle{
  width: 79px;
  height: 50px;
  position: absolute;
  vertical-align: middle;
  margin-top: 50px;
  margin-left: -114px;
  border: 0px none;
  background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%;
  font: normal normal bold normal 20px Arial;
  text-align: center;
  color: rgb(34, 34, 34);
  padding: 0px;
}

.spd{
  width: 79px;
  height: 50px;
  position: absolute;
  vertical-align: middle;
  margin-top: 50px;
  margin-left: -114px;
  border: 0px none;
  background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%;
  font: normal normal bold normal 50px Arial;
  text-align: center;
  color: rgb(34, 34, 34);
  padding: 0px;
}

.imageDiv{
    padding: 5%;
 }

.flx{
  display: flex;
}

</style>
<body>
<div style="width:100%;">
<div style="width:50%;  margin: 0 auto;">
  <h3>Circuits4you.com</h3>
  <h4>ESP8266 Servo Motor Control Demo</h4>
</div>
</div>

<div style="width: 50%; margin: 0 auto;" class="flx">
  <svg viewBox="0 0 500 500" width="250" height="250" id="mySVG" style="background:#fff; border: 1px solid black">
  <path fill="none" stroke="#30D8D9"  stroke-width="50" d="M 376.79805300444093 404.6682053761632 A 200 200 0 1 0 121.44247806269212 403.2088886237956"></path>
  <path id="arc1" fill="none" stroke="#00A8A9" stroke-width="50" style="stroke-linecap: round;"/>
  <text x="230" y="260" fill="#777" id="angle" class="spd">0</text>
  <text x="200" y="300" fill="#777" class="angle">Servo Angle</text>
  </svg>
</div>

<script>
function sendData(pos) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      console.log(this.responseText);
    }
  };
  xhttp.open("GET", "setPOS?servoPOS="+pos, true);
  xhttp.send();
}

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
  var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

  return {
    x: centerX + (radius * Math.cos(angleInRadians)),
    y: centerY + (radius * Math.sin(angleInRadians))
  };
}

function describeArc(x, y, radius, startAngle, endAngle){

    var start = polarToCartesian(x, y, radius, endAngle);
    var end = polarToCartesian(x, y, radius, startAngle);

    var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";

    var d = [
        "M", start.x, start.y, 
        "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
    ].join(" ");

    return d;       
}

window.onload = function() {
  document.getElementById("arc1").setAttribute("d", describeArc(250, 250, 200, 220, 210));
};

var svg  = document.getElementById("mySVG");
    pt   = svg.createSVGPoint(),

svg.addEventListener('mousedown',function(evt){
  var loc = cursorPoint(evt);
  var degrees = Math.atan2(loc.x-250,loc.y-250)*180/Math.PI + 90;

  var offset = 220;
  
  degrees = (degrees + 90)
  degrees = degrees + offset;
  if(degrees > 360)
  {
    degrees = degrees - 360;
  } 
  degrees = 360 - degrees;
  angle = degrees + offset;

  console.log(degrees, angle);  
  
  if(degrees<281)
  {
    document.getElementById("arc1").setAttribute("d", describeArc(250, 250, 200, offset, angle));
    var servoAng = Math.round(((angle - 220)/280) * 100);
    document.getElementById("angle").innerHTML=servoAng;
    sendData(servoAng);
  }
});

// Get point in global SVG space
function cursorPoint(evt){
  pt.x = evt.clientX; pt.y = evt.clientY;
  return pt.matrixTransform(svg.getScreenCTM().inverse());
}

</script>

</body>
</html>
)=====";

Working of Web Controlled Servo using ESP8266

Let us now see the working of the Web Controlled Servo using ESP8266. After making all the connections as per the circuit diagram, upload the NodeMCU code.

After the code is uploaded, if you open the serial monitor, you can see the status of the ESP8266 WiFi Module. After all the initialization steps are done (set mode to Station mode, connect ESP8266 to WiFi and start web server), you can proceed for Web Control.

Now Get IP address of ESP8266 from serial monitor and open it using any web browser. If everything is right, when you change the position of the slider, the position of the servo Motor will be changed.

ESP8266 Servo Motor Control using web

Applications

The idea behind Web Controlled Servo using ESP8266 is to implement a web-controlled device (in this case, a Servo Motor) i.e. to control a motor through internet.

This application can be further extended to more advanced and complex projects like controlling a Robot from the Internet.

5 thoughts on “ESP8266 Servo Motor Control

  1. The “5v” pin is a VIN pin. That is for 5v power input into the board. It will not produce a 5v out. This will def not work properly.

  2. I would very much like to do this project, but instead of a webserver, I just want to issue a tcp command of some sort from a linux system on the same network to move the servo angle. How would I do that ?

  3. Doesn’t work for me. I copied the code examples and configured my wifi, compiled, loaded. It boots up and serial says it’s connected to my wifi. As soon as I try to access the webserver, I get “Exception(3)” and a stack trace, and the chip reboots.

Leave a Reply