Lack of skills, need a better solution.

My project is rushing forward, today's fun was to include the rotary encoder.

The goal for this (my first Arduino project) was: Control three pwm outputs to dim LED lights in the Saloon, the riggings and some RBG LED stripes. Include a 2x16 char display. Use a rotary encoder with push button to select and change all values.

Everything works as it is but sometime the encoder misses a click, it was as cheap as cheap can get so it could be the quality or lack there of. :)

I've found the encoder-code http://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino and got it to work but I've several questions.

tmpdata counts four times each tick. Surely there must be a better solution to reduce that to one tick than this below?

 tmpdata = read_encoder();
  if(tmpdata) 
  {
    if(tmpdata == 1)
    {
      leftOrRight++;
    }
    if (leftOrRight == 4)
    {
      leftOrRight = 0;
      toRight = 1; // knob turned CCW      
    }
    if (tmpdata == -1)
    {
      leftOrRight--;
    }
    if (leftOrRight == -4)
    {
      leftOrRight = 0;
      toLeft = 1; // knob turned CCW

    }
  }

This below is the full code. What could I've done different to save precious resources?

Please remember that I started to play with Arduino last week and that I've never programmed in C before. :-/

The code was to large, will try to part it.

#include <LiquidCrystal.h>

#define ENC_A 14 //define analog pins 0 for encoder
#define ENC_B 15 //define analog pins 1 for encoder
#define ENC_PORT PINC // ***Don't know what this is!***

// select the pins used on the LCD panel
LiquidCrystal lcd(13, 12, 8, 4, 7, 2);

int pwmLevelStream1 = 8; //lightsource 1
int pwmLevelStream2 = 8; //lightsource 2
int pwmLevelStream31 = 8; //lightsource 31 (only red)
int pwmLevelStream32 = 8; //lightsource 32 (combined RGB)
int colorRGB1 = 0; // red light as default

int outputValue1;        // value output to PWM#1 (analog out)
int outputValue2;        // value output to PWM#2 (analog out)
int outputValue31;       // value output to PWM#3 (analog out) Red
int outputValue32;       // value output to PWM#3 (analog out) Combined RGB
int pushEncoderState = 0;  // high / low state
int lastPushEncoderState = 0;  //high or low last loop
int encoderPushed = 0;  //encoderPushed is set high by pushEncoderState & lastPushEncoderState
int selectedMenu = 1;  //the active menu set to 1 (default menu)
int leftOrRight = 0;  // counts four ticks to set toLeft or toRight
int toLeft = 0;      //rather bad solution, 
int toRight = 0;      //need a better one!

const int pushEncoderPin = 11; // pushbutton on encoder
const int analogOutPin1 = 5; // Analog output pin that the PWM-controlled LED#1 is attached to
const int analogOutPin2 = 3; // Analog output pin that the PWM-controlled LED#2 is attached to
const int analogOutPin3 = 6; // Analog output pin that the PWM-controlled RGB-LED (GREEN) is attached to
const int analogOutPin4 = 9; // Analog output pin that the PWM-controlled RGB-LED (BLUE) is attached to
const int analogOutPin5 = 10; // Analog output pin that the PWM-controlled RGB-LED (RED) is attached to
const byte brightnessLookup [] = {
  0, 1, 3, 8, 14, 20, 27, 35, 44, 55, 69, 86, 107, 133, 165, 206, 255}; // array for brightnesslookup
const byte brightnessLookupRGB [] = {
  0, 1, 4, 9, 14, 20, 27, 35, 44, 55, 69, 86, 107, 133, 165, 206, 254}; // array for the inverted brightnesslookup


/*
code from http://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino
works like a charm, thank you Oleg!
*/

/* returns change in encoder state (-1,0,1) */
int8_t read_encoder()
{
  static int8_t enc_states[] = {
    0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0            };
  static uint8_t old_AB = 0;
  /**/
  old_AB <<= 2;                   //remember previous state
  old_AB |= ( ENC_PORT & 0x03 );  //add current state
  return ( enc_states[( old_AB & 0x0f )]);
}

void setup()
{
  TCCR1A = B11110001; // set fast pwm and invert pwm output for pin 9 & 10
  TCCR1B = B00001011; // set fast pwm and invert pwm output for pin 9 & 10
  TCCR0A = B11000011; // set fast pwm and invert pwm output for pin 6
  TCCR0B = B00000011; // set fast pwm and invert pwm output for pin 6
  lcd.begin(16, 2);              // start the library
  pinMode(ENC_A, INPUT); //set up encoder a
  digitalWrite(ENC_A, HIGH); //set up encoder a
  pinMode(ENC_B, INPUT); //set up encoder b
  digitalWrite(ENC_B, HIGH);//set up encoder b
  pinMode(pushEncoderPin, INPUT); //set up encoder push button
}

void loop()
{

  static uint8_t counter = 0;      //this variable will be changed by encoder input
  int8_t tmpdata;
   
/* Code between ### works but feels somewhat bloated, need a better solution here! */
  
/* ### */
  tmpdata = read_encoder();
  if(tmpdata) 
  {
    if(tmpdata == 1)
    {
      leftOrRight++;
    }
    if (leftOrRight == 4)
    {
      leftOrRight = 0;
      toRight = 1; // knob turned CCW      
    }
    if (tmpdata == -1)
    {
      leftOrRight--;
    }
    if (leftOrRight == -4)
    {
      leftOrRight = 0;
      toLeft = 1; // knob turned CCW

    }
  }
/* ### */

  pushEncoderState = digitalRead(pushEncoderPin); // read state for encoder push button
  if (pushEncoderState != lastPushEncoderState) // has the state changed?
  {
    if (pushEncoderState == HIGH) { // if state is HIGH set
      encoderPushed = 1; //encoderPushed to 1
    }
  }

  switch (selectedMenu) { //menu system
    
  case 1:
    lcd.setCursor(0,0); //set cursor position and write text to display
    lcd.print("Saloon Light"); //
    lcd.setCursor(0,1); //
    lcd.print(" "); //
    lcd.print(pwmLevelStream1); //
    lcd.print("             "); //
    if (toRight == 1) { // handle encoder turns to change active menu page to 
      selectedMenu = 2; // the one next in line to the right
    }      
    if (toLeft == 1) { // handle encoder turns to change active menu page to 
      selectedMenu = 3; // the one next in line to the left
    }      
    if (encoderPushed == 1) { // pushbutton is used to select the active menu
      selectedMenu = 11; // the under menu below menu 1
    }
    break;

  case 2:
    lcd.setCursor(0,0);  // see comments above
    lcd.print("Spreader Light");
    lcd.setCursor(0,1);
    lcd.print(" ");
    lcd.print(pwmLevelStream2);
    lcd.print("             ");
    if (toRight == 1) {
      selectedMenu = 3;
    }
    if (toLeft == 1) {
      selectedMenu = 1;
    }    
    if (encoderPushed == 1) {
      selectedMenu = 21;
    }
    break;

  case 3:
    
    lcd.setCursor(0,0);
    lcd.print("Night Light    ");
    lcd.setCursor(0,1);
    lcd.print(" ");
    if (colorRGB1 == 0) { // if RGB is set to 0 (red) 
    lcd.print(pwmLevelStream31); // print value for red
    }
    if (colorRGB1 == 1) { // if RGB is set to 1 (white) 
    lcd.print(pwmLevelStream32); // print value for white
    }
    lcd.print("             ");    
    if (toRight == 1) {
      selectedMenu = 1;
    }      
    if (toLeft == 1) {
      selectedMenu = 2;
    }
    if (encoderPushed == 1) { // set selectedMenu depending on colorRGB
      if (colorRGB1 == 0) {
        selectedMenu = 31;
      }
      if (colorRGB1 == 1) {
        selectedMenu = 32;
      }
    }
    break;

  case 11:
    lcd.setCursor(0,0);
    lcd.print("Saloon Light");
    lcd.setCursor(0,1);
    lcd.print("Dimmer ");
    lcd.print(pwmLevelStream1);
    lcd.print("       ");
    if (toRight == 1) {
      if (pwmLevelStream1 < 16) { // increase pwmLevelStream1 
        pwmLevelStream1++;  // up to 16
      }
    }      
    if (toLeft == 1) {
      if (pwmLevelStream1 > 1) { // decrease pwmLevelStream1
        pwmLevelStream1--; // not below 1
      }
    }      
    if (encoderPushed == 1) {
      selectedMenu = 1;
    }
    break;

  case 21:
    lcd.setCursor(0,0);
    lcd.print("Spreader Light");
    lcd.setCursor(0,1);
    lcd.print("Dimmer ");
    lcd.print(pwmLevelStream2);
    lcd.print("       ");
    if (toRight == 1) {
      if (pwmLevelStream2 < 16) {
        pwmLevelStream2++;
      }
    }      
    if (toLeft == 1) {
      if (pwmLevelStream2 > 1) {
        pwmLevelStream2--;
      }
    }      
    if (encoderPushed == 1) {
      selectedMenu = 2;
    }
    break;

  case 31:
    colorRGB1 = 0; // set colorRGB to red
    lcd.setCursor(0,0);
    lcd.print("Night Light    ");
    lcd.setCursor(0,1);
    lcd.print("      Red       ");
    if (toRight == 1) {
      selectedMenu = 32;
    }      
    if (toLeft == 1) {
      selectedMenu = 32;
    }      
    if (encoderPushed == 1) {
      selectedMenu = 33;
    }
    break;

  case 32:
    colorRGB1 = 1; // set colorRGB to white
    lcd.setCursor(0,0);
    lcd.print("Nightlight durk ");
    lcd.setCursor(0,1);
    lcd.print("      White     ");
    if (toRight == 1) {
      selectedMenu = 31;
    }      
    if (toLeft == 1) {
      selectedMenu = 31;
    }      
    if (encoderPushed == 1) {
      selectedMenu = 34;
    }
    break;

  case 33:
    lcd.setCursor(0,0);
    lcd.print("Night Light red  ");
    lcd.setCursor(0,1);
    lcd.print("Dimmer ");
    lcd.print(pwmLevelStream31);
    lcd.print("       ");
    if (toRight == 1) {
      if (pwmLevelStream31 < 16) {
        pwmLevelStream31++;
      }
    }      
    if (toLeft == 1) {
      if (pwmLevelStream31 > 1) {
        pwmLevelStream31--;
      }
    }      
    if (encoderPushed == 1) {
      selectedMenu = 3;
    }
    break;

  case 34:
    colorRGB1 = 1;
    lcd.setCursor(0,0);
    lcd.print("Night Light White");
    lcd.setCursor(0,1);
    lcd.print("Dimmer ");
    lcd.print(pwmLevelStream32);
    lcd.print("       ");
    if (toRight == 1) {
      if (pwmLevelStream32 < 16) {
        pwmLevelStream32++;
      }
    }      
    if (toLeft == 1) {
      if (pwmLevelStream32 > 1) {
        pwmLevelStream32--;
      }
    }      
    if (encoderPushed == 1) {
      selectedMenu = 3;
    }
    break;
  }
  outputValue1 = brightnessLookup [pwmLevelStream1 & 0x1f] ; // get outputValue from array
  outputValue2 = brightnessLookup [pwmLevelStream2 & 0x1f] ; // get outputValue from array
  outputValue31 = brightnessLookupRGB [pwmLevelStream31 & 0x1f] ; // get outputValueRGB from array
  outputValue32 = brightnessLookupRGB [pwmLevelStream32 & 0x1f] ; // get outputValueRGB from array

  analogWrite(analogOutPin1, outputValue1); // set pwm for analogOutPin1 to outputValue1
  analogWrite(analogOutPin2, outputValue2); // set pwm for analogOutPin2 to outputValue2

  if (colorRGB1 == 0) // if colorRGB is red
  {
    analogWrite(analogOutPin5, outputValue31); // red value
    analogWrite(analogOutPin3, 255); //do not lit green and blue
    analogWrite(analogOutPin4, 255);
  }
  else
  {
    analogWrite(analogOutPin3, outputValue32); //use the "white" value for 
    analogWrite(analogOutPin4, outputValue32); // all colors
    analogWrite(analogOutPin5, outputValue32); // not really white light to me though
  }
  lastPushEncoderState = pushEncoderState; // reset lastPushEncoderState for next loop
  encoderPushed = 0; // reset encoderPushed
  toLeft = 0; //reset toLeft
  toRight = 0; //reset toRight
}

How is the encoder connected to the Arduino? The read_encoder function does not seem to tell you whether the encoder has moved, or not. Or, at least you don't appear to be reacting as though it was telling you that.

What kind of name is leftOrRight? What am I supposed to infer from that name that I am not?

What kind of name is tmpData? I certainly would not expect a variable of that name to contain encoder change information.

Meaningful names are important.

Some nesting of the if tests and proper use of else if would shorten the code.

Just a wild guess but since this is a mechanical rotary encoder you might be getting switch bounce which might explain why you get 4 counts per detent.

Take the simple sketch from where you got the encoder code and do some tests to see if you need to debounce it.

PaulS: How is the encoder connected to the Arduino? The read_encoder function does not seem to tell you whether the encoder has moved, or not. Or, at least you don't appear to be reacting as though it was telling you that.

The read_encoder function works like a charm. I do not understand the magic of it but it does work. For some, for me unknown, reason it reads four times each tick on this encoder.

PaulS: What kind of name is leftOrRight? What am I supposed to infer from that name that I am not?

It's named leftOrRight because it alters both if the encoder is turned clockwise and counter clockwise. I guess I could have called it theEncoderHasMoved or something too. ;)

PaulS: What kind of name is tmpData? I certainly would not expect a variable of that name to contain encoder change information.

Meaningful names are important.

That kind of name the original poster of that code gave, I do not fully understand that part of the code.

PaulS: Some nesting of the if tests and proper use of else if would shorten the code.

I will try to clean that up some, thank you for your time!

justone: Just a wild guess but since this is a mechanical rotary encoder you might be getting switch bounce which might explain why you get 4 counts per detent.

Take the simple sketch from where you got the encoder code and do some tests to see if you need to debounce it.

I do not think it's due to bouncing. It's always exactly four counts each tick. The original coder mentioned something about "divide by four" but that does not work (or I am too stupid to manage to make it work).

You did say that sometimes you miss an encoder tick and that it takes four counts for each tick. Hmmmm -maybe there wasn't four counts when you "missed the tick". Now how would you go about to see if this is happening? Maybe blink an led the actual "count" value.

justone: You did say that sometimes you miss an encoder tick and that it takes four counts for each tick. Hmmmm -maybe there wasn't four counts when you "missed the tick". Now how would you go about to see if this is happening? Maybe blink an led the actual "count" value.

I've monitored the ticks in serial monitor and it looks like they all show up there. I think its a quality problem, if I press the shaft slightly or pull out it some it never misses the tick. I guess that is what one get for US$1.35 ;)

Without tracing through all the code I can see that the encoder is reading 2 binary states to find 4 positions. 2 bits can count 0 to 3.

I’ve seen this done inside trackball mice, it is very ingenious. Those have a spoke wheel with equally wide spoke and spaces to block or pass light and 2 light-interrupt elements set so that when one is totally blocked or open the other is half blocked/half open. Most all of the time neither is exactly 100% blocked or open, the other not exactly 50%. The 2 sensors must be out of phase by 1/2 a spoke width but don’t have to be next to each other.

You get a physical situation where either sensor might be OFF if 0%-49% and ON if 50%-100%. OTOH it could be 0-49 = OFF and 50-100 = ON, doesn’t really matter. But the sensors must read not % but ON or OFF.

I will try and show what happens as the wheel moves:

Start: sensor 1 is fully blocked and sensor 2 is 1/2 open, both read OFF.

Turn: No matter which way the wheel turns, sensor 1 becomes more open. However depending on which direction the wheel turns, sensor 2 becomes either more open or more blocked.

More turn: turned far enough sensor 1 changes from OFF to ON while sensor 2 may stay OFF or also turn ON. Sensor 1 is now 1/2 open while sensor 2 is completely open or blocked - depending on which way the wheel had turned.

This below is crude because the ‘spokes’ are only 4 characters wide but should show the mechanics involved.
I just hope that the format looks the same on everyone’s monitors as they do on mine.

1111_______2222____…1=0%=OFF, 2=50%=ON
XXXX____XXXX____XXXX____XXXX____

1111_______2222____…1=25%=OFF, 2=75%=ON
XXX____XXXX____XXXX____XXXX____… <<===== move

1111_______2222____…1=50%=ON, 2=100%=ON
XX____XXXX____XXXX____XXXX____… <<===== move

1111_______2222____…1=75%=ON, 2=75%=ON
X____XXXX____XXXX____XXXX____… <<===== move

1111_______2222____…1=100%=ON, 2=50%=ON
XXXX____XXXX____XXXX… <<===== move

1111_______2222____…1=75%=ON, 2=25%=OFF
XXXX____XXXX____XXXX_… <<===== move

1111_______2222____…1=50%=ON, 2=0%=OFF
XXXX____XXXX____XXXX__… <<===== move

If moved the other way then just read the lines upward.

Once you know the pattern you can use the changes in state to get direction while every change tells you approximately 1/2 a spoke width distance moved.

Anyway, that or something very like it is what is going on inside your rotary encoder. The code is the changing pattern of 4 combinations of the 2 sensors.

I see. Thank you ever so much for clearing that out. This is a truly remarkable forum, almost everyone is friendly, helpful and clever. ;)

I’ve done some changes, to have a condition to the switch/case really helped to speed up things.

#include <LiquidCrystal.h>

#define ENC_A 14 //define analog pins 0 for encoder
#define ENC_B 15 //define analog pins 1 for encoder
#define ENC_PORT PINC // ***Dunno***

// select the pins used on the LCD panel
LiquidCrystal lcd(13, 12, 8, 4, 7, 2);

int pwmLevelStream1 = 8; //lightsource 1
int pwmLevelStream2 = 8; //lightsource 2
int pwmLevelStream31 = 8; //lightsource 31 (only red)
int pwmLevelStream32 = 8; //lightsource 32 (combined RGB)
int colorRGB1 = 0; // red light as default

int outputValue1;        // value output to PWM#1 (analog out)
int outputValue2;        // value output to PWM#2 (analog out)
int outputValue31;       // value output to PWM#3 (analog out) Red
int outputValue32;       // value output to PWM#3 (analog out) Combined RGB
int pushEncoderState = 0;  // high / low state
int lastPushEncoderState = 0;  //high or low last loop
int encoderPushed = 0;  //encoderPushed is set high by pushEncoderState & lastPushEncoderState
int selectedMenu = 1;  //the active menu set to 1 (default menu)
int activeMenu = 0; //the active menu on the display
int leftOrRight = 0;  // counts four ticks to set toLeft or toRight
int toLeft = 0;      //rather bad solution, 
int toRight = 0;      //need a better one!

const int pushEncoderPin = 11; // pushbutton on encoder
const int analogOutPin1 = 5; // Analog output pin that the PWM-controlled LED#1 is attached to
const int analogOutPin2 = 3; // Analog output pin that the PWM-controlled LED#2 is attached to
const int analogOutPin3 = 6; // Analog output pin that the PWM-controlled RGB-LED (GREEN) is attached to
const int analogOutPin4 = 9; // Analog output pin that the PWM-controlled RGB-LED (BLUE) is attached to
const int analogOutPin5 = 10; // Analog output pin that the PWM-controlled RGB-LED (RED) is attached to
char *StrBrightness[73] = {"0", "0,5", "1,0", "1,5", "2,0", "3,0", "4,0", "5,0", "6,0", "8,0", "10", "12", "14", "16", "18", "20", "25", "30", "35", "40", "45", "50", "55", "60", "65", "70", "75", "80", "85", "90", "95", "100"};
char *StrBrightnessRGB[73] = {"0", "0,5", "1,0", "1,5", "2,0", "3,0", "4,0", "5,0", "6,0", "8,0", "10", "12", "14", "16", "18", "20", "25", "30", "35", "40", "45", "50", "55", "60", "65", "70", "75", "80", "85", "90", "95", "100"};
const byte brightnessLookupRGB [] = {
  0, 1, 2, 3, 5, 8, 11, 14, 17, 20, 23, 27, 31, 35, 39, 44, 49, 55, 62, 69, 77, 86, 96, 107, 120, 133, 146, 165, 185, 206, 230, 254}; // 31-value array for brightnessRGB
const byte brightnessLookup [] = {
  0, 1, 2, 3, 5, 8, 11, 14, 17, 20, 23, 27, 31, 35, 39, 44, 49, 55, 62, 69, 77, 86, 96, 107, 120, 133, 146, 165, 185, 206, 230, 255}; // 31-value array for brightness

/*
code from http://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino
works like a charm, thank you Oleg!
*/

/* returns change in encoder state (-1,0,1) */
int8_t read_encoder()
{
  static int8_t enc_states[] = {
    0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0            };
  static uint8_t old_AB = 0;
  /**/
  old_AB <<= 2;                   //remember previous state
  old_AB |= ( ENC_PORT & 0x03 );  //add current state
  return ( enc_states[( old_AB & 0x0f )]);
}

void setup()
{
  TCCR1A = B11110001; // set fast pwm and invert pwm output for pin 9 & 10
  TCCR1B = B00001011; // set fast pwm and invert pwm output for pin 9 & 10
  TCCR0A = B11000011; // set fast pwm and invert pwm output for pin 6
  TCCR0B = B00000011; // set fast pwm and invert pwm output for pin 6
  lcd.begin(16, 2);              // start the library
  pinMode(ENC_A, INPUT); //set up encoder a
  digitalWrite(ENC_A, HIGH); //set up encoder a
  pinMode(ENC_B, INPUT); //set up encoder b
  digitalWrite(ENC_B, HIGH);//set up encoder b
  pinMode(pushEncoderPin, INPUT); //set up encoder pushbutton
}

void loop()
{

  static uint8_t counter = 0;      //this variable will be changed by encoder input
  int8_t tmpdata;
   
  tmpdata = read_encoder();
  if(tmpdata) 
  {
    if(tmpdata == 1)
    {
      leftOrRight++;
    }
    if (leftOrRight == 4)
    {
      leftOrRight = 0;
      toRight = 1; // knob turned CCW      
    }
    if (tmpdata == -1)
    {
      leftOrRight--;
    }
    if (leftOrRight == -4)
    {
      leftOrRight = 0;
      toLeft = 1; // knob turned CCW

    }
  }

  pushEncoderState = digitalRead(pushEncoderPin); // read state for encoder push button
  if (pushEncoderState != lastPushEncoderState) // has the state changed?
  {
    if (pushEncoderState == HIGH) { // if state is HIGH set
      encoderPushed = 1; //encoderPushed to 1
    }
  }

[continues in next message]

if (toLeft == 1 || toRight == 1 || encoderPushed == 1 || activeMenu != selectedMenu) {
  
  switch (selectedMenu) { //menu system
  
  case 1:
    lcd.setCursor(0,0); //set cursor position and write text to display
    lcd.print("Salongsbelysning"); //
    lcd.setCursor(0,1); //
    lcd.print("          "); //
    lcd.print(StrBrightness[pwmLevelStream1]);
    lcd.print("% "); //
    if (toRight == 1) { // handle encoder turns to change active menu page to 
      selectedMenu = 2; // the one next in line to the right
    }      
    if (toLeft == 1) { // handle encoder turns to change active menu page to 
      selectedMenu = 3; // the one next in line to the left
    }      
    if (encoderPushed == 1) { // pushbutton is used to select the active menu
      selectedMenu = 11; // the under menu below menu 1
    }
    activeMenu = 1;
    break;

  case 2:
    lcd.setCursor(0,0);  // see comments above
    lcd.print("Spridarbelysning");
    lcd.setCursor(0,1);
    lcd.print("          "); //
    lcd.print(StrBrightness[pwmLevelStream2]);
    lcd.print("% "); //
    if (toRight == 1) {
      selectedMenu = 3;
    }
    if (toLeft == 1) {
      selectedMenu = 1;
    }    
    if (encoderPushed == 1) {
      selectedMenu = 21;
    }
    activeMenu = 2;
    break;

  case 3:
    
    lcd.setCursor(0,0);
    lcd.print("Nightlight durk ");
    lcd.setCursor(0,1);
    lcd.print("          "); //
    if (colorRGB1 == 0) { // if RGB is set to 0 (red) 
    lcd.print(StrBrightness[pwmLevelStream31]);
    }
    if (colorRGB1 == 1) { // if RGB is set to 1 (white) 
    lcd.print(StrBrightness[pwmLevelStream32]);
    }
    lcd.print("% "); //
    if (toRight == 1) {
      selectedMenu = 1;
    }      
    if (toLeft == 1) {
      selectedMenu = 2;
    }
    if (encoderPushed == 1) { // set selectedMenu depending on colorRGB
      if (colorRGB1 == 0) {
        selectedMenu = 31;
      }
      if (colorRGB1 == 1) {
        selectedMenu = 32;
      }
    }
    activeMenu = 3;
    break;

  case 11:
    if (toRight == 1 && pwmLevelStream1 < 31) { // increase pwmLevelStream1 
        pwmLevelStream1++;  // up to 31
      }
          
    if (toLeft == 1 && pwmLevelStream1 > 1) { // decrease pwmLevelStream1
        pwmLevelStream1--; // not below 1
      }
          
    if (encoderPushed == 1) {
      selectedMenu = 1;
    }
    lcd.setCursor(0,0);
    lcd.print("Salongsbelysning");
    lcd.setCursor(0,1);
    lcd.print("  Dimmer ");
    lcd.print(StrBrightness[pwmLevelStream1]);
    lcd.print("%   ");
    
    activeMenu = 11;
    break;

  case 21:
    if (toRight == 1 && pwmLevelStream2 < 31) {
        pwmLevelStream2++;
      }        
    if (toLeft == 1 && pwmLevelStream2 > 1) {
        pwmLevelStream2--;
      }          
    if (encoderPushed == 1) {
      selectedMenu = 2;
    }
    lcd.setCursor(0,0);
    lcd.print("Spridarbelysning");
    lcd.setCursor(0,1);
    lcd.print("  Dimmer ");
    lcd.print(StrBrightness[pwmLevelStream2]);
    lcd.print("%   ");
    activeMenu = 21;
    break;

  case 31:
    colorRGB1 = 0; // set colorRGB to red
    lcd.setCursor(0,0);
    lcd.print("Nightlight durk ");
    lcd.setCursor(0,1);
    lcd.print("      Red       ");
    if (toRight == 1) {
      selectedMenu = 32;
    }      
    if (toLeft == 1) {
      selectedMenu = 32;
    }      
    if (encoderPushed == 1) {
      selectedMenu = 33;
    }
    activeMenu = 31;
    break;

  case 32:
    colorRGB1 = 1; // set colorRGB to white
    lcd.setCursor(0,0);
    lcd.print("Nightlight durk ");
    lcd.setCursor(0,1);
    lcd.print("      White     ");
    if (toRight == 1) {
      selectedMenu = 31;
    }      
    if (toLeft == 1) {
      selectedMenu = 31;
    }      
    if (encoderPushed == 1) {
      selectedMenu = 34;
    }
    activeMenu = 32;
    break;

  case 33:
    if (toRight == 1 && pwmLevelStream31 < 31) {
        pwmLevelStream31++;
      }
          
    if (toLeft == 1 && pwmLevelStream31 > 1) {
        pwmLevelStream31--;
      }
          
    if (encoderPushed == 1) {
      selectedMenu = 3;
    }
    lcd.setCursor(0,0);
    lcd.print("Nightlight red  ");
    lcd.setCursor(0,1);
    lcd.print("  Dimmer ");
    lcd.print(StrBrightnessRGB[pwmLevelStream31]);
    lcd.print("%   ");
    activeMenu = 33;
    break;

  case 34:
    if (toRight == 1 && pwmLevelStream32 < 31) {
        pwmLevelStream32++;
      }
          
    if (toLeft == 1 && pwmLevelStream32 > 1) {
        pwmLevelStream32--;
      }
          
    if (encoderPushed == 1) {
      selectedMenu = 3;
    }
    lcd.setCursor(0,0);
    lcd.print("Nightlight vitt ");
    lcd.setCursor(0,1);
    lcd.print("  Dimmer ");
    lcd.print(StrBrightnessRGB[pwmLevelStream32]);
    lcd.print("%   ");
    activeMenu = 34;
    break;
  }
  
}

  outputValue1 = brightnessLookup [pwmLevelStream1 & 0x1f] ; // get outputValue from array
  outputValue2 = brightnessLookup [pwmLevelStream2 & 0x1f] ; // get outputValue from array
  outputValue31 = brightnessLookupRGB [pwmLevelStream31 & 0x1f] ; // get outputValueRGB from array
  outputValue32 = brightnessLookupRGB [pwmLevelStream32 & 0x1f] ; // get outputValueRGB from array

  analogWrite(analogOutPin1, outputValue1); // set pwm for analogOutPin1 to outputValue1
  analogWrite(analogOutPin2, outputValue2); // set pwm for analogOutPin2 to outputValue2

  if (colorRGB1 == 0) // if colorRGB is red
  {
    analogWrite(analogOutPin5, outputValue31); // red value
    analogWrite(analogOutPin3, 255); //do not lit green and blue
    analogWrite(analogOutPin4, 255);
  }
  else
  {
    analogWrite(analogOutPin3, outputValue32); //use the "white" value for 
    analogWrite(analogOutPin4, outputValue32); // all colors
    analogWrite(analogOutPin5, outputValue32); // not really white light to me though
  }
  lastPushEncoderState = pushEncoderState; // reset lastPushEncoderState for next loop
  encoderPushed = 0; // reset encoderPushed
  toLeft = 0; //reset toLeft
  toRight = 0; //reset toRight
}