Question about sleep_us vs sleep_ms in timer

The official PYBD running MicroPython, and its accessories.
Target audience: Users with a PYBD
Post Reply
monquarter
Posts: 14
Joined: Sat Jan 11, 2020 2:31 pm

Question about sleep_us vs sleep_ms in timer

Post by monquarter » Fri Dec 18, 2020 3:06 pm

I have a question regarding the difference in utime.sleep_ms() compared to utime.sleep_us(). I am using a Pyboard D-Series SF6 with Micropython V 1.13. First off, I know that I should not generally be calling utime.sleep inside of a timer callback. I am doing this as a unit test as part of a larger program. With that in mind, when I run this program everything is fine:

Code: Select all

import pyb
import utime
dum1 = utime.ticks_us()
dum2 = 0
def tick_motor(timer):
    global dum1,dum2
    dum2 = utime.ticks_us()
    print(dum2-dum1)
    utime.sleep_us(1000)
    dum1 = dum2

tim1 = pyb.Timer(5)
tim1.init(freq=500)
tim1.callback(tick_motor)
However, when I replace utime.sleep_us(1000) with utime.sleep_ms(1) it hangs. The above program even runs fine when I use utime.sleep_us(1500). The larger question is if I ever need to use sleep, should I avoid utime.sleep_ms

User avatar
pythoncoder
Posts: 4929
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Question about sleep_us vs sleep_ms in timer

Post by pythoncoder » Fri Dec 18, 2020 6:11 pm

I haven't delved into the source, but this strikes me as unsurprising. Calling sleep_ms(n) where n is an integer may well involve a -0 +1 digit uncertainty. Given your interrupt interval of 2ms, a potential 2ms sleep doesn't bode well. Clearly a -0 +1 uncertainty on 1000μs doesn't carry that hazard.

You are right to say that issuing sleeps in ISR's is bad practice.
Peter Hinch

monquarter
Posts: 14
Joined: Sat Jan 11, 2020 2:31 pm

Re: Question about sleep_us vs sleep_ms in timer

Post by monquarter » Fri Dec 18, 2020 8:42 pm

Thanks for the reply. That certainly makes sense. Another oddity I see is when running this code:

Code: Select all

import pyb
import utime
dum1 = utime.ticks_us()
dum2 = 0
dum3 = 0
dum4 = 300
dum5 = 0
a = 0.5
def tick_motor(timer):
    global dum1,dum2,dum3,dum4,dum4
    dum2 = utime.ticks_us()
    print(dum2-dum1)
    while dum3<dum4:
        dum3 = dum3 + 1
    dum3 = 0
    dum5 = utime.ticks_us()
    print('Loop Time: ', utime.ticks_diff(dum5,dum2))
    dum1 = dum2

tim1 = pyb.Timer(5)
tim1.init(freq=500)
tim1.callback(tick_motor)
Some occasions I see this output:

Code: Select all

1999
Loop Time:  1479
2000
Loop Time:  1489
2000
Loop Time:  1479
2000
Loop Time:  1483
2000
Loop Time:  1477
2000
Loop Time:  1479
But if I break and soft reset and run again, I see this output without changing the code:

Code: Select all

1000
Loop Time:  481
1000
Loop Time:  478
1000
Loop Time:  477
1000
Loop Time:  478
1000
Loop Time:  482

Post Reply