On souhaite programmer le robot MR25 pour détecter un frappement de main en utilisant le microphone.
👏👏👏
Voici un exemple de programme pour détecter le frappement de main :
-> la led rouge s’allume lors d’une détection de frappement de main
import subprocess
import numpy as np
import MR25, time
# Paramètres
DEVICE = "hw:0,0"
RATE = 48000
CHANNELS = 1
CHUNK = 1024
# Seuil de détection
THRESHOLD = 0.01
cmd = [
"arecord",
"-D", DEVICE,
"-f", "S16_LE",
"-r", str(RATE),
"-c", str(CHANNELS),
"-t", "raw",
"-"
]
print("Écoute du microphone...")
print("Frappez dans vos mains pour tester.")
print("Ctrl+C pour arrêter.\n")
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL
)
try:
while True:
data = process.stdout.read(CHUNK * 2)
if len(data) != CHUNK * 2:
break
# Conversion des échantillons 16 bits
audio = np.frombuffer(data, dtype=np.int16)
# Normalisation entre -1 et +1
audio = audio.astype(np.float32) / 32768.0
# Calcul RMS
volume = np.sqrt(np.mean(audio ** 2))
# Affichage du niveau
bar = int(volume * 50)
print(
f"\rVolume : {volume:.3f} "
f"[{'#' * bar:<50}]",
end="",
flush=True
)
# Détection
if volume > THRESHOLD:
print("\n>>> FRAPPEMENT DETECTE ! <<<")
MR25.ledRGB("100") # allumer led rouge
time.sleep(1)
MR25.ledRGB("000") # eteindre led rouge
except KeyboardInterrupt:
print("\n\nArrêt.")
finally:
process.terminate()
Algorithme
- Acquisition audio
- Conversion des données
- Les octets reçus sont convertis en entiers
.
- Ils sont ensuite normalisés entre
et
:
- Calcul du niveau sonore
- Le programme calcule la valeur RMS (Root Mean Square) du bloc.
- Comparaison avec un seuil
- Le niveau calculé est comparé à
- Action
- La LED rouge du robot
s’allume.

Détection de plusieurs frappements de main
👏👏👏
Voici un autre exemple de programme pour détecter plusieurs frappement de main :
- 1 frappement de main -> LED ROUGE
- 2 frappements de main -> LED VERTE
- 3 frappements de main -> LED BLEU
import subprocess
import numpy as np
import MR25
import time
DEVICE = "hw:0,0"
RATE = 48000
CHANNELS = 1
CHUNK = 1024
THRESHOLD = 0.01
# Temps minimum entre deux frappes
DEBOUNCE_TIME = 0.20
# Temps maximum pour regrouper les frappes
GROUP_TIMEOUT = 0.80
cmd = [
"arecord",
"-D", DEVICE,
"-f", "S16_LE",
"-r", str(RATE),
"-c", str(CHANNELS),
"-t", "raw",
"-"
]
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL
)
nombre_frappes = 0
derniere_frappe = 0
dernier_signal = 0
print("Écoute du microphone...")
print("1 frappe = LED rouge")
print("3 frappes = LED verte")
print("Ctrl+C pour arrêter.\n")
try:
while True:
data = process.stdout.read(CHUNK * 2)
if len(data) != CHUNK * 2:
break
audio = np.frombuffer(data, dtype=np.int16)
audio = audio.astype(np.float32) / 32768.0
volume = np.sqrt(np.mean(audio ** 2))
maintenant = time.time()
# Affichage du volume
bar = min(50, int(volume * 50))
print(
f"\rVolume : {volume:.3f} "
f"[{'#' * bar:<50}] "
f"Frappes : {nombre_frappes}",
end="",
flush=True
)
# Détection d'une frappe
if volume > THRESHOLD:
# Évite de compter plusieurs fois la même frappe
if maintenant - derniere_frappe > DEBOUNCE_TIME:
nombre_frappes += 1
derniere_frappe = maintenant
print(f"\n>>> Frappe {nombre_frappes}")
# Si le délai entre les frappes est dépassé,
# on analyse le nombre de frappes
if (
nombre_frappes > 0
and maintenant - derniere_frappe > GROUP_TIMEOUT
):
if nombre_frappes == 1:
print(">>> 1 FRAPPE : LED ROUGE")
MR25.ledRGB("100")
time.sleep(0.5)
MR25.ledRGB("000")
elif nombre_frappes == 2:
print(">>> 2 FRAPPES : LED VERTE")
MR25.ledRGB("010")
time.sleep(0.5)
MR25.ledRGB("000")
elif nombre_frappes == 3:
print(">>> 3 FRAPPES : LED BLEU")
MR25.ledRGB("001")
time.sleep(0.5)
MR25.ledRGB("000")
else:
print(f">>> {nombre_frappes} frappes : aucune action")
# Réinitialisation
nombre_frappes = 0
except KeyboardInterrupt:
print("\n\nArrêt.")
finally:
process.terminate()
Fin du tuto !