taches-cooperatives.py
Three periodic tasks (LED 2 Hz, beep 1 Hz, reading every 5 s) run on a 15-line cooperative mini scheduler. This pattern replaces nested delay() calls as soon as a project animates more than one pin.
Hardware
A Raspberry Pi Pico W (RP2040 + 2.4 GHz Wi-Fi radio chip) with MicroPython installed, powered over USB. 1 LED + 330 Ω on GP15, 1 passive buzzer on GP2 (optional, drop the task otherwise).
Wiring
LED on GP15 through 330 Ω to GND; buzzer between GP2 and GND. Adapt pins to your free ones.
How it works
Each task stores its deadline; the loop compares with time.ticks_diff (robust to 32-bit wraparound) and reschedules the next deadline. sleep_ms(1) avoids full CPU occupancy.
Running it
Install the « Pico W » MicroPython build (BOOTSEL + .uf2), copy the script via Thonny. Since the user LED sits behind the radio chip, output examples use an external LED.
Variants
Add tasks on the fly with creer(), or move to uasyncio (MicroPython asyncio) for event-driven tasks with non-blocking waits.
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