Understanding Math

In the Fade sketch from the example sketches. is this piece of code:

/*
 Fade

 This example shows how to fade an LED on pin 9
 using the analogWrite() function.

 The analogWrite() function uses PWM, so if
 you want to change the pin you're using, be
 sure to use another PWM capable pin. On most
 Arduino, the PWM pins are identified with 
 a "~" sign, like ~3, ~5, ~6, ~9, ~10 and ~11.

 This example code is in the public domain.
 */

int led = 9;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // set the brightness of pin 9:
  analogWrite(led, brightness);

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);
}

Simple enough till I get to this part

 if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ;

So brightness = 0 or brightness = 255 then fadeamount = -fadeamount

My question is why doesn't the fadeamount start at -5 and stay at -5. I don't see how to get to +5.

-(-5) = 5

I know I'm going to sound like a dunce.

If fadeamount which is set at 5 now I change it to -5

Now fadeamount = -5 so i set it to -5 again.

I'm reading this as

+5 = -5 then -5 = -5 I know in math -5 + -5 = +10. But is not math??? Or am I looking to deep into this?

It's pre-algebra. I gave you all you needed to know in reply #1. If fadeamount happens to be -5, then -fadeamount will be -(-5). Which is 5.

When fadeamount is +5, the value goes up till it gets to 255 then fadeamount becomes -fadeamount so it's now -5.

So then it goes down until it gets to 0, when fadeamount becomes -fadeamount again, but it's -5 at the moment so -(-5) is +5 so it goes up again.

edit.... think of...

fadeamount = -fadeamount

as...

fadeamount = -1 * fadeamount

.... ie, just change the sign from + to - or - to +

Now that I can understand Thanks

It's bad programming, because think about what happens if fadeamount is = 7.

Just before the reverse direction, if you coerce the value of brightness to be within 0 to 255, then it won't matter what value is used for fadeAmount, the direction change will not cause the brightness go out of range. The result is smooth fading at the up/down transitions.

This will coerce fadeAmount to 0-255 range:

brightness = brightness < 0 ? 0 : brightness > 255 ? 255 : brightness;

Add just before the reverse direction part, test using various values of fadeAmount.

Delta_G Thank you. I was up till 3am my time working on this. I am still trying to learn the language of the Arduino. You are correct, my fault.

But I had some sleep so I'm at it again.

The constraint approach seems too obfuscated to me. I'd rather use the KISS principle. As a bonus, it's easy to have different fade in and fade out rates...

//...
  // set the brightness of pin 9:
  analogWrite(led, brightness);

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness > 255)
  {
    brightness = 255;
    fadeAmount = -13 ;
  }
  else if (brightness < 0)
  {
    brightness = 0;
    fadeAmount = 7 ;
  }
//...

Just to mention that KISS approach has the exact same constraints, in fact, expanding the nested ternary gives the same code. However, I agree using the if/else format easier to follow, easier to add more options.

Sometimes I use the ternary if that all that's needed and its commented appropriately.

Now all that's left is an algorithm to adjust for the human eye's response to brightness...

dlloyd:
Just to mention that KISS approach has the exact same constraints, in fact, expanding the nested ternary gives the same code. However, I agree using the if/else format easier to follow, easier to add more options.

Sometimes I use the ternary if that all that's needed and its commented appropriately.

Now all that's left is an algorithm to adjust for the human eye's response to brightness...

Ooh, actually before we go there, it's also best to use the smallest step possible to get the smoothest brightness steps. Namely 1. The 30 millisecond delay is what should change, in order to alter the rate in this simple implementation. So forget what I wrote. :slight_smile:

An implementation that takes into account the gamma or whatever, should also only modify the delays.

But I think there might be a problem with calling analogWrite too frequently. I recall from way back, that the PWM pulses can't stay synchronous with the pulses that were running from the previous call. This means that if it's called too often a beat frequency might be created. I'll have to investigate.

But it goes without saying that an example sketch is supposed to be simple. It should definitely not trot out anything that is unreliable.