Catégories
MICRO PYTHON RASPBERRY PICO W

CAPTEURS COULEURS TCS34725

RASPBERRY PICO W

Le capteur de couleur TCS34725 (Gravity)

À quoi ça sert sur notre robot ?

Le TCS34725 est un capteur de couleur.
Sur la compétition Rescue Line, il sert principalement à :

  • suivre la ligne noire
  • repérer les carrés verts pour savoir quand tourner à droite ou à gauche

Comment “voit” le capteur ?

Il éclaire le sol

Le capteur possède quatre petites LEDs blanches.

  • Elle éclaire le sol juste en dessous du robot
  • La lumière rebondit sur le sol et revient vers le capteur
  • Un sol clair renvoie beaucoup de lumière
  • Un sol foncé (ligne noire) renvoie peu de lumière

Il sépare la lumière en couleurs

À l’intérieur du capteur, il y a 4 détecteurs :

  • 🔴 Rouge (R)
  • 🟢 Vert (G)
  • 🔵 Bleu (B)
  • ⚪ Luminosité totale (Clear)

Pour chaque couleur, le capteur donne un nombre.

Ces nombres sont envoyés au microcontrôleur (ex : Raspberry Pico, mBot, etc.).

Le multiplexeur I2C

Pourquoi on en a besoin avec plusieurs capteurs de couleur ?

Rappel : c’est quoi le bus I2C ?

Le bus I2C, c’est comme une route avec quatres fils :

  • SDA : pour envoyer et recevoir les données
  • SCL : pour donner le rythme (l’horloge)

Tous les capteurs sont branchés sur la même route et parlent avec le microcontrôleur.

Avec un bus I2C ont peut dialoguer avec plusieurs dispositifs sur le même bus.

Chaque capteur a une adresse

Sur cette route, chaque capteur a une adresse, comme un numéro de maison.

Exemple :

  • Capteur température : adresse 0x48
  • Capteur distance : adresse 0x29
  • Capteur couleur TCS34725 : adresse 0x29

Quand le microcontrôleur veut parler à un capteur, il dit :

« Je parle au capteur numéro 0x29 »

Le problème avec plusieurs capteurs identiques

Dans notre robot, on utilise plusieurs capteurs de couleur identiques :

  • gauche
  • centre
  • droite

Et ils ont tous la même adresse I2C

Résultat :

  • Le microcontrôleur dit :
    « Capteur 0x29, réponds ! »
  • Tous répondent en même temps
  • Ça crée un conflit → le bus ne fonctionne plus

La solution : le multiplexeur I2C

Un multiplexeur I2C (ex : TCA9548A) est comme :

un aiguillage ou un feu de circulation pour le bus I2C

Il permet de choisir quel capteur est connecté au bus à un instant donné.

Comment fonctionne le multiplexeur ?

Le multiplexeur est lui-même un appareil I2C

  • Il a sa propre adresse
  • Le microcontrôleur peut lui parler

Il possède plusieurs “canaux” de 1 à 8 canaux

Par exemple :

  • canal 0
  • canal 1
  • canal 2
  • jusqu’à 8 canaux

Chaque canal peut avoir :

  • un capteur
  • ou même plusieurs capteurs (s’ils ont des adresses différentes)

On ouvre un canal à la fois

Le microcontrôleur dit au multiplexeur :

« Ouvre le canal 2 »

Résultat :

  • Seul le capteur branché sur le canal 2 est visible
  • Les autres sont déconnectés temporairement

Pour programmer, le capteur TCS34725 utilise la librairie class tcs34725.py à télécharger sur le microcontroleur :

Dans ton programme importe ces bibliothèques :

from machine import I2C
import time
from tcs34725 import TCS34725

Recherche les adresses sur le bus i2c :

from machine import I2C
import time
from tcs34725 import TCS34725

print("Initialisation I2C...")
i2c = I2C(0)
print("Scan I2C en cours...")
devices = i2c.scan()
print("Adresses trouvées:", [hex(d) for d in devices])
  • 0x29 : capteur de couleur
  • 0x72 : multiplexeur i2c

Exemple d’un programme de test pour lire les valeurs de deux capteurs sur les port 0 et 1 :

from machine import I2C
import time
from tcs34725 import TCS34725

print("Initialisation I2C...")
i2c = I2C(0)
print("Scan I2C en cours...")
devices = i2c.scan()
print("Adresses trouvées:", [hex(d) for d in devices])
# Initialisation du capteur
# Si vous n'utilisez PAS de multiplexeur, laissez multiplexer_addr=None
# Si vous en utilisez un, changez multiplexer_addr=0x70 (ou autre) et le port=0-7
ADDRESS_MULTIPLEXER = const(0x72)
try:
    print("Initialisation TCS34725...")
    #sensor = TCS34725(i2c)
    # Pour un multiplexeur:
    sensor01 = TCS34725(i2c, ADDRESS_MULTIPLEXER, 0)
    sensor02 = TCS34725(i2c, ADDRESS_MULTIPLEXER, 1)

    print("Capteur trouvé !")

    # Configuration optionnelle
    sensor01.integration_time(50) # 50ms (plus rapide mais moins précis que 2.4ms * n)
    sensor01.gain(4) # Gain 4x (1, 4, 16, 60)
    sensor02.integration_time(50)
    sensor02.gain(4)
    while True:
        # Lecture brute
        r, g, b, c = sensor01.read(raw=True)

        # Lecture interprétée
        temp, lux = sensor01.read(raw=False) # Note: refait une lecture

        print(f"R:{r} G:{g} B:{b} C:{c} | Temp:{temp}K Lux:{lux}")

        gray01 = sensor01.read_grayscale()
        gray02 = sensor02.read_grayscale()
        print("Read Gray : ", gray01)

        # Détection simple couleur
        if sensor01.is_red():
            print(" >> ROUGE détecté !")
        elif sensor01.is_green():
            print(" >> VERT détecté !")
        elif sensor01.is_blue():
            print(" >> BLEU détecté !")

        time.sleep(1)

except RuntimeError as e:
    print("ERREUR FATALE:", e)
except Exception as e:
    print("Erreur inattendue:", e)

Exemple initialisation capteur de couleur en direct sans le multiplexeur :

    sensor = TCS34725(i2c)

Exemple initialisation capteurs couleur via le multiplexeur :

    sensor01 = TCS34725(i2c, ADDRESS_MULTIPLEXER, 0)
    sensor02 = TCS34725(i2c, ADDRESS_MULTIPLEXER, 1)

Lecture de la nuance de gris :

        gray01 = sensor01.read_grayscale()
        print("Read Gray : ", gray01)

Détection d’une couleur :

if sensor01.is_red():
print( » >> ROUGE détecté ! »)
elif sensor01.is_green():
print( » >> VERT détecté ! »)
elif sensor01.is_blue():
print( » >> BLEU détecté ! »)

Catégories
MICRO PYTHON RASPBERRY PICO W Robotique

Entrées et sorties numériques

CARTE DE DEVELOPPEMENT RASPBERRY PICO W

LED intégrée à la carte

Sur la Raspberry Pi Pico, il y a une petite LED intégrée à la carte.

Cette LED est reliée à une broche spéciale.

Quand on met cette broche :

  • à 1 (ON) → la LED s’allume
  • à 0 (OFF) → la LED s’éteint

Comment la Pico contrôle la LED ?

La Pico utilise une sortie numérique.

C’est comme un interrupteur :

  • ON = courant qui passe
  • OFF = courant coupé

En MicroPython, on utilise la classe Pin.

Allumer la LED

from machine import Pin

led = Pin("LED",Pin.OUT) # LED sur la carte
led.on()                # Allumer la LED

La LED s’allume

Eteindre la LED

led.off()  # Éteindre la LED

La LED s’éteint

Faire clignoter la LED

from machine import Pin
from time import sleep

led = Pin("LED", Pin.OUT)

while True:
    led.on()      # LED allumée
    sleep(1)      # attendre 1 seconde
    led.off()     # LED éteinte
    sleep(1)      # attendre 1 seconde

Résultat :

  • la LED s’allume 1 seconde
  • puis s’éteint 1 seconde
  • et recommence en boucle

Une autre façon

from machine import Pin, Timer

# led de la carte
led=Pin("LED",Pin.OUT)

timerLed=Timer() # déclare un objet timer

def loopLed(timerLed): 
    led.toggle()

timerLed.init(freq=5, callback=loopLed)

La LED clignote toute seule, sans bloquer le programme.

C’est comme une alarme tous les x secondes :

  • tu règles l’heure
  • et il sonne tout seul
  • même si tu fais autre chose

Création du timer

  • Timer → pour créer un minuteur automatique

timerLed = Timer()

On crée un minuteur qui appellera une fonction tout seul.

Démarrage du timer

timerLed.init(freq=5, callback=loopLed)

  • freq=5 → 5 fois par seconde
  • callback=loopLed → appelle la fonction loopLed

La fonction appelée par le timer

def loopLed(timerLed):
led.toggle()

Cette fonction :

  • est appelée automatiquement par le timer
  • change l’état de la LED à chaque appel (allumée, éteinte)

Faire clignoter une LED sur le PIN GP2

Installe une LED de couleur bleue sur le port GP2 :

from machine import Pin, Timer

# led de la carte
ledBlue=Pin(2,Pin.OUT)

timerLedBlue=Timer() # déclare un objet timer

def loopLedBlue(timerLedBlue): 
    ledBlue.toggle()

timerLedBlue.init(freq=1, callback=loopLedBlue)

Faire clignoter une LED bleue avec un Timer

(sans boucle while)

  • La LED clignote toute seule,
  • une fois par seconde,
  • sans bloquer le programme.

C’est comme un réveil :

  • tu règles le rythme
  • et il déclenche la LED tout seul
  • pendant que le programme fait autre chose

La LED

ledBlue = Pin(2, Pin.OUT)

La LED est branchée sur la broche 2
C’est une sortie (ON / OFF)

Allumer / éteindre une LED avec un bouton poussoir (interruption)

Quand on appuie sur le bouton poussoir :

  • la LED change d’état
    • allumée → éteinte
    • éteinte → allumée

Installe une LED de couleur bleue sur le port GP2 et un bouton poussoir sur GP3 :

Le code complet

from machine import Pin, Timer

# led de la carte
ledBlue = Pin(2, Pin.OUT)
button1 = Pin(3, Pin.IN, Pin.PULL_UP)

ledBlue.off()

button1.irq( 
        #définition de l'interruption sur la broche
        handler = lambda btn1: ledBlue.toggle(),
        # mode de déclenchement IRQ_RISING IRQ_FALLING
        trigger = button1.IRQ_FALLING 
       )

Explication ligne par ligne

Importation

from machine import Pin, Timer

On utilise :

  • Pin → pour la LED et le bouton

La LED bleue sur GP2

ledBlue = Pin(2, Pin.OUT)

La LED est branchée sur la broche 2
C’est une sortie (ON / OFF)

Le bouton poussoir sur GP3

button1 = Pin(3, Pin.IN, Pin.PULL_UP)

Le bouton est :

  • sur la broche 3
  • configuré en entrée
  • avec une résistance pull-up interne

Pull-up, ça veut dire :

  • sans appui → niveau 1
  • bouton appuyé → niveau 0

Éteindre la LED au départ

ledBlue.off()

On commence avec la LED éteinte
État connu = pas de surprise

La partie la plus importante : l’interruption

button1.irq(
handler = lambda btn1: ledBlue.toggle(),
trigger = button1.IRQ_FALLING
)

C’est quoi une interruption ? :

  • le programme fait autre chose
  • Ding ! → bouton appuyé
  • la Pico réagit tout de suite

IRQ_FALLING

L’interruption se déclenche :

  • quand le signal passe de 1 à 0
  • donc quand on appuie sur le bouton

(parce qu’il est en pull-up)

ledBlue.toggle()

toggle() le LED inverse son état :

  • ON → OFF
  • OFF → ON

Pourquoi lambda btn1: ?

C’est une petite fonction rapide :

lambda btn1: ledBlue.toggle()

  • Elle est appelée automatiquement
  • btn1 représente le bouton (obligatoire)
  • On n’en a pas besoin ici, mais MicroPython l’exige

Pourquoi utiliser une interruption ? (le gros avantage)

Sans interruption

while True:
    if button1.value() == 0:
        ledBlue.toggle()
        sleep(0.3)

Le programme regarde le bouton tout le temps
Risque de rater un appui
Le robot est ralenti

Avec interruption

  • Le bouton est détecté instantanément
  • Le programme reste rapide

C’est quoi lambda en Python ?

lambda permet de créer une toute petite fonction,

  • en une seule ligne,
  • sans lui donner de nom.

Une fonction jetable, rapide à écrire.

Une fonction normale (classique)

def addition(a, b):
    return a + b

Cette fonction :

  • a un nom (addition)
  • fait une action
  • renvoie un résultat

La même chose avec lambda

addition = lambda a, b: a + b

C’est exactement pareil, mais :

  • en une seule ligne
  • plus court
  • sans def

Comment lire une lambda

lambda a, b: a + b

Ça se lit comme :

« Une fonction qui prend a et b et qui retourne a + b »

Tout ce qui est après : est le résultat

Catégories
MICRO PYTHON RASPBERRY PICO W

L’écran OLED SSD1306

CARTE DE DEVELOPPEMENT RASPBERRY PICO W

C’est quoi un écran OLED SSD1306 ?

Un écran OLED SSD1306 est un petit écran que l’on branche à un microcontrôleur (comme une Raspberry Pi Pico) pour afficher du texte ou des dessins sur un port I2C.

OLED, ça veut dire quoi ?

  • Chaque pixel s’allume tout seul
  • Pas besoin de rétroéclairage
  • Noir = pixel éteint → économie d’énergie

Taille courante :

  • 128 × 64 pixels
  • 128 × 32 pixels

Comment la Pico communique avec l’écran ?

La Pico communique avec l’écran grâce au bus I²C.

C’est comme une conversation :

  • La Pico = celui qui parle
  • L’écran = celui qui écoute

Les 2 fils importants du bus i2c

FilRôle
SDADonnées envoyées à l’écran
SCLCadence (rythme de communication)

L’écran a une adresse (souvent 0x3C) pour qu’on sache à qui on parle.

À quoi sert la bibliothèque micropython-ssd1306 ?

La bibliothèque sert à :

  • permettre d’écrire simplement :
    • du texte
    • des pixels
    • des formes

https://github.com/stlehmann/micropython-ssd1306

Comment fonctionne l’affichage ? (idée clé)

L’écran ne s’actualise pas tout seul.

  1. La Pico dessine dans une image invisible (le buffer)
  2. Quand tout est prêt, on dit :
oled.show()

Et l’image apparaît à l’écran

Comme dessiner sur une feuille, puis l’afficher d’un coup

Exemple simple de programme

# Création du bus I2C
i2c = I2C(0)

# Création de l'écran
oled = SSD1306_I2C(128, 64, i2c)

# Effacer l'écran
oled.fill(0)

# Écrire du texte
oled.text("Bonjour !", 0, 0)
oled.text("Initialisation", 0, 10)

# Afficher à l'écran
oled.show()

Les commandes principales (les plus utiles)

Écrire du texte

oled.text("Texte", x, y)
  • x → position horizontale
  • y → position verticale

🧹 Effacer l’écran

oled.fill(0)

Allumer tous les pixels

oled.fill(1)

Allumer un pixel

oled.pixel(x, y, 1)

Dessiner une ligne

oled.line(x1, y1, x2, y2, 1)

0 ou 1 pour éteindre ou allumer la ligne

Exemple amusant (point qui bouge)

for x in range(128):
    oled.fill(0)
    oled.pixel(x, 30, 1)
    oled.show()

Le point se déplace à l’écran

Catégories
MICRO PYTHON RASPBERRY PICO W

MICRO PYTHON RASPBERRY

CARTE DE DEVELOPPEMENT RASPBERRY PICO W

La carte dispose :

  • et 2Mo de Flash programme, ce qui veut dire un espace de stockage à minima intégré.
  • d’un microcontrôleur ARM M0 double coeur cadencé à 130 MHz,
  • de plus de 200 Ko de RAM

La carte propose l’écosystème C/C++ mais également celui du Micropython.

Pi Pico bénéficie des avantages de micro-python et on peut citer notamment :

  • le mode interpréteur qui permet d’interagir avec la carte « à la volée » ce qui est très pratique pour apprendre, faire des essais, etc.
  • une programmation « puissante », synthétique et facile à apprendre à la fois,
  • la programmation par fichiers (et non plus code compilé) ce qui rend la maintenance d’un projet très facile : sur la carte on dispose du code !

Sur une carte à microcontrôleur, on dispose :

  • Processeur ARM Cortex M0 à double cœur
  • Horloge 133 Mhz.
  • 2 Mo de mémoire Flash.
  • 264 ko de RAM.
  • 2 interfaces UART.
  • 2 interfaces SPI.
  • 2 contrôleurs I2C.
  • 16 canaux PWM.
  • 3 ADC 12 bits.
  • Un module Wifi.
https://www.youtube.com/watch?v=o-tRJPCv0GA&t=29s

Le pico pi est vendu « vide », autrement dit, il ne dispose pas du Micropython et il faut le programmer sur la carte avant toute chose.

Vous pouvez voir Micropython comme une sorte de firmware, un micrologiciel, que l’on flashe dans la carte et qui va ajouter l’interpréteur Python à la carte

Documentation Raspberry PI

https://micropython.org/download

Puis rechercher :

Download Firmware :

https://micropython.org/download/RPI_PICO2_W

Appuyez sur le bouton BOOTSEL de votre pico et maintenez le enfoncé.

Connectez votre Pico au port USB de votre PC tout en maintenant le bouton enfoncé.

Attendez quelques secondes et relâchez le bouton BOOTSEL.

Le Pico doit apparaître comme un lecteur amovible baptisé RP2350 :

Copier le fichier sur le Pico. Lorsque la copie du Firmware, le pico se relance.

Lancer l’IDE Thonny :

Cliquer sur «Options » dans le menu « Outils».

Choisir l’interpréteur « MicroPython (Raspberry Pi Pico) »

et indiquer le port COM utilisé par la carte Raspberry PICO puis
cliquer sur « OK ».

Ma présence du MicroPython du Pico apparaît dans la console.

Saisir ce code dans la console pour allumer la LED du Pico :

>>> from machine import Pin
>>> led=Pin("LED",Pin.OUT)
>>> led.on()
>>> 

Saisie ce programme et demande son exécution sur la Pico :

from machine import Pin 
import time 
pin_led = Pin('LED', mode = Pin.OUT) # La broche de la LED built-in est placée en sortie 
while True: 
    pin_led.value(True) 
    time.sleep(1) 
    pin_led.value(False) 
    time.sleep(1) 

Si sous Thonny, vous rencontrez ce problème :
Unable to connect to COM24: port not found

Vérifier la configuration de Thonny :

  • Outils → Options
  • Onglet Interpréteur

Vérifie :

  • Interpréteur : MicroPython (Raspberry Pi Pico)

Port :

  • soit Automatique