Plataforma autopropulsada en el esp8266 MK con micropython

Hola Habr!

Este artículo describe el sufrimiento de un principiante en el proceso de fabricación de una plataforma de plataforma autopropulsada basada en esp8266 MK con micropython , administrada a través de un servidor web integrado.

KDPV:



Interfaz:
imagen

Como mencioné en el primer artículo , el proyecto es educativo, por lo tanto, no juzgue estrictamente.

Entonces, la tarea de la primera etapa es hacer una plataforma de oruga que se pueda controlar a través de wi-fi.
Con qué propósito en los contenedores se encontró un viejo tanque de juguete, y también se compraron MK esp8266 (ESP-12E) y un controlador de motor.

montaje esp8266 y motor


Además, todo lo anterior se recopiló de acuerdo con el esquema:



y después de un par de días de un breve estudio de la documentación , quedó claro cómo controlar los motores:

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)

Por lo tanto, pin5 y pin4 - le permiten configurar la velocidad de rotación de los motores a través del PWM, y pin0 y pin2 - controlan el reverso de las salidas "A" y "B", respectivamente. Además, dado que el LED también está conectado al pin2 en mi placa, observamos efectos de luz en paralelo con el movimiento :)

Sin embargo, no despegó de inmediato ...

Google sobre un tema dado condujo a un foro donde había una recomendación para eliminar dos resistencias "adicionales", Lo cual fue hecho. Cita a partir de ahí:
Medí estas resistencias, en la entrada al L293DD, la resistencia es de 1K, pero tienen una resistencia de solo 100 ohmios a tierra. Esto significa que la señal de entrada del controlador NodeMCU no puede alcanzar el L293DD. Realmente no sé por qué están allí: L293DD puede procesar hasta 7 V en su entrada, y NodeMCU proporciona una salida de 3,3 V. Quité
estas dos resistencias de 100 ohmios (el primero y el tercero a la izquierda cuando la antena está a la derecha), y ahora El escudo funciona.


Después de eso, las cosas salieron bien y

versión final del código
# 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 = """<html><head><title>RoboTank WEB</title> 
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,"> <style>
  html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;}
  h1{color: #0F3376; padding: 2vh;}p{font-size: 1.5rem;}
  .button{display: inline-block; background-color: #33c080; border: none; 
  border-radius: 4px; color: white; text-decoration: none; font-size: 30px; width:100%}
  .button2{background-color: #4286f4; width:30%}
  .button3{background-color: #eb2b10; width:35%}
  .button4{background-color: #8386f4; width:44%}
  </style></head>
  <body> <h1>RoboTank WEB</h1> 
  <p>Status : <strong>""" + motor_state + """</strong></p>
  <p><a href='/?forward'><button class="button">Forward</button></a></p>
  <p><a href='/?left_turn'><button class="button button2">LEFT</button></a>
  <a href='/?stop'><button class="button button3">STOP</button></a>
  <a href='/?right_turn'><button class="button button2">RIGHT</button></a>
  <p><a href='/?backward'><button class="button">Backward</button></a></p>
  <p><a href='/?left'><button class="button button4">L-rotate</button></a>
  <a href='/?right'><button class="button button4">R-rotate</button></a></p>
  </body></html>""" 

  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()


Resultó ser bastante eficiente y resolvió con éxito la tarea establecida en la primera etapa.

El primer pokatushki:


Primera parte (Instalar micropython en ESP8266 y trabajar con él en Linux)

Siguiente parte (Robot simple en MK esp8266 con micropython)

Fuentes de inspiración:

funprojects.blog/2019/02/12/micropython-air-boat
www.instructables.com/id / más simple-Wifi-Car-Utilizando-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

All Articles