NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Sensors, Actuators, and Robotics » HC-SR04 ultrasonic distance sensor with NerdKits
March 30, 2012 by victor |
I've got the HC-SR04 ultrasonic distance sensor. I looked up online but was only able to find those Arduino tutorials to make it work. Here is one example. http://www.alt42.com/2011/12/hc-sr04-ultrasonic-distance-sensor/ I'm wondering how to implement this particular function which is available in Arduino ? Basically it's measuring the input pin voltage change, to calculate the distance (d = v*t/2). //get the time to receive rebound duration = pulseIn(us_echoPin, HIGH); |
---|---|
March 30, 2012 by victor |
I've got the HC-SR04 ultrasonic distance sensor. I looked up online but was only able to find those Arduino tutorials to make it work. Here is one example. http://www.alt42.com/2011/12/hc-sr04-ultrasonic-distance-sensor/ I'm wondering how to implement this particular function which is available in Arduino ? Basically it's measuring the input pin voltage change, to calculate the distance (d = v*t/2).
|
March 30, 2012 by pcbolt |
Victor - Try here. A similar question. |
March 31, 2012 by lukel |
That code will work with that. I have one of those and it works with that code just fine. Change the trigger pin to PC5. Here is the complete code.
|
March 31, 2012 by victor |
Hi Luke! I spent the whole morning trying to reproduce your code in your previous post. I'm able to compile it and fixed some minor bugs in your previous code like line 88, you used "start_pulse()" which should be "send_pulse()". :) I'm now trying to upload the hex to the board, but no luck so far. weird problem:
|
March 31, 2012 by Ralphxyz |
victor, you are not actually making contact with the Nerdkit.
Pull your USB cable or maybe a reboot, of course check your wiring and battery voltage (under load). Ralph |
March 31, 2012 by victor |
Hi Ralph, I just figured out that I forgot the switch to the programmable mode. I was able to upload a new hex onto it, to display different words on the LED screen. I also upload the ultrasound hex onto it, but then I only see a screen filled with black blocks. any clue? |
March 31, 2012 by victor |
Hey guys! Good news! I've successfully made my ultrasonic range sensor working! :) Luke, I noticed that the error is a bit huge. 10 inches measured as 8.93. Also, there is about 1 second delay, right? Awesome small project! I'll take a video clip today and share with you guys! thanks! :) |
March 31, 2012 by Ralphxyz |
The two rows of black boxes means the LCD is not getting "initialized" so there is either a problem with your wiring or code. Sorry I cannot be more specific. Ralph |
March 31, 2012 by victor |
Hi Luke, I've been debugging the accuracy issue for a while. I found this info by the manufactures, that maybe the root of the issue. It says we should trigger at least 10us, but in the code, we said: OCR0A = 74; // set "top" for 5 usec "Using IO trigger for at least 10us high level signal The Module automatically sends eight 40 kHz and detect whether there is a pulse signal back" Firstly, my device is HC-SR04, as listed below the Amazon link. http://www.amazon.com/Ultrasonic-Module-HC-SR04-Distance-Arduino/dp/B004U8TOE6/ref=pd_cp_e_0 |
March 31, 2012 by victor |
Hey guys, the more I read the datasheets, the more I'm confused. Here is my understanding, please help me out. To measure the distance, 1, send a high voltage from pin PC5 to trigger, Luke used 5us, but the HC-SR04 datasheet says at least 10us. Confusion 1. 2, we set the timer basic unit as 74 cpu cycles, that is 5us. 3, once the PC5 is set to high for that 5us (or 10us), we start measuring the PC4, echo pin. Confusion 2. 4, once the PC5 changes , will trigger an interupt, then we get the "pulse_count", which is proportional to a distance by dist = time * speed/2. could anyone help me out? thanks! |
March 31, 2012 by lukel |
It's because this code is for a ping((( ultrasonic sensor. It worked for me, but it also had the delay. I tried to make it as accurate as possible. |
March 31, 2012 by victor |
Ahh i see! Ping))) uses 5us as trigger. How much of the code needs to be changed to be able to use 10us? I've tried to change 74 to 148, but it looks like it can only measure 1.1 meter far. Beyond 1.1 meter, I got some weird reading... Any clue? |
March 31, 2012 by victor |
Thank you guys! My UltraSonic measuring system is up and running! :) Pretty agile and accurate! |
March 31, 2012 by victor |
Oops, repost the photos here: |
March 31, 2012 by victor |
|
March 31, 2012 by victor |
Luke, I think I've fixed the bug you had been suffering. You need to put a delay_ms(200) at the end of your while(1) loop. Otherwise the measuring won't be stable, since sometimes the 5us will mess up the previous execution. Mine is quite agile and accurate now. HTH |
March 31, 2012 by victor |
|
March 31, 2012 by pcbolt |
Hi victor - If you set the timer "top" value to 148 (OCR0A = 148), this will execute the code in the "ISR(TIMER0_COMPA_vect)" routine every 10 uSec. So when you call "send_pulse()", all it does is turn the output pin high, set the timer to 0 and set the pulse_flag. 10 uSec later the timer ISR will execute and since the pulse_flag is on ( == 1) it turns the output pin off, pulse_flag off ( == 0), and sets the pulse_count to 0. Now every 10 uSec, when the ISR gets triggered, the pulse_count variable counts how many times it has been called and it sets the timing_flag to 1. When a pin change happens on the input pin (when the return sound comes back), the pin change interrupt "ISR(PCINT1_vect)" checks to see if you are in "timing" mode by checking the timing_flag. If it is, it takes a "snapshot" of the current 10 uSec pulse counts. So I think all you need to do is change line 90 from:
To:
(I'm not sure why the * 100 is in there since the answer should be in inches). |
March 31, 2012 by pcbolt |
Whoops - Looks like we were posting at the same time....glad to see it working. |
April 01, 2012 by Ralphxyz |
Hey Luke, what Ping))) sensor do you have? I have the one from Radio Shack (about two years ago) it is from parallax I corrected your code from above with pcbolts corrections and have the program running but all I see on the LCD is "0.00 inches". I am using PC1 instead of PC4 (I need PC4 for my I2C LCD). I am putting out a signal I see approx 8 milivolts and I can see the signal on my scope but I am not receiving anything or not calculating the distance correctly. Here is my code:
Hope someone can see something, Ralph |
April 01, 2012 by victor |
a quick fix: line 98, remove "void " |
April 01, 2012 by victor |
also, line 104, remove "void". |
April 01, 2012 by victor |
Also, add these 2 functions in your code. You didn't define them correctly.
|
April 01, 2012 by Ralphxyz |
Thanks Victor, when I removed the line 104 void I get this error:
Here is the code:
start_pulse is not defined anywhere!! Ralph |
April 01, 2012 by victor |
Hi Ralphxyz, That's one easy fix from Luke's code. Basically just change it to send_pulse(). |
April 01, 2012 by Ralphxyz |
Well apparently start_pulse should be send_pulse, which victor noted previously. Made the changes and now I get a constant 325.31 inches. Ralph |
April 01, 2012 by victor |
Ralph, try printing out at the 2nd line the value of "pulse_time" would help you debug. Also, delay 500ms is not necessary. The sensor can only measure up to 5 meters, which takes the round trip time of 5*2/340 = 29ms. So delay 100ms would be enough. Check your pins first. did u connect Trig and Echo pins correctly? |
April 01, 2012 by Ralphxyz |
I am using PC1 not PC5 or PC4! Made the corrections but still getting "325.31 inches" The led flashes every couple of seconds. Ralph |
April 01, 2012 by Ralphxyz |
Thanks for the help victor, I am getting 0.00 for pulse_time!! re: pins I do not have a Trig or Echo pin I only have tree pins + - and Signal. That's the reason I asked luke what Ping))) device he was using to make sure we were using the same device. So with pulse_time 0.00 what does that mean? Ralph |
April 01, 2012 by victor |
Ralph, that means the device is not powered.... actually, Ping))) is just a simplification of my HC sensor. Ping))) hardwired the Trig pin as a constant triggering module which keeps sending out US waves. take a snapshot so we could help you.... |
April 02, 2012 by Ralphxyz |
Oh the device definitely is powered the LED flashes every two seconds and I looked at the signal on my scope! I bet the error is in my switching from PC4 to PC1. I am using Rick's I2C_LCD and I2C (TWI) uses PC4. Here is my latest code Ralph |
April 02, 2012 by Ralphxyz |
Here is a shot of the face of the device, the yellow wire in the background (SIG) goes to PC1 on the mcu. I wonder what the purpose of the led (the box in the center label ACT) is for? Ralph |
April 02, 2012 by victor |
Ralph, Check carefully you code, esp. those parts that are related to setting PC1. , like:
Post your code here so we can take a look. |
April 02, 2012 by 6ofhalfdozen |
Ralph, I would guess the ACT led is an "activity LED". I would guess that it is there to tell you the ultrasonics are ON. We recently got an outdoor ultrasonic cat repeller (our neighbors cat loves to spray our house and crash into/attack the windows scaring our cats badly). Anyhow, the paperwork mentions that even though you can't hear it, >90db of ultrasonics can do damage to your ears. While I doubt the sensor puts out >90db, I imagine the light lets you know when not to put your head in front of the thing. perhaps. |
April 02, 2012 by Ralphxyz |
Here is the whole thing: Now I am getting 0.00 inches and 0.00 pulse_time
|
April 02, 2012 by victor |
changed to
|
April 02, 2012 by victor |
Ralph, I know your problem. You didn't configure the input pin correctly. Hint, you need something like this. I will let you explore and learn instead of spoiling you. Read carefully Luke's code and the ATmel chip datasheet.
|
April 02, 2012 by Ralphxyz |
I am confused about Luke's use of PC4 and PC5 (there is even a PC2 mentioned). I am using the code from this page now but I only have one pin SIG on my Ping))) unit PC1. So I guess I am at a loss about how this is supposed to work. Well now I am getting 3318.67/3319.30/3319.33/3319.12 inches with 1750/1753/1763 pulse_time. It used to be static so I guess I am making progress. Ralph |
April 02, 2012 by pcbolt |
@ lukel - I couldn't understand why you added *100 to this:
What happened was when computing the speed of sound in air using 1115 ft/sec, I divided that number by 12 to get inches/sec. That was wrong. I should have multiplied by 12 to get 13,380 in/sec. So the final formula should have been...
This can simplify down to:
Sorry about the mix-up. |
April 02, 2012 by pcbolt |
Ralph - I checked out the datasheet for the Ping))) sensor and it turns out to be quite a bit different from the sensors lukel and victor are using. The Ping))) needs a 5 uSec trigger pulse to get things started (SIG line high for 5 uSec). Then it waits "about" 200 uSec to send its sound pulse. It will set the SIG line high until it gets the return sound at which time it goes low. So the code above won't really work for you. You'll need to start the timing when the SIG line goes high after a send_pulse() is used. Then stop the timer when the SIG line goes low. The code I posted for lukel right above this post should work to convert to inches. |
April 03, 2012 by Ralphxyz |
Thanks pcbolt, that was why I asked Luke when I started trying this.
My need for a Ping))) sensor is a long way off but I thought since I had one and with the ongoing conversation figured I I'd give it a whirl. Plus I really needed to understand timers and interrupts for a upcoming project so I thought this would be a good way to lean. I thought I might just have to start from scratch so I Googled "AVR Ping" and found this site.
Does this Pseudo Code look right? Also I am using this to finally learn how to use my oscilloscope, so this has been a really good experience so far. I do not have a lot of time but like I said I need to understand interrupts so here we go. So thanks victor for your help so far, I'll be back for more. Ralph |
April 03, 2012 by pcbolt |
Ralph - It looks pretty good. But on that site they mention the conversions to inches and cm were "clock dependent" so you most likely will have to tweak those numbers. The clock timer lukel used increments the "pulse_count" (and therefore "pulse_time") variable every 5 uSec. So this should work...
|
April 04, 2012 by lukel |
Ralph, I think you need to define an input pin. Replace pin_init with this.
|
April 04, 2012 by lukel |
I mean this.
|
April 04, 2012 by pcbolt |
lukel - Were you able to modify your code with the new conversion factor I listed about 4 post ago on this thread? Again, sorry for the mix up. |
April 04, 2012 by Ralphxyz |
lukel, what Ping))) device do you have is it the same one I have from Parallex that I have? Ralph |
April 04, 2012 by lukel |
Yes, I have that one. I also have the HC-S904. |
April 05, 2012 by Ralphxyz |
Good then that probable explains some of my confusion, some of the discussion/code was about the Ping))) sensor and other was about the HC-S904 and I was mixing them up. Looking forward to your Nerdkit Community Library Project Ultra Sonic Sensor project. I see you have gotten started. Ralph |
April 05, 2012 by lukel |
Ralph, try this code.
|
April 05, 2012 by Ralphxyz |
Thanks lukel, i'll have to try it later on got work to do now :-) Ralph |
April 05, 2012 by Ralphxyz |
lukel why are you still using PC4 and PC5?
I can not use PC4 or PC5 so I am using PC1. Now I am getting a steady pulse the led is on constantly!! Also I am not getting anything on the LCD!! Here is my modified code.
|
April 05, 2012 by lukel |
On line 35, add
|
April 05, 2012 by Ralphxyz |
Made the change but still get the led on constantly and nothing on the LCD!! Ralph |
April 05, 2012 by pcbolt |
Ralph - Try using these subroutines:
Oh...and I usually like to write a test string to the LCD right after it is initialized. Just as a sanity check. If it does work, you can get rid of all the interrupt code since you are not using them. |
April 06, 2012 by Ralphxyz |
Now I need to understand getting rid of the interrupts, which were the reason I was pursuing this. And yes I like the debug message. Oh,
should be
The indicator LED is still on constantly and I am not getting anything on the LCD. I'll look at my I2C_LCD changes for that. Ralph |
April 06, 2012 by Ralphxyz |
Now I setup a regular Nerdkit breadboard using PC4. I am still seeing the LED on constantly with nothing displayed on the LCD!! Here is my current code using PC4:
There are no interrupts but they are still referenced which is confusing. Ralph |
April 06, 2012 by pcbolt |
Ralph - If you are not getting even the "Hello World" message it may mean the "time_it()" subroutine is not returning. Try putting lines 77,78,79 above the while(1) statement (after say line 67), just to test the LCD. You mentioned in one of your posts (another thread) that you have a good O-scope. Might be time to break that bad boy out to test the PC4 pin to see if it is sending the 5 uSec pulse, and if the sensor is reacting the way it should. |
April 07, 2012 by Ralphxyz |
I have been trying to use my scope (which I know veryvery little about using) but so far I have not seen a 5 volt blip. My multi meter registers a steady 5 volts. I really need to learn how to use the scope. I am seeing two different things with the two probes on the same pin and both are just miniscule blips but different. Ralph |
April 07, 2012 by lukel |
|
April 07, 2012 by lukel |
See if you can find my library post, it has the code for a ping((( sensor. |
April 07, 2012 by pcbolt |
lukel - I remember you said you have both sensors...did you get both to work? If so, great job. I had one question though, did you have to change the output trigger pulse to 10 uSec? The reason I ask is the "TOP" value is set as 148 which is 10 uSec instead of 74 which is what you used in the second code list in the library. |
April 07, 2012 by lukel |
I got "pingy" working, but it just delayed a long time to read. |
April 08, 2012 by Ralphxyz |
lukel said:
Thanks lukel for adding your Ping))) Sensor (always nice to have links) code. But sorry to have to tell you this but it doesn't compile! First error:
You missed the opening ( ). And then there isn't any pin_init() code! I added pin_init() code from prior builds:
Now the code compiles, but I am still getting a blank LCD. Also now the LED only flashes once and then stays off. Now don't be surprised especially as this was your first post to the Nerdkit Community Library which I really appreciate your effort. This is just one of life's embarrassing moments (which can happen a lot, through one's life if not careful). You made certain assumptions before posting your code. Starting with assuming your code worked especially since you have seen it work. But you did not test the code you uploaded immediately before uploading. and then (and this might be the most important step) you did not download your code and test it again. Now we expect broken code in the forum but when you post to the library the actual uploaded code should be tested and working. You cannot run code a couple of days before and then just upload that, you have to test it before uploading. You will find that there are certain Gremlins that get into your code and mess it and components up, they take great delight in doing things like this and are very pernicious unless you have a diligently followed testing plan. The nice thing about the Library is that if I had been able to fix the code I could have fixed it without making mention but I think there are some important lessons to be learnt here. I am sorry to do this publicly but if we had a decent forum service we could message each other privately. Ralph |
Please log in to post a reply.
Did you know that you need to think about wires differently when you're transmitting signals more than a few inches? Learn more...
|