Empty commit message
This commit is contained in:
373
base_roulante_fredo.py
Normal file
373
base_roulante_fredo.py
Normal file
@@ -0,0 +1,373 @@
|
||||
"""
|
||||
Contrôle d'une base roulante avec ESP32-C3-DevkitM-1
|
||||
- Pont en H L298N pour 2 moteurs DC
|
||||
- Capteur à ultrasons pour détection d'obstacles
|
||||
"""
|
||||
|
||||
from machine import Pin, PWM, time_pulse_us
|
||||
import time
|
||||
import math
|
||||
|
||||
# ============================================================================
|
||||
# Configuration des pins GPIO
|
||||
# ============================================================================
|
||||
|
||||
# Capteur à ultrasons
|
||||
TRIG_PIN = 8
|
||||
ECHO_PIN = 9
|
||||
|
||||
# Pont en H L298N
|
||||
ENA_PIN = 4 # PWM pour moteur A
|
||||
IN1_PIN = 5 # Direction moteur A
|
||||
IN2_PIN = 6 # Direction moteur A
|
||||
IN3_PIN = 2 # Direction moteur B
|
||||
IN4_PIN = 1 # Direction moteur B
|
||||
ENB_PIN = 0 # PWM pour moteur B
|
||||
|
||||
# ============================================================================
|
||||
# Paramètres
|
||||
# ============================================================================
|
||||
|
||||
PWM_FREQ = 1000 # Fréquence PWM en Hz
|
||||
MAX_PWM = 65535 # Valeur PWM maximale pour ESP32
|
||||
SPEED_MAX = 65535 # Vitesse maximale (100%)
|
||||
SPEED_MIN = 32767 # Vitesse minimale (50%)
|
||||
|
||||
# Distance de sécurité pour le capteur à ultrasons (en cm)
|
||||
SAFE_DISTANCE = 20
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Classe pour le contrôle des moteurs
|
||||
# ============================================================================
|
||||
|
||||
class MoteurDC:
|
||||
"""Classe pour contrôler un moteur DC via le pont en H"""
|
||||
|
||||
def __init__(self, en_pin, in1_pin, in2_pin):
|
||||
"""
|
||||
Initialise un moteur DC
|
||||
|
||||
Args:
|
||||
en_pin: PIN PWM pour la vitesse
|
||||
in1_pin: PIN pour la direction (sens 1)
|
||||
in2_pin: PIN pour la direction (sens 2)
|
||||
"""
|
||||
self.en = PWM(Pin(en_pin))
|
||||
self.en.freq(PWM_FREQ)
|
||||
self.in1 = Pin(in1_pin, Pin.OUT)
|
||||
self.in2 = Pin(in2_pin, Pin.OUT)
|
||||
|
||||
def avant(self, vitesse=SPEED_MAX):
|
||||
"""
|
||||
Fait tourner le moteur vers l'avant
|
||||
|
||||
Args:
|
||||
vitesse: Vitesse (0-65535), par défaut vitesse maximale
|
||||
"""
|
||||
vitesse = min(vitesse, SPEED_MAX)
|
||||
vitesse = max(vitesse, 0)
|
||||
self.in1.on()
|
||||
self.in2.off()
|
||||
self.en.duty_u16(vitesse)
|
||||
|
||||
def arriere(self, vitesse=SPEED_MAX):
|
||||
"""
|
||||
Fait tourner le moteur vers l'arrière
|
||||
|
||||
Args:
|
||||
vitesse: Vitesse (0-65535), par défaut vitesse maximale
|
||||
"""
|
||||
vitesse = min(vitesse, SPEED_MAX)
|
||||
vitesse = max(vitesse, 0)
|
||||
self.in1.off()
|
||||
self.in2.on()
|
||||
self.en.duty_u16(vitesse)
|
||||
|
||||
def arreter(self):
|
||||
"""Arrête le moteur"""
|
||||
self.in1.off()
|
||||
self.in2.off()
|
||||
self.en.duty_u16(0)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Classe pour le capteur à ultrasons
|
||||
# ============================================================================
|
||||
|
||||
class CapteurUltrasons:
|
||||
"""Classe pour lire la distance avec un capteur à ultrasons HC-SR04"""
|
||||
|
||||
def __init__(self, trig_pin, echo_pin):
|
||||
"""
|
||||
Initialise le capteur à ultrasons
|
||||
|
||||
Args:
|
||||
trig_pin: PIN de déclenchement (TRIG)
|
||||
echo_pin: PIN de retour (ECHO)
|
||||
"""
|
||||
self.trig = Pin(trig_pin, Pin.OUT)
|
||||
self.echo = Pin(echo_pin, Pin.IN)
|
||||
|
||||
def mesurer_distance(self):
|
||||
"""
|
||||
Mesure la distance avec le capteur à ultrasons
|
||||
|
||||
Returns:
|
||||
Distance en centimètres (float)
|
||||
"""
|
||||
# Envoyer une impulsion de 10µs sur TRIG
|
||||
self.trig.off()
|
||||
time.sleep_us(2)
|
||||
self.trig.on()
|
||||
time.sleep_us(10)
|
||||
self.trig.off()
|
||||
|
||||
# Mesurer le temps de l'impulsion ECHO
|
||||
try:
|
||||
pulse_time = time_pulse_us(self.echo, 1, 30000) # Timeout: 30ms
|
||||
except OSError:
|
||||
# En cas de timeout, retourner une grande valeur
|
||||
return 400.0
|
||||
|
||||
# Calculer la distance (vitesse du son ≈ 343 m/s à 20°C)
|
||||
# Distance = (temps / 2) * vitesse = (pulse_time / 2) * 343 * 10^-6 * 100
|
||||
distance_cm = (pulse_time / 2) * 0.01715
|
||||
|
||||
return distance_cm
|
||||
|
||||
def obstacle_detecte(self, distance_min=SAFE_DISTANCE):
|
||||
"""
|
||||
Détecte si un obstacle est présent
|
||||
|
||||
Args:
|
||||
distance_min: Distance minimale en cm (par défaut SAFE_DISTANCE)
|
||||
|
||||
Returns:
|
||||
True si un obstacle est détecté, False sinon
|
||||
"""
|
||||
distance = self.mesurer_distance()
|
||||
return distance < distance_min
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Classe pour la base roulante
|
||||
# ============================================================================
|
||||
|
||||
class BaseRoulante:
|
||||
"""Classe pour contrôler la base roulante complète"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialise la base roulante"""
|
||||
# Initialiser les moteurs
|
||||
self.moteur_a = MoteurDC(ENA_PIN, IN1_PIN, IN2_PIN)
|
||||
self.moteur_b = MoteurDC(ENB_PIN, IN3_PIN, IN4_PIN)
|
||||
|
||||
# Initialiser le capteur à ultrasons
|
||||
self.capteur = CapteurUltrasons(TRIG_PIN, ECHO_PIN)
|
||||
|
||||
print("Base roulante initialisée ✓")
|
||||
|
||||
def avancer(self, vitesse=SPEED_MAX):
|
||||
"""
|
||||
Fait avancer la base roulante
|
||||
|
||||
Args:
|
||||
vitesse: Vitesse (0-65535), par défaut vitesse maximale
|
||||
"""
|
||||
self.moteur_a.avant(vitesse)
|
||||
self.moteur_b.avant(vitesse)
|
||||
|
||||
def reculer(self, vitesse=SPEED_MAX):
|
||||
"""
|
||||
Fait reculer la base roulante
|
||||
|
||||
Args:
|
||||
vitesse: Vitesse (0-65535), par défaut vitesse maximale
|
||||
"""
|
||||
self.moteur_a.arriere(vitesse)
|
||||
self.moteur_b.arriere(vitesse)
|
||||
|
||||
def tourner_droite(self, vitesse=SPEED_MAX):
|
||||
"""
|
||||
Fait tourner la base roulante à droite
|
||||
|
||||
Args:
|
||||
vitesse: Vitesse (0-65535), par défaut vitesse maximale
|
||||
"""
|
||||
self.moteur_a.avant(vitesse)
|
||||
self.moteur_b.arriere(vitesse)
|
||||
|
||||
def tourner_gauche(self, vitesse=SPEED_MAX):
|
||||
"""
|
||||
Fait tourner la base roulante à gauche
|
||||
|
||||
Args:
|
||||
vitesse: Vitesse (0-65535), par défaut vitesse maximale
|
||||
"""
|
||||
self.moteur_a.arriere(vitesse)
|
||||
self.moteur_b.avant(vitesse)
|
||||
|
||||
def arreter(self):
|
||||
"""Arrête la base roulante"""
|
||||
self.moteur_a.arreter()
|
||||
self.moteur_b.arreter()
|
||||
|
||||
def obtenir_distance(self):
|
||||
"""
|
||||
Obtient la distance mesurée par le capteur à ultrasons
|
||||
|
||||
Returns:
|
||||
Distance en centimètres (float)
|
||||
"""
|
||||
return self.capteur.mesurer_distance()
|
||||
|
||||
def avancer_securise(self, vitesse=SPEED_MAX, distance_min=SAFE_DISTANCE):
|
||||
"""
|
||||
Fait avancer la base roulante avec détection d'obstacle
|
||||
|
||||
Args:
|
||||
vitesse: Vitesse (0-65535)
|
||||
distance_min: Distance minimale de sécurité en cm
|
||||
"""
|
||||
distance = self.obtenir_distance()
|
||||
|
||||
if distance > distance_min:
|
||||
self.avancer(vitesse)
|
||||
return True
|
||||
else:
|
||||
self.arreter()
|
||||
print(f"Obstacle détecté à {distance:.1f} cm!")
|
||||
return False
|
||||
|
||||
def comportement_autonome(self, duree=None):
|
||||
"""
|
||||
Fait se déplacer la base roulante de manière autonome en évitant les obstacles
|
||||
|
||||
Args:
|
||||
duree: Durée du comportement autonome en secondes (None = infini)
|
||||
"""
|
||||
debut = time.time()
|
||||
|
||||
print("Démarrage du mode autonome...")
|
||||
|
||||
try:
|
||||
while duree is None or (time.time() - debut) < duree:
|
||||
# Vérifier les obstacles
|
||||
distance = self.obtenir_distance()
|
||||
|
||||
if distance > SAFE_DISTANCE:
|
||||
# Pas d'obstacle, avancer
|
||||
self.avancer(SPEED_MAX)
|
||||
print(f"Distance: {distance:.1f} cm - Avance")
|
||||
else:
|
||||
# Obstacle détecté, arrêter et tourner
|
||||
print(f"Obstacle à {distance:.1f} cm - Demi-tour!")
|
||||
self.arreter()
|
||||
time.sleep(0.5)
|
||||
|
||||
# Faire un demi-tour (tourner à gauche)
|
||||
self.tourner_gauche(SPEED_MAX)
|
||||
time.sleep(1)
|
||||
|
||||
time.sleep(0.1) # Délai pour la lecture capteur
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("Mode autonome interrompu")
|
||||
|
||||
finally:
|
||||
self.arreter()
|
||||
print("Base arrêtée")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Fonction de démonstration
|
||||
# ============================================================================
|
||||
|
||||
def demonstration():
|
||||
"""Fonction de démonstration des mouvements"""
|
||||
|
||||
base = BaseRoulante()
|
||||
|
||||
# Afficher la distance initiale
|
||||
distance = base.obtenir_distance()
|
||||
print(f"Distance initiale: {distance:.1f} cm\n")
|
||||
|
||||
# Séquence de test
|
||||
print("=== Test des mouvements ===\n")
|
||||
|
||||
# Avancer
|
||||
print("Avance pendant 2 secondes...")
|
||||
base.avancer(SPEED_MAX)
|
||||
time.sleep(2)
|
||||
base.arreter()
|
||||
print("Arrêt\n")
|
||||
|
||||
# Reculer
|
||||
print("Recule pendant 2 secondes...")
|
||||
base.reculer(SPEED_MAX)
|
||||
time.sleep(2)
|
||||
base.arreter()
|
||||
print("Arrêt\n")
|
||||
|
||||
# Tourner gauche
|
||||
print("Tourne à gauche pendant 1 seconde...")
|
||||
base.tourner_gauche(SPEED_MAX)
|
||||
time.sleep(1)
|
||||
base.arreter()
|
||||
print("Arrêt\n")
|
||||
|
||||
# Tourner droite
|
||||
print("Tourne à droite pendant 1 seconde...")
|
||||
base.tourner_droite(SPEED_MAX)
|
||||
time.sleep(1)
|
||||
base.arreter()
|
||||
print("Arrêt\n")
|
||||
|
||||
# Test avec vitesse réduite
|
||||
print("Avance lentement pendant 3 secondes (50% vitesse)...")
|
||||
base.avancer(SPEED_MIN)
|
||||
time.sleep(3)
|
||||
base.arreter()
|
||||
print("Arrêt\n")
|
||||
|
||||
print("Démonstration terminée!")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Point d'entrée principal
|
||||
# ============================================================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
# Créer l'instance de la base roulante
|
||||
base = BaseRoulante()
|
||||
|
||||
# Décommenter la fonction à exécuter:
|
||||
|
||||
# Démonstration simple
|
||||
# demonstration()
|
||||
|
||||
# Mode autonome (infini)
|
||||
# base.comportement_autonome()
|
||||
|
||||
# Mode autonome (60 secondes)
|
||||
# base.comportement_autonome(duree=60)
|
||||
|
||||
# Pour tester manuellement, vous pouvez faire:
|
||||
# base.avancer()
|
||||
# time.sleep(2)
|
||||
# base.arreter()
|
||||
|
||||
print("Base roulante prête! Utilisez les méthodes de la classe BaseRoulante")
|
||||
print("Exemples:")
|
||||
print(" base.avancer()")
|
||||
print(" base.reculer()")
|
||||
print(" base.tourner_gauche()")
|
||||
print(" base.tourner_droite()")
|
||||
print(" base.arreter()")
|
||||
print(" base.obtenir_distance()")
|
||||
print(" base.comportement_autonome(duree=60)")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Erreur: {e}")
|
||||
Reference in New Issue
Block a user