Самоходная платформа на МК esp8266 с micropython

Привет, Хабр!

Эта статья описывает страдания начинающего процесс изготовления самоходной платформы на базе МК esp8266 с micropython, управляемой через встроенный веб-сервер.

КДПВ:

xq68kcbzxjotjf-zvquabsaq5jk.jpeg

Интерфейс:
image


Как я уже упоминал в первой статье, проект учебный, так что прошу не судить строго.

Итак, задача первого этапа — сделать гусеничную платформу, которой можно управлять через wi-fi.
Для чего в закромах был найден старый игрушечный танк, а также закуплен МК esp8266 (ESP-12E) и драйвер моторов к нему.

esp8266 и motorshield в сборе
iolnswwraxouwbvpka3tegfskqs.jpeg


Далее, всё вышеперечисленное было собрано в соответствии со схемой:

izb3qbe6dtgx8c1b6zdxmfpmxlq.jpeg

И после пары дней непродолжительного изучения документации, стало понятно, как же управлять моторами:

from machine import Pin, PWM
""" nodemcu pins from the motor shield """
servo_1 = Pin(5, Pin.OUT)  # PWMA-GPIO5
servo_2 = Pin(4, Pin.OUT)  # PWMB-GPIO4
revrs_L = Pin(0, Pin.OUT, value=0)  # DA-GPIO0
revrs_R = Pin(2, Pin.OUT, value=0)  # DB-GPIO2
""" named after the L9110 h-bridge pins """
motor_L = PWM(servo_1, freq=1000, duty=0)
motor_R = PWM(servo_2, freq=1000, duty=0)
""" TODO: variable speed """
speed = 1023 
def stop_all():
    revrs_L.value(0)
    motor_L.duty(0)
    revrs_R.value(0)
    motor_R.duty(0)

def forward():
    revrs_L.value(0)
    motor_L.duty(speed)
    revrs_R.value(0)
    motor_R.duty(speed)


Таким образом, pin5 и pin4 — позволяют задать скорость вращения моторов через ШИМ, а pin0 и pin2 — управляют реверсом для выходов «А» и «В» соответственно. Кроме того, так как на моей плате к pin2 ещё подключен и светодиод — то параллельно с движением наблюдаем и световые эффекты :)

Однако, сразу не взлетело…

Гугление на заданную тему, привело на форум, где была рекомендация удалить два «лишних» резистора, что и было проделано. Цитата оттуда:

Я измерил эти резисторы, на входе в L293DD сопротивление 1КОм, но они имеют сопротивление только 100 Ом к земле. Это означает, что входной сигнал от контроллера NodeMCU не может достичь L293DD. Я действительно не знаю, почему они там — L293DD может обрабатывать до 7 В на своем входе, а NodeMCU выдает выход 3,3 В.
Я удалил эти два резистора по 100 Ом (первый и третий слева, когда антенна находится справа), и теперь шилд работает.

e1oaten8v4vuj05qi3xajgwj2io.jpeg

После этого, дело пошло на лад, и 

финальный вариант кода
# RoboTank based on ESP8266 with motor shield
import network
import socket
from machine import Pin, PWM

""" nodemcu pins from the motor shield """
servo_1 = Pin(5, Pin.OUT)  # PWMA-GPIO5
servo_2 = Pin(4, Pin.OUT)  # PWMB-GPIO4
revrs_L = Pin(0, Pin.OUT, value=0)  # DA-GPIO0
revrs_R = Pin(2, Pin.OUT, value=0)  # DB-GPIO2

""" named after the L9110 h-bridge pins """
motor_L = PWM(servo_1, freq=1000, duty=0)
motor_R = PWM(servo_2, freq=1000, duty=0)

""" TODO: variable speed """
speed = 1023 

""" function for connecting to your local WiFi network """
def do_connect():
    essid = 'home_wifi'
    password = '12345678'
    sta_if = network.WLAN(network.STA_IF)
    if not sta_if.isconnected():
        print('connecting to network...')
        sta_if.active(True)
        sta_if.connect(essid, password)
        while not sta_if.isconnected():
            pass
    print('network config:', sta_if.ifconfig())

def stop_all():
    revrs_L.value(0)
    motor_L.duty(0)
    revrs_R.value(0)
    motor_R.duty(0)

def backward():
    revrs_L.value(1)
    motor_L.duty(speed)
    revrs_R.value(1)
    motor_R.duty(speed)

def forward():
    revrs_L.value(0)
    motor_L.duty(speed)
    revrs_R.value(0)
    motor_R.duty(speed)

def right():
    revrs_L.value(0)
    motor_L.duty(speed)
    revrs_R.value(1)
    motor_R.duty(speed)

def left():
    revrs_L.value(1)
    motor_L.duty(speed)
    revrs_R.value(0)
    motor_R.duty(speed)
    
def right_turn():
    revrs_L.value(0)
    motor_L.duty(speed)
    revrs_R.value(0)
    motor_R.duty(0)

def left_turn():
    revrs_L.value(0)
    motor_L.duty(0)
    revrs_R.value(0)
    motor_R.duty(speed)

def web_page(request):
  motor_state="Stopped"
  if request.find('GET /?forward') > 0:
    motor_state="Going Forward"
    forward()
  if request.find('GET /?left') > 0:
    motor_state="Rotate Left"
    left()
  if request.find('GET /?right') > 0:
    motor_state="Rotate Right" 
    right()
  if request.find('GET /?left_turn') > 0:
    motor_state="Turn Left"
    left_turn()
  if request.find('GET /?right_turn') > 0:
    motor_state="Turn Right" 
    right_turn()
  if request.find('GET /?backward') > 0:
    motor_state="Going Backward"
    backward()
  if request.find('GET /?stop') > 0:
    motor_state="Stopped"
    stop_all()
  
  html = """RoboTank WEB 
  
   
   

RoboTank WEB

Status : """ + motor_state + """

""" return html #Stop all motors first stop_all() # connect to wi-fi network do_connect() # create socket for web srvr addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] s = socket.socket() try: s.bind(addr) s.listen(1) except: s.close() s.bind(addr) s.listen(1) # main loop while True: conn, addr = s.accept() print('Got a connection from %s' % str(addr)) request = conn.recv(1024) request = str(request) print('The Content = %s' % request) response = web_page(request) conn.send('HTTP/1.1 200 OK\n') conn.send('Content-Type: text/html\n') conn.send('Connection: close\n\n') conn.sendall(response) conn.close()


оказался вполне работоспособным, и успешно решающим поставленную на первый этап задачу.

Первые покатушки:


Первая часть (Установка micropython на ESP8266 и работа с ним под Linux)

Источники вдохновения:

funprojects.blog/2019/02/12/micropython-air-boat
www.instructables.com/id/Simplest-Wifi-Car-Using-ESP8266-Motorshield
forum.micropython.org/viewtopic.php? t=3977
randomnerdtutorials.com/esp32-esp8266-micropython-web-server
docs.micropython.org/en/latest/esp8266/tutorial/index.html

© Habrahabr.ru