Empty commit message
This commit is contained in:
38
TP - 03-12-25/logique_hcsr04.py
Normal file
38
TP - 03-12-25/logique_hcsr04.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Objectif : compléter la fonction de calcul de distance du HC-SR04.
|
||||||
|
# Le capteur renvoie un temps d'écho en microsecondes.
|
||||||
|
# Vous devez convertir ce temps en distance en centimètres.
|
||||||
|
#
|
||||||
|
# Zones à compléter : ____ ou "TODO".
|
||||||
|
|
||||||
|
|
||||||
|
def calcul_distance_cm(temps_echo_us):
|
||||||
|
|
||||||
|
"""
|
||||||
|
temps_echo_us : durée du signal echo en microsecondes
|
||||||
|
Retour :
|
||||||
|
- distance en centimètres (float)
|
||||||
|
- ou None si le temps est invalide
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 1) Gérer les cas invalides :
|
||||||
|
# - temps_echo_us est None
|
||||||
|
# - temps_echo_us <= 0
|
||||||
|
# TODO : compléter la condition
|
||||||
|
|
||||||
|
if temps_echo_us is None or temps_echo_us <= 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 2) Convertir le temps en secondes :
|
||||||
|
# 1 seconde = 1 000 000 microsecondes
|
||||||
|
# TODO : compléter la conversion
|
||||||
|
|
||||||
|
temps_s = temps_echo_us / 1000000
|
||||||
|
|
||||||
|
# 3) Calculer la distance :
|
||||||
|
# distance(cm) = (temps_s * vitesse_du_son_cm_par_s) / 2
|
||||||
|
# vitesse du son ≈ 34300 cm/s
|
||||||
|
# TODO : compléter la formule
|
||||||
|
|
||||||
|
distance_cm = (temps_s * 34300) / 2
|
||||||
|
|
||||||
|
return distance_cm
|
||||||
71
TP - 03-12-25/logique_moteur.py
Normal file
71
TP - 03-12-25/logique_moteur.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# logique_moteur_eleve.py
|
||||||
|
#
|
||||||
|
# Objectif : écrire la logique de contrôle d'un moteur DC
|
||||||
|
# à partir d'une consigne de vitesse en pourcentage
|
||||||
|
#
|
||||||
|
# À compléter zones marquées avec ____ ou TODO
|
||||||
|
|
||||||
|
|
||||||
|
def calcul_signaux_moteur(vitesse_pourcent, pwm_max=1023):
|
||||||
|
|
||||||
|
"""
|
||||||
|
Entrée :
|
||||||
|
vitesse_pourcent : nombre entre -100 et 100
|
||||||
|
> 0 -> marche avant
|
||||||
|
< 0 -> marche arrière
|
||||||
|
= 0 -> arrêt
|
||||||
|
|
||||||
|
Sortie :
|
||||||
|
dictionnaire avec :
|
||||||
|
"in1" : 0 ou 1 (sens)
|
||||||
|
"in2" : 0 ou 1 (sens)
|
||||||
|
"pwm" : valeur entre 0 et pwm_max
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 1) Limiter la vitesse entre -100 et 100
|
||||||
|
# Si vitesse_pourcent > 100, on force à 100
|
||||||
|
# Si vitesse_pourcent < -100, on force à -100
|
||||||
|
# TODO : compléter les conditions
|
||||||
|
|
||||||
|
if vitesse_pourcent > 0:
|
||||||
|
vitesse_pourcent = 100
|
||||||
|
|
||||||
|
if vitesse_pourcent < 0:
|
||||||
|
vitesse_pourcent = -100
|
||||||
|
|
||||||
|
# 2) Cas arrêt : si vitesse_pourcent == 0
|
||||||
|
# -> in1 = 0, in2 = 0, pwm = 0
|
||||||
|
# TODO : compléter la condition et le retour
|
||||||
|
|
||||||
|
if vitesse_pourcent == 0:
|
||||||
|
return {
|
||||||
|
"in1": 0,
|
||||||
|
"in2": 0,
|
||||||
|
"pwm": 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# 3) Détermination du sens
|
||||||
|
# Si vitesse_pourcent > 0 : avant (in1=1, in2=0)
|
||||||
|
# Si vitesse_pourcent < 0 : arrière (in1=0, in2=1)
|
||||||
|
# amplitude = valeur absolue de vitesse_pourcent
|
||||||
|
|
||||||
|
if vitesse_pourcent > 0:
|
||||||
|
in1 = 1
|
||||||
|
in2 = 0
|
||||||
|
amplitude = vitesse_pourcent # ici, amplitude = vitesse_pourcent
|
||||||
|
else:
|
||||||
|
in1 = 0
|
||||||
|
in2 = 1
|
||||||
|
amplitude = -vitesse_pourcent # ici, amplitude = -vitesse_pourcent
|
||||||
|
# 4) Conversion pourcentage -> PWM
|
||||||
|
# pwm = pwm_max * (amplitude / 100)
|
||||||
|
# TODO : compléter le calcul
|
||||||
|
|
||||||
|
pwm = int( pwm_max * (amplitude / 100) )
|
||||||
|
|
||||||
|
# 5) Retour des valeurs à appliquer sur le pont en H
|
||||||
|
return {
|
||||||
|
"in1": in1,
|
||||||
|
"in2": in2,
|
||||||
|
"pwm": pwm
|
||||||
|
}
|
||||||
37
TP - 03-12-25/test_logique_hcsr04.py
Normal file
37
TP - 03-12-25/test_logique_hcsr04.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Objectif : écrire des tests unitaires pour vérifier calcul_distance_cm().
|
||||||
|
# Aucune réponse n'est fournie. Les valeurs exactes doivent être déduites
|
||||||
|
# de la formule vue en cours.
|
||||||
|
|
||||||
|
from logique_hcsr04_eleve import calcul_distance_cm
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
|
||||||
|
# Test 1 : temps invalide = 0
|
||||||
|
dist = calcul_distance_cm(0)
|
||||||
|
assert dist is None , "Test temps 0 : incorrect"
|
||||||
|
|
||||||
|
# Test 2 : temps négatif
|
||||||
|
dist = calcul_distance_cm(-100)
|
||||||
|
assert dist is None , "Test temps négatif : incorrect"
|
||||||
|
|
||||||
|
# Test 3 : temps None
|
||||||
|
dist = calcul_distance_cm(None)
|
||||||
|
assert dist is None , "Test None : incorrect"
|
||||||
|
|
||||||
|
# Test 4 : temps court (quelques centaines de microsecondes)
|
||||||
|
# Compléter avec une plage de valeurs acceptables.
|
||||||
|
dist = calcul_distance_cm(1000)
|
||||||
|
assert dist > 17.15 , "Test 1000us : trop petit"
|
||||||
|
assert dist < 17.15 , "Test 1000us : trop grand"
|
||||||
|
|
||||||
|
# Test 5 : temps plus long
|
||||||
|
dist = calcul_distance_cm(3000)
|
||||||
|
assert dist > 51.45 , "Test 3000us : trop petit"
|
||||||
|
assert dist < 51.45 , "Test 3000us : trop grand"
|
||||||
|
|
||||||
|
print("Tests HC-SR04 réussis si vous voyez ce message.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test()
|
||||||
57
TP - 03-12-25/test_logique_moteur.py
Normal file
57
TP - 03-12-25/test_logique_moteur.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# Tests unitaires pour la fonction calcul_signaux_moteur().
|
||||||
|
#
|
||||||
|
# IMPORTANT :
|
||||||
|
# - Aucun résultat attendu n'est donné directement.
|
||||||
|
# - Les élèves doivent connaître / déduire le comportement attendu
|
||||||
|
# d'après l'énoncé du TP
|
||||||
|
|
||||||
|
from fredo.TP.logique_moteur import calcul_signaux_moteur
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
pwm_max = 1000
|
||||||
|
|
||||||
|
# Test 1 : arrêt
|
||||||
|
# Vérifier que les trois valeurs (in1, in2, pwm) correspondent à un moteur à l'arrêt
|
||||||
|
sortie = calcul_signaux_moteur(0, pwm_max)
|
||||||
|
assert sortie["in1"] == 0 , "Test arrêt : valeur in1 incorrecte"
|
||||||
|
assert sortie["in2"] == 0 , "Test arrêt : valeur in2 incorrecte"
|
||||||
|
assert sortie["pwm"] == 0 , "Test arrêt : valeur pwm incorrecte"
|
||||||
|
|
||||||
|
# Test 2 : vitesse maximale en avant
|
||||||
|
# Vérifier la direction et la valeur maximale du PWM
|
||||||
|
sortie = calcul_signaux_moteur(100, pwm_max)
|
||||||
|
assert sortie["in1"] == 1 , "Test avant : in1 incorrect"
|
||||||
|
assert sortie["in2"] == 0 , "Test avant : in2 incorrect"
|
||||||
|
assert sortie["pwm"] == pwm_max , "Test avant : pwm incorrect"
|
||||||
|
|
||||||
|
# Test 3 : vitesse maximale en arrière
|
||||||
|
# Vérifier la direction inverse et le PWM maximal
|
||||||
|
sortie = calcul_signaux_moteur(-100, pwm_max)
|
||||||
|
assert sortie["in1"] == 0 , "Test arrière : in1 incorrect"
|
||||||
|
assert sortie["in2"] == 1 , "Test arrière : in2 incorrect"
|
||||||
|
assert sortie["pwm"] == pwm_max , "Test arrière : pwm incorrect"
|
||||||
|
|
||||||
|
# Test 4 : valeur trop grande positive
|
||||||
|
# Vérifier que la valeur est bien "clampée" à la valeur maximale
|
||||||
|
sortie = calcul_signaux_moteur(150, pwm_max)
|
||||||
|
assert sortie["pwm"] == pwm_max , "Test clamp positif : pwm incorrect"
|
||||||
|
|
||||||
|
# Test 5 : valeur trop grande négative
|
||||||
|
# Vérifier que la valeur est bien "clampée" et le sens correct
|
||||||
|
sortie = calcul_signaux_moteur(-200, pwm_max)
|
||||||
|
assert sortie["in2"] == 1 , "Test clamp négatif : in2 incorrect"
|
||||||
|
assert sortie["pwm"] == -pwm_max , "Test clamp négatif : pwm incorrect"
|
||||||
|
|
||||||
|
# Test 6 : valeur intermédiaire (par exemple 50 %)
|
||||||
|
# Vérifier la direction et la proportion du PWM
|
||||||
|
sortie = calcul_signaux_moteur(50, pwm_max)
|
||||||
|
assert sortie["in1"] == 1 , "Test intermédiaire : in1 incorrect"
|
||||||
|
assert sortie["in2"] == 0 , "Test intermédiaire : in2 incorrect"
|
||||||
|
assert sortie["pwm"] == pwm_max / 2 , "Test intermédiaire : pwm incorrect"
|
||||||
|
|
||||||
|
print("Tous les tests du moteur sont PASSÉS si vous voyez ce message !")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test()
|
||||||
12
base_roulante.py
Normal file
12
base_roulante.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
from logique_BR import *
|
||||||
|
def main():
|
||||||
|
print("Démarrage")
|
||||||
|
sleep(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
|
||||||
|
|
||||||
|
# Lancer automatiquement si ce fichier est main.py
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
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}")
|
||||||
159
logique_BR.py
Normal file
159
logique_BR.py
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
from machine import Pin, PWM, time_pulse_us
|
||||||
|
from time import sleep_us, sleep_ms, sleep
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Configuration des broches
|
||||||
|
# PINS d'exemple, à adapter selon le câblage
|
||||||
|
# -------------------------
|
||||||
|
|
||||||
|
# Moteur gauche (L298N - côté A)
|
||||||
|
PIN_ENA = 25 # PWM moteur gauche
|
||||||
|
PIN_IN1 = 26
|
||||||
|
PIN_IN2 = 27
|
||||||
|
|
||||||
|
# Moteur droit (L298N - côté B)
|
||||||
|
PIN_ENB = 14 # PWM moteur droit
|
||||||
|
PIN_IN3 = 12
|
||||||
|
PIN_IN4 = 13
|
||||||
|
|
||||||
|
# Capteur HC-SR04
|
||||||
|
PIN_TRIG = 5
|
||||||
|
PIN_ECHO = 18
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Initialisation des broches
|
||||||
|
# -------------------------
|
||||||
|
|
||||||
|
# Moteur gauche
|
||||||
|
in1 = Pin(PIN_IN1, Pin.OUT)
|
||||||
|
in2 = Pin(PIN_IN2, Pin.OUT)
|
||||||
|
ena_pwm = PWM(Pin(PIN_ENA))
|
||||||
|
ena_pwm.freq(1000) # fréquence PWM
|
||||||
|
|
||||||
|
# Moteur droit
|
||||||
|
in3 = Pin(PIN_IN3, Pin.OUT)
|
||||||
|
in4 = Pin(PIN_IN4, Pin.OUT)
|
||||||
|
enb_pwm = PWM(Pin(PIN_ENB))
|
||||||
|
enb_pwm.freq(1000)
|
||||||
|
|
||||||
|
# HC-SR04
|
||||||
|
trig = Pin(PIN_TRIG, Pin.OUT)
|
||||||
|
echo = Pin(PIN_ECHO, Pin.IN)
|
||||||
|
|
||||||
|
# Vitesse par défaut (0 à 1023)
|
||||||
|
VITESSE_BASE = 600
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Fonctions moteur
|
||||||
|
# -------------------------
|
||||||
|
|
||||||
|
def moteur_gauche_stop():
|
||||||
|
"""Arrête le moteur gauche."""
|
||||||
|
in1.value(0)
|
||||||
|
in2.value(0)
|
||||||
|
ena_pwm.duty(0)
|
||||||
|
|
||||||
|
|
||||||
|
def moteur_droit_stop():
|
||||||
|
"""Arrête le moteur droit."""
|
||||||
|
in3.value(0)
|
||||||
|
in4.value(0)
|
||||||
|
enb_pwm.duty(0)
|
||||||
|
|
||||||
|
|
||||||
|
def moteurs_stop():
|
||||||
|
"""Arrête les deux moteurs."""
|
||||||
|
moteur_gauche_stop()
|
||||||
|
moteur_droit_stop()
|
||||||
|
|
||||||
|
|
||||||
|
def moteur_gauche_avant(vitesse):
|
||||||
|
"""Fait tourner le moteur gauche en avant."""
|
||||||
|
in1.value(1)
|
||||||
|
in2.value(0)
|
||||||
|
ena_pwm.duty(vitesse)
|
||||||
|
|
||||||
|
|
||||||
|
def moteur_gauche_arriere(vitesse):
|
||||||
|
"""Fait tourner le moteur gauche en arrière."""
|
||||||
|
in1.value(0)
|
||||||
|
in2.value(1)
|
||||||
|
ena_pwm.duty(vitesse)
|
||||||
|
|
||||||
|
|
||||||
|
def moteur_droit_avant(vitesse):
|
||||||
|
"""Fait tourner le moteur droit en avant."""
|
||||||
|
in3.value(1)
|
||||||
|
in4.value(0)
|
||||||
|
enb_pwm.duty(vitesse)
|
||||||
|
|
||||||
|
|
||||||
|
def moteur_droit_arriere(vitesse):
|
||||||
|
"""Fait tourner le moteur droit en arrière."""
|
||||||
|
in3.value(0)
|
||||||
|
in4.value(1)
|
||||||
|
enb_pwm.duty(vitesse)
|
||||||
|
|
||||||
|
|
||||||
|
def avancer(vitesse):
|
||||||
|
"""Le robot avance tout droit."""
|
||||||
|
moteur_gauche_avant(vitesse)
|
||||||
|
moteur_droit_avant(vitesse)
|
||||||
|
|
||||||
|
|
||||||
|
def reculer(vitesse):
|
||||||
|
"""Le robot recule tout droit."""
|
||||||
|
moteur_gauche_arriere(vitesse)
|
||||||
|
moteur_droit_arriere(vitesse)
|
||||||
|
|
||||||
|
|
||||||
|
def tourner_gauche(vitesse):
|
||||||
|
"""
|
||||||
|
Le robot tourne sur place vers la gauche :
|
||||||
|
- moteur droit en avant
|
||||||
|
- moteur gauche en arrière
|
||||||
|
"""
|
||||||
|
moteur_gauche_arriere(vitesse)
|
||||||
|
moteur_droit_avant(vitesse)
|
||||||
|
|
||||||
|
|
||||||
|
def tourner_droite(vitesse):
|
||||||
|
"""Le robot tourne sur place vers la droite."""
|
||||||
|
moteur_gauche_avant(vitesse)
|
||||||
|
moteur_droit_arriere(vitesse)
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Fonction mesure HC-SR04
|
||||||
|
# -------------------------
|
||||||
|
|
||||||
|
def mesure_distance_cm():
|
||||||
|
"""
|
||||||
|
Mesure la distance en cm avec le HC-SR04.
|
||||||
|
Retourne None si la mesure échoue.
|
||||||
|
"""
|
||||||
|
# S'assurer que TRIG est bas
|
||||||
|
trig.value(0)
|
||||||
|
sleep_ms(2)
|
||||||
|
|
||||||
|
# Envoyer une impulsion de 10 us sur TRIG
|
||||||
|
trig.value(1)
|
||||||
|
sleep_us(10)
|
||||||
|
trig.value(0)
|
||||||
|
|
||||||
|
# Mesurer la durée de l'impulsion sur ECHO
|
||||||
|
# timeout_us permet d'éviter de bloquer si pas de réponse
|
||||||
|
duree = time_pulse_us(echo, 1, 30000) # 30 ms max
|
||||||
|
|
||||||
|
if duree < 0:
|
||||||
|
# -1, -2, -3 = codes d'erreur
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Convertir en distance :
|
||||||
|
# vitesse du son ≈ 343 m/s = 0,0343 cm/us
|
||||||
|
# distance aller-retour -> on divise par 2
|
||||||
|
distance = (duree * 0.0343) / 2
|
||||||
|
|
||||||
|
return distance
|
||||||
|
|
||||||
Reference in New Issue
Block a user