Lego + Raspberry = voiture télécommandée – Partie 2

Suite au post expliquant comment réaliser une voiture télécommandée à partir d’anciens Lego, ce post décrit les options “possibles” pour améliorer la voiture.

On/off de la voiture

Pour cette étape, on rajoute un relais, asservi sur l’entrée GPIO 4 du RP pour démarrer/stopper le véhicule. Il s’agit d’un simple relais 5V 2 canaux. J’utilise la sortie NO (Normally Open) pour commander mon relais. Le relais sera fermé et activera les moteurs que si l’entrée IO4 est activée (état HIGH).

Note :

  • Pas besoin de transistor ou autre composant pour s’assurer du contrôle du relais, les GPIO du RP0 semblent fournir le voltage nécessaire pour la bascule du relais.

Ajout de la caméra

Rien de bien compliqué, la caméra se fixe très simplement à l’aide d’une nappe. Pour utiliser et tester la caméra, le binaire raspistill permet de prendre des photos et le binaire raspivid les vidéos.

$ raspistill -w 640 -h 480 -e jpg -t 0 -o test.jpg
$ raspivid -t 10000 -o test.h264

Note :

  • attention à la connectique du RP0, plus petite que celle du RP3. Il est nécessaire d’avoir un faisceau spécial.

Rajout de la marche arrière

Pour la marche arrière, il a fallu trouver une solution permettant d’inverser la polarité des piles 9V pour faire tourner les moteurs dans l’autre sens et donc de faire marche arrière. Plusieurs solutions possibles mais je me suis orienté vers la solution que j’ai trouvée la plus simple : l’utilisation d’un composant dédié au contrôle des moteurs, le L293D de Texas Instrument. Le pilotage des entrées et l’alimentation du composant se fait sur du +5V et la sortie pour les moteurs varie de +4V à +36V, en fonction de la tension fournie (Vcc 2). 

L’utilisation de ce composant est fort simple :

Le souci est que les entrées GPIO du RP fournissent du +3V et non du +5V. Pour cela, un convertisseur logique est utilisé. On alimente Vcc A avec la pin +3V du RP et Vcc B avec la pin +5V du RP. Ainsi, quand l’entrée 1 est activée avec une GPIO à +3V, la sortie 2 est activée et délivrera une tension de +5V. C’est cette sortie qui sera ensuite connectée à l’entrée du L293D pour piloter le moteur.

Le montage électrique pour commander les 2 sens d’un moteur +5V depuis le RP est le suivant :

Les GPIO 04, 17 et 27 sont donc utilisées pour contrôler le moteur. Le script python est le le script testMotor.py.

Le montage électrique complet, avec le servo et les 2 moteurs Lego 9V est le suivant :

Les scripts

listener.py – version “relais”

#!/usr/bin/env python

import sys
import evdev
from subprocess import Popen

devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]

if len(devices) == 0:
 print ("No devices found, try running with sudo")
 sys.exit(1)

for device in devices:
 print(device)
 device.grab()
 for event in device.read_loop():
   if (event.type==3 and event.code==0 and event.value==0):
     print("Left")
     p = Popen(['./servo.py 5 0.25'], shell=True)
   elif (event.type==3 and event.code==0 and event.value==255):
     print("Right")
     p = Popen(['./servo.py 10 0.25'], shell=True)
   elif (event.type==3 and event.code==1 and event.value==0):
     print("Straigtening (Up)")
     p = Popen(['./servo.py 7.5 0.25'], shell=True)
   elif (event.type==1 and event.code==308 and event.value==1):
     print("Stopping (Y)")
     p = Popen(['./gpio.py 4 1'], shell=True)
   elif (event.type==1 and event.code==305 and event.value==1):
     print("Moving (B)")
     p = Popen(['./gpio.py 4 0'], shell=True)
   elif (event.type==1 and event.code==310 and event.value==1):
     print("Taking photo (L)")
     p = Popen(['./picture.sh'], shell=True)
   elif (event.type==1 and event.code==311 and event.value==1):
     print("Taking video (R)")
     p = Popen(['./video.sh'], shell=True)
   elif (event.type==1 and event.code==315 and event.value==1):
     print("Exiting")
     exit(0)

listener.py – version “marche arrière”

#!/usr/bin/env python

import sys
import evdev
from subprocess import Popen

devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]

if len(devices) == 0:
 print ("No devices found, try running with sudo")
 sys.exit(1)

for device in devices:
 print(device)
 device.grab()
 for event in device.read_loop():
   if (event.type==3 and event.code==0 and event.value==0):
     print("Left")
     p = Popen(['./servo.py 5 0.25'], shell=True)
   elif (event.type==3 and event.code==0 and event.value==255):
     print("Right")
     p = Popen(['./servo.py 10 0.25'], shell=True)
   elif (event.type==3 and event.code==1 and event.value==0):
     print("Straigtening (Up)")
     p = Popen(['./servo.py 7.5 0.25'], shell=True)
   elif (event.type==1 and event.code==308 and event.value==1):
     print("Stopping (Y)")
     p = Popen(['./stop.py'], shell=True)
   elif (event.type==1 and event.code==305 and event.value==1):
     print("Moving (B)")
     p = Popen(['./forward.py'], shell=True)
   elif (event.type==1 and event.code==304 and event.value==1):
     print("Back (A)")
     p = Popen(['./reverse.py'], shell=True)
   elif (event.type==1 and event.code==310 and event.value==1):
     print("Taking photo (L)")
     p = Popen(['./picture.sh'], shell=True)
   elif (event.type==1 and event.code==311 and event.value==1):
     print("Taking video (R)")
     p = Popen(['./video.sh'], shell=True)
   elif (event.type==1 and event.code==307 and event.value==1):
     print("Transfering media (X)")
     p = Popen(['./transfer.sh'], shell=True)
   elif (event.type==1 and event.code==315 and event.value==1):
     print("Exiting")
     exit(0)

testMotor.py

#!/usr/bin/python3

import RPi.GPIO as GPIO
from time import sleep
import sys

EnableDisable=4
DirectionBit0=17
DirectionBit1=27

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(EnableDisable, GPIO.OUT)
GPIO.setup(DirectionBit0, GPIO.OUT)
GPIO.setup(DirectionBit1, GPIO.OUT)

try:
 while True:
 GPIO.output(EnableDisable, GPIO.LOW)
 sleep(1)
 print("forward")
 GPIO.output(DirectionBit0, GPIO.LOW)
 GPIO.output(DirectionBit1, GPIO.HIGH)
 GPIO.output(EnableDisable, GPIO.HIGH)
 sleep(2)

GPIO.output(EnableDisable, GPIO.LOW)
 sleep(1)
 print("reverse")
 GPIO.output(DirectionBit0, GPIO.HIGH)
 GPIO.output(DirectionBit1, GPIO.LOW)
 GPIO.output(EnableDisable, GPIO.HIGH)
 sleep(2)

except KeyboardInterrupt:
 print ("exiting")
 GPIO.cleanup()

GPIO.cleanup()

video.sh

#!/bin/bash
dateTime=`date +%Y%m%d-%H%M%S`
videoDirectory=/home/pi/videos
echo "Taking a video for 10 seconds"
raspivid -t 10000 -o $videoDirectory/$dateTime.h264

picture.sh

#!/bin/bash
dateTime=`date +%Y%m%d-%H%M%S`
pictureDirectory=/home/pi/pictures
raspistill -o $pictureDirectory/$dateTime.jpg

stop.py

#!/usr/bin/python3

import RPi.GPIO as GPIO
from time import sleep
import sys

EnableDisable=4
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(EnableDisable, GPIO.OUT)
GPIO.output(EnableDisable, GPIO.LOW)
GPIO.cleanup()

forward.py

#!/usr/bin/python3

import RPi.GPIO as GPIO
from time import sleep
import sys

EnableDisable=4
DirectionBit0=17
DirectionBit1=27

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(EnableDisable, GPIO.OUT)
GPIO.setup(DirectionBit0, GPIO.OUT)
GPIO.setup(DirectionBit1, GPIO.OUT)

print("forward")
GPIO.output(DirectionBit0, GPIO.HIGH)
GPIO.output(DirectionBit1, GPIO.LOW)
GPIO.output(EnableDisable, GPIO.HIGH)

reverse.py

#!/usr/bin/python3

import RPi.GPIO as GPIO
from time import sleep
import sys

EnableDisable=4
DirectionBit0=17
DirectionBit1=27

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(EnableDisable, GPIO.OUT)
GPIO.setup(DirectionBit0, GPIO.OUT)
GPIO.setup(DirectionBit1, GPIO.OUT)

print("forward")
GPIO.output(DirectionBit0, GPIO.LOW)
GPIO.output(DirectionBit1, GPIO.HIGH)
GPIO.output(EnableDisable, GPIO.HIGH)

Test et vidéo

Tagged with: , ,