Created
July 25, 2011 06:22
-
-
Save zeroeth/1103653 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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