HC-SR04 and FreeBSD

Evandro Nunes evandronunes12 at gmail.com
Sun Aug 24 22:29:29 UTC 2014


On Sat, Aug 23, 2014 at 5:51 PM, Patrick Tracanelli <
eksffa at freebsdbrasil.com.br> wrote:

> On 08/22/14 16:55, Luiz Otavio O Souza wrote:
> > On 22 August 2014 00:43, Evandro Nunes wrote:
> >> On Thu, Aug 21, 2014 at 4:13 PM, Rui Paulo wrote:
> >>
> >>> You can use an led instead of a multimeter. The point I'm trying to
> make
> >>> is to make sure the gpio number really corresponds to that port number.
> >>>
> >>
> >> still no success, but just an update...
> >>
> >> ok I added two led:
> >>
> >> pin 02:    0    gpio_2<IN>  ===> echo (orange LED)
> >> pin 03:    0    gpio_3<OUT> ===> trigger (blue LED)
> >> pin 49:    0    gpio_49<IN> ===> previous echo
> >>
> >> and I have the two simple loops below.
> >>
> >> when I run loop1, BLUE LED blinks every second;
> >> when I run loop2 while loop1 stills run, ORANGE LED won't blink, and
> loop2
> >> value still shows 0 value
> >>
> >> if I "gpioctl -c 2 OUT ; gpioctl -t 2", ORANGE LED will light,
> confirming
> >> LED is OK; thoses leds will light with 2-5v input... however I have no
> idea
> >> if the sonar output will range 2-5 or if it will be below 2 (i tried
> adding
> >> my hand very close and far away from the sensor but led was never lit)
>
> Hello,
>
> As far as I know, for this specific ultrasonic sensor, you are missing
> to set the echo GPIO pin to high. This sonar sensor will bring it back
> to 0 when the triggered sound get back to the sensor (round-trip).
>
> So the correct sequence should be, in a loop:
>
> 1 - Set echo pin to HIGH
> 2 - Trigger the sensor for 10us (it means your 100ms is more than you
> need, but no, it won’t cause a problem)
> 3 - Wait until echo in is LOW
>
> When the sound come back to sensor, the device will LOW the GPIO pin again.
>
> So what you have to do is to measure how long it took from step 1 to 3.
> This is your duration. And it means a sound-speed duration from 0 (your
> transmitter) until the object and back. We are talking about a 58.22
> sound speed.
>
> Therefore, what you want is to determine the duration of a pulse with
> microsecond accuracy, to measure the duration of HIGH or LOW pulse on a
> pin.
>
> How to do this? I don’t know how you can get this with in the command
> line. First of, date(1) won’t display the time with enough precision. I
> believe date “+%s” is the best precision you have and it’s epoch (1 full
> second, not a fraction).
>
> You can use some code, however, to get a usec precision “now”. Example
> code below I have used in the past will do the trick.
>
> But how will you “wait” from 1 to 0 on your GPIO echo pin, on a shell
> script, without using almost all CPU you’ve got in your BeagleBone (and
> this is not much CPU), I have no idea.
>
> I would test some loop similar to this:
>
> #/bin/sh
> gpioctl -c 2 IN
> gpioctl -c 3 OUT
> gpioctl 3 0
> gpioctl 2 0
>
> while true ; do
>  gpioctl 3 1 ; sleep .10; gpioctl 3 0 # trigger
>  gpioctl 2 1 # set echo HIGH
>
>  inicio=$(/root/date-precisao) # what time is it?
>
>    while [ $(gpioctl 2 | tail -1) -gt 0 ] ; do
>     echo "...” #does nothing, because the pin is still HIGH
>    done
>
>   fim=$(/root/date-precisao) # pin is now LOW, what time is it?
>   dura=$(( $fim - $inicio )) # echo duration (HIGH to LOW usec duration)
>   dura2=$(( $dura * 10 )) # sh doesn’t like X.Y precision, make it integer
>   dist=$(( $dura2 / 582 )) # 58.22 should be the number but 58.2 is OK
>   echo "Distance: $dist” # this is your not much precise distance
>  sleep 1
> done
>
> The above code is untested, I just wrote it on this e-mail. Your CPU
> will be insanely high because this is not something that should be done
> on shell script, and therefore, your distance precision won’t be
> reliable. However, you will have a relative reference.
>
> Meaning, add an object 10cm from the sensor and you will have a number.
> Add an object 100cm from the and you will have another number, hopefully
> a 10 times higher number — maybe 9, maybe 12, expect imprecision caused
> by high CPU usage and a big latency on shell commands getting executed
> to do a math that should be done somehow else.
>
> Good luck with your experiments.
>
> FreeBSD/arm with a BeagleBone is a HELL of a FUN ]:-)
>
> /*
>  * Dummy code to print date with usec precision
>  * Patrick Tracanelli <eksffa at freebsdbrasil.com.br>
>  *
>  * clang date-precisao.c -o date-precisao (should cleanly compile)
>  *
> */
> #include <time.h>
> #include <stdio.h>
> #include <sys/time.h>
> int main(void)
> {
>   struct timeval agora;
>   struct tm *t;
>   char time[9];
>   int ret;
>
>   ret = gettimeofday(&agora, 0);
>   t = localtime(&agora.tv_sec);
>   ret = strftime(time, sizeof(time), "%H%M%S", t);
>   // xunxo 999 pq as vezes em armv6 fica zerado...
>   printf("999%s%06ld\n", time, agora.tv_usec);
>   return 0;
> }
>
>
hey patrick
yea somehow it made some sense now
first test was your afirmation that sensor will set pin value to zero, it
really does as soon as I set to 1, sensor will set it to 0 again
i really expected to get a value on echo pin other than 0 or 1 :(
i run your shell script and while cpu was high, it was not exausting the
board, about 20% cpu comsuption running this loop
when i add an object say 5cm from the sensor I get values that mean
nothing, around 2201, 2300
when i add the object at 10cm i get values around 48000-49000
when i add the object at 1 meter i get values around 200000-230000
so yes the values mean nothing but they make some relative sense, with a
lot of imprecision for sure, sometimes deviation is upper some times lower
so it means we need a library in freebsd for electronics, so we can have
functions like arduino's pulseIn which seem to do just that, wait for a pin
status and return how long it took until that value was received, the kind
of libs we see out there in nodejs, python...
now that you made clear how the sensor works, i will try to write something
to do that more precisely instead of using a shell script
thank you all


More information about the freebsd-arm mailing list