Ping sensor and LED lightbox

Hi

I am trying to interface a Ping sensor with an led light box.

So that when you are less than or equal to 100cm from the sensor the Leds slowly lights up to the maximun 225. When you step out of the range the leds then fade away to 0.

Thought it would be within my simple abilities obviously not.

Any help would be greatly appreciated

Kato

Here is my code:

cm = total / numReadings;
// brightness = 0;
//cm = constrain(cm,20,100);

if(cm <= 100)
{

brightness = brightness++;
analogWrite(LED,brightness);
delay(10);

}

else

{

brightness = brightness--;
analogWrite(LED,brightness);
delay(10);
}

A

Here is my code:

You need to post all of your code. From that snippet, we have no way of knowing whether you are getting any distance readings, or if they are anywhere near correct. A distance reading takes time. If you are not allowing for that, you will not get decent data. You typically do not need to average ping sensor readings. Simply ignore a value if it is radically different from a previous reading.

 brightness = brightness++;

brightness++; is shorthand for brightness = brightness + 1; Your statement, then, is equivalent to

brightness = brightness = brightness + 1;

I think you should be able to compare these two statements, and figure out what to remove from yours.

Thought it would be within my simple abilities obviously not.

You haven't told us what this code does that you do not want, or what it does not do that you want it to do. Without that information, it is hard to tell you how to change it to do what you want.

Hi Paul

Here is all the code

What I am trying to do is control when a led lightbox comes on and goes off. I have constrained it to a window of between 20cm to 100cm.

Inside the window the Led will fade up to it's max value once stepped outside the window the led lightbox will fade back to 0.

The leds where flickering which is the reason I thought it would help if I averaged the readings.

Hope the this information helps

/*

Smoothing

*/

// Define the number of samples to keep track of. The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input. Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
const int numReadings = 60;

int readings[numReadings]; // Number of readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int cm = 0; // the average value in cm
long brightness = 0;

const int pingPin = 7; // PING input connected to pin 7
int LED = 3; // LED is connected to pin 3

void setup()
{

Serial.begin(9600); // initialize serial communication with computer:

for (int thisReading = 0; thisReading < numReadings; thisReading++) // initialize all the readings to 0:
readings[thisReading] = 0;
}

void loop() {

// establish variables for duration of the ping,
// and the distance result in centimeters:
long duration,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
pinMode(pingPin, INPUT); // pulse whose duration is the time (in microseconds) from the sending
duration = pulseIn(pingPin, HIGH); // of the ping to the reception of its echo off of an object.

cm = microsecondsToCentimeters(duration); // convert the time into a distance

total= total - readings[index]; // subtract the last reading:

readings[index] = cm; // read from the sensor:

total= total + readings[index]; // add the reading to the total:

index = index + 1; // advance to the next position in the array:

if (index >= numReadings) // if we're at the end of the array...
// ...wrap around to the beginning:
index = 0;

cm = total / numReadings; // calculate the average:

cm = total / numReadings;
rightness = 0;
//cm = constrain(cm,20,100);

if(cm <= 100)
{

brightness = brightness+1;
analogWrite(LED,brightness);
delay(10);

}

else

{

brightness = brightness-1;
analogWrite(LED,brightness);
delay(10);
}

Serial.print(cm);
Serial.print("cm");
Serial.println();

}
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;
}

It helps when you post code to select all of it and hit th "#" (code tag) button. That makes it look nicer and avoids some problems with code looking like forum tags.

Now for your problem, I am worried about this:

  if(cm <= 100)
  {
    brightness = brightness+1;                       
    analogWrite(LED,brightness);
    delay(10);
  }
  else
  {
    brightness = brightness-1;
    analogWrite(LED,brightness);
    delay(10);
  }

A "long" can have quite a large value, so if you are away from the box for a while, it could go very negative (eg. -437463), so then when you get close again it has a lot of catching up to do (ditto if you get close).

I would constrain brightness to be within valid ranges (eg. 0 to 1023).

Hi Nick

Thanks for the advice again!

Did think it was something to do with not having the values constrained. (and some sort of over run problem)

Had tryed putting a for loop inside the if statement but I dont think that is allowed.

The below code works which I will have to use for the exhibition has to installed for Tuesdy.

As you approach the light box the LEDs get brighter.

cm = total / numReadings; // calculate the average:

cm = constrain(cm,20,100);
i = map(cm,20,100,225,0); // map "i" 20 to 0 and 100 to 225 and assign it varialble "i"
analogWrite(LED,i);
//delay(10);

Serial.print(cm);
Serial.print("cm");
Serial.println();

thanks

Malcolm

I would constrain brightness to be within valid ranges (eg. 0 to 1023).

If that's for an analogWrite, make it 0...255.

Aww, it was just an example! Anyway I was thinking of analogRead which returns 0 to 1023. Strange how you can read 0 to 1023 but only write 0 to 255. A strange asymmetry there. :wink:

A strange asymmetry there.

The Arduino is capable of distinguishing 1023 different voltage levels. Using PWM to vary the brightness of an LED, can YOU distinguish 1023 levels? Can you tell the difference between 118 and 119?

PaulS:

A strange asymmetry there.

The Arduino is capable of distinguishing 1023 different voltage levels. Using PWM to vary the brightness of an LED, can YOU distinguish 1023 levels? Can you tell the difference between 118 and 119?

By that argument there is no need to sense 1024 different input values either :wink: ... can you tell the difference (by eyemeasurment alone) the difference betweden 118cm and 119 cm ? Besides the PWM can be used to control other things than LEDs :slight_smile:

kato:
The below code works which I will have to use for the exhibition has to installed for Tuesdy.
As you approach the light box the LEDs get brighter.

  cm = constrain(cm,20,100);

i = map(cm,20,100,225,0);                                   // map "i" 20 to 0 and 100 to 225 and assign it varialble "i"
  analogWrite(LED,i);

That works if you want people to be able to control the brightness by how close they get. If you want the original effect:

  if(cm <= 100)
  {
    if (brightness < 255)
        brightness++;
  }
  else
  {
    if (brightness > 0)
        brightness--;
  }
  analogWrite(LED,brightness);
  delay(10);

how did the installation go, kato?