## Pulse width in microseconds (like pulseIn in Arduino)

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
SkG
Posts: 18
Joined: Mon Mar 10, 2014 2:57 pm

### Pulse width in microseconds (like pulseIn in Arduino)

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):

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?

fma
Posts: 163
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

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

Have a look at the last section of this tutorial:

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

Hope this helps.
Frédéric

fma
Posts: 163
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

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

You may in addition use external interrupts:

http://micropython.org/doc/module/pyb/ExtInt
Frédéric

SkG
Posts: 18
Joined: Mon Mar 10, 2014 2:57 pm

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

Awww! Thanks, I didn't though about Timer for implementing the microseconds counter! (I was right I was missing something ).

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.

fma
Posts: 163
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

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

Feel free to post your results; I know someone using this sensor with a RPi, and he could be interesting by the micropython solution
Frédéric

SkG
Posts: 18
Joined: Mon Mar 10, 2014 2:57 pm

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

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

SkG
Posts: 18
Joined: Mon Mar 10, 2014 2:57 pm

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

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)

rankor
Posts: 38
Joined: Sun Nov 30, 2014 12:38 am

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

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)?

pythoncoder
Posts: 4793
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

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

@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)
Peter Hinch

manitou
Posts: 69
Joined: Wed Feb 25, 2015 12:15 am

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

dhylands has an example of measuring pulse width using timer callback, see

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