Page 1 of 1

Pulse width in microseconds (like pulseIn in Arduino)

Posted: Wed May 14, 2014 9:36 am
by SkG
Hi all,

I'm making a library for SRF04/HC-SR04 I'm missing something (maybe it's there but somehow I can't find it).

This ultrasonic sensor that works as follows (most works like this, indeed):
Image

In Arduino you typically do:

Code: Select all

digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
duration = pulseIn(echoPin, HIGH);
cm = duration/29/2 /* For inches: /74/2 */
pulseIn returns the length of the pulse in microseconds so my approach was:

Code: Select all

trigger = pyb.Pin(pyb.Pin.board.X3)
trigger.init(Pin.OUT_PP, pull=Pin.PULL_NONE)
trigger.low()

echo = pyb.Pin(pyb.Pin.board.X4)
trigger.init(Pin.IN, pull=Pin.PULL_NONE)

pyb.udelay(10) # Just a little wait.

trigger.high()
pyb.udelay(10) # Mantain pulse for 10 useconds.
trigger.low()

# And then the part that is wrong wrong wrong! I'm meauring milliseconds...
while not echo.value():
    continue

start = pyb.millis()
while echo.value():
    continue
end = pyb.millis()

cm = (start-end) / 29 / 2
Well this works when the pulse is 1 or more ms so I can't measure smaller pulses.

I'm probably missing something...

Any hint?

Re: Pulse width in microseconds (like pulseIn in Arduino)

Posted: Wed May 14, 2014 10:39 am
by fma
Have a look at the last section of this tutorial:

http://micropython.org/doc/tut-timer

Hope this helps.

Re: Pulse width in microseconds (like pulseIn in Arduino)

Posted: Wed May 14, 2014 10:42 am
by fma
You may in addition use external interrupts:

http://micropython.org/doc/module/pyb/ExtInt

Re: Pulse width in microseconds (like pulseIn in Arduino)

Posted: Wed May 14, 2014 1:38 pm
by SkG
Awww! Thanks, I didn't though about Timer for implementing the microseconds counter! (I was right I was missing something :oops:).

About the ExtInt I've already thought about it but I wanted to get a simple test working first. It's sure more accurate that method than the while: contine.

Re: Pulse width in microseconds (like pulseIn in Arduino)

Posted: Wed May 14, 2014 2:13 pm
by fma
Feel free to post your results; I know someone using this sensor with a RPi, and he could be interesting by the micropython solution ;)

Re: Pulse width in microseconds (like pulseIn in Arduino)

Posted: Wed May 14, 2014 2:32 pm
by SkG
I use it too in the RPi :)

Sure this code sounds you like the first I posted:

Code: Select all

import time
import RPi.GPIO as GPIO

SRF04_TRIGGER = 14
SRF04_ECHO = 15
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

def getDist():
    GPIO.setup(SRF04_TRIGGER, GPIO.OUT)
    GPIO.setup(SRF04_ECHO, GPIO.IN)

    GPIO.output(SRF04_TRIGGER, False)
    time.sleep(0.5)

    GPIO.output(SRF04_TRIGGER, True)
    time.sleep(0.00001)
    GPIO.output(SRF04_TRIGGER, False)

    while not GPIO.input(SRF04_ECHO):
            continue
    start = time.time()

    while GPIO.input(SRF04_ECHO):
            continue
    end = time.time()
[...]
Anyway I'm planning to open a github repo in my account for this kind of things ;)

Re: Pulse width in microseconds (like pulseIn in Arduino)

Posted: Wed May 14, 2014 10:29 pm
by SkG
Well, seems my sensor is dead :(

It has been stored a years or so in a not proper place and broke. Is not working with nor Arduino neither RPi so I can't test the code until I get a new one :(

Code: Select all

import pyb

triggerPin = pyb.Pin.board.X3
echoPin = pyb.Pin.board.X4

trigger = pyb.Pin(triggerPin)
trigger.init(pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE)
trigger.low()

echo = pyb.Pin(echoPin)
echo.init(pyb.Pin.IN, pyb.Pin.PULL_NONE)

micros = pyb.Timer(2, prescaler=83, period=0x3fffffff)

start = 0
end = 0

while True:
    micros.counter(0)
    pyb.udelay(10)
    trigger.high()
    pyb.udelay(10)
    trigger.low()

    while not echo.value():
        start = micros.counter()
    while echo.value():
        end = micros.counter()

    print("cm: ", end-start / 29 / 2) # /!\ have to check if this calc is ok.
    pyb.delay(1000)

Re: Pulse width in microseconds (like pulseIn in Arduino)

Posted: Fri Jun 26, 2015 8:34 pm
by rankor
Why are you not taking the 8 bursts into account? They come before the input signal on the echo pin to right? So how do you know it is the bursts or the actual measurement if you don't capture the 8 bursts first?
It seems your algorithm would always return the same (and erronous) distance since it would stop after the first of the 8 pulses.

However, I tried your module and it works, I can't see why it does though.


Or is the sonic burst not on the echo/output line? Then where is it (makes no sense)?

Re: Pulse width in microseconds (like pulseIn in Arduino)

Posted: Sat Jun 27, 2015 9:04 am
by pythoncoder
@rankor The sonic burst represents the sound signal emitted by the device and isn't available as an electrical signal. The device produces a pulse whose width is proportional to distance.

@SkG Your solution is fine but could be simplified: the pyb module has micros() and elapsed_micros() functions which enable you to time a pulse without needing to use a timer. Try this:

Code: Select all

    while not echo.value():
    	pass
    start = pyb.micros()
    while echo.value():
    	pass
    width = elapsed_micros(start)

Re: Pulse width in microseconds (like pulseIn in Arduino)

Posted: Tue Jun 30, 2015 10:10 am
by manitou
dhylands has an example of measuring pulse width using timer callback, see

https://github.com/dhylands/upy-example ... ic_test.py