In this video I will show you how to use Rotary Encodedrs with Arduino Interrupts.It is quite fascinating that this component looking similar to the rotary potentiometer is actually totally different.Hope you would find this tutorial useful.
If you have never used potentiometer with Arduino probably you want to view this tutorial first:
And here is Rotary Encoder tutorial:
🛠️ เจาะลึกเบื้องหลังการทำงาน (Deep Dive / Technical Analysis)
A standard potentiometer relies on shifting variable voltages. It only turns 270 degrees before it hits a physical metallic stop and breaks. A Rotary Encoder (e.g., KY-040) is entirely distinct! It spins seamlessly infinitely! Inside the encoder are two physical contacts. As you spin the dial violently, it creates two insanely high-speed offset square waves (A and B channels) physically overlapping in "Quadrature." If you use standard digitalRead() in a large loop, the Arduino will miss incredibly fast clicks, rendering the volume knob feeling "broken." The system mandates the absolute employment of severe Hardware Interrupt Logic natively capturing every single microscopic logic transition securely!
The Twin Channel Interrupt Matrix (CLK and DT)
Channel A (CLK) and Channel B (DT) are directly mapped explicitly onto Interrupt-capable Arduino pins (e.g., Pin 2 and Pin 3).
- When the user rotates the dial, the hardware intercepts the signal, physically ripping the Arduino out of any
delay()loop instantaneously! - The Interrupt Service Routine (ISR) executes entirely blindly.
- If Pin 2 fires first (Pin A goes LOW), the code aggressively checks the state of Pin 3!
- The Critical Logic: If Pin
AandBare identical, the user spun Clockwise. If they are aggressively conflicting, the user spun Counter-Clockwise!
int pinA = 2; // HW Interrupt 0
int pinB = 3; // HW Interrupt 1
volatile int encoderPosition = 0; // MUST explicitly declare complex volatile execution status!
void setup() {
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
// Track whenever Pin A physically clicks DOWN!
attachInterrupt(digitalPinToInterrupt(pinA), executeTurnISR, FALLING);
}
// Executes instantaneously upon ANY microscopic physical click natively!
void executeTurnISR() {
int aState = digitalRead(pinA);
int bState = digitalRead(pinB);
// Severe Quadrature Directional Decoding Logic
if (aState != bState) {
encoderPosition++; // Right Clockwise Vector!
} else {
encoderPosition--; // Left Counter-Clockwise Rotation!
}
}
Debouncing the Mechanical Chatter Algorithmically!
Mechanical rotary encoders are incredibly dirty physical objects.
- When the copper contact connects, it doesn't cleanly transition; it violently bounces on a microscopic level creating 50 phantom pulses in 2 milliseconds (Chatter).
- To prevent bouncing from ruining the
encoderPositioncounting architecture, developers either heavily solder0.1µFceramic bypass capacitors explicitly from Pins 2 and 3 straight to GND (Hardware RC Filter) or explicitly build a rigidmillis()ignoring lockout timer directly acting inside the ISR entirely!
Advanced Input Hardware Parameters
- Arduino Uno/Nano (Mandatory constraint utilizing solely Pins 2 and 3 specifically reserved explicitly for hardware interrupts natively!).
- KY-040 Rotary Encoder Module (Featuring 20 discrete tactical steps per revolution and an additional
SWPush-Button internally built-in for GUI execution matrices). - Ceramic Capacitors (Optional but critical) (For professional pristine hardware-level debouncing logic completely bypassing cumbersome software-filtering vectors!).