Any hints how I can make the power button make the led full brightness

Hello,

IM finally at the last challenge of the McWorther course where I have to do this :

When you press the power button , the RGB led needs to be white full brightness
When you press the undo button, the RGB led needs to be off.
When you press the 1 button, the RGB led needs to be red

So far no problems.

but now it getting a little hard for me

When you press the |<< button the brightness must be less but when you press the power button , the white needs to be full bright
and when I choose another button for another color, the brightness must stay the same.

Any hints how I can achieve this ?

Project so far : https://wokwi.com/projects/454673983435304961

I would guess all your answers are in the instructions (the person has been doing Arduino instruction for some years), so, include a link to the instructions.

add a 4th parameter which is the brightness on top of the R, G and B Values.

You then need a function that takes the theoretical R, G and B and the expected brightness and make some adjustment. A function like this could possibly work

void adjustedRgbForBrightness(uint8_t r, uint8_t g, uint8_t b, uint8_t targetBrightness,
  uint8_t &outR, uint8_t &outG, uint8_t &outB)
{
  float currentBrightness = 0.299f * r + 0.587f * g + 0.114f * b;
  if (currentBrightness == 0) {
    outR = outG = outB = 0;
    return;
  }
  float scale = targetBrightness / currentBrightness;

  int tempR = r * scale;
  int tempG = g * scale;
  int tempB = b * scale;

  outR = tempR > 255 ? 255 : tempR;
  outG = tempG > 255 ? 255 : tempG;
  outB = tempB > 255 ? 255 : tempB;
}

The formula for brightness uses the weighted sum 0.299*R + 0.587*G + 0.114*B because human vision is more sensitive to green light, less to red, and even less to blue

That is cool. 3:6:1... i was visually happy with 1:1:1 for increasing/decreasing "white"

The coefficients 0.299 for red, 0.587 for green, and 0.114 for blue come from the ITU-R BT.601 standard (quite old - formalized in 1982) where they defined the luminance component (Y) for standard-definition television.

They were derived from measurements of human visual sensitivity, specifically the photopic luminosity function, which quantifies how the human eye perceives brightness at different wavelengths.

oke

So I can use then 255 for full brightness of the white and a lower number for the rest of the colors ?

You maintain R,G, B and Y (for the brightness) but when updating the led, you call the function to get the adjusted r, g, b

bringing back full brightness Y = 255
lowering the brightness Y = (Y-1); (as Y is a uint8_t it will circle back to 255 if you go below 0)
increasing the brightness Y = (Y+1); (as Y is a uint8_t it will circle back to 0 if you go above 255)

oke,

So this is what you mean

#include <IRremote.hpp>

const byte irReceivePin = 2;

const byte rPin = 9;
const byte gPin = 6;
const byte bPin = 5;

int brightness = 255; 

byte r, g, b;
byte outR, outG, outB;

void adjustedRgbForBrightness(uint8_t r, uint8_t g, uint8_t b, uint8_t targetBrightness,
  uint8_t &outR, uint8_t &outG, uint8_t &outB)
{
  float currentBrightness = 0.299f * r + 0.587f * g + 0.114f * b;
  if (currentBrightness == 0) {
    outR = outG = outB = 0;
    return;
  }
  float scale = targetBrightness / currentBrightness;

  int tempR = r * scale;
  int tempG = g * scale;
  int tempB = b * scale;

  outR = tempR > 255 ? 255 : tempR;
  outG = tempG > 255 ? 255 : tempG;
  outB = tempB > 255 ? 255 : tempB;
}


void handleCommand() {
 if (IrReceiver.decode()) {
    switch (IrReceiver.decodedIRData.decodedRawData) {
      case 0x5DA2FF00 : 
        adjustedRgbForBrightness(255, 255, 255, brightness, outR, outG, outB);
        break; // POWER for full bright white
      case 0x3DC2FF00 :
         adjustedRgbForBrightness(0, 0, 0, 0, outR, outG, outB);
         break; // undo for all lights off
      case 0xCF30FF00 :
           adjustedRgbForBrightness(255, 0, 0, brightness, outR, outG, outB);
         break; //  1 button for red
      case 0X1FE0FF00:
        if (brightness > 0) {
          brightness--; 
        }
        break; 
      default: break;
    }
    
    analogWrite(rPin,outR);
    analogWrite(gPin, outG);
    analogWrite(bPin, outB);
    IrReceiver.resume();
  }
}

void setup() {
  pinMode(rPin, OUTPUT);
  pinMode(gPin, OUTPUT);
  pinMode(bPin, OUTPUT);

  Serial.begin(115200);
  IrReceiver.begin(irReceivePin);
  Serial.println(F("Ready"));
}

void loop() {
  handleCommand();
}

if 0x5DA2FF00 is POWER, we usually put the comment there, not after the break

      case 0x5DA2FF00 : // POWER means full bright white
        adjustedRgbForBrightness(255, 255, 255, brightness, outR, outG, outB);
        break; 

and in that case if it's full bright then you need to change brightness

      case 0x5DA2FF00 : // POWER means full bright white
        brightness = 255;
        adjustedRgbForBrightness(255, 255, 255, brightness, outR, outG, outB);
        break; 

also I would keep track of the original r, g, b so more something like

#include <IRremote.hpp>

const byte irReceivePin = 2;

const byte rPin = 9;
const byte gPin = 6;
const byte bPin = 5;

byte brightness = 255;

byte r, g, b;
byte outR, outG, outB;

void adjustedRgbForBrightness(uint8_t r, uint8_t g, uint8_t b, uint8_t targetBrightness,
                              uint8_t &outR, uint8_t &outG, uint8_t &outB)
{
  float currentBrightness = 0.299f * r + 0.587f * g + 0.114f * b;
  if (currentBrightness == 0) {
    outR = outG = outB = 0;
    return;
  }
  float scale = targetBrightness / currentBrightness;

  int tempR = r * scale;
  int tempG = g * scale;
  int tempB = b * scale;

  outR = tempR > 255 ? 255 : tempR;
  outG = tempG > 255 ? 255 : tempG;
  outB = tempB > 255 ? 255 : tempB;
}


void handleCommand() {
  if (IrReceiver.decode()) {
    switch (IrReceiver.decodedIRData.decodedRawData) {
      case 0x5DA2FF00 : // POWER for full bright white
        r = 255; g = 255; b = 255; brightness = 255;
        break;

      case 0x3DC2FF00 : // undo for all lights off
        r = 0; g = 0; b = 0; brightness = 0;
        break;

      case 0xCF30FF00 ://  1  for red, (don't change brightness ?)
        r = 255; g = 0; b = 0;
        break;

      case 0X1FE0FF00: // a comment is needed here
          brightness--;
        break;

      default: break;
    }
    
    adjustedRgbForBrightness(r, g, b, brightness, outR, outG, outB);
    analogWrite(rPin, outR);
    analogWrite(gPin, outG);
    analogWrite(bPin, outB);
    IrReceiver.resume();
  }
}

void setup() {
  pinMode(rPin, OUTPUT);
  pinMode(gPin, OUTPUT);
  pinMode(bPin, OUTPUT);

  Serial.begin(115200);
  IrReceiver.begin(irReceivePin);
  Serial.println(F("Ready"));
}

void loop() {
  handleCommand();
}

(typed here)

oke

but it is then not , that if I change the brightness it also changes for the white.
That is not the challenge as I understand it.

As far as I understand the brightness needs to change for all colors except when you press the power button. then it always needs to be full bright.

When you change to another color, which I have to implement, then the "last" brightness needs to be used.

and if i want to increase the brightness do I need a check that the brightness cannot be above 255?

when I do this for red, I don't touch the brightness variable, so whatever it its, it stays.

but when I do

then I go full white and full brightness.

➜ do you mean that going full white should be full white but then not influence the existing brightness for the others ?

I changed the type to byte, so it's always going to be between 0 and 255 and if you do 255+1 it goes back automatically to 0.

oke,

Then I think I can implement the decrease function and the other 5 colors

yeah, just do it and see if it works to your liking

Done :

the only thing I would change is that if you change color it fades to the next color.
But that is pure looks.

I hope I did a good job and ready for some more difficult challenges.

give it a try

oke

First some googling to see how to approach this.

I think the easies way would be to use an Hue Saturation Brightness model (HSB) rather than RGB.

Only convert the HSB value to RGB at the very end when you want to address the LED's pins.

this way ramping Brightness is straight, and going from one Hue to the next is also a simple interpolation over time.

there are also an infinite number of path to go from one color to another - you'll have to decide on that too.

oke

Then I have to find out what the HSB values of the colors are.
and how I can use them in the output

yes. study a bit the color models and what they offer.