JWF wrote: ↑Wed Jun 16, 2021 8:22 pm
even without the SPI in the below even more minimal case, the issue seems to persist.
That could be a result of garbage collection. If garbage collection is happening within the callback or when called, the callback time will be extended and callbacks may be dropped or deferred - I admit I don't know what is meant to happen.
That seems to be the case with my test code which doesn't need any hardware connections or links; the 'inp' monitors the same 'pwm' pin ...
Code: Select all
from machine import Pin, PWM
import gc
import time
count = 0
def Irq(arg):
global count
count += 1
inp = Pin(16, Pin.IN)
inp.irq(trigger=Pin.IRQ_FALLING, handler=Irq)
pwm = PWM(Pin(16, Pin.OUT))
pwm.freq(4000)
pwm.duty_u16(0x8000)
while True:
# gc.disable()
count = 0
time.sleep_ms(100)
counted = count
# gc.enable()
print(counted)
That consistently reports 400 or 401 as expected.
Now change "def Irq(arg):" to "def Irq(*_):" which reflects how you are doing things.
That also reports 400 as expected, but occasionally drops lower, also goes higher -
Something is preventing the callback from being called, preventing count being incremented.
With my original code "def Irq(arg):" and uncommenting the two 'gc.disable()' and 'gc.enable() calls and everything is fine, same as before, 400 or 401.
But with "def Irq(*_):' we soon hit "MemoryError" which suggests to me that more garbage collection is going on in that case because disabling that causes a major problem.
I am not entirely convinced it is just the use of "*_" which is the problem. Given the issues with pin callbacks, timer callbacks, threading, I suspect there are some systemic issues playing their part.
And just for a laugh - Back to my original code; replace "time.sleep_ms(100)" with the functional equivalent of "time.sleep_us(100_000)" and, as described elsewhere, count is always zero.
BTW : None of this explains the PWM case.