maj
This commit is contained in:
30
base_roulante/base_roulante.py
Normal file
30
base_roulante/base_roulante.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from logique_BR import *
|
||||
def main():
|
||||
print("Démarrage")
|
||||
sleep(1)
|
||||
|
||||
try:
|
||||
while True:
|
||||
if mesure_distance_cm() > 0:
|
||||
avancer(100)
|
||||
else:
|
||||
moteurs_stop(0)
|
||||
tourner_gauche(90)
|
||||
if mesure_distance_cm()>0:
|
||||
avancer(100)
|
||||
else:
|
||||
tourner_droite(180)
|
||||
if mesure_distance_cm()>0:
|
||||
avancer(100)
|
||||
else:
|
||||
tourner_droite(90)
|
||||
avancer(100)
|
||||
except KeyboardInterrupt:
|
||||
moteurs_stop()
|
||||
print("impossible d'avancer")
|
||||
|
||||
|
||||
|
||||
# Lancer automatiquement si ce fichier est main.py
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
159
base_roulante/logique_BR.py
Normal file
159
base_roulante/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
|
||||
|
||||
38
tests/logique_hcsr04.py
Normal file
38
tests/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 == None or temps_echo_us <= 0:
|
||||
return 0
|
||||
|
||||
# 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
|
||||
72
tests/logique_moteur.py
Normal file
72
tests/logique_moteur.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# 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 > 100:
|
||||
vitesse_pourcent = 100
|
||||
|
||||
if vitesse_pourcent < -100:
|
||||
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
tests/test_logique_hcsr04.py
Normal file
37
tests/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 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 -100 , "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 > 1000 , "Test 1000us : trop petit"
|
||||
assert dist < 1000 , "Test 1000us : trop grand"
|
||||
|
||||
# Test 5 : temps plus long
|
||||
dist = calcul_distance_cm(3000)
|
||||
assert dist > 3000 , "Test 3000us : trop petit"
|
||||
assert dist < 3000 , "Test 3000us : trop grand"
|
||||
|
||||
print("Tests HC-SR04 réussis si vous voyez ce message.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test()
|
||||
57
tests/test_logique_moteur.py
Normal file
57
tests/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 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"] == 100 , "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"] == -100 , "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"] == 100 , "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"] == 0 , "Test clamp négatif : in2 incorrect"
|
||||
assert sortie["pwm"] == -100 , "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"] == 50 , "Test intermédiaire : pwm incorrect"
|
||||
|
||||
print("Tous les tests du moteur sont PASSÉS si vous voyez ce message !")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test()
|
||||
Reference in New Issue
Block a user