Dual Rotary encoders fading one led.

Hi,

having trouble setting up 2 rotary encoders to fade one Led at pin 9.

Found this code in an tutorial with one encoder to fade the led, and managed to change the pins etc to match my hardware, and it works just great.

But since i’m completely new to arduino i dont know have to add another encoder to the code.

the second encoder will be connected to pins 5 and 6. and will also fade the led at pin 9.

/*
** Rotary Encoder Example
** Use the Sparkfun Rotary Encoder to vary brightness of LED
**
** Sample the encoder at 200Hz using the millis() function
*/

int brightness = 120;    // how bright the LED is, start at half brightness
int fadeAmount = 5;    // how many points to fade the LED by
unsigned long currentTime;
unsigned long loopTime;
const int pin_A = 12;  // pin 12
const int pin_B = 11;  // pin 11
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;

void setup()  {
  // declare pin 9 to be an output:
  pinMode(9, OUTPUT);
  pinMode(pin_A, INPUT);
  pinMode(pin_B, INPUT);
  currentTime = millis();
  loopTime = currentTime; 
} 

void loop()  {
  // get the current elapsed time
  currentTime = millis();
  if(currentTime >= (loopTime + 5)){
    // 5ms since last check of encoder = 200Hz  
    encoder_A = digitalRead(pin_A);    // Read encoder pins
    encoder_B = digitalRead(pin_B);   
    if((!encoder_A) && (encoder_A_prev)){
      // A has gone from high to low 
      if(encoder_B) {
        // B is high so clockwise
        // increase the brightness, dont go over 255
        if(brightness + fadeAmount <= 255) brightness += fadeAmount;               
      }   
      else {
        // B is low so counter-clockwise      
        // decrease the brightness, dont go below 10
        if(brightness - fadeAmount >= 10) brightness -= fadeAmount;               
      }   

    }   
    encoder_A_prev = encoder_A;     // Store value of A for next time    
    
    // set the brightness of pin 9:
    analogWrite(9, brightness);   
   
    loopTime = currentTime;  // Updates loopTime
  }
  // Other processing can be done here
                           
}

appreciate all help. Thanks.

It doesn't make sense to use two encoders to control the PWM value to one LED. Why do you want to? What, exactly, will each encoder click count do?

Unless they are very slow encoders, reading them once every 5 milliseconds will miss pulses.

It is best to move the encoder handling into a function and call it with the values specific to each encoder. That way you can add as many encoders as you need without bloating the sketch with duplicated code:

unsigned char encoder(unsigned char pinA, unsigned char pinB, unsigned char previousA) {
  encoder_A = digitalRead(pinA);    // Read encoder pins
  encoder_B = digitalRead(pinB);
  if (!encoder_A && previousA) {
    // A has changed from high to low
    if (encoder_B) {
      // B is high so clockwise
      // increase the brightness, dont go over 255
      if (brightness + fadeAmount <= 255)
        brightness += fadeAmount;
    }
    else {
      // B is low so counter-clockwise
      // decrease the brightness, dont go below 10
      if (brightness - fadeAmount >= 10)
        brightness -= fadeAmount;
    }
  }
  return encoder_A;     // Store value of A for next time
}

Hi PaulS,

The rotary encoders will be hand controlled so they wont be spinning that fast.
The reason to use 2 encoders will be to control the position of a kamera from 2 different positions in a big room. the kamera automation is controlled by 0-5V signal, 0V is full left, and 5 volt is Full Right. the Led in the sketch is just a simulation to get the code right...
i hope this make more sense to you know when you know the use of it.

Hi johnwasser,

A think i get the idea of using the handling of the encoder as a function, but dont know how to do it in theory. i see that you have changed the code a bit from my example, but it's still only one encoder in the code right? how do i add anotcher one?

Thanks for the answers guys.

i hope this make more sense to you know when you know the use of it.

It does not. An encoder outputs pulses when it is turned. You are incrementing or decrementing a value, based on the way that one encoder is turned.

If you have two encoders, you'll have two counts. How are the two counts supposed to be used to control the position of one camera?

No, that function works for any number of encoders. You just have to pass it the right values for the encoder you want it to look at.

Here’s a more complete example which uses John Wasser’s function.

int brightness = 120;    // how bright the LED is, start at half brightness
int fadeAmount = 5;    // how many points to fade the LED by
const int encoder1_pin_A = 12;  
const int encoder1_pin_B = 11;  
const int encoder2_pin_A = 2;   //you didn't tell us which pins are used for the second encoder
const int encoder2_pin_B = 3;  
unsigned char encoder1_prev;
unsigned char encoder2_prev;
const int LED_pin = 9;

void setup()  {
  pinMode(LED_pin, OUTPUT);
  pinMode(encoder1_pin_A, INPUT_PULLUP);
  pinMode(encoder1_pin_B, INPUT_PULLUP);
  pinMode(encoder2_pin_A, INPUT_PULLUP);
  pinMode(encoder2_pin_B, INPUT_PULLUP);
  encoder1_prev = digitalRead(encoder1_pin_A);
  encoder2_prev = digitalRead(encoder2_pin_A);
} 

void loop()  {
    encoder1_prev = encoder(encoder1_pin_A, encoder1_pin_B, encoder1_prev);
    encoder2_prev = encoder(encoder2_pin_A, encoder2_pin_B, encoder2_prev);

    analogWrite(LED_pin, brightness);      
}


//John Wasser's encoder function...
unsigned char encoder(unsigned char pinA, unsigned char pinB, unsigned char previousA) {
  unsigned char encoder_A = digitalRead(pinA);    // Read encoder pins
  unsigned char encoder_B = digitalRead(pinB);
  if (!encoder_A && previousA) {
    // A has changed from high to low
    if (encoder_B) {
      // B is high so clockwise
      // increase the brightness, dont go over 255
      if (brightness + fadeAmount <= 255)
        brightness += fadeAmount;
    }
    else {
      // B is low so counter-clockwise
      // decrease the brightness, dont go below 10
      if (brightness - fadeAmount >= 10)
        brightness -= fadeAmount;
    }
  }
  return encoder_A;     // Store value of A for next time
}

PaulS:
It does not. An encoder outputs pulses when it is turned. You are incrementing or decrementing a value, based on the way that one encoder is turned.

If you have two encoders, you'll have two counts. How are the two counts supposed to be used to control the position of one camera?

PaulS, I think he is trying to avoid walking all the way across a large room to control one camera. The left/right position of the camera could therefore be determined by a sum of the counts from each encoder, as only one could be manipulated at a time. Of course, when the total camera count reaches either zero or maximum, both of the encoder counts would have to be zeroed, or set to the maximum, so that further manipulation by either encoder would continue to be able to move the camera from the limit position.

Maybe this is a bad idea so let me know if it wouldn't work but just thought:

What if you connected the two encoders in parallel on the same pins, because encoders make pulses right? So it would be just like two momentary buttons in parallel to control something from two different areas. I can't see why this wouldn't work but if it wouldn't, please explain why not.

Good luck

No, they don't make pulses although sometimes we talk about it like it was pulses. I think the original idea is sound.

I don't think you have any problem with "zeroing" either. Just don't turn the knobs so that the camera smacks into the wall.