Friday 26 March 2021

Rotary Encoders - arduino

Encoders.
I've built quite a few eurorack modules in the past using these puppies, but never really understood what they are.
They are rotary devices just like a potentiometer.
However, they measure rotation, rather than resistance.
They are digital not analog.

You will sometimes hear them described as electro-mechanical. They convert the position of a shaft, into a digital signal.

There are two main types of rotary encoder: absolute and incremental.
Absolute:  indicates the current shaft position.
Incremental: provides information about the motion of the shaft.
 
Encoders  can be commonly found in synths. Other possible applications are to control a LED strip light level via PWM, or to control a servo motor angle. You could also use them to control devices like digital potentiometers.
 
The encoder on the left is an incremental rotary encoder. It's called a KY-040.
It's soldered to a breakout board making it easy to connect to projects.
 
It has 5 pins:
1. CLK - Clock (Out B)
2. DT - data (Out A)
3. SW - switch (when we press the shaft, the switch connects to GND. Otherwise it is floating.)
4. + : Vcc
5. GND
 

You most often will find encoders without the breakout board.
 
They still have 5 pins.
Here there are two GNDs
There is no Vcc
 
 
 
 
 
 
 

 
The encoder on the left is a RGB encoder.
 
It has Red, Blue, and Green LEDs mounted inside it which illuminate the clear shaft, and has a built-in switch when you press on the shaft.
 
 All encoders, whatever the type output digital signals (LOW & HIGH)
There is no limiting point -- ie they have infinite turns
 
They are also known as quadrature rotary encoders.



This refers to the fact that the pulses emitted from the data lines are 90 degrees out of phase. 
These data pulses are referred to as Grey Code. 

The quadrature nature allows you to  measure when the encoder has being turned & what way it has been turned.

Notice how the A & B signals shift by 90 degrees when you turn the knob clockwise (CW) and counter clockwise (CCW).

Below is a first basic setup.
I'm using an Arduino Uno.
 
This project will dim / brighten the LED when you turn the encoder.
 

 
It will also output data to your serial monitor, so you need to keep the module plugged into your computer
while running the program.


The connections are:
+ pin 10 - to encoder
+ Pin 11 to encoder
+ Pin 12 to encoder
+ pin 6 to LED
   The cathode (short leg) of the LED connects to GND
   The anode connects to pin 6 of the arduino via a resistor - 220 Ohm
+ gnd
 
//-------------------------------------------------------------------
// Code: eg 1
// This is the code that reads the encoder and switch.
 
 
#define ENC_DATA_PIN       10 // may also be called A
#define ENC_CLK_PIN        11 // may also be called B
#define ENC_SW_PIN         12
#define LED_PWM_PIN         6
#define INCREMENT           1 // change this for different steps sizes

byte enc_clk, enc_clk_old; // comparing the clock signal transition
byte enc_switch, enc_switch_old; // comparing the switch signals
int rotary_value;

void setup() { 
 // these are our 3 input pins 
  pinMode (ENC_CLK_PIN,INPUT_PULLUP);
  pinMode (ENC_DATA_PIN,INPUT_PULLUP);
  pinMode (ENC_SW_PIN,INPUT_PULLUP);
 // next we read the old clock & switch values
 enc_clk_old    = digitalRead(ENC_CLK_PIN);
 enc_switch_old = digitalRead(ENC_SW_PIN);
 // some serial printing
  Serial.begin (9600);
  Serial.println("Rotary Value");
  Serial.println(rotary_value);
}

void loop() {
// READ SWITCH
//we read the switch pin and give the value to enc_switch
 enc_switch = digitalRead(ENC_SW_PIN);
// here we compare old vs new values of the switch
 if((enc_switch_old == 1) && (enc_switch == 0)) { // 1->0 transition
    Serial.println("SWITCH is PRESSED");
    delay(10); // add this delay to avoid bouncing in software
  }
  enc_switch_old = enc_switch; // changes the old value into the new value

// READ ROTARY
  enc_clk = digitalRead(ENC_CLK_PIN);
  if((enc_clk_old == 0) && (enc_clk == 1)) { // 0->1 transition
    if(digitalRead(ENC_DATA_PIN) == 1)
      rotary_value = rotary_value + INCREMENT;
    else
      rotary_value = rotary_value - INCREMENT;
    Serial.println(rotary_value);// prints on serial monitor screen
    analogWrite(LED_PWM_PIN, rotary_value);
    delay(10);// anti bounce
  }
  enc_clk_old = enc_clk;
}
//-----------------------------------
 
 Info and code from Rudy's Model Railway
https://www.youtube.com/watch?v=I6-lU2SMdw8&t=1s 
+ http://adam-meyer.com/arduino/Rotary_Encoder 
 ---------------------------------
-------------------------------------

No comments:

Post a Comment