Fade out LED from undefined brightness, over linear time

ok... clunky title!

i have the led connected up to react to an ir sensor, i have a low setting, so the led outputs nothing at the low level, and the idea being that when your hand is 10cm away its at half brightness and when its 2cm away its at full brightness...

this i have working fine.

what i want is when i take my hand away, instead of turning off, i want it to fade out.

bright2 is a mapped reading from the analog sensor

if (ir2<lowsetting1) {
   analogWrite(led2, LOW);
}  else {
   analogWrite(led2, bright2);
}

i can put a fade in, but it just constantly drops the brightness.. i cant get around my head, how to detect for a constant interruption (hand), and then change when the interruption disappears.

thanks!

static int lastBrightness = 0;
if (ir2 < lowsetting1) {
   if (lastBrightness > 0)
      lastBrightness --;  // Dim the light til it reaches 0
}  else {
   lastBrightness = bright2; //  Set the brightness to match distance
}
   analogWrite(led2, lastBrightness);

much appreciated, not for the code as much, but for the introduction to static int... this would have solved quite a lot of my if / else issues... but also for the code guidance!

thankyou thankyou!

i'd opt for a hardware solution... have it 'breathe' / fade out (a capacitor, transistor, resistor)

that gives me an idea :slight_smile:

well, this way works at the moment, but its quite twitchy if i change the fade to more than 1. and 1 is a little too slow.

i would do a hardware only version, but i want to be able to change the fade times, and also to run demo patterns when not in use.

static int lastBrightness = 0;
if (ir2 < lowsetting1) {
   if (lastBrightness > 0)
      lastBrightness --;  // Dim the light til it reaches 0
   if (lastBrightness > 0)
      lastBrightness --;  // Dim the light twice as fast
}  else {
   lastBrightness = bright2; //  Set the brightness to match distance
}
   analogWrite(led2, lastBrightness);

kelvinmead:
well, this way works at the moment, but its quite twitchy if i change the fade to more than 1. and 1 is a little too slow.

Linear fade is rubbish anyway. Things like this work much better:

brightness -= brightness/4;

i did set a variable for the fade time, then did
lastBrightness -x;

but anything above 2, the led would stick on, or weirdly, drop to 0 and then flash at full brightness.

i did think that it was interpreting negative numbers incorrectly, so i added a

if (lastBrightness < 0)
lastBrightness = 0;

but not much fun was had!

maybe it needs an

if (lastBrightness < 0)
lastBrightness == 0;

Linear fade is rubbish anyway. Things like this work much better:

brightness -= brightness/4;

[/quote]

how do interpret this?

brightness when negative = brightness / 4

or

when brightness is decreasing / 4

kelvinmead:

brightness -= brightness/4;

how do interpret this?

The "X -= Y;" operation is shorthand for "X = X - Y;" so the expression above means:

brightness = brightness - (brightness/4);  // Reduce brightness by 1/4

kelvinmead:

fungus:
Linear fade is rubbish anyway. Things like this work much better:

brightness -= brightness/4;

how do interpret this?

brightness when negative = brightness / 4

It's standard C++ code, no interpretation needed. It means:

brightness = brightness - (brightness/4);

ok, so i've got this bad boy working how it should be, and i've gone for a more streamlined way of getting the fade, by multiplying by a sub 1 integer... basically, getting a percentage fade;
50%
256, 128, 64, 32, 16, 8, 4, 2, 1

75%
256, 192, 144, 108, 81, 61, 45, 34

which is really easy to control, and gives a nice fade...

but it leads me into another slight issue, but i've a feeling its not overly easy to fix.

when i get down to low levels of light, the leds are noticeably flickery... not a massive issue, but noticeable enough to take the professional look away from it. if i was to 10% frost you wouldn't notice...

just wondering if anyone else has a better solution.

ok, i know why this doesn't work, what i don't know is how to make it work!

this is the layout for setting the fade1 integer

[code]

int fade1 = 0.9;

void setup ()

void loop ()

and here is the chunk of code it refers to;

  static int lastBright1 = 0;                 // set the lastbright variable
if (ir1<lowsetting1) {                         // check to see if the ir is detecting above the base level 
  analogWrite(led1, LOW);                 // turn the led off
      if (lastBright1 > 0)                      // check to see if the last brightness is more than 0 
      lastBright1 = lastBright1 * fade1;  // Dim the light til it reaches 0
}  else {                              
  lastBright1 = max1;                        //  Set the brightness to match distance
}
  if (lastBright1 < lowestbrightness) {  // check to see if the led has got to a low level
    lastBright1 = 0;                           // then turn the led off
  }
  analogWrite(led1, lastBright1);       // write the brightness to the led

[/code]

if i change the lastBright1 = lastBright1 * 0.9 i get the desired fade

if i set a static int for fade1 just before the if(), it treats it as * 1 (no fade)

if i take the int out of the void loop () then i get the error not declared in scope, which i know is to do with setting a variable outside the if / else brackets.

no matter where i seem to plonk the int, it won't seem to take reference.

i know its a silly error!

int fade1 = 0.9;

I'm surprised it doesn't set fade1 to 0. Floats are generally truncated (not rounded) when stored in an integer.

how do i solve this? leave as a fraction like;

int x = 9;
int fade1 = (1/10)*x;

im looking for an easy way to adjust the fade speed, without just referring to many cases

i think i will eventually map a pot to adjust the fade.

yup, keeping the 0.9 as a fraction works!

simple things eh!

kelvinmead:
when i get down to low levels of light, the leds are noticeably flickery... not a massive issue, but noticeable enough to take the professional look away from it. if i was to 10% frost you wouldn't notice...

just wondering if anyone else has a better solution.

the blinking serial monitor!

I'm displaying lots of useful information, and i start up the serial monitor everytime so i can see the numbers changing... im getting real close to everything running smoothly so i dont start up comment out the serial monitor and bang! all the fading now runs 3 times as fast and its real smooth!

you live and learn eh... now i've just gotta slow down the fading some more! lol

every silver lining has a cloud eh?

Still thinks you should have gone for a hardware version ]:slight_smile:

if i had, i couldn't have had different settings for fade in, fade out, length of fade and random patterns (easily) if i had gone hardware only...

...which was always the objective!