En los blogs anteriores sobre el Coche Robot, hemos utilizado los robustos microcontroladores compatibles Uno y Nano. Ahora les vamos a explicar cómo realizarlo con Raspberry Pi. Poco después de su lanzamiento en 2012, los controladores de motor basados en el ICs L293D y los kits para automóviles robot estaban disponibles para el Raspberry Pi. Con el anual Pi Wars incluso hay una competencia por los modelos más versátiles; las tareas han sido muy exigentes hasta ahora.
En este blog quiero aprovechar una de las ventajas del Raspi y conectar un teclado inalámbrico al puerto USB. Además, utilizo una de las raras Raspberry Pi 3A+, ideal para nuestros propósitos. Básicamente, sin embargo, el código que se presenta a continuación funciona para cada modelo Raspi. Como un Controlador del Motor utilizo el MotoZero de ThePiHut. Como su nombre indica, este es un HAT (Hardware Adjunto en la parte Superior) en formato Pi Zero. Pero el encabezado J6 (mejor conocido como GPIO-pins) se ha mantenido sin cambios para todos los modelos durante años.
Un convertidor DC-DC es indispensable para nuestra construcción; utilizo el LM2596S Convertidor reductor DC-DC con Pantalla Digital en el que los voltajes se muestran directamente. La conmutación entre el voltaje de entrada o de salida se realiza a través del pequeño botón a la derecha de la pantalla de tres dígitos. Dado que la fuente de alimentación es a través del pin de 5V (pin 2 o 4), el voltaje de entrada para el Raspi debe ser muy preciso de 5.0 a 5.1 V. Los picos de voltaje pueden destruir la Raspberry Pi. Esto nunca me había pasado antes. Pero incluso un reinicio no planificado es lo suficientemente molesto, porque el proceso de arranque toma alrededor de un minuto.
Hardware Requerido
Número | Componente |
---|---|
1 | Raspberry Pi 3A+ |
o Raspberry Pi 3B / 3B+ o Raspberry Pi Zero / WH Nota: Al final, también queremos usar WLAN |
|
1 |
Controlador de Motor MotoZero |
1 | LM2596S Convertidor reductor DC-DC con Pantalla Digital |
1 | Teclado inalámbrico |
1 | Kit de coche robot con dos motores / ruedas |
Compartimiento de la batería, Cable de puente, Material pequeño |
Atornillé el convertidor DC-DC en la parte delantera debajo del chasis, el alojamiento para la Raspi y el compartimiento de la batería lo fijé con cinta de velcro o cinta de dos caras (alfombra) como antes.
Imagen: Coche Robot desde arriba con Raspberry Pi 3A + y Batería (2 baterías LiPo)
Imagen desde abajo: 2 motores y Convertidor DC-DC
Unas palabras más sobre el Raspberry Pi 3A + y el MotoZero: El modelo 3A + es la versión reducida del 3B + con procesador four-core, memoria de 512MB, WLAN/Bluetooth y un puerto USB-A. Puedo prescindir de una conexión LAN y otro puerto USB y tener el menor consumo de energía. Con el Pi Zero con el procesador simple, me molestó especialmente el hecho de que siempre necesitaba adaptadores para cables HDMI y USB.
El MotoZero es un simple Controlador de Motor con dos circuitos integrados del tipo L293D. Se pueden regular hasta cuatro motores. La ventaja de un HAT es que puede ahorrar una gran cantidad de conexiones de cable conectando el encabezado J6. El MotoZero viene como un kit y debe ser soldado. También se presenta esta Instrucción. Consejo: En lugar del cabezal GPIO de 40 pines suministrado, use el llamado cabezal apilable, donde los pines sobresalen significativamente hacia arriba. Los controladores de motor no utilizan todos los GPIOs, por lo que puede usar algunos pines para sensores u otras extensiones. Por razones estructurales utilicé las conexiones de motor 3 y 4. Y como descubrí en experimentos, el voltaje de referencia para la modulación de ancho de pulso (PWM) es decir, el control del motor, está en el pin de habitación del L293D.
Pinout
Motor | 1 | 2 | 3 | 4 |
---|---|---|---|---|
Habilitar Pin | 5 | 17 | 12 | 25 |
Terminal Positivo ( + ) | 24 | 6 | 23 | 13 |
Terminal Negativo ( - ) | 27 | 22 | 16 | 18 |
Software
Al igual que en publicaciones anteriores sobre Raspberry Pi y Python, esta vez también me gusta reconocer el módulo del programa gpiozero de Ben Nuttall et al, para mí un excelente ejemplo de programación orientada a objetos. Por supuesto, se implementan todas las funciones para el control de los motores, pero también la evaluación de sensores.
Dado que usamos los mismos motores que antes, decidí volver a utilizar el sistema con cinco pasos de velocidad por sentido. Como recordatorio: si el voltaje es demasiado bajo, los motores solo zumban, pero no arrancan. Y dependiendo de la fuente de alimentación, el voltaje también debe regularse hacia arriba. Por lo tanto, la lista speedLevel con los 11 elementos puede tener un aspecto diferente para usted. Con gpiozero, los valores deben estar entre -1 y + 1; por lo tanto, la división por 1000 tiene lugar con la asignación de valores. Además, tengo la oportunidad de adaptar los controles remotos de desarrollo propio con HC-12 y nRF24L01.
Script de Python
#! /usr/bin/python3
# Code for driving a robot car with MotoZero
# Motors attached to M3 and M4
# For motor control, use keybord w,a,s,y or arrow keys
# By Bernd54Albrecht for AZ-Delivery
from gpiozero import Robot, Motor, OutputDevice, LED
from signal import pause
import _thread
import sys
import termios
import tty
robot = Robot(left=(16,23), right=(13,18))
motor1_enable = OutputDevice(12, initial_value=1)
motor2_enable = OutputDevice(25, initial_value=1)
led = LED(4)
led.on()
code = 505
inkey_buffer = 1
def inkey():
fd=sys.stdin.fileno()
remember_attributes=termios.tcgetattr(fd)
tty.setraw(sys.stdin.fileno())
character=sys.stdin.read(inkey_buffer)
termios.tcsetattr(fd,termios.TCSADRAIN, remember_attributes)
return character
def readkey():
k1 = inkey()
if ord(k1) != 0x1b:
return k1
k2 = inkey()
if ord(k2) != 0x5b:
return k1
k3 = inkey()
return chr(0x10 + ord(k3) - 65) # 16=Up, 17=Down, 18=Right, 19=Left arrows
def getCode():
global code
key = readkey()
print("key = ",key,"ord(key)",ord(key))
if (key=='w' or ord(key) == 16) and code<1000:
code = code + 100
elif (key=='y' or ord(key) == 17) and code>100:
code = code-100
elif (key=='s' or ord(key) == 18) and code%100<10:
code = code+1
elif (key=='a' or ord(key) == 19) and code%100>0:
code = code-1
elif key == ' ':
code = 505
elif ord(key) == 3:
code=505
led.off()
exit()
print(code)
return
def motor(y,x):
print("y = ",y, " x = ", x)
speedLevel = [-600,-500,-400,-320,-250,0,250,320,400,500,600]
speed = speedLevel[y]
if x==10:
left = min(speed+250,600)
right = max(speed-250,-600)
elif x==9:
left = min(speed+200,600)
right = max(speed-200,-600)
elif x==8:
left = min(speed+150,600)
right = max(speed-150,-600)
elif x==7:
left = min(speed+100,600)
right = max(speed-100,-600)
elif x==6:
left = min(speed+50,600)
right = max(speed-50,-600)
elif x==4:
right = min(speed+50,600)
left = max(speed-50,-600)
elif x==3:
right = min(speed+100,600)
left = max(speed-100,-600)
elif x==2:
right = min(speed+150,600)
left = max(speed-150,-600)
elif x==1:
right = min(speed+200,600)
left = max(speed-200,-600)
elif x==0:
right = min(speed+250,600)
left = max(speed-250,-600)
else:
left = speed
right = speed
robot.value = (left/1000, right/1000)
while True:
getCode()
y = int(code/100)
x = code - 100*y
_thread.start_new_thread(motor,(y,x))
En el programa utilizo un módulo de programa, con el que puedo consultar una sola pulsación de tecla incluso sin una tecla de retorno. Sin embargo, este módulo requiere que se inicie en el terminal. De lo contrario, recibirá el siguiente mensaje de error:
Imagen: Mensaje de error si el programa no se inicia en el terminal
Si no lo desea, puede prescindir del módulo y trabajar con el comando input. Sin embargo, cada entrada debe completarse con la tecla Return.
Durante mi configuración, el programa Python comenzará en el terminal de todos modos, así como escribí el inicio del programa en el archivo autostart. Así que puedo encender el Raspi sin un monitor y tener mi coche Robot listo después de arrancar. Para el inicio automático, hay varios métodos que han cambiado en los últimos años, a todos los efectos. Utilizo la opción oficialmente llamada "System method". Para hacer esto, abra el archivo anterior con:
sudo nano / etc / xdg / lxsession / LXDE-pi / autostart
De las siguientes líneas, ya encontrará las tres primeras en el archivo de inicio automático:
@lxpanel profile perfil LXDE-pi
@pcmanfm desktop escritorio profile perfil LXDE-pi
@xscreensaver-no-splash
@lxterminal-e python3 /path/my_script.py
Con la cuarta línea arranco el terminal y ejecuto nuestro programa Python3 allí. Es importante que el programa se especifique con la ruta completa, en mi caso
@lxterminal-e python3 /home/pi/robotCar/robotCar_MotoZero3_4_Code505.py
Como indicación de que el sistema y el inicio del programa están completos, conecté un LED al pin 4. Así que cuando la luz se enciende, el pequeño coche robot está listo para su uso y espera a que los comandos del teclado w, a, s, f, las teclas de flecha o la barra espaciadora para detenerse rápidamente. Ctrl + C cierra el programa.
Si no tiene un teclado de radio, por supuesto también puede iniciar el programa en un programa de terminal en el PC, por ejemplo, Putty.
Imagen: Configuración y comienzo Putty
Después de iniciar sesión, cambie al directorio correcto, en mi caso
cd robotCar
e inicie el programa Python con
python3 robotCar_____.py
Sin embargo, se inicia una nueva instancia del programa Terminal y Python. Si su coche robot se inclina mientras conduce, se ejecuta en paralelo todavía el programa que se abre con autostart. Esto debe terminarse primero y posiblemente eliminarse de autostart.
Imagen: Inicio de sesión y programa de Putty
El programa termina con Ctrl + C; y si desea apagar el Raspi de manera ordenada, ingrese lo siguiente:
sudo shutdown-h now
Por último, lo contrario a autostart, el apagado automático sin monitor y teclado. Una herramienta de Adafruit, pero incomprensible sin la explicación de Michael Horne (https://www.recantha.co.uk/blog/).
Todo funciona conectando brevemente los dos últimos pines (board #39=Ground y #40=GPIO21), ya sea con un enchufe de cortocircuito o un clip de papel.
El programa es obligatorio git, que hoy está preinstalado en el sistema operativo Raspberry Pi. Si aún no lo tiene, comience con (después de la actualización obligatoria y la actualización)
sudo apt-get install git
Git clone luego descargará el script Adafruit:
clon de git https://github.com/adafruit/Adafruit-GPIO-Halt
o git clone git: / / github. com / adafruit / Adafruit-GPIO-Halt
Clonación significa que el directorio ha sido copiado a nuestra Raspi. Cambiamos a este directorio con
cd Adafruit-GPIO.Mantener
Allí introducimos los siguientes comandos uno tras otro:
maquillaje
sudo make install
Esto instalará el script en el directorio / usr / local / bin / gpio-halt
Para ejecutar este script como un "service", creamos el archivo requerido con:
sudo nano / lib / systemd / system / gpio-halt.Servicio
[Unidad]
Descripción = Pasadores cortos 21 y tierra para apagar el Pi
After = multi-usuario.objetivo[Servicio]
Type=inactivo
ExecStart=/usr/local/bin/gpio-halt 21 &[Instalar]
WantedBy=multiusuario.target
En nano, el script se guarda con Ctrl + o y "Okay", luego nano se termina con Ctrl + x.
Estamos de vuelta en el terminal de la línea de mando. Aquí el programa se ejecuta con:
sudo chmod 644 /lib/systemd/system/gpio-halt.service
Y systemd debe utilizar el script a partir de ahora:
sudo systemctl daemon-reload
sudo systemctl enable gpio-halt.service
Por último, el Raspi será
se reinicia y podemos probar el script.reinicio de sudo
¡Diviértase probándolo!