Thursday, October 6, 2011

Decoding a Rotary Encoder - Cont'd

See previous post.

This Rotary Encoder Test Program is archived here, and available for review. Actually, I am using a Teensy 2.0 for this effort.

Skip this post, if you are not into Arduino Programming.

It works GREAT!

UPDATE: The previous shown program was replaced with the following, smaller, faster Interrupts Handlers:


/*
 Coded for Teensy 2.0, but with maybe some different pin
 assignments should work with all Arduinos

 This is my LCD and Rotary Encoder Test and Development Sketch Template
 By: Eldon R. Brown eldonb@ebcon.com
 Oct 7, 2011
 
 The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 0
 * LCD D5 pin to digital pin 1
 * LCD D6 pin to digital pin 2
 * LCD D7 pin to digital pin 3
 * LCD R/W pin to ground
 * LCD 15 pin BackLight, to 220 ohm, to digital pin 9
 *
 * Encoder pins as defined in below
 */

// include the library code:
#include <LiquidCrystal.h>

// Setup Pins for Encoders, and .0022uf Cap to ground
#define encoder0PinA  5    // PD0
#define encoder0PinB 15    // PB6
#define encoder0Switch 7   // PD2
//#define encoder1PinA  6    // PD1
//#define encoder1PinB 16    // PF7
//#define encoder1Switch 8   // PD3

#define lcd_BL_pin 9    // PC6 -  The BackLight

#define INT0 0
#define INT1 1
#define INT2 2
#define INT3 3


// Set Initial Encoder
volatile byte g_encoder0Pos = 0;
volatile byte g_encoder0SwStat = 0;
//volatile int encoder1Pos = 0;
//volatile int encoder1SwStat = 0;

// Initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 3, 2, 1, 0);


//////////////////////////////////////////////////////////////
// Interrupt Handler /////////////////////////////////////////
//////////////////////////////////////////////////////////////

void doEncoder0() {    // Rotary Encoder
    digitalRead(encoder0PinB) ? g_encoder0Pos++ : g_encoder0Pos--;
    return;
}

void doEncoder0Switch() {     // Button
    g_encoder0SwStat = digitalRead(encoder0Switch);  
    return;
}

//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
// Main Setup ////////////////////////////////////////////////
void setup() {

    // set up the LCD's number of columns and rows: 
    lcd.begin(16, 2);

    // Setup for Interrupts

    // Configure for Input
    pinMode(encoder0PinA, INPUT);    
    pinMode(encoder0PinB, INPUT);
    pinMode(encoder0Switch, INPUT);

    // Turn on pullup resistors, Pin must be in INPUT mode
    digitalWrite(encoder0PinA, HIGH);   
    digitalWrite(encoder0PinB, HIGH);
    digitalWrite(encoder0Switch, HIGH);

    // Set up for Interrupt
    // Only RISING is needed for Encoder    
    attachInterrupt(INT0, doEncoder0, RISING);
    attachInterrupt(INT2, doEncoder0Switch, CHANGE);
    interrupts();

    // Init LCD
    analogWrite(lcd_BL_pin, 128);
    // set up the LCD's number of columns and rows: 
    lcd.begin(16, 2);
    // Init Message
    lcd.print("--Initializing--");
    lcd.setCursor(0,1);
    lcd.print("   ebcon.com");
    delay(2000);
    lcd.clear();
    g_encoder0Pos = 0;

}

// Main Program Loop //////////////////////////////////////////
void loop() {
   
    doGetEncoderValue();
    //delay(100);
    //doBusyBox();
   
}

//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////
void doBusyBox() { // A Debug Function to make busy the processor
    delay(random(10,100));
    return;
} 

//////////////////////////////////////////////////////////////
int doGetEncoderValue() {
    volatile static int pos = 0;
    byte tmp;

    // Get Encoder input
    //noInterrupts();
    tmp = g_encoder0Pos;
    g_encoder0Pos = 0;
    //interrupts();
    
    if (tmp<128) pos += tmp;
    if (tmp>127) pos += tmp - 256;

    lcd.setCursor(0,0);
    // Print a message to the LCD.
    lcd.print("Pos= ");
    lcd.print(pos);
    lcd.print(" ");
    lcd.print(char(pos+65));
    lcd.print("   ");

    // Blink Cursor, for fun
    doBlinkCursor(15,1,!g_encoder0SwStat);
    return true;
}

////////////////////////////////////////////////////////////// 
void doBlinkCursor(char x,char y, char style) {
    switch (style) {
    case 1:        // Block Cursor
        lcd.setCursor(x,y);
        lcd.blink();
        delay(300);
        lcd.noBlink();
        break;
    default:        // Underline Cursor
        lcd.setCursor(x,y);
        lcd.cursor();
        delay(300);
        lcd.noCursor();
    }   
}

// End ////////////////////////////////////////////////////////


--

1 comment: