Empty commit message

This commit is contained in:
2025-12-03 14:13:20 +01:00
commit 74dd3ebc67
7 changed files with 747 additions and 0 deletions

373
base_roulante_fredo.py Normal file
View 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}")