utime/pyb delay error

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

utime/pyb delay error

Post by nikhiledutech » Sat Jan 20, 2018 10:30 am

Hello,

I tried to test utime and pyb.udelay by observing But i found that delay is not generated as per the value given.

Below is my testing program for generating delay of 1,10,100 us using pyb.udelay funaction and utime module.
import pyb
from pyb import Pin
import utime as time

x = pyb.Pin('PD5',Pin.OUT)
y= pyb.Pin('PD6',Pin.OUT)

while True:
x.value(1)
pyb.udelay(1)
x.value(0)
pyb.udelay(1)

while True:
y.value(1)
time.sleep_us(1)
y.value(0)
time.sleep_us(1)
Results for the above program:
pyb
1us = 30us
10 us = 40us
100us = 130us

utime
1us = 27us
10 us = 36us
100us = 127us


So i wanted to know, why my 1us delay is giving me 27-30us delay. Is it because of the transition from high to low ? Or few microseconds for execution of instructions gets added into the O/P delay. Is their any other way to generate more precise us delays. If yes, kindly guide me through it.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: utime/pyb delay error

Post by Roberthh » Sat Jan 20, 2018 11:10 am

Executing the python statements takers the time. And I'm surprised that it takes that long. I recall something like <0.5 µs per simple statement and 2-4 µs net for a function call (just doing the call). You can speed up the example using direct calls and native/viper:

Code: Select all

from pyb import Pin, udelay
from utime import sleep_us

x = Pin('Y5',Pin.OUT)
y= Pin('Y6',Pin.OUT)

@micropython.native
def run():
    while True:
        x(1)
        sleep_us(1)
        x(0)
        sleep_us(1)

run()
Beyond that, you can in viper code directly access the GPIO port registers. The example above would the read as:

Code: Select all

from pyb import Pin, udelay
from utime import sleep_us
import stm

x = Pin('Y5',Pin.OUT)
y= Pin('Y6',Pin.OUT)

@micropython.viper
def run():
    gpiob = ptr16(stm.GPIOB + stm.GPIO_BSRR)
    y5bit = 1 << 12  # Y5 is Bit 12 of Port B
    while True:
        gpiob[1] = y5bit
        sleep_us(1)
        gpiob[0] = y5bit
        sleep_us(1)

run()
That results in a period time of ~8 µs. If you comment out the sleep statements, you'll get loop time of 60 ns, so a single sleep_us(1) call takes ~4 µs, which matches my previous experience about the net time for a function call.

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

Re: utime/pyb delay error

Post by pythoncoder » Sat Jan 20, 2018 6:09 pm

Or you can get really radical and use the inline assembler...
Peter Hinch
Index to my micropython libraries.

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: utime/pyb delay error

Post by nikhiledutech » Mon Jan 22, 2018 6:08 am

Okay thanks....
So now i get the following values using viper and native.

UTIME Module
Normal Native(us) Viper(us)
0 = 26 6
1us = 27 13 4
10us = 36 21-22 13

So viper give me more appropriate value (i.e 1us = 4us) compared to normal utime module giving 27us as delay.
But i found that the signals generated on CRO are of 2.10V instead of 3.3V. Why is it so ?

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: utime/pyb delay error

Post by Roberthh » Mon Jan 22, 2018 6:47 am

So you see that you have a constant offset in timing, with viper about 3 µs. There are many reasons why you notice a lower voltage at the output. Of the many, a few:
a) wrong setting of the instrument you use for measurement, or mis-interpretation of the displayed value.
b) mismatch between output impedance and load.
Without more details, it's hard to guess the reason.

Post Reply