En esta práctica haremos la Instalación básica de una raspberry pi 4B, así cómo una implementación de
códigos que nos permiten interactuar con ella mediante los pines disponibles en la placa.
Para terminar, adaptaremos el código de la práctica anterior para mostrar el estado del vehículo.
Instalación del OS:
El sistema operativo ya se encobraba instalado previamente en la tarjeta SD, solo quedaba configurar
algunos parámetros: usuario, contraseña, zona horaria, habilitar el ssh ...
La instalación fué muy simple, se realizó directamente usando la interfaz gráfica. Una vez
realizados estos pasos ya podemos trabajar directamente con la ventana de comandos usando ssh.
Para conectarnos por ssh usaremos «ssh nombre-usuario@ip-host» en nuestro caso
ssh el-calmador@192.168.154.179
Una vez hecho esto realizaremos los siguientes comandos:
sudo su
apt update
apt upgrade -y
apt install neofetch
Estos comandos actualizan la raspberry y son importantes, no solo por el tema de eficiencia o seguridad,
sino que las librerías que necesitaremos para controlar los pines no funcionarán si no se encuentra
nuestro sistema actualizado.
Podemos comprobar que todo funciona correctamente empleando el comando neofetch:
Otro comando que nos puede resultar útil es: pinout que nos da el siguiente resultado:
Cableado de los componentes:
Para realizar el cableado, simplemente se ha seguido el vídeo, cabe destacar que el tutorial está
mal explicado, ya que en multiples ocasiones se hace un abuso del lenguaje dando lugar a
confusiones, un ejemplo muy claro es cuando se hablan
de pins y de GPIOS ya que en el vídeo se usan indiferentemente pero en la realidad, los GPIOs no
tienen porqué seguir la misma enumeración que los pines, también la precisión con la que se expresa
es un poco inexacta cuando habla de arriba, abajo...
Estos detalles hicieron que una vez terminara de cablear todo y me pusiera a probar el código,
este no funcionara.
Configuración del puerto TELEM2
La configura del puerto telem2 se vió en la anterior práctica,
solo quedaría configurar el uart para comunicar la raspberry con la pixhawk.
Al intentar realizar este paso y editar el fichero txt, me dí cuenta que no estaba disponible
esta opción. La escribí de forma manual pero no he logrado conseguir a fecha de esta entrada. De
todos modos, aún queda una alternativa: conectarse al puerto
de telemetía mediante un USB tal y cómo se hizo anteriormente. Solo hace falta tener en cuenta que
estamos trabajando con una máquina UNIX y que la sintaxis cambia un poco.
Actualización sobre el apartado del puerto TELEM2:
Cómo las indicaciones aportadas por el vídeo de la asignatura no me llevaban a ninguna parte, decidí
buscar por mi mismo hasta encontrar los pasos necesarios para habilitar los puertos serie UART:
Para ello lo primero de todo llamaremos al siguiente comando: sudo raspi-config, no s
aparecerá un menú como este:
Luego iremos a 3. Interface options, en este menú nuevo seleccionaremos la opción
P6 Serial Port. Finalmente nos preguntará si queremos una consola para login,
a lo que repondremos no y luego se nos preguntará por si queremos activar el si queremos activar el
hardware del serial port a lo que repondremos que sí. Al terminar la Configuración se reiniciará la
raspberry.
Para ver que el UART se encuentra activado ejecutaremos el comando tail /boot/config.txt que
nos arroja la siguiente información:
Para terminar con la configuración del UART lanzaremos el comando ls -la /dev/ttyAMA* para
listar todos los puertos UART activados y asegurarnos que el UART4 se encuentre disponible:
Códigos para controlar la raspberry:
En esta sección se presentarán los distintos códigos e implementaciones para controlar la raspberry y
los distintos periféricos:
Botón:
Nuestro montaje dispone de un botón el cual hemos programado para que ser reinicie, el código es el
siguiente:
Disponemos también de una placa que funciona a modo de tira de LEDs, una cosa que me ha sorprendido,
es que no he visto ninguna resistencia en la circuitería y al probar el resultado, los LEDs brillan
mucho.
Esto me hace pensar que realmente no tiene ninguna resistencia, pero de ser así seria un fallo
muy grande ya que la corriente que pediría el circuito sería muy alta y acabaría por dañar la placa
de la raspberry.
El código empleado es el siguiente:
integración de los códigos anteriores con la práctica 3:
Ahora se integrarán los códigos anteriores, para ello realizaremos un thread adicional para
monitorizar el botón continuamente, también se ha añadido la funcionalidad de los LEDs que cambian
de color dependiendo
de la fase que se encuentren dentro del ciclo de vida del código. El main contiene un control de
excepciones pensado especialmente para cuando no se logre comunicar dronkit con la controlador. A
continuación se muestra el main con todas las modificaciones necesarias:
import threading
import dronekit
import time
import datetime
import board
import neopixel
import time
from reboot import *
from control import controller
from gestor import *
from graficas import *
def mandunga():
#conexion = '/dev/ttyUSB0 #Linux'
#conexion = 'tcp:127.0.0.1:5762'
#conexion = 'com10' #windows
conexion = '/dev/ttyAMA1' #serial bus 1 'UART'
baud = 57600 #57600 ==> radio, baud=115200 net/usb
try:
vehicle = dronekit.connect(conexion, wait_ready=True, baud=115200)
print('vehicle connected')
pixels[:3]=(225,0,0)
pixels[3] = (255,215,0)
pixels[3:] = (225,0,0)
thread=threading.Thread(target=listener_sql, args=( vehicle,))
print('SQL thread started')
thread.start()
thread=threading.Thread(target=main_reboot)
print('thread boton started')
thread.start()
controller(vehicle=vehicle)
vehicle.close()
except dronekit.TimeoutError:
t=0
print('Unable to conect to the rover, shutting down ...')
while t < 10:
if t%2 ==0:
pixels.fill((0,0,0))
else:
pixels.fill((0,0,153))
t+=1
time.sleep(1)
pixels.fill((0,0,0))
quit()
if __name__ == '__main__':
print('starting')
global pixels
pixels = neopixel.NeoPixel(board.D18,5)
for i in range(5):
pixels[i] = (225,0,0)
mandunga()
for i in range(5):
pixels[i] = (0,100,0)
mapa()
Adaptación del paquete reboot
Para que la función reboot funcione correctamente, es necesario crear otra función desde donde se
llamará a reboot. El motivo por el que se tiene que hacer así es porque al hacer el import del
paquete se ejecutan todas las líneas.
Haciendo que el hilo principal se quede parado en el signal.pause(), por este motivo, es
importante que estas instrucciones se encuentres anidadas dentro de una función desde la cual se
creará un hilo secundario donde este sí se congelará.
import gpiozero
import board
import neopixel
import signal
import subprocess
def main_reboot():
boton = gpiozero.Button(24, hold_time =2)
boton.when_held = reboot
signal.pause()
def reboot():
print('Button pressed')
pixels = neopixel.NeoPixel(board.D18,5)
for i in range(5):pixels[i]=(0,0,0,0)
subprocess.check_call(['sudo','reboot'])
if __name__ =='__main__':
main_reboot()
Demostración del control de excepciones controladas:
Automatización de los scripts:
Podemos automatizar el proceso para no tener que llamar los códigos y que estos se ejecuten al
iniciar la raspberry, para ello lanzaremos el comando:
sudo crontab -e
Podemos lanzar cualquier comando que deseamos, es importante poner la ruta absoluta del archivo y
también añadir un & al final de cada comando, para que se realicen en segundo plano.
Comprobación de los resultado:
Una vez llegado a este punto, instalamos la raspberry al rover. Mediante Mission Planner creamos una
misión simple, calibramos el compás y nos conectamos por ssh a la raspberry, ejecutando el main del
proyecto. Una vez armado el rover, este empezará con su ruta
Telemetía recogida:
A continuación se mostrará algunos datos de telemetía recogidos en la raspberry y con el .tlog de
Mission Planner: