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)