taches-cooperatives.py

Raspberry Pi Pico 2 W · Fichier : taches-cooperatives.py · Langage : Python · Usage : Ordonnanceur de tâches non bloquant pour animer plusieurs broches

Trois tâches périodiques (LED 2 Hz, bip 1 Hz, mesure 5 s) s'exécutent sur un mini-ordonnanceur coopératif de 15 lignes. Le motif remplace les delay() imbriqués dès qu'un projet dépasse une broche animée.

Matériel requis

Une Raspberry Pi Pico 2 W (RP2350 + radio Wi-Fi 2,4 GHz) avec MicroPython installé, alimentée par USB. 1 LED + 330 Ω sur GP15, 1 buzzer passif sur GP2 (optionnel, retirer la tâche sinon).

Câblage

LED sur GP15 via 330 Ω vers GND ; buzzer entre GP2 et GND. Adapter les broches libres selon le projet.

Fonctionnement

Chaque tâche stocke son échéance ; la boucle compare avec time.ticks_diff (robuste au débordement des 32 bits) et reprogramme la prochaine échéance. sleep_ms(1) évite l'occupation CPU totale.

Exécution

Installer le MicroPython « Pico 2 W » (BOOTSEL + .uf2), copier le script via Thonny. Comme sur la Pico W, la LED utilisateur n'est pas sur un GPIO : utiliser une LED externe pour les sorties.

Variantes

Ajouter des tâches à la volée avec creer(), ou passer à uasyncio (asyncio de MicroPython) pour des tâches événementielles avec attente non bloquante.

taches-cooperatives.py

# Ordonnanceur cooperatif : plusieurs taches sans fil ni RTOS.
# Chaque tache est appelee a sa frequence ; aucune ne bloque les autres.
from machine import Pin, ADC
import time

led = Pin(15, Pin.OUT)
buzz = Pin(2, Pin.OUT)
adc = ADC(4)

taches = []

def creer(periodo_ms, fonction):
    taches.append([time.ticks_ms() + periodo_ms, periodo_ms, fonction])

def clignoter():
    led.value(not led.value())

def bip_court():
    buzz.on()
    time.sleep_ms(20)
    buzz.off()

def mesurer():
    v = adc.read_u16() * 3.3 / 65535.0
    t = 27.0 - (v - 0.706) / 0.001721
    print("T = %.1f C" % t)

creer(500, clignoter)     # 2 Hz
creer(1000, bip_court)    # 1 Hz
creer(5000, mesurer)      # toutes les 5 s

print("Ordonnanceur demarre (%d taches)" % len(taches))
while True:
    maintenant = time.ticks_ms()
    for tache in taches:
        if time.ticks_diff(maintenant, tache[0]) >= 0:
            tache[0] = time.ticks_add(tache[0], tache[1])
            tache[2]()
    time.sleep_ms(1)   # cede la main : evite la pleine charge CPU

← Retour à la fiche