Schéma de montage
Quelques explications :
- J’ai volontairement inversé le sens d’alimentation du moteur 2, puisqu’il est inversé physiquement sur le châssis.
- J’utilise le régulateur de tension du module pour alimenter la partie logique du L298N. Il est également possible d’utiliser la sortie +5V du Raspberry Pi. Plus d’info ici.
- Sur le L298N, l’état bas est entre -0.3V et 1.5V, l’état haut entre 2.3V et 7V, ce qui colle bien avec les sorties 3V du Raspberry Pi.
- J’utilise la numération BCM des broches du Raspberry Pi. Ce guide est très pratique pour s’y retrouver et en savoir plus sur les GPIO.
| Raspberry Pi | L298N | Description |
|---|---|---|
| 18 | ENA | Activation du moteur A. Peut être raccordé à une sortie PWM pour contrôler la vitesse de rotation |
| 23 | IN1 | Sens du moteur A : 3V → Avant / GND → Arrière |
| 24 | IN2 | Sens du moteur A : GND → Avant / 3V → Arrière |
| 17 | ENB | Activation du moteur B. Peut être raccordé à une sortie PWM pour contrôler la vitesse de rotation |
| 27 | IN3 | Sens du moteur B : 3V → Avant / GND → Arrière |
| 22 | IN4 | Sens du moteur B : GND → Avant / 3V → Arrière |
| GND | GND | Pour avoir une masse commune (Sur le Raspberry, peut importe laquelle) |
| MOTOR A | Sortie de puissance sur le moteur A | |
| MOTOR B | Sortie de puissance sur le moteur B | |
| VMS/GND | À raccorder sur l’alimentation de puissance. Attention au sens, sinon ça chauffe 😉 | |
| 04 | Led ou buzzer |
Un peu de code
L’idée est d’écouter 3 boutons du contrôleur :
- Gâchette droite : En avant
- Gâchette gauche : En arrière
- Joystick gauche : Rotation sur soi-même
Ces boutons sont analogiques, on peut récupérer une valeur entre 0 et 100%. Si plusieurs boutons sont pressés en même temps, on prend la direction de celui qui a la plus forte intensité.
On reprend la même arborescence de fichiers que pour les tests de la manette de xbox :
. ├── lib │ ├── __init__.py Vide │ ├── xbox_read.py Script de Zephod pour traiter les évenements └── controller.py Script principal
#!/usr/bin/python
# -*- coding:Utf-8 -*-
import RPi.GPIO as GPIO
import atexit
from lib import xbox_read
import time
# Evenement a la fermeture
def exit_handler():
print 'Tchao blaireau !'
gauche_pwm.stop()
droite_pwm.stop()
GPIO.output(MOTEUR_GAUCHE_AVANT_PIN, 0)
GPIO.output(MOTEUR_GAUCHE_ARRIERE_PIN, 0)
GPIO.output(MOTEUR_DROIT_AVANT_PIN, 0)
GPIO.output(MOTEUR_DROIT_ARRIERE_PIN, 0)
atexit.register(exit_handler)
#-------------[ CABLAGE ]--------------------
MOTEUR_GAUCHE_PWM_PIN = 18
MOTEUR_GAUCHE_AVANT_PIN = 23
MOTEUR_GAUCHE_ARRIERE_PIN = 24
MOTEUR_DROIT_PWM_PIN = 17
MOTEUR_DROIT_AVANT_PIN = 27
MOTEUR_DROIT_ARRIERE_PIN = 22
LED_PIN = 04
#-------------[ INITIALISATION DES GPIOS ]--------------
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
# Sens de sortie
GPIO.setup(MOTEUR_GAUCHE_PWM_PIN, GPIO.OUT)
GPIO.setup(MOTEUR_GAUCHE_AVANT_PIN, GPIO.OUT)
GPIO.setup(MOTEUR_GAUCHE_ARRIERE_PIN, GPIO.OUT)
GPIO.setup(MOTEUR_DROIT_PWM_PIN, GPIO.OUT)
GPIO.setup(MOTEUR_DROIT_AVANT_PIN, GPIO.OUT)
GPIO.setup(MOTEUR_DROIT_ARRIERE_PIN, GPIO.OUT)
GPIO.setup(LED_PIN, GPIO.OUT)
# Initialisation des PWM
gauche_pwm = GPIO.PWM(MOTEUR_GAUCHE_PWM_PIN, 100000) # Frequence 1 kHz
gauche_pwm.start(0)
droite_pwm = GPIO.PWM(MOTEUR_DROIT_PWM_PIN, 100000) # Frequence 1 kHz
droite_pwm.start(0)
# On commence en marche avant
GPIO.output(MOTEUR_GAUCHE_AVANT_PIN, 1) # ou GPIO.HIGH ou True
GPIO.output(MOTEUR_GAUCHE_ARRIERE_PIN, 0) # ou GPIO.LOW ou False
GPIO.output(MOTEUR_DROIT_AVANT_PIN, 1)
GPIO.output(MOTEUR_DROIT_ARRIERE_PIN, 0)
#-------------[ FONCTIONS ]---------------
vitesse_gauche_courante = 0
vitesse_droite_courante = 0
# Controle la pwm des moteurs en fonction de gauche et droit (de -100% a 100%)
def piloter_moteurs(gauche, droit):
global vitesse_gauche_courante
global vitesse_droite_courante
# Contrôle des GPIOS => Sens des moteurs
GPIO.output(MOTEUR_GAUCHE_AVANT_PIN, gauche >= 0)
GPIO.output(MOTEUR_GAUCHE_ARRIERE_PIN, gauche < 0)
GPIO.output(MOTEUR_DROIT_AVANT_PIN, droit >= 0)
GPIO.output(MOTEUR_DROIT_ARRIERE_PIN, droit < 0)
# Contrôle de la PWM => Vitesse des moteurs
vitesse_gauche = float(abs(gauche))
vitesse_droite = float(abs(droit))
if (vitesse_gauche != vitesse_gauche_courante):
gauche_pwm.ChangeDutyCycle(vitesse_gauche)
vitesse_gauche_courante = vitesse_gauche
if (vitesse_droite != vitesse_droite_courante):
droite_pwm.ChangeDutyCycle(vitesse_droite)
vitesse_droite_courante = vitesse_droite
#-------------[ ECOUTE DU CONTROLEUR ]--------------
rt_intensite = 0 # Gachette droite -> Marche avant
lt_intensite = 0 # Gachette gauche -> Marche arriere
x1_intensite = 0 # Joystick gauche -> Rotation
print 'En avant Guingamp !'
# En attente d'evenement du controleur
for event in xbox_read.event_stream(deadzone=12000):
boutons = ['RT', 'LT', 'X1', 'A']
if event.key in boutons:
# MAJ des valeurs des boutons
if event.key == 'RT': # De 0 a 255
rt_intensite = event.value * 100 / 255 # en %
if event.key == 'LT': # De 0 a 255
lt_intensite = event.value * 100 / 255 # en %
if event.key == 'X1': # De -32767 a 32767
x1_intensite = min(100, max(-100, event.value * 100 / 32767)) # Pour rester entre -100 et 100
if event.key == 'A':
GPIO.output(LED_PIN, event.value)
# On choisit la direction avec la plus grande valeur
directions = {
'avant': rt_intensite,
'droite': x1_intensite if x1_intensite >= 0 else 0,
'arriere': lt_intensite,
'gauche': -x1_intensite if x1_intensite < 0 else 0
}
direction = max(directions, key=directions.get)
# On pilote les moteurs
if direction == 'avant' :
piloter_moteurs(rt_intensite, rt_intensite)
if direction == 'droite' :
piloter_moteurs(x1_intensite, -x1_intensite)
if direction == 'arriere' :
piloter_moteurs(-lt_intensite, -lt_intensite)
if direction == 'gauche' :
piloter_moteurs(x1_intensite, -x1_intensite)


