[EN] ESP8266+RoboServo

This article is an example of programming in Python to operate a DC electric motor called a servo motor, and when a servo motor is used to drive the wheels on the left and right, it can easily work as a wheeled robot. Also, an example program of this article is to commands the movement of a wheel-driven robot to move forward, backward, turn left, turn right and stop.

(Figure. 1)

Equipment

The equipment used to compose this article consists of

  1. ESP8266
  2. ETT’s R-Base, which is a car body kit made of ALUMINUM 3 mm thick.
  3. Two servos that can rotate 360 degrees.
  4. The wheel or a crawler set(R-TANK V1 KIT).
  5. Support wheels.
  6. Power supply (We use a Power Bank)
(Figure. 2 ESP8266)
(Figure. 3 Servo Motor)

Programming the Servo

The servo motor has 3 wires for Vcc (red), Gnd (black or brown) and control signal (yellow). The voltage supplied to the Vcc pin depends on the properties of the selected servo.

To operate the servo, it has to send a pulse (Pulse) to the control pin of the motor to command the servo to turn counterclockwise, clockwise and stop with Duty Cycle configuration. The pattern for creating control objects can be written as follows.

var = machine.PWM( machine.Pin( pin ), freq=50 )

To activate the clockwise direction of the servo, the Duty Cycle must be configured. Each motor model may have different values. But the motor used in this article can be written as follows

var.duty( 120 )

Ordering it to turn clockwise is written as follows.

var.duty( 40 )

For stop command is as follows.

var.duty( 0 )

Connection

For the connection between ESP8266 and servo motor, the author has performed as follows:

  1. D1 pin or GPIO5 of the ESP8266 is connected to the left motor’s signal pin of the wheeled robot.
  2. D2 pin or GPIO4 of the ESP8266 is connected to the right motor’s signal pin of the wheeled robot.

Commanding the wheeled robot to move with the wheels with the following principles:

  1. Forwarding relies on rotating the left motor counterclockwise and the right motor clockwise.
  2. Reversing relies on rotating the left motor clockwise and the right motor counterclockwise.
  3. Turning left is to instructs the left motor to turn clockwise and the right motor counterclockwise.
  4. Turning right requires that the left motor rotates counterclockwise and the right motor clockwise.
  5. Stop by commanding both motors to stop or with a Duty Cycle value of 0.

Example code

Example code11-1 allows a wheeled robot to move forward, backward, turn left, turn right, and stop using a web browser by connecting to the AP named JarutEx-AP and set the access code to 123456789 (can be modified to the desired AP name and password), after that, enter the Browser and set the URL as 192.168.4.1, the screen will display as in Figure 4-8 which shows the status of stop, forward, backward, turn left and turn right of the robot.

# code11-1
import socket
import network
import esp
import time
import gc
import time
import machine as mc
servoL = mc.PWM(mc.Pin(5),freq=50)
servoR = mc.PWM(mc.Pin(4),freq=50)

def robotForward():
    global servoL,servoR
    servoL.duty(120)
    servoR.duty(40)

def robotStop():
    global servoL,servoR
    servoL.duty(0)
    servoR.duty(0)
    
def robotBackward():
    global servoL,servoR
    servoL.duty(40)
    servoR.duty(120)
    
def robotTurnRight():
    global servoL,servoR
    servoL.duty(120)
    servoR.duty(120)
    
def robotTurnLeft():
    global servoL,servoR
    servoL.duty(40)
    servoR.duty(40)

motionState = 0 # 0-Stop,1-Forward,2-Backward,3-TurnLeft,4-TurnRight

def webPage():
    global motionState
    html = """
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.button {  border: none;  color: white;  padding: 20px;  text-align: center;  text-decoration: none;
  display: inline-block;  font-size: 14
  px;  margin: 4px 2px;  cursor: pointer;  border-radius: 4%;
  width: 100%; height: 100%;
}
.button1 {  background-color: #3ABC40; }
.button2 {  background-color: #BC4040; }
</style></head><body><table>
"""
    if motionState == 0:
        html += """
<tr>
<td></td>
<td><a href='/?robot=forward'><button class='button button2'>Forward</button></a></td>
<td></td>
</tr>
<tr>
<td><a href='/?robot=left'><button class='button button2'>Turn Left</button></a></td>
<td><a href='/?robot=stop'><button  class='button button1'>Stop</button></a></td>
<td><a href='/?robot=right'><button class='button button2'>Turn Right</button></a></td>
</tr>
<tr>
<td></td>
<td><a href='/?robot=backward'><button class='button button2'>Backward</button></a></td>
<td></td>
</tr>
"""
    elif motionState == 1:
        html += """
<tr>
<td></td>
<td><a href='/?robot=forward'><button class='button button1'>Forward</button></a></td>
<td></td>
</tr>
<tr>
<td><a href='/?robot=left'><button class='button button2'>Turn Left</button></a></td>
<td><a href='/?robot=stop'><button  class='button button2'>Stop</button></a></td>
<td><a href='/?robot=right'><button class='button button2'>Turn Right</button></a></td>
</tr>
<tr>
<td></td>
<td><a href='/?robot=backward'><button class='button button2'>Backward</button></a></td>
<td></td>
</tr>
"""
    elif motionState == 2:
        html += """
<tr>
<td></td>
<td><a href='/?robot=forward'><button class='button button2'>Forward</button></a></td>
<td></td>
</tr>
<tr>
<td><a href='/?robot=left'><button class='button button2'>Turn Left</button></a></td>
<td><a href='/?robot=stop'><button  class='button button2'>Stop</button></a></td>
<td><a href='/?robot=right'><button class='button button2'>Turn Right</button></a></td>
</tr>
<tr>
<td></td>
<td><a href='/?robot=backward'><button class='button button1'>Backward</button></a></td>
<td></td>
</tr>
"""
    elif motionState == 3:
        html += """
<tr>
<td></td>
<td><a href='/?robot=forward'><button class='button button2'>Forward</button></a></td>
<td></td>
</tr>
<tr>
<td><a href='/?robot=left'><button class='button button1'>Turn Left</button></a></td>
<td><a href='/?robot=stop'><button  class='button button2'>Stop</button></a></td>
<td><a href='/?robot=right'><button class='button button2'>Turn Right</button></a></td>
</tr>
<tr>
<td></td>
<td><a href='/?robot=backward'><button class='button button2'>Backward</button></a></td>
<td></td>
</tr>
"""
    else:
        html += """
<tr>
<td></td>
<td><a href='/?robot=forward'><button class='button button2'>Forward</button></a></td>
<td></td>
</tr>
<tr>
<td><a href='/?robot=left'><button class='button button2'>Turn Left</button></a></td>
<td><a href='/?robot=stop'><button  class='button button2'>Stop</button></a></td>
<td><a href='/?robot=right'><button class='button button1'>Turn Right</button></a></td>
</tr>
<tr>
<td></td>
<td><a href='/?robot=backward'><button class='button button2'>Backward</button></a></td>
<td></td>
</tr>
"""
    html += "</table></body></html>"
    return html

# main program
if __name__ == '__main__':
    robotStop()
    ap = network.WLAN(network.AP_IF)
    ssid = 'JarutEx-AP'
    password = '123456789'
    ap.active(True)
    ap.config(essid=ssid, password=password)
    while ap.active() == False:
          pass
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('', 80))
    s.listen(1)
    while True:
        conn, addr = s.accept()
        #print('conn {} from {}'.format(conn, addr))
        request = str(conn.recv(1024))
        #print('request = {}'.format(request))
        robotCmdStop = request.find('/?robot=stop')
        robotCmdForward = request.find('/?robot=forward')
        robotCmdBackward = request.find('/?robot=backward')
        robotCmdTurnLeft = request.find('/?robot=left')
        robotCmdTurnRight = request.find('/?robot=right')
        if robotCmdStop == 6:
            motionState = 0
            robotStop()
        if robotCmdForward == 6:
            motionState = 1
            robotForward()
        if robotCmdBackward == 6:
            motionState = 2
            robotBackward()
        if robotCmdTurnLeft == 6:
            motionState = 3
            robotTurnLeft()
        if robotCmdTurnRight == 6:
            motionState = 4
            robotTurnRight()
        response = webPage()
        conn.send('HTTP/1.1 200 OK\n')
        conn.send('Content-Type: text/html\n')
        conn.send('Connection: close\n\n')
        conn.send(response)
        conn.close() 
(Figure. 4 The screen when wheeled robot stop moving.)
(Figure. 5 The screen when wheeled robot moving forward.)
(Figure. 6 The screen when wheeled robot moving backward.)
(Figure. 7 The screen when wheeled robot turning left.)
(Figure. 8 The screen when wheeled robot turning right.)

Conclusion

From this article, readers can write a Python program to control servo motors with the PWM function and setting the Duty Cycle so that the motor turns counterclockwise, clockwise and stop as well as being applied to drive a moving wheeled robot and giving command through the website.

We hope that this article will be more or less helpful to the reader, and finally, enjoy programming.

If you want to discuss something, feel free to leave comments below.

(C) 2020, Jarut Busarathid and Danai Jedsadathitikul
Updated 2021-05-13