Repeatable, periodic glitch in timer

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
ryanGT
Posts: 24
Joined: Fri Jan 28, 2022 12:15 am

Repeatable, periodic glitch in timer

Post by ryanGT » Thu Mar 03, 2022 7:45 pm

I am trying to use a pyboard to generate a squarewave that is used as a pin interrupt by an Arduino. I have a timer on the pyboard setup with a 500 Hz frequency and in a for loop I check to see if the timer callback function has set a flag variable. The problem I am having is that there is a very repeatable glitch every roughly 196 loop cycles (196/500 Hz = 0.39 seconds). I asked the Arduino to tell me how much time as elapsed since the last pin interrupt and I generated this graph (hopefully inline below):
dt_micros.png
dt_micros.png (119.17 KiB) Viewed 2271 times
So, if the squarewave were perfect, it would always be exactly 2000 microseconds between edges, but every 0.39 seconds it goes up to 2600 or so and then makes up the time on the next cycle. The weird thing is that I overlaid 5-10 test runs and they overlay almost perfectly. I don't know if the timer has to reset something, but 0.6 milliseconds is a lot of clock cycles.

Here is my timer code:

def tick(timer):
global isr_happened, nISR
isr_happened = 1
nISR += 1

tim = Timer(1, freq=1000)
tim.counter() # get counter value
tim.freq(500) # 0.5 Hz
tim.callback(tick)

And here is the top of the loop that waits for the flag and generates the squarewave:

for i in range(N):
#pin_A15.on()
while (isr_happened == 0):
# wait for next interrupt
time.sleep_us(100)
#pin_A15.off()

# square wave that toggles each time step
if isr_state == 1:
isr_state = 0
pin_B4.off()
else:
isr_state = 1
pin_B4.on()


Any thoughts on what could cause such a repeatable 0.6ms glitch every 0.4 seconds?

Thanks,
Ryan

OutoftheBOTS_
Posts: 847
Joined: Mon Nov 20, 2017 10:18 am

Re: Repeatable, periodic glitch in timer

Post by OutoftheBOTS_ » Thu Mar 03, 2022 7:54 pm

First why don't you use the hardware timer to toggle the pin? Why are you toggling the pin with software??

Python is a not real time system. It has an interrupter and that interrupter can be doing thing in the back ground like garbage collection. Don't confuse python software call backs and C hardware interrupts.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Repeatable, periodic glitch in timer

Post by dhylands » Thu Mar 03, 2022 8:11 pm

So the loops will gradually get out of phase with the timer, and you'll eventually wind up slipping by around 100 usec (the duration of your sleep). You'd need to time how long your loop actually takes to see if that contributes more.

You'll get much less jitter if you toggle B4 from inside the timer IRQ (i.e. tick routine).

ryanGT
Posts: 24
Joined: Fri Jan 28, 2022 12:15 am

Re: Repeatable, periodic glitch in timer

Post by ryanGT » Thu Mar 03, 2022 9:48 pm

Thanks for the quick responses.

I did the thing where I tried to post the minimum needed to recreate my problem, but by not giving more context the problem could not be fully understood. My bad.

I am trying to create a real-time feedback control system using a pyboard and an Arduino together. I have done this in the past with a raspberry pi and two arduinos, but it is messy and a bit unreliable because Python on a raspberry pi is not at all real-time. I had to put in a lot of effort to make one of the Arduinos act like a precise timer for Python on the rasbperry pi. It works most of the time, but glitches out for about 10ms roughly once every 0.5 to 1 seconds.

In my system, higher level logic and calculations are done in Python and the Arduino takes care of low-level grunt work (sending voltages to an H-bridge, reading encoder interrupts, ...). So, I need the pyboard and the Arduino to both do a few small things every 2ms and I need them to communicate over i2c every 2ms. A hardware generated squarewave won't completely meet my needs, because I need the pyboard to do somethings in Python when the timer event happens. So, I need a software trigger every 2ms.

By moving the pin toggle code into the callback ISR, I can make the squarewave much more reliable, but if the pyboard still glitches in the software, my problem remains. In this case, the Arduino receives its pin trigger signal at the correct time every time, but the data it needs does not arrive over i2c during the glitches.

So, I would love to get rid of the software glitches if possible. Are we saying that a 0.6ms glitch every 0.4 seconds is just kind of expected from the python interpreter or something on the pyboard? I guess I don't understand the details of how micropython executes python code while acting like a microcontroller (I am going from raspberry pi or python on a laptop).

Thanks,
Ryan

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Repeatable, periodic glitch in timer

Post by dhylands » Fri Mar 04, 2022 6:20 pm

Probably the thing to do then would be to have your timer callback use micropython.schedule to schedule a function to run. Things scheduled by micropython.schedule will run "between" VM instructions. This will give you minimal jitter while still being able to call i2c functions.

Post Reply