Note: I am using MicroPython v1.19.1 where rp2 memory corruption bug in thread was fixed.
I came across these two links which seem to be about the same issue, with no solution:
Timer callback stops with uart thread
Problem with machine.Timer() and _thread on Raspberry Pi Pico (RP2040)
I wrote a simple example that demonstrates the problem and is easy to reproduce with any Pico board.
In the example, the Pico LED is toggled in a thread and a timer runs with a callback that prints an incrementing counter.
Code: Select all
import time
import _thread
from machine import Pin, Timer
led = Pin(25, Pin.OUT)
counter = 0
def blink_func():
led.toggle()
def print_func():
global counter
print(f"counter = {counter}")
counter += 1
def thread_loop(freq, func):
delay = 1/freq
while True:
func()
time.sleep(delay)
def start_timer(freq, func):
tim = Timer()
tim.init(freq=freq, mode=Timer.PERIODIC, callback=lambda t:func())
def start_thread(freq, func):
_thread.start_new_thread(thread_loop, (freq, func))
start_timer(3000, print_func)
start_thread(50, blink_func)
# This avoids an error from Thonny that probably has to do with the REPL and the printing
try:
while True:
pass
finally:
pass
In my project, I am trying to do the following things simultaneously:
- Play a wave file from an SD card using I2S (the builtin MicroPython I2S)
- Light an RGB LED strip (8 WS2812B LEDS) with a sequence of RGB values using a Timer. The LEDS are controlled using the PIO.
The first thing I found out was that the LED must use a state machine with ID 1-7. If I used ID 0, the I2S would stop the LEDS immediately, probably some config is overwritten by the I2S object.
Still, the code did not work correctly. The LEDS would randomly stop after a few seconds. I tried to narrow down the problem. I found that if I use the I2S on the main thread (no second thread) or use a loop for controlling the LEDS instead of a timer, there were no problems. I also found that the higher the frequency of the timer, the faster it would get stuck.
I assume there is some problem using the timer and a thread simultaneously.