Page 1 of 1

utime/pyb delay error

Posted: Sat Jan 20, 2018 10:30 am
by nikhiledutech
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.

Re: utime/pyb delay error

Posted: Sat Jan 20, 2018 11:10 am
by Roberthh
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.

Re: utime/pyb delay error

Posted: Sat Jan 20, 2018 6:09 pm
by pythoncoder
Or you can get really radical and use the inline assembler...

Re: utime/pyb delay error

Posted: Mon Jan 22, 2018 6:08 am
by nikhiledutech
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 ?

Re: utime/pyb delay error

Posted: Mon Jan 22, 2018 6:47 am
by Roberthh
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.