Système de traduction et d'apprentissage du Braille

Auteur avatarGOACOLO | Dernière modification 26/05/2025 par Yawen

Objet qui permet de traduire et d'apprendre le braille.
Difficulté
Difficile
Durée
72 heure(s)
Catégories
Électronique, Bien-être & Santé
Coût
250 EUR (€)

Sommaire

Licence : Attribution (CC BY)

Introduction

Présentation d'un tutoriel notre projet de classe de terminale STI2D afin de le reproduire chez soi

Matériaux

-Bois 3mm

-Plastique pour découpeuse laser ( ici du PLA)

Outils

-Découpeuse laser

-Imprimante 3D (ici la Ultimaker 2+)

Étape 1 - Découpe des pièces en bois du boitier

-Connecter l'ordinateur à la découpeuse laser

-Ouvrir le logiciel Trotek ( Nécessaire à la découpe)

-Ouvrir les pièces à découper en format dxf dans le logiciel

-Optimiser l'espace sur la planche afin d'avoir les moins de perte de matière et déplaçant les pièces

-Lancer la découpe

-Nettoyer les pièces afin d'éviter des tâches dues au bois brûlé.

Étape 2 - Assemblage des pièces en bois

Étape 3 -

Étape 4 -

Étape 5 - Branchement entre les carte électroniques et les servo-moteurs

- Brancher les servo moteur sur la carte arduino - inséré le code arduino
Servo servos[6];  // Tableau de 6 servos
const int pinsServos[6] = {3, 5, 6, 9, 10, 11};  // Broches des servos

unsigned long tempsServo = 0;
bool servosActifs = false;

void setup() {
    Serial.begin(9600);  // Initialisation du moniteur série
    Serial.println("✅ Arduino prêt, en attente des commandes I2C...");

    Wire.begin(8); // Arduino en esclave I2C (adresse 8)
    Wire.onReceive(recevoirCommande);

    // Initialiser les servos à la position souhaitée (par exemple, 45°)
    for (int i = 0; i < 6; i++) {
        servos[i].attach(pinsServos[i]);
        servos[i].write(45);  // Position initiale (en bas)
    }
}

void loop() {
    if (servosActifs && millis() - tempsServo >= 3000) {
        Serial.println("🔄 Retour des servos à la position initiale.");
        for (int i = 0; i < 6; i++) {
            servos[i].write(45);  // Retour à la position initiale (en bas)
        }
        servosActifs = false;
    }
}

void recevoirCommande(int nombreOctets) {
    if (Wire.available()) {
        int valeur = Wire.read();  // Lire le nombre envoyé par le Raspberry Pi
        Serial.print("📩 Commande reçue: ");
        Serial.println(valeur, BIN); // Afficher la valeur en binaire (code Braille)

        // Déplacer chaque servo un par un avec un petit délai
        for (int i = 0; i < 6; i++) {
            if (valeur & (1 << (5 - i))) {  // Vérifier si le bit i est actif
                Serial.print("🔼 Servo ");
                Serial.print(i);
                Serial.println(" activé.");
                servos[i].write(135);  // Position haute (en haut)
            } else {
                Serial.print("🔽 Servo ");
                Serial.print(i);
                Serial.println(" désactivé.");
                servos[i].write(45);  // Position initiale (en bas)
            }
            delay(100);  // Petite pause entre les déplacements des servos
        }

        tempsServo = millis();  // Démarrer le timer pour retour automatique
        servosActifs = true;
    }
}
- Se munir de la carte raspery Pi - Brancher relier les broches Gpio raspery Pi avec celle de arduino(gnd,vcc) taper sur internet broche raspery pi - inséré ce code
import smbus
import time
import RPi.GPIO as GPIO  
import random
import os  
import threading
import cv2
import pytesseract
import numpy as np

I2C_ADDR = 8  
bus = smbus.SMBus(1)  

# GPIO des boutons
BOUTON_PRECEDENT = 17  
BOUTON_SUIVANT = 27    
BOUTON_LECON = 23  
BOUTON_EXERCICE = 24
BOUTON_CAMERA = 22  # Bouton pour la caméra

# GPIO du capteur ultrason HCSR04
TRIG = 5  # GPIO pour le trigger du capteur
ECHO = 6  # GPIO pour l'echo du capteur

# Configuration des GPIO
try:
    GPIO.cleanup()
except:
    pass

GPIO.setmode(GPIO.BCM)
GPIO.setup(BOUTON_PRECEDENT, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BOUTON_SUIVANT, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BOUTON_LECON, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BOUTON_EXERCICE, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BOUTON_CAMERA, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Configuration du capteur ultrason
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)
GPIO.output(TRIG, False)  # S'assurer que le trigger est bas au démarrage

# Dictionnaire Braille
braille_dict = {
    "a": 0b100000, "b": 0b110000, "c": 0b101000, "d": 0b101100,
    "e": 0b100100, "f": 0b111000, "g": 0b111100, "h": 0b110100,
    "i": 0b011000, "j": 0b011100, "k": 0b100010, "l": 0b110010,
    "m": 0b101010, "n": 0b101110, "o": 0b100110, "p": 0b111010,
    "q": 0b111110, "r": 0b110110, "s": 0b011010, "t": 0b011110,
    "u": 0b100011, "v": 0b110011, "w": 0b011101, "x": 0b101011,
    "y": 0b101111, "z": 0b100111, " ": 0b000000
}

texte = "bonjour"  # Texte par défaut
index = 0
lecon_en_cours = False
exercice_en_cours = False
attente_texte = False  # Pour savoir si on attend une saisie de texte
camera_en_cours = False  # Pour indiquer si une capture par caméra est en cours

# Paramètres de capture d'image
IMAGE_PATH = "capture.jpg"
CROPPED_PATH = "cropped.jpg"
DISTANCE_OPTIMALE = 15  # Distance optimale en cm
MARGE_DISTANCE = 2.5    # Marge de tolérance en cm (+/-)

def mesurer_distance():
    """Mesure la distance avec le capteur ultrason HCSR04."""
    # Envoyer une impulsion de 10µs au trigger
    GPIO.output(TRIG, True)
    time.sleep(0.00001)  # 10µs
    GPIO.output(TRIG, False)
    
    # Attendre que l'écho commence
    start_time = time.time()
    timeout = start_time + 1.0  # Timeout de 1 seconde
    
    while GPIO.input(ECHO) == 0:
        if time.time() > timeout:
            return -1  # Erreur: pas de signal
        pulse_start = time.time()
    
    # Attendre que l'écho se termine
    while GPIO.input(ECHO) == 1:
        if time.time() > timeout:
            return -1  # Erreur: signal trop long
        pulse_end = time.time()
    
    # Calculer la durée de l'impulsion
    pulse_duration = pulse_end - pulse_start
    
    # Calculer la distance (vitesse du son = 34300 cm/s)
    # Diviser par 2 car le signal fait l'aller-retour
    distance = (pulse_duration * 34300) / 2
    
    return round(distance, 1)  # Arrondir à 1 décimale

def guide_position():
    """Guide l'utilisateur pour positionner correctement le texte."""
    global camera_en_cours
    
    print("📏 Positionnement du texte...")
    os.system('espeak -v fr "Positionnez le texte" --stdout | aplay')
    
    # Attendre que la distance soit stable dans la plage optimale
    position_stable = False
    nb_mesures_stables = 0
    
    while camera_en_cours and not position_stable:
        distance = mesurer_distance()
        
        if distance < 0:
            print("⚠️ Erreur de mesure de distance")
            time.sleep(0.5)
            continue
            
        print(f"📏 Distance mesurée : {distance} cm")
        
        if distance < DISTANCE_OPTIMALE - MARGE_DISTANCE:
            # Trop proche
            os.system('espeak -v fr "Reculez" --stdout | aplay')
            nb_mesures_stables = 0
        elif distance > DISTANCE_OPTIMALE + MARGE_DISTANCE:
            # Trop loin
            os.system('espeak -v fr "Avancez" --stdout | aplay')
            nb_mesures_stables = 0
        else:
            # Distance correcte
            print(f"✅ Distance correcte : {distance} cm")
            nb_mesures_stables += 1
            
            # Si 3 mesures consécutives sont dans la plage, on considère la position comme stable
            if nb_mesures_stables >= 3:
                position_stable = True
                os.system('espeak -v fr "Position correcte" --stdout | aplay')
        
        time.sleep(0.5)  # Attendre avant la prochaine mesure
    
    return position_stable

def envoyer_nombre(nombre, mode=None):
    """Envoie une lettre en Braille et annonce (avec délai optionnel en mode exercice)."""
    try:
        lettre = [key for key, val in braille_dict.items() if val == nombre][0]  
        bus.write_byte(I2C_ADDR, nombre)
        print(f"✅ Lettre envoyée: {lettre.upper()} ({bin(nombre)})")
        
        # Si c'est le mode exercice, attendre 2 secondes avant d'énoncer la lettre
        if mode == "exercice":
            # Vérifier périodiquement si l'exercice a été arrêté pendant l'attente
            debut = time.time()
            while time.time() - debut < 2 and exercice_en_cours:
                time.sleep(0.1)
            
            # Ne prononcer la lettre que si l'exercice est toujours en cours
            if exercice_en_cours:
                os.system(f'espeak -v fr "{lettre}" --stdout | aplay')
        else:
            # Pour les autres modes, énoncer la lettre immédiatement
            os.system(f'espeak -v fr "{lettre}" --stdout | aplay')  
    except IOError:
        print("❌ Erreur de communication avec l'Arduino")
    except IndexError:
        print("❌ Erreur: code braille non trouvé dans le dictionnaire")
    except Exception as e:
        print(f"❌ Erreur inattendue: {str(e)}")

def demander_nouveau_texte():
    """Demande un nouveau texte et réinitialise l'index."""
    global texte, index, attente_texte
    
    # Annonce vocale
    os.system('espeak -v fr "Entrez un nouveau texte" --stdout | aplay')
    
    # Lancer un thread pour attendre la saisie sans bloquer le reste du programme
    def attendre_saisie():
        global texte, index, attente_texte
        nouveau_texte = input("\n🆕 Entrez un texte (ou appuyez sur Entrée pour garder 'bonjour') : ").lower()
        if nouveau_texte:  # Si l'utilisateur a entré quelque chose
            texte = nouveau_texte
        index = 0
        print(f"🔠 Texte actuel : {texte}")
        print("📌 Appuyez sur le bouton 'Suivant' pour parcourir le texte, ou sur 'Leçon'/'Exercice' pour ces modes.")
        attente_texte = False  # Fin de l'attente
    
    attente_texte = True  # Début de l'attente
    t = threading.Thread(target=attendre_saisie)
    t.daemon = True
    t.start()

def bouton_precedent(channel):
    """Affiche la lettre précédente pendant la lecture du texte."""
    global index
    
    # Ne pas exécuter si un mode est en cours ou si on attend une saisie
    if lecon_en_cours or exercice_en_cours or attente_texte or camera_en_cours:
        return
    
    time.sleep(0.2)  # Anti-rebond
    if GPIO.input(BOUTON_PRECEDENT) == GPIO.LOW:
        if index > 0:
            index -= 1
            envoyer_nombre(braille_dict.get(texte[index], 0))
            print(f"🔙 Lettre précédente: {texte[index]}")
        else:
            print("🚫 Déjà à la première lettre.")
            os.system('espeak -v fr "Première lettre" --stdout | aplay')

def bouton_suivant(channel):
    """Affiche la lettre suivante et lit le mot en entier à la fin."""
    global index
    
    # Ne pas exécuter si un mode est en cours ou si on attend une saisie
    if lecon_en_cours or exercice_en_cours or attente_texte or camera_en_cours:
        return
    
    time.sleep(0.2)  # Anti-rebond
    if GPIO.input(BOUTON_SUIVANT) == GPIO.LOW:
        if texte and index < len(texte):
            envoyer_nombre(braille_dict.get(texte[index], 0))
            index += 1
            print(f"🔜 Lettre suivante: {texte[index-1]}")
            if index == len(texte):
                print("🔁 Fin du texte, lecture complète...")
                os.system(f'espeak -v fr "{texte}" --stdout | aplay')
                demander_nouveau_texte()

def lancer_lecon():
    """Fonction pour lancer la leçon dans un thread séparé."""
    global lecon_en_cours
    
    # Si on attend une saisie de texte, annuler cette attente
    global attente_texte
    attente_texte = False
    
    # Marquer le début de la leçon
    lecon_en_cours = True
    print("📖 Début de la leçon...")
    os.system('espeak -v fr "Début de la leçon" --stdout | aplay')
    
    # Parcourir l'alphabet
    for lettre in "abcdefghijklmnopqrstuvwxyz":
        # Vérifier si la leçon a été arrêtée
        if not lecon_en_cours:
            return
        
        # Afficher et annoncer la lettre
        print(f"📝 Leçon : Lettre {lettre.upper()}")
        envoyer_nombre(braille_dict[lettre])
        
        # Attendre 8 secondes, en vérifiant si la leçon a été arrêtée
        debut = time.time()
        while time.time() - debut < 8:
            if not lecon_en_cours:
                return  # Sortir immédiatement si la leçon a été arrêtée
            time.sleep(0.1)
    
    # Fin normale de la leçon
    print("✅ Leçon terminée !")
    os.system('espeak -v fr "Leçon terminée" --stdout | aplay')
    lecon_en_cours = False
    
    # Proposer d'entrer un nouveau texte sans bloquer
    demander_nouveau_texte()

def lancer_exercice():
    """Fonction pour lancer l'exercice dans un thread séparé."""
    global exercice_en_cours
    
    # Si on attend une saisie de texte, annuler cette attente
    global attente_texte
    attente_texte = False
    
    # Marquer le début de l'exercice
    exercice_en_cours = True
    print("🎲 Début de l'exercice...")
    os.system('espeak -v fr "Début de l\'exercice" --stdout | aplay')
    
    # Préparer les lettres dans un ordre aléatoire
    lettres = list("abcdefghijklmnopqrstuvwxyz")
    random.shuffle(lettres)
    
    # Parcourir les lettres aléatoires
    for lettre in lettres:
        # Vérifier si l'exercice a été arrêté
        if not exercice_en_cours:
            return
        
        # Afficher et annoncer la lettre avec délai de 2 secondes
        print(f"📝 Exercice : Lettre {lettre.upper()}")
        envoyer_nombre(braille_dict[lettre], mode="exercice")
        
        # Attendre le reste des 8 secondes (moins les 2 secondes d'attente déjà écoulées), 
        # en vérifiant si l'exercice a été arrêté
        debut = time.time()
        while time.time() - debut < 6:  # 8 - 2 = 6 secondes restantes
            if not exercice_en_cours:
                return  # Sortir immédiatement si l'exercice a été arrêté
            time.sleep(0.1)
    
    # Fin normale de l'exercice
    print("🏆 Exercice terminé !")
    os.system('espeak -v fr "Exercice terminé" --stdout | aplay')
    exercice_en_cours = False
    
    # Proposer d'entrer un nouveau texte sans bloquer
    demander_nouveau_texte()

def capturer_et_lire_texte():
    """Fonction pour capturer une image avec la caméra et en extraire le texte."""
    global camera_en_cours, texte, index, attente_texte
    
    # Si on attend une saisie de texte, annuler cette attente
    attente_texte = False
    
    # Marquer le début de la capture
    camera_en_cours = True
    print("📸 Préparation de la capture...")
    os.system('espeak -v fr "Préparation de la capture" --stdout | aplay')
    
    # Guide de positionnement avec le capteur ultrason
    if guide_position():
        # Capture de l'image (réduction du temps à 3s car on a déjà guidé l'utilisateur)
        print("📸 Capture en cours...")
        os.system('espeak -v fr "Capture en cours" --stdout | aplay')
        os.system(f"libcamera-jpeg -o {IMAGE_PATH} -t 3000 --width 1920 --height 1080 --quality 100")
        
        # Vérifier si l'image existe
        if not os.path.exists(IMAGE_PATH):
            print("❌ Erreur : L'image n'a pas été capturée.")
            os.system('espeak -v fr "Erreur de capture" --stdout | aplay')
            camera_en_cours = False
            return
        
        print("⚡ Optimisation de l'image...")
        try:
            # Chargement et conversion en niveaux de gris
            image = cv2.imread(IMAGE_PATH)
            gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            
            # Correction de l'orientation
            try:
                osd = pytesseract.image_to_osd(gray)
                angle = int(osd.split("\n")[1].split(":")[1].strip())
                if angle != 0:
                    (h, w) = gray.shape[:2]
                    center = (w // 2, h // 2)
                    M = cv2.getRotationMatrix2D(center, -angle, 1.0)
                    gray = cv2.warpAffine(gray, M, (w, h))
            except:
                print("⚠ Impossible de détecter l'orientation, passage à l'étape suivante.")
            
            # Prétraitement (amélioration du contraste et du bruit)
            gray = cv2.GaussianBlur(gray, (3, 3), 0)
            gray = cv2.equalizeHist(gray)  # Augmentation du contraste
            gray = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 10)
            
            # Détection des contours pour recadrer uniquement le texte
            print("📐 Détection du texte...")
            edges = cv2.Canny(gray, 50, 150)
            contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            
            filtered_contours = [c for c in contours if cv2.contourArea(c) > 1000]
            
            if filtered_contours:
                x, y, w, h = cv2.boundingRect(cv2.convexHull(np.vstack(filtered_contours)))
                cropped = image[y:y+h, x:x+w]
                cropped = cv2.resize(cropped, None, fx=1.5, fy=1.5, interpolation=cv2.INTER_LINEAR)
                cv2.imwrite(CROPPED_PATH, cropped)
            else:
                print("⚠ Aucun texte clairement détecté, extraction sur l'image entière.")
                cropped = image
            
            # OCR optimisé
            print("🔍 Extraction du texte...")
            detected_text = pytesseract.image_to_string(cropped, lang="eng+fra", config="--psm 6 --oem 3").strip()
            
            # Nettoyer le texte détecté (supprimer les caractères spéciaux et garder lettres, chiffres et espaces)
            cleaned_text = ''.join(c.lower() for c in detected_text if c.isalnum() or c.isspace())
            
            # Si le texte est vide après nettoyage, afficher un message
            if not cleaned_text:
                print("⚠ Aucun texte détecté après nettoyage.")
                os.system('espeak -v fr "Aucun texte détecté" --stdout | aplay')
                camera_en_cours = False
                return
            
            # Afficher le texte détecté
            print(f"\n📄 Texte détecté : {cleaned_text}")
            os.system(f'espeak -v fr "Texte détecté" --stdout | aplay')
            
            # Mettre à jour le texte global et réinitialiser l'index
            texte = cleaned_text
            index = 0
            print(f"🔠 Nouveau texte : {texte}")
            print("📌 Appuyez sur le bouton 'Suivant' pour parcourir le texte.")
            
        except Exception as e:
            print(f"❌ Erreur lors du traitement de l'image : {str(e)}")
            os.system('espeak -v fr "Erreur de traitement" --stdout | aplay')
    else:
        print("❌ Positionnement annulé.")
        os.system('espeak -v fr "Positionnement annulé" --stdout | aplay')
    
    # Marquer la fin de la capture
    camera_en_cours = False

def bouton_lecon_presse(channel):
    """Fonction appelée lorsque le bouton leçon est pressé."""
    global lecon_en_cours
    
    # Ne pas réagir si un autre mode est en cours
    if exercice_en_cours or camera_en_cours:
        return
    
    time.sleep(0.2)  # Anti-rebond
    if GPIO.input(BOUTON_LECON) == GPIO.LOW:
        # Basculer l'état de la leçon
        if lecon_en_cours:
            lecon_en_cours = False
            print("📖 Leçon arrêtée par l'utilisateur.")
            os.system('espeak -v fr "Leçon arrêtée" --stdout | aplay')
            # La leçon est arrêtée, sera nettoyée dans le thread
        else:
            # Lancer la leçon dans un thread séparé
            t = threading.Thread(target=lancer_lecon)
            t.daemon = True  # Le thread s'arrêtera quand le programme principal s'arrête
            t.start()

def bouton_exercice_presse(channel):
    """Fonction appelée lorsque le bouton exercice est pressé."""
    global exercice_en_cours
    
    # Ne pas réagir si un autre mode est en cours
    if lecon_en_cours or camera_en_cours:
        return
    
    time.sleep(0.2)  # Anti-rebond
    if GPIO.input(BOUTON_EXERCICE) == GPIO.LOW:
        # Basculer l'état de l'exercice
        if exercice_en_cours:
            exercice_en_cours = False
            print("🎲 Exercice arrêté par l'utilisateur.")
            os.system('espeak -v fr "Exercice arrêté" --stdout | aplay')
            # L'exercice est arrêté, sera nettoyé dans le thread
        else:
            # Lancer l'exercice dans un thread séparé
            t = threading.Thread(target=lancer_exercice)
            t.daemon = True  # Le thread s'arrêtera quand le programme principal s'arrête
            t.start()

def bouton_camera_presse(channel):
    """Fonction appelée lorsque le bouton caméra est pressé."""
    global camera_en_cours
    
    # Ne pas réagir si un autre mode est en cours
    if lecon_en_cours or exercice_en_cours or camera_en_cours:
        return
    
    time.sleep(0.2)  # Anti-rebond
    if GPIO.input(BOUTON_CAMERA) == GPIO.LOW:
        # Lancer la capture dans un thread séparé
        t = threading.Thread(target=capturer_et_lire_texte)
        t.daemon = True  # Le thread s'arrêtera quand le programme principal s'arrête
        t.start()

# Supprimer les détecteurs d'événements existants s'il y en a
try:
    GPIO.remove_event_detect(BOUTON_SUIVANT)
    GPIO.remove_event_detect(BOUTON_PRECEDENT)
    GPIO.remove_event_detect(BOUTON_LECON)
    GPIO.remove_event_detect(BOUTON_EXERCICE)
    GPIO.remove_event_detect(BOUTON_CAMERA)
except:
    pass

# Configuration des détecteurs d'événements
GPIO.add_event_detect(BOUTON_SUIVANT, GPIO.FALLING, callback=bouton_suivant, bouncetime=500)
GPIO.add_event_detect(BOUTON_PRECEDENT, GPIO.FALLING, callback=bouton_precedent, bouncetime=500)
GPIO.add_event_detect(BOUTON_LECON, GPIO.FALLING, callback=bouton_lecon_presse, bouncetime=500)
GPIO.add_event_detect(BOUTON_EXERCICE, GPIO.FALLING, callback=bouton_exercice_presse, bouncetime=500)
GPIO.add_event_detect(BOUTON_CAMERA, GPIO.FALLING, callback=bouton_camera_presse, bouncetime=500)

# Initialisation du capteur ultrason (attendre qu'il se stabilise)
print("⚙️ Initialisation du capteur ultrason...")
time.sleep(0.5)
GPIO.output(TRIG, False)
time.sleep(0.5)

# Afficher les instructions au démarrage
print("👋 Bienvenue dans l'application d'apprentissage du Braille")
print("📋 Instructions:")
print("  - Bouton LEÇON: Apprendre l'alphabet (8s par lettre)")
print("  - Bouton EXERCICE: Pratiquer avec des lettres aléatoires (2s de réflexion, puis annonce)")
print("  - Bouton SUIVANT: Afficher la lettre suivante du texte")
print("  - Bouton PRÉCÉDENT: Afficher la lettre précédente du texte")
print("  - Bouton CAMÉRA: Guide le positionnement, puis capture une image et extrait le texte")
print("⚠️ Appuyez à nouveau sur LEÇON/EXERCICE pour arrêter à tout moment")
print(f"🔠 Texte par défaut : {texte}")
print("📌 Appuyez sur le bouton 'Suivant' pour parcourir le texte, ou choisissez un mode.")

# Boucle principale pour maintenir le programme actif
try:
    while True:
        time.sleep(0.1)
except KeyboardInterrupt:
    print("\n🛑 Arrêt du programme.")
    GPIO.cleanup()


Étape 6 - Système d'interface homme-machine

Le système est équipé de 5 boutons physiques qui permettent de contrôler les différents modes d'apprentissage et la détection du texte.

-Brancher les bouton aux broches gpio correspondantes grâce au code inséré précédement



Étape 7 - Système de détection de texte

Le système utilise une caméra et un capteur à ultrasons pour détecter du texte .

-Se munir du Capteur ultrason et le brancher sur la broche gpio (regardez le code rasperypi pour savoir )

- Brancher la camera à la Raspberry Pi, il y a un tuto ici

-Lancer en premier lieu sur raspery pi



Étape 8 -

Commentaires

Published