taches-cooperatives.py

RP2040 (carte / puce générique) · 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 carte générique à microcontrôleur RP2040 (double Cortex-M0+) programmée en MicroPython. 1 LED + 330 Ω sur GP25, 1 buzzer passif sur GP2 (optionnel, retirer la tâche sinon).

Câblage

LED sur GP25 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

Flasher MicroPython via BOOTSEL (fichier .uf2), puis copier le script sur le lecteur de la carte. Vérifier la broche de la LED utilisateur de votre carte (souvent GP25) et l'adapter si besoin.

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(25, 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