Pages: [1] 2   Go Down
Author Topic: Fading an LED using a Ping  (Read 1319 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tiny little project just to get my head around how to use the Arduino.

So far, I have this:

Code:
/* 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 Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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 Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Or use the cm result for an instant 2.54 times improvement.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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 Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
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 Offline
Faraday Member
**
Karma: 92
Posts: 4717
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Code:
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

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Edison Member
*
Karma: 5
Posts: 1730
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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 Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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 Offline
Brattain Member
*****
Karma: 290
Posts: 25731
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 0
Posts: 25
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.   smiley-grin

Which, now that i think about it, the ping is only a viable option to 2 cm, so I stand corrected.
Logged

Offline Offline
Edison Member
*
Karma: 5
Posts: 1730
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1] 2   Go Up
Jump to: