Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Aug 2014 16:57:39 -0300
From:      Patrick Tracanelli <eksffa@freebsdbrasil.com.br>
To:        Evandro Nunes <evandronunes12@gmail.com>
Cc:        "freebsd-arm@freebsd.org" <freebsd-arm@freebsd.org>, Rui Paulo <rpaulo@felyko.com>
Subject:   Re: HC-SR04 and FreeBSD
Message-ID:  <3949AF9C-B5BD-44E8-A049-21F26B8B6B9A@freebsdbrasil.com.br>
In-Reply-To: <CAG4HiT4RXsUyGfjDDTTJPoeB8bqpY39z6C-_f0S3Zmka0C8gNQ@mail.gmail.com>
References:  <CAG4HiT6wwbmSA_KWsgHOqdeZVOCUsdhRxDhMubvkG1tEwVH5Sw@mail.gmail.com> <5D802942-2D0F-4324-8212-C2871EEB6327@FreeBSD.org> <CAG4HiT6fiqVXMoqcJra1Yh8aFVbOcezP8rRqst6WC8aHuaF_rA@mail.gmail.com> <01562FB1-32C6-45AF-AB77-5BB80526E18C@FreeBSD.org> <CAG4HiT4kKz18iauXfuF0Dpv-USghunssUvwkTF7bDx_gE_VS2w@mail.gmail.com> <CCD5AEE5-798D-4EAC-BAE7-A086DE55B5D2@FreeBSD.org> <CAG4HiT6YUBCxXrK_KyRW6zTthPa-wDe=A9=CmMHQf-Gh54s7QA@mail.gmail.com> <EA5A973C-960A-4B0F-A690-8AA9BF66244A@felyko.com> <CAG4HiT4EbX=Lar_o8YZc5B51Yao1-B=Ebck0vQajyzoZwesWwQ@mail.gmail.com> <CAB=2f8zBDTVkQd15C_icZpOMC14XxFycW_ZR2Sa--updv=dX2w@mail.gmail.com> <53F8FED8.6030409@freebsdbrasil.com.br> <CAG4HiT4RXsUyGfjDDTTJPoeB8bqpY39z6C-_f0S3Zmka0C8gNQ@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On 24/08/2014, at 19:29, Evandro Nunes <evandronunes12@gmail.com> wrote:

> On Sat, Aug 23, 2014 at 5:51 PM, Patrick Tracanelli =
<eksffa@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>  =3D=3D=3D> echo (orange LED)
> >> pin 03:    0    gpio_3<OUT> =3D=3D=3D> trigger (blue LED)
> >> pin 49:    0    gpio_49<IN> =3D=3D=3D> 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)
>=20
> Hello,
>=20
> 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).
>=20
> So the correct sequence should be, in a loop:
>=20
> 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=92t cause a problem)
> 3 - Wait until echo in is LOW
>=20
> When the sound come back to sensor, the device will LOW the GPIO pin =
again.
>=20
> 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.
>=20
> 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.
>=20
> How to do this? I don=92t know how you can get this with in the =
command
> line. First of, date(1) won=92t display the time with enough =
precision. I
> believe date =93+%s=94 is the best precision you have and it=92s epoch =
(1 full
> second, not a fraction).
>=20
> You can use some code, however, to get a usec precision =93now=94. =
Example
> code below I have used in the past will do the trick.
>=20
> But how will you =93wait=94 from 1 to 0 on your GPIO echo pin, on a =
shell
> script, without using almost all CPU you=92ve got in your BeagleBone =
(and
> this is not much CPU), I have no idea.
>=20
> I would test some loop similar to this:
>=20
> #/bin/sh
> gpioctl -c 2 IN
> gpioctl -c 3 OUT
> gpioctl 3 0
> gpioctl 2 0
>=20
> while true ; do
>  gpioctl 3 1 ; sleep .10; gpioctl 3 0 # trigger
>  gpioctl 2 1 # set echo HIGH
>=20
>  inicio=3D$(/root/date-precisao) # what time is it?
>=20
>    while [ $(gpioctl 2 | tail -1) -gt 0 ] ; do
>     echo "...=94 #does nothing, because the pin is still HIGH
>    done
>=20
>   fim=3D$(/root/date-precisao) # pin is now LOW, what time is it?
>   dura=3D$(( $fim - $inicio )) # echo duration (HIGH to LOW usec =
duration)
>   dura2=3D$(( $dura * 10 )) # sh doesn=92t like X.Y precision, make it =
integer
>   dist=3D$(( $dura2 / 582 )) # 58.22 should be the number but 58.2 is =
OK
>   echo "Distance: $dist=94 # this is your not much precise distance
>  sleep 1
> done
>=20
> 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=92t be
> reliable. However, you will have a relative reference.
>=20
> 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 =97 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.
>=20
> Good luck with your experiments.
>=20
> FreeBSD/arm with a BeagleBone is a HELL of a FUN ]:-)
>=20
> /*
>  * Dummy code to print date with usec precision
>  * Patrick Tracanelli <eksffa@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;
>=20
>   ret =3D gettimeofday(&agora, 0);
>   t =3D localtime(&agora.tv_sec);
>   ret =3D 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;
> }
>=20
>=20
> 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

Good...

> 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...=20
> 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

Yes, that=92s it.

What you wanna do is to measure how long HIGH takes.

I just made a better test so you can actually "see" the sensor working. =
Run this more simple loop:

gpioctl -c 2 IN
gpioctl -c 3 OUT
gpioctl 3 0

while true ; do
 gpioctl 3 1 ; sleep .10; gpioctl 3 0
   while [ $(gpioctl 2 | tail -1) -gt 0 ] ; do
    echo "..." #nada
   done
 sleep 1
done

On a second shell, run this horrible cpu consuming loop:

sh -c "while true ; do /root/date-precisao && gpioctl 2 ; done"

And check for the date when PIN 2 becomes high and later when it becomes =
low again.

Speed of sound is 340 meters per second. Since this sensor measures =
round-trip, you shall divide by two, so here is a simple measurement by =
hand:

An object added 1 meter from sensor:

(eksffa@localhost):~% echo "((999013225427212-999013225364525)/340)/2" | =
bc
92

An object added 2 meters from sensor:

(eksffa@localhost):~% echo "((999013003943898-999013003811223)/340)/2" | =
bc
195

So, now you have a better precision, but insanely high CPU usage due to =
the second loop.

Yes, you are right, I personally agree some library with basic =
electronic functions would be very valuable to FreeBSD.

Good to read you will try to write something, I believe Rui Paulo's =
library is a good start to hack, reading GPIO device, detecting when a =
PIN is HIGH and measuring the time until it becomes LOW is probably a =
good starter challenge ;-)

One sensor I am trying to make work is DHT11 temperature and humidity, =
according to datasheet[1] on section 7, this "single-wire =
bi-directional" sensor seems to return a 32bit value which shall be =
calculated in 4 octets.

This is a kind of sensor that deserves a library for sure (and FreeBSD =
deserves to have such a library) but hopefully not the kind of Arduino =
library which is device specific. A more generic library that reads a =
selectable 8/16/32bit value and returns it in different formats =
(decimal, hex, ...) would do the job for this sensor as well as other =
single-wire pin sensors.

[1]http://akizukidenshi.com/download/ds/aosong/DHT11.pdf

--
Patrick Tracanelli

FreeBSD Brasil LTDA.
Tel.: (31) 3516-0800
316601@sip.freebsdbrasil.com.br
http://www.freebsdbrasil.com.br
"Long live Hanin Elias, Kim Deal!"




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3949AF9C-B5BD-44E8-A049-21F26B8B6B9A>