Skip to content

Instantly share code, notes, and snippets.

@zeroeth
Created July 25, 2011 06:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zeroeth/1103653 to your computer and use it in GitHub Desktop.
Save zeroeth/1103653 to your computer and use it in GitHub Desktop.
// 2 INT Rotary Knob decoder.
// by Kevin Alford (zeroeth) JUL-25-2011
// http://pixelflow.org http://github.com/zeroeth
//
// Description:
// This code does pattern matching on pin change to find valid rotations and filter out bad data.
// Events: 1/3 A HI/LO, 2/3 A HI/LO
// Valid transitions: Clock-wise 3412, Counterclock-wise 4321
#include <SoftwareSerial.h>
#define txPin 4
SoftwareSerial LCD = SoftwareSerial(-1, txPin);
#define encoderPinA 2
#define encoderPinB 3
#define buffer_length 4
int pattern_buffer[buffer_length] = {0};
int expected_value = 0;
int wheel_value = 0;
char wheel_value_str[5] = {0};
// SETUP //////////////////////////////////////
void setup() {
lcd_setup();
encoder_setup();
}
void encoder_setup() {
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
digitalWrite(encoderPinA, HIGH);
digitalWrite(encoderPinB, HIGH);
attachInterrupt(0, intA, CHANGE);
attachInterrupt(1, intB, CHANGE);
}
void lcd_setup() {
pinMode(txPin, OUTPUT);
LCD.begin(9600);
delay (1000);
backlightOn();
clearLCD();
}
// MAIN LOOP ////////////////////////////////////
void loop()
{
delay(1000);
}
// INTERRUPTS ///////////////////////////////////
// Look at pin change, and opposite pin to set next valid value, ignore if invalid.
void intA() {
int pin_a = digitalRead(encoderPinA);
int pin_b = digitalRead(encoderPinB);
if (pin_a == HIGH) {
if (expected_value == 0 || expected_value == 1) {
push_state(1);
match_and_display();
if (pin_b == LOW) {
expected_value = 2;
}
else {
expected_value = 4;
}
}
}
else {
if (expected_value == 0 || expected_value == 3) {
push_state(3);
match_and_display();
if (pin_b == LOW) {
expected_value = 2;
}
else {
expected_value = 4;
}
}
}
}
void intB() {
int pin_b = digitalRead(encoderPinB);
int pin_a = digitalRead(encoderPinA);
if (pin_b == HIGH) {
if (expected_value == 0 || expected_value == 2) {
push_state(2);
match_and_display();
if (pin_a == LOW) {
expected_value = 1;
}
else {
expected_value = 3;
}
}
}
else {
if (expected_value == 0 || expected_value == 4) {
push_state(4);
match_and_display();
if (pin_a == LOW) {
expected_value = 1;
}
else {
expected_value = 3;
}
}
}
}
// PATTERN MATCHING /////////////////////////////
// push to end of array, pop out oldest value
void push_state(int value) {
for(int i = 0; i < buffer_length-1; i++) {
pattern_buffer[i] = pattern_buffer[i+1];
}
pattern_buffer[buffer_length-1] = value;
}
// Show us the pattern, match it, and increment/decrement the value
void match_and_display() {
selectLineOne();
LCD.print(pattern_buffer[0]);
LCD.print(pattern_buffer[1]);
LCD.print(pattern_buffer[2]);
LCD.print(pattern_buffer[3]);
if (pattern_buffer[0] == 3 &&
pattern_buffer[1] == 4 &&
pattern_buffer[2] == 1 &&
pattern_buffer[3] == 2) {
wheel_value += 1;
}
else if (pattern_buffer[0] == 4 &&
pattern_buffer[1] == 3 &&
pattern_buffer[2] == 2 &&
pattern_buffer[3] == 1) {
wheel_value -= 1;
}
selectLineTwo();
sprintf(wheel_value_str, "%-4d", wheel_value);
LCD.print(wheel_value_str);
}
// Sparkfun serial LCD code /////////////////////
void selectLineOne(){ //puts the cursor at line 0 char 0.
goTo(0);
}
void selectLineTwo(){ //puts the cursor at line 0 char 0.
goTo(16);
}
void goTo(int position) {
//position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
if (position<16){
serCommand(); //command flag
LCD.print((position+128), BYTE); //position
}
else if (position<32){
serCommand(); //command flag
LCD.print((position+48+128), BYTE); //position
}
else {
goTo(0);
}
//delay(10);
}
void clearLCD(){
serCommand(); //command flag
LCD.print(0x01, BYTE); //clear command.
delay(10);
}
void backlightOn(){ //turns on the backlight
LCD.print(0x7C, BYTE); //command flag for backlight stuff
LCD.print(157, BYTE); //light level.
}
void backlightOff(){ //turns off the backlight
LCD.print(0x7C, BYTE); //command flag for backlight stuff
LCD.print(128, BYTE); //light level for off.
}
void serCommand(){ //a general function to call the command flag for issuing all other commands
LCD.print(0xFE, BYTE);
//delay(10);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment