Various unexpeced errors, if initialized timer is not referenced by pythoncode
When Timer is initialized, but instance is no longer referenced from python code, it's probably subject for GC.
Unfortunatelly after GC there are unexpected errors, when timer should fire.
Most probably underlaying RTOS or c++ code is still trying to reference memory, which was used by python Timer object, which is now gone.
initial topic: https://forum.micropython.org/viewtopic.php?f=2&t=5898&p=33812#p33812
OSError: [Errno 12] ENOMEM when using RP2040 using multiple timers
to generate a pulse "train (1_0_1_0_1_0) with specific intervals driving a GPIO pin, I was experimenting with 6 one_shot timers. As the use-case is a real_time, multi-event system, I would need 3 of these set-ups. In other words 3 * 6 timers.
The documentation on rp2040 says on the topic of timers: "The software timer is available currently, and there are unlimited number of them (memory permitting)." Great !
Yet, when activating more than 16 timers, the error ENOMEM appears. I have activated the garbage collector and its reports after each instantiation in excess of 200k mem available. So, likely, a different type of memory is referenced in the errormessage.
Leave it to the experts to judge if this (a bit excessive use of timers) should be labeled as bug or that the documentation should reflect that there is a limitation after all.
By the way, starting the script generates the error, refering to the line of the 17th timer to be instantiated and that while the 3 GPIO pins "toggle" in the specified sequence (as asked for).
Using: Rp2040, using MicroPython v1.20.0-93-g05e143dbd on 2023-05-19; Raspberry Pi Pico with RP2040.
from machine import Timer, Pin
import gc
import time
p0 = Pin(13, Pin.OUT, value = 0)
p1 = Pin(14, Pin.OUT, value = 0)
p2 = Pin(15, Pin.OUT, value = 0)
delay = 2000
gc.enable()
gc.collect()
print(gc.mem_free())
tim00 = Timer(period=delay, mode=Timer.ONE_SHOT, callback = lambda t:p0.value(1))
tim01 = Timer(period=delay + 1000, mode=Timer.ONE_SHOT, callback = lambda t:p0.value(0))
tim02 = Timer(period=delay + 1500, mode=Timer.ONE_SHOT, callback = lambda t:p0.value(1))
tim03 = Timer(period=delay + 2500, mode=Timer.ONE_SHOT, callback = lambda t:p0.value(0))
tim04 = Timer(period=delay + 3000, mode=Timer.ONE_SHOT, callback = lambda t:p0.value(1))
tim05 = Timer(period=delay + 4000, mode=Timer.ONE_SHOT, callback = lambda t:p0.value(0))
print(gc.mem_free())
tim10 = Timer(period=delay, mode=Timer.ONE_SHOT, callback = lambda t:p1.value(1))
tim11 = Timer(period=delay + 1000, mode=Timer.ONE_SHOT, callback = lambda t:p1.value(0))
tim12 = Timer(period=delay + 1500, mode=Timer.ONE_SHOT, callback = lambda t:p1.value(1))
tim13 = Timer(period=delay + 2500, mode=Timer.ONE_SHOT, callback = lambda t:p1.value(0))
tim14 = Timer(period=delay + 3000, mode=Timer.ONE_SHOT, callback = lambda t:p1.value(1))
tim15 = Timer(period=delay + 4000, mode=Timer.ONE_SHOT, callback = lambda t:p1.value(0))
print(gc.mem_free())
tim20 = Timer(period=delay, mode=Timer.ONE_SHOT, callback = lambda t:p2.value(1))
tim21 = Timer(period=delay + 1000, mode=Timer.ONE_SHOT, callback = lambda t:p2.value(0))
tim22 = Timer(period=delay + 1500, mode=Timer.ONE_SHOT, callback = lambda t:p2.value(1))
tim23 = Timer(period=delay + 2500, mode=Timer.ONE_SHOT, callback = lambda t:p2.value(0))
tim24 = Timer(period=delay + 3000, mode=Timer.ONE_SHOT, callback = lambda t:p2.value(1))
tim25 = Timer(period=delay + 4000, mode=Timer.ONE_SHOT, callback = lambda t:p2.value(0))
gc.collect()
print(gc.mem_free())