Switch between color/brightness with rotary encoder for Nano (RGB LED Strip)

Hello all,
I am new to this form so thanks for any input you may be able to give to a noobie.
I am having a little bit of trouble with the code that would be required to switch between controlling color and controlling brightness with a rotary encoder. I am using the click button on the encoder to do the switching but right now I have to hold the button down to control color, else the brightness is controlled. I would like to be able to switch over to controlling the color with just a single click, and then click again to return to controlling brightness.

Here is the code that I have currently:

//rotary encoder inputs
int EN_PIN_BUTTON = 5;
int EN_PIN_A = 6;
int EN_PIN_B = 7;

//Led Outputs
int greenled = 9;
int redled = 10;
int blueled = 11;

int brightnessLevel = 0;
int Color = 0;

int Red = 0;
int Green = 0;
int Blue = 0;

//EN_PIN_A current state and last state
int aState;
int aLastState;

void setup() {
  pinMode (EN_PIN_A, INPUT);
  pinMode (EN_PIN_B, INPUT);
  pinMode (redled, OUTPUT);
  pinMode (greenled, OUTPUT);
  pinMode (blueled, OUTPUT);
  Serial.begin (9600);

  brightnessLevel = 250; //initial brightness

  Color = 35; //initial color

  aLastState = digitalRead(EN_PIN_A);

void loop() {

// switching between color and brightness
   if (digitalRead(EN_PIN_BUTTON) == LOW) {
          aState = digitalRead(EN_PIN_A);
       if (aState != aLastState) {
        if (digitalRead(EN_PIN_B) != aState) {
          Color += 1;
          } else {
           Color -= 1;
   } else {
          aState = digitalRead(EN_PIN_A);
       if (aState != aLastState) {
        if (digitalRead(EN_PIN_B) != aState) {
          brightnessLevel += 10;
          } else {
           brightnessLevel -= 10;
    brightnessLevel = constrain (brightnessLevel, -255, 250);

//define color functions
     Red =  255 * sin(0.1 * Color - 2 * 3.14159265 / 3) + brightnessLevel;
     Green = 255 * sin(0.1 * Color) + brightnessLevel;
     Blue = 255 * sin(0.1 * Color + 2 * 3.14159265 / 3) + brightnessLevel;
     Red = constrain(Red, 0, 250);
     Green = constrain(Green, 0, 125);
     Blue = constrain(Blue, 0, 125);
// Write color to outputs
     analogWrite(redled, Red);
     analogWrite(greenled, Green);
     analogWrite(blueled, Blue);
  aLastState = aState;


I hope this all makes sense. Thanks in advance for the help!

You need additional variables: previousButtonCondition, encoderFunction.

  • read condition of button
  • if button is pressed and previous condition is depressed, toggle encoder function
  • write condition of button to previous condition variable

  • do your "if" loop, but not with reading button, instead use encoder function.

Do you understand?

Im not sure I understand how to toggle the state. I can detect the button change from unpressed to pressed, but i don't know what to write to toggle the function state.

encoderFunction = !encoderFunction;

This command will change TRUE to FALSE or vice versa.

Ah I see. So assign it as either "true" or "false" in the "Void Setup()" first and then inside the loop write something like:

void loop(){
    buttonState = digitalRead(en_pin_button);
    if (buttonLastState == HIGH) && (buttonState == LOW) {
        encoderFunction = !encoderFunction;


That's right. In the rest of the code that you already have, instead of reading state of the button, use encoderFunction for decision if rotary encoder will change brightness or color.

Awesome! Thanks for the help! just tested and it is working!

I'm glad :-)

This is almost what i'm looking for..... :wink:

But instead of a RGB LED strip I want to use a addressable RGB Led Strip (like WS2812B or WS2813)

So I do not have 3 Led Outputs, but just one. Search for day's all over the internet, but this is as close as i get...... Unfortunately I am a complete noob when it comes to programming.

Is there someone who can help me?

jaysonmilroy: Awesome! Thanks for the help! just tested and it is working!

Any chance you can post the final working code?