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>