Timer callback stops with uart thread

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
Post Reply
ChriPy
Posts: 2
Joined: Sun Mar 27, 2022 3:44 pm

Timer callback stops with uart thread

Post by ChriPy » Tue Mar 29, 2022 4:44 pm

I am reasonably familiar with microcontrollers having worked since the 8051 came out in the 80's.
However python is a new acquaintance, as is the RPi Pico.
My little home automation project came to a halt when the timer isr (callback) stopped for some reason.
a) when running the code and not enabling the serialport read thread, the timer ticks for days.
b) however, when the serialport thread is enabled (started), it takes minutes and the timer (callback) freezes.
(the serial thread still functioning).

Anyone have any idea or knowledge of any anomalities with the timer and/or serialport?
My simplified code for testing:

Code: Select all

""" timertest2.py
    Testing if timer hangs every now and then when using timer callback (timer isr)
    220325, ChB, works fine with timer only
    220327, ChB, added serial read as a thread: hangs after 5 - 10 minutes
                    (even if no data on Rx; timer stops, but serial still works; 
                     ctrl-C/D/B not responding)
"""

from machine import Pin, Timer, UART
import _thread

led = Pin(25, Pin.OUT)  #RPi Pico onboard LED

#global variables
baT = bytearray(1)  #timer counter
baM = bytearray(1)  #main counter
baC = bytearray(1)  #copy of T in main
Rxtmoc = 0

baT[0] = baM[0] = baC[0] = 0

acount = bcount = 0
sRx = ''    #response to R-command
#-------------------------------

#timer callback routine (isr)
#just increases a global byte variable; 0-255-0...
def tick(timer):
    global baT
    baT[0] += 1
    pass
#-------------------------------

#thread for receiving serial data
def U0Rx():
    global Rxtmoc
    global u0   #necessary? Sometimes yes, sometimes no! 
    u0.write('timertest2.py\r\n')
    #read loop
    while (1):
        rxc = u0.read(1)    #return None if timeout; ie. returns once every second
        if (rxc == None):   #timeout - just count 'em
            Rxtmoc += 1
            pass
        else:
            u0.write(rxc)   #echo character
            if (ord(rxc) == 0x52):
            #if (rxc == 'R'):
                sRx = '\r\nbaT {bt} baC {bc} rxtmo {rc}\r\n'.format(bt=baT[0], bc=baC[0], rc=Rxtmoc)
                u0.write(sRx)
                sRx = 'acount {ac} bcount {bc}\r\n'.format(ac=acount, bc=bcount)
                u0.write(sRx)
        pass    #not needed
#-------------------------------

#Start of main program
print('Main start')     #only while testing

led.on()    #let there be light

#start timer    
print('Timer start')    #only while testing
tim = Timer()
tim.init(freq=1, mode=Timer.PERIODIC, callback=tick)

#serial port setup
print('Serialport setup')   #only while testing
u0 = UART(0, 9600, timeout=1000)    #read timeout 1 sec.; speed 9600, 8N1

print('Serial thread start')    #only while testing
_thread.start_new_thread(U0Rx, ())  #name of thread, () no parameters
#-------------------------------

#also globals
tnow = tmax = 0
tmin = 1000000

#main loop forever
while (True):
    #event #1: timer
    baC[0] = baT[0]   #a snapshot of the timer counter
    if (baM[0] != baC[0]):
        led.toggle()
        baM[0] = baC[0]   #current timecounter
        if (tnow > tmax):
            print('Idlemax:', tnow)
            tmax = tnow
        if (tnow < tmin):
            print('Idlemin:', tnow)
            tmin = tnow
        tnow = 0
        acount += 1     #count seconds
        if (acount > 9):
            acount = 0
            bcount += 10
            s = 'seconds {sb} (baC {bc}) (rxtmo {rc})\r\n'.format(sb=bcount, bc=baC[0], rc=Rxtmoc)
            u0.write(s)
    else:
        tnow += 1     #count loops waiting for timer
        pass
    #end of event #1
    #event #2
    pass    #to be completed
    #end of event #2
All suggestions highly appreciated!

Post Reply