Intro
originally published on wordpress.com
This is a quick tutorial on how to use a rotary encoder as an input.
I will also show the circuit needed to operate a 7 segment display through a MAX7219 LED driver.
Parts
- a Rotary Encoder (I used this one)
- a MAX7219 LED driving IC (available here)
- an Arduino (available here)
- your choice of mounting method (I used a breadboard and jumper wires)
Circuit
I planned what I did using Fritzing
Here is the Fritzing schematic:
As you can see, the rotary encoder uses two pins on the Arduino (plus an extra pin for the push button functionality that the model I used has).
The MAX7219 uses 3 pins on the Arduino.
This is how the circuit could be implemented using strip-board; making it a lot neater than breadboard and wires.
Here is the actual circuit on a breadboad (it's a mess because it is implemented with jumper wires):
Once the circuit is implemented, upload this sketch to the Arduino and it all should work.
(reference for the rotary encoder code)
(reference for the MAX7219 LEDcontrol library)
The source code below is commented and should help further.
//We always have to include a library
#include "LedControl.h"
/* Rotary encoder read example */
#define ENC_A 14
#define ENC_B 15
#define ENC_PORT PINC
#define ENC_PUSH 4
/*
Now we need a LedControl to work with.
***** These pin numbers will probably not work with your hardware *****
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
We have only a single MAX72XX.
*/
LedControl lc=LedControl(12,11,10,1);
void setup()
{
/* Setup encoder pins as inputs */
pinMode(ENC_A, INPUT);
digitalWrite(ENC_A, HIGH);
pinMode(ENC_B, INPUT);
digitalWrite(ENC_B, HIGH);
pinMode(ENC_PUSH, INPUT);
digitalWrite(ENC_PUSH, HIGH);
/*
The MAX72XX is in power-saving mode on startup,
we have to do a wakeup call
*/
lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);
}
void loop()
{
static uint8_t counter = 4; //this variable will be changed by encoder input
int8_t tmpdata;
tmpdata = read_encoder();
if( tmpdata ) {
lc.setDigit(0,0,(counter/4)%16,false);
counter += tmpdata;
}
if (!digitalRead(ENC_PUSH)){
counter = 0;
lc.setDigit(0,0,(counter/4)%16,false);
}
}
/* 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 )]);
}