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