Offline
Newbie
Karma: 0
Posts: 25
|
 |
« on: January 10, 2012, 06:44:20 pm » |
Tiny little project just to get my head around how to use the Arduino. So far, I have this: /* Ping))) Sensor This sketch reads a PING))) ultrasonic rangefinder and returns the distance to the closest object in range. To do this, it sends a pulse to the sensor to initiate a reading, then listens for a pulse to return. The length of the returning pulse is proportional to the distance of the object from the sensor. The circuit: * +V connection of the PING))) attached to +5V * GND connection of the PING))) attached to ground * SIG connection of the PING))) attached to digital pin 6
http://www.arduino.cc/en/Tutorial/Ping created 3 Nov 2008 by David A. Mellis modified 30 Aug 2011 by Tom Igoe This example code is in the public domain.
*/
// this constant won't change. It's the pin number // of the sensor's output: const int pingPin = 3; int ledpin = 11; int brightness = 0; // how bright the LED is int fadeAmount = 5; // how many points to fade the LED by
void setup() { // initialize serial communication: Serial.begin(9600); pinMode(ledpin, OUTPUT); }
void loop() { // establish variables for duration of the ping, // and the distance result in inches and centimeters: long duration, inches, cm;
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds. // Give a short LOW pulse beforehand to ensure a clean HIGH pulse: pinMode(pingPin, OUTPUT); digitalWrite(pingPin, LOW); delayMicroseconds(2); digitalWrite(pingPin, HIGH); delayMicroseconds(5); digitalWrite(pingPin, LOW);
// The same pin is used to read the signal from the PING))): a HIGH // pulse whose duration is the time (in microseconds) from the sending // of the ping to the reception of its echo off of an object. pinMode(pingPin, INPUT); duration = pulseIn(pingPin, HIGH);
// convert the time into a distance inches = microsecondsToInches(duration); cm = microsecondsToCentimeters(duration); Serial.print(inches); Serial.print("in, "); Serial.print(cm); Serial.print("cm"); Serial.println();
//Controlling the LED brightness if (inches <= 15 && inches >= 2) { brightness = map(inches, 15, 2, 0, 255); } else if (inches > 15) { brightness = 0; } else { brightness = 255; }
analogWrite(11, brightness);
delay(50); }
long microsecondsToInches(long microseconds) { // According to Parallax's datasheet for the PING))), there are // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per // second). This gives the distance travelled by the ping, outbound // and return, so we divide by 2 to get the distance of the obstacle. // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf return microseconds / 74 / 2; }
long microsecondsToCentimeters(long microseconds) { // The speed of sound is 340 m/s or 29 microseconds per centimeter. // The ping travels out and back, so to find the distance of the // object we take half of the distance travelled. return microseconds / 29 / 2; } As you can see, this is based heavily (ie: almost entirely) on the ping tutorial included with the program. My addition is towards the bottom. My problem is that due to the map(), and the reading being in whole numbers, my "fade" of the LED isn't fading so much as stepping. I'd like to have readings to the second decimal place. It'd do a smoother job I think, and is more along the lines of what I'm trying to get out of this exercise. The question is, how do I do this?
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35483
Seattle, WA USA
|
 |
« Reply #1 on: January 11, 2012, 06:00:21 am » |
As you can see, this is based heavily (ie: almost entirely) on the ping tutorial included with the program. If you don't care about the value in cm, why are you still computing it? The time taken to send and receive an echo does not limit the sensor to whole inch values. Make microsecondsToInches() return a float, so you get fractions. Of course, you need to fix the arithmetic to make this work. And, you'll need to get rid of the call to map, and create your own mapping function.
|
|
|
|
|
Logged
|
|
|
|
|
Gosport, UK
Offline
Faraday Member
Karma: 19
Posts: 3118
|
 |
« Reply #2 on: January 11, 2012, 06:14:17 am » |
Or use the cm result for an instant 2.54 times improvement.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #3 on: January 11, 2012, 07:55:30 pm » |
If you don't care about the value in cm, why are you still computing it? Um, because I hadn't thought about not computing it. No real reason. The time taken to send and receive an echo does not limit the sensor to whole inch values. Make microsecondsToInches() return a float, so you get fractions. Of course, you need to fix the arithmetic to make this work.
And, you'll need to get rid of the call to map, and create your own mapping function.
I didn't think this was working, but I figured it out. Turns out I forgot to change some Longs to Floats. However, I'm still using the same map function. How was I supposed to make it work with a new rewritten map function?
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35483
Seattle, WA USA
|
 |
« Reply #4 on: January 12, 2012, 06:33:51 am » |
Turns out I forgot to change some Longs to Floats. However, I'm still using the same map function. The map function expects integer input and returns an integer output, so it is rather pointless to use it with floats. Which longs (there are no Longs) did you forget to change to floats (there are no Floats)?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #5 on: January 12, 2012, 09:19:00 am » |
The map function expects integer input and returns an integer output, so it is rather pointless to use it with floats.
Which longs (there are no Longs) did you forget to change to floats (there are no Floats)?
The longs/floats I was referring to was in the code, not the map function... When duration, inches and cm were defined in the beginning of the loop, I had left that as Longs, and changed the others to Floats, which made it default to Long results I guess. As far as the map function, I'd just use the format: long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } But with floats, correct?
|
|
|
|
|
Logged
|
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 30
Posts: 2913
I only know some basic electricity....
|
 |
« Reply #6 on: January 12, 2012, 10:58:01 am » |
long microsecondsToHundredthsOfInches(long microseconds) { // According to Parallax's datasheet for the PING))), there are // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per // second). This gives the distance travelled by the ping, outbound // and return, so we divide by 2 to get the distance of the obstacle. // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf return microseconds * 100000 / 73746 / 2; }
And there you have your 2 decimal places into inches. But since there are less than 100 micros per inch it would probably be smarter to go by TenthsOfInches, return microseconds * 10000 / 73746 / 2 The Hundredths is good as long as you don't have a ping over 2 seconds. You can go higher by reducing the accuracy of 73.746 microseconds per inch. Notice how that fits in? OTOH you could figure inches per microsecond to 3 or 4 places and multiply microseconds by that then do what you must to display 10ths or 100ths of an inch. Considering the conversion and speed of sound, inches is already pushing it.
|
|
|
|
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
Offline
Edison Member
Karma: 3
Posts: 1712
|
 |
« Reply #7 on: January 12, 2012, 02:05:05 pm » |
Another idea would be to smooth out the steps, by instead of jumping to the new value, just moving towards the new value in much smaller steps that are not noticable
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #8 on: January 12, 2012, 02:11:15 pm » |
Another idea would be to smooth out the steps, by instead of jumping to the new value, just moving towards the new value in much smaller steps that are not noticable
That's what the map function was for, but with it only using whole numbers, and only 13 of them, it was too choppy. But I think when I rework the map function to use float numbers, using #.##, it should be much more fluid. That's on the agenda for tonight. Realized at lunch today that this simple little setup would work perfectly for a back up system in a car, telling you when you get close down to the nearest hundredth cm.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35483
Seattle, WA USA
|
 |
« Reply #9 on: January 12, 2012, 02:16:38 pm » |
Realized at lunch today that this simple little setup would work perfectly for a back up system in a car, telling you when you get close down to the nearest hundredth cm. On a car moving at what speed?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #10 on: January 12, 2012, 02:21:02 pm » |
On a car moving at what speed?
Well, I was thinking parallel parking, so less than 2 mph. FYI, this is not the intent of my project, just an observation.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35483
Seattle, WA USA
|
 |
« Reply #11 on: January 12, 2012, 02:32:36 pm » |
so less than 2 mph. Even at 2 mph, a delta distance of 0.01 cm is pretty silly, don't you think?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 137
Posts: 19030
I don't think you connected the grounds, Dave.
|
 |
« Reply #12 on: January 12, 2012, 02:35:35 pm » |
Is a tenth of a mm even achievable, given the granularity of pulseIn?
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 25
|
 |
« Reply #13 on: January 12, 2012, 02:36:58 pm » |
so less than 2 mph. Even at 2 mph, a delta distance of 0.01 cm is pretty silly, don't you think? I was just stating what was possible with what I currently have. Just a conceptual statement, not like I have the tools in my hand and heading out the door.  Which, now that i think about it, the ping is only a viable option to 2 cm, so I stand corrected.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 3
Posts: 1712
|
 |
« Reply #14 on: January 12, 2012, 03:40:53 pm » |
I meant more of a smoothing like slowly averaging to the next level, so even if it jumped from 0 to the top it wouldn't just kick on but fade on slowly
|
|
|
|
|
Logged
|
|
|
|
|
|