Radio button behavior with fancy features

Hi Everyone!

I have a box with three LED's and three buttons. I want to implement radio button behavior, meaning if light_A is on and I press button_B, I want light_A to go off and light_B to come on. One light on at a time.

I also want to make it so that it looks like the lights are really hot. So, when a light turns off, it will dim out rather than turn right off. Something like below

for (val=255; val >=0; val--){
        analogWrite(myLED, val);
        delay(fadeDelay);
}

I am dying here tying to figure it out. I can't call that fade function haphazardly, because lights that are currently off would go through the fade routine.

I try to write my routine, and I keep getting to WAY TOO MUCH repeated code, nuking it, and starting from scratch.

I have a feeling one of you arduino champions out there knows how to do this in a few lines using binary, bitwise AND / OR behavior, and bitmasks (or something like that. Maybe arrays?).

If I figure it out first I will update, but please share your magic

Good news! I have a radio button sketch in the playground, it's nothing fancy, but it should work.. Here you go. RadioButtons

A couple of thoughts...

The Right Way to do the fade is like blinkwithoutdelay. I wrote this in like 3 minutes off the top of my head; expect typos and syntax errors.

#define fadeDelay 10
long nextFadeAt=0;
byte fadeStep;
byte fadeLED;

void loop(){

if (millis() > nextFadeAt && nextFadeAt !=0 ) { //use nextFadeAt=0 to signal no fading to do.
analogWrite(fadeLED,fadeStep);
if fadeStep==0 {
nextFadeAt=0;
} else {
fadeStep--;
nextFadeAt=millis()+fadeDelay;
}
}

void startFade(led){
if (nextFadeAt) { //if another fade is still in progress
digitalWrite(fadeLED,0); //turn the LED all the way off
}
fadeLED=led; //set the LED we want to fade
fadeStep=255; //start at full brightness
nextFadeAt=millis();
}

You could certainly do it the way you're trying to do (with a for loop with delay() in it), and call that function when you turn off a LED, but that would block until it finishes fading the LED, which is probably undesirable.

The hardware way to do this is to put a cap across the LED, and play with the value of the cap until it fades like you want it to.

Along the lines of what @DrAzzy has said, I would have a variable to hold the level of each of the 3 LEDs and the state of the 3 LEDs

byte ledLevel[3];
byte ledState[3]

And I would have a function that switches on the LEDs depending on the level

void lightLeds() {
   for (n = 0; n < 3; n++) {
      analogWrite(ledPin[n], ledLevel[n];
   }
}

Then I would use the code from the button to set the value of the appropriate ledLevel.

For example if button1 is pressed then ledState[1] = 1 and the other will be set to 0.

And I would then apply the fade code in the case of any LED whose state was 0 and whose level was greater than 0. Something like

void fadeLedLevels() {
   for (n = 0; n < 3; n++) {
       if (ledState[n] == 0 && ledLevel[n] > 0) {
            ledLevel[n] = ledLevel[n] - fadeStep;
       }
   }

}

And the whole code would be structured something like this

void loop() {
  readButtons();
  updateLedState();
  fadeLedLevels();
  lightLeds();
}

...R