Issues with fading

Hello,
I am working on a lighting project using an sharp IR proximity sensor and some LEDs. My goal is to use the proximity of a person to slowly fade a light on. Originally, I wanted to use the sensor to judge the brightness of the LEDs based off of proximity, but the sensor had too much feedback and the LED would flicker randomly. All I want now is for the LED to fade on slowly at a certain distance. Once the person walks out of that distance, the LED will fade out slowly.

I know this sounds like a simple motion sensor, but I want a nice gradual fade in both directions to help with my concept.

here is my code so far, I have eliminated my attempts to fade for they were probably ridiculous:

int SensorPin = A0;
#define ledPin = 9;

void setup() {
// initialize the digital pins as an output.

pinMode(9, OUTPUT);
pinMode(SensorPin, INPUT);
Serial.begin(9600);

}

void loop() {

int val = analogRead(SensorPin);
if (val >= 150)
{digitalWrite(9, HIGH); // Turns ON Relay on digital pin 4
delay(1000); // wait for a second
}

else if (val <= 170)
{digitalWrite(9, LOW); // Turns OFF Relay on digital pin 4
delay(1000); // wait for a second // wait for a second
}
Serial.print(val);
Serial.println(" ");}

#define ledPin = 9;

So, wherever ledPin appears later in the code, = 9; will be substituted. Does that make sense?

if (val >= 150)
   {digitalWrite(9, HIGH);   // Turns ON Relay on digital pin 4
  delay(1000);              // wait for a second
   }

That does not look like fading an LED. It looks like code to turn a relay on. That comment is just plain stupid. It is NOT at all what the code is doing. Not the same pin. Not the same hardware connect to the pin.

you can try something like this...

Notice your numbers 150 and 170 corresponding to your range to fade from max brightness of the LED at 255 to minimum brightness of zero.

#define ledPin 9

int sensorPin = A0;
//
void setup() 
{  
  Serial.begin(9600);  
  pinMode(ledPin, OUTPUT); 
  pinMode(sensorPin, INPUT);
}
//
void loop() 
{
  analogWrite(ledPin, map(constrain(analogRead(sensorPin), 150, 170), 150, 170, 255, 0));
}

you can try broadening the range...

  analogWrite(ledPin, map(constrain(analogRead(sensorPin), 100, 450), 100, 450, 255, 0));

or inverting the fade:

  analogWrite(ledPin, map(constrain(analogRead(sensorPin), 150, 170), 150, 170, 0, 255));

PaulS:

#define ledPin = 9;

So, wherever ledPin appears later in the code, = 9; will be substituted. Does that make sense?

That's a bit unfair Paul.

Unless you explain to someone how are they supposed to know that the silly C/C++ system requires an = when you do byte ledPin = 9; and requires you to omit the = (and the ;) when you do #define ledPin 9

...R

That's a bit unfair Paul.

Not really. A person might look at my comment and say "No, that doesn't make sense. Why would that happen?". Or, a person might look at that and say "Well, duh. That was stupid. I'll fix that right away!". I don't know how OP will react, so I offer a hint or clue.

When I get stuck, I don't want someone to write the code for me. I want a hint. If I'm really stuck, like 47 hints later and I still don't know what I'm doing wrong, then I want someone to write (some of) the code for me, I prefer to assume that most of the posters here are like me.

Hey Guys,

I appreciate the feedback.
I do apologize for the "// comments" in my code, for they were residual comments from an earlier code i wrote.

however, what i want is for the LED to fade on at a specific distance rather then it fade with actual proximity.
this would be like a modified "motion sensor" that has a slow fade on/off when the user get within X distance of it.

here is my revised code that I need to add fade feature:

int SensorPin = A0;
#define ledPin 9;

void setup() {

pinMode(9, OUTPUT);
pinMode(SensorPin, INPUT);
Serial.begin(9600);
}

void loop() {

int val = analogRead(SensorPin);

if (val >= 150) // pre-defined distance i am using
{digitalWrite(9, HIGH);} // At this point I want the LED to FADE ON

else if (val <= 170) // pre-defined distance i am using
{digitalWrite(9, LOW);} // At this point I want the LED to FADE OFF

Serial.print(val);
Serial.println(" ");}

did you try the suggestion I posted?

You have to use analogWrite to use PWM (fading).

#define ledPin 9

int sensorPin = A0;
//
void setup() 
{  
  Serial.begin(9600);  
  pinMode(ledPin, OUTPUT); 
  pinMode(sensorPin, INPUT);
}
//
void loop() 
{
  analogWrite(ledPin, map(constrain(analogRead(sensorPin), 150, 170), 150, 170, 255, 0));
}

the first thing its does is analogRead your sensor pin

analogRead(sensorPin)

then it constrains it to your 150 and 170 limits:

constrain(analogRead(sensorPin), 150, 170)

and then it maps the differential to the output expectations of analogWrite (a byte from 0 to 255):

map(constrain(analogRead(sensorPin), 150, 170), 150, 170, 255, 0)

then it writes that value to your ledPin

analogWrite(ledPin, map(constrain(analogRead(sensorPin), 150, 170), 150, 170, 255, 0));

thanks BulldogLowell,

It seems to be close, however I'm not getting the slow fade on and off...
I want the light to gradually (around 1.5 seconds) turn on/off once the proximity is reached.

I was thinking it could be a feature the actually maps out a few brightness values to ramp up the when it turns on and off.

This seems right to me, but it doesn't work:
int SensorPin = A0;
#define ledPin 9;

void setup() {

pinMode(9, OUTPUT);
pinMode(SensorPin, INPUT);
Serial.begin(9600);
}

void loop() {

int val = analogRead(SensorPin);

if (val >= 150) // pre-defined distance i am using
{for (int i=0; i<255; i++)
analogWrite(9, i);} // At this point I want the LED to FADE ON

else if (val <= 170) // pre-defined distance i am using
{for (int i=255; i>0; i--)
analogWrite(9, i);} // At this point I want the LED to FADE OFF

Serial.print(val);
Serial.println(" ");
}

you should not put the ";" after the 9 here:

#define ledPin 9;

you are better off using an assignment like you did on the other pin

int ledPin = 9;

another approach would be to set the distances for the fades to start:

int SensorPin = A0; 
int ledPin = 9;
int oldVal;

void setup() {                

  pinMode(9, OUTPUT); 
  pinMode(SensorPin, INPUT);
  Serial.begin(9600);
}

void loop() {

  int val = analogRead(SensorPin);
  if (val <= 150 && oldVal > 150)
  {
    fadeUp();
  }      
  else if (val >= 170  && oldVal < 170)
  {
    fadeDown();
  }
  oldVal = val; 
}

void fadeUp()
{
  for (int i = 0; i <= 255; i++)
  {
    analogWrite(ledPin, i);
    delay(10);
  }
}

void fadeDown()
{
  for (int i = 0; i <= 255; i++)
  {
    analogWrite(ledPin, 255 - i);
    delay(10);
  }
}

We will need to get rid of the delays for it to work really well, but you can mess around with this.

EDIT: added <= and >= in sketch, my error

We are so close!

The fade looks great, however, when something is not in the range it is on and fading in and out. When I get in range, the light just fades off...

i just want the light to fade on when you are close, and fade off when you move away..

so... experiment with the values that trigger the fades in the example below...

or are you trying to modify the fade if the person moves closer (fade up) or further (fade down) at any value along the sensor's range?

perhaps you should define exactly what you want your sensor/led to do, and then (we can help) program it.

int SensorPin = A0; 
int ledPin = 9;
int oldVal;

void setup() {                

  pinMode(9, OUTPUT); 
  pinMode(SensorPin, INPUT);
  Serial.begin(9600);
}

void loop() {

  int val = analogRead(SensorPin);
  if (val <= 150 && oldVal > 150)//<<<<<<<<<<<< HERE I wrote when the sensor returns less than 150... should you change that?
  {
    fadeUp();
  }      
  else if (val >= 170  && oldVal < 170)//<<<<<<<<<<HERE I wrote when the sensor returns greater than 170... should you adjust that?
  {
    fadeDown();
  }
  oldVal = val; 
}

void fadeUp()
{
  for (int i = 0; i <= 255; i++)
  {
    analogWrite(ledPin, i);
    delay(10);
  }
}

void fadeDown()
{
  for (int i = 0; i <= 255; i++)
  {
    analogWrite(ledPin, 255 - i);
    delay(10);
  }
}

Basically,
I want the sensor to turn ON and stay ON when someone is within a certain distance. When they walk away (outside of the distance) the LED will turn OFF and stay OFF. The fade is just a transitional effect into those states of ON and OFF.
I just don't want an abrupt switch between ON and OFF.

thanks again for your help BulldogLowell, we are getting closer.

did you try reply # 12 above?

The sensor I have read in values of around 0 through about 450ish.

The values I plotted are pretty accurate based off of my initial tests.

150 for close proximity

170 for cut off point.