Good day all
I have a project where I require two rotary encoders to change the display on two i2c LCD's - one encoder per LCD. I'm using an Arduino Mega board.
While I get the first encoder to work flawlessly, I cannot get the second encoder to respond at all.
The code as it stands:
/*******Interrupt-based Rotary Encoder write to LCD*******
/********************************/
// include the library code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
/**********************************************************/
LiquidCrystal_I2C lcd1(0x20,16,2); // set the LCD1 address to 0x20 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd2(0x21,16,2); // set the LCD2 address to 0x20 for a 16 chars and 2 line display
static int RE1_pinA = 2; // Our first hardware interrupt pin is digital pin 2
static int RE1_pinB = 3; // Our second hardware interrupt pin is digital pin 3
volatile byte RE1_aFlag = 0; // let's us know when we're expecting a rising edge on pinA to signal that the encoder has arrived at a detent
volatile byte RE1_bFlag = 0; // let's us know when we're expecting a rising edge on pinB to signal that the encoder has arrived at a detent (opposite direction to when aFlag is set)
volatile uint16_t RE1_encoderPos = 250; //this variable stores our current value of encoder position. Change to int or uint16_t instead of byte if you want to record a larger range than 0-255
volatile uint16_t RE1_oldEncPos = 250; //stores the last encoder position value so we can compare to the current reading and see if it has changed (so we know when to print to the LCD)
volatile uint16_t RE1_reading = 0; //somewhere to store the direct values we read from our interrupt pins before checking to see if we have moved a whole detent
static int RE2_pinA = 18; // Our first hardware interrupt pin is digital pin 18
static int RE2_pinB = 19; // Our second hardware interrupt pin is digital pin 19
volatile byte RE2_aFlag = 0; // let's us know when we're expecting a rising edge on pinA to signal that the encoder has arrived at a detent
volatile byte RE2_bFlag = 0; // let's us know when we're expecting a rising edge on pinB to signal that the encoder has arrived at a detent (opposite direction to when aFlag is set)
volatile uint16_t RE2_encoderPos = 150; //this variable stores our current value of encoder position. Change to int or uint16_t instead of byte if you want to record a larger range than 0-255
volatile uint16_t RE2_oldEncPos = 150; //stores the last encoder position value so we can compare to the current reading and see if it has changed (so we know when to print to the LCD)
volatile uint16_t RE2_reading = 0; //somewhere to store the direct values we read from our interrupt pins before checking to see if we have moved a whole detent
void setup()
{
lcd1.init(); //initialize the lcd
lcd1.backlight(); //open the backlight
lcd1.setCursor(0,0);
lcd1.print("Encoder pos: ");
lcd1.setCursor(13,0);
lcd1.print(RE1_encoderPos);
lcd2.init(); //initialize the lcd
lcd2.backlight(); //open the backlight
lcd2.setCursor(0,0);
lcd2.print("Encoder pos: ");
lcd2.setCursor(13,0);
lcd2.print(RE2_encoderPos);
pinMode(RE1_pinA, INPUT_PULLUP); // set pinA as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
pinMode(RE1_pinB, INPUT_PULLUP); // set pinB as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
pinMode(RE2_pinA, INPUT_PULLUP); // set pinA as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
pinMode(RE2_pinB, INPUT_PULLUP); // set pinB as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
attachInterrupt(0,RE1_PinA,RISING); // set an interrupt on PinA (connected to pin 2 on MEGA), looking for a rising edge signal and executing the "PinA" Interrupt Service Routine (below)
attachInterrupt(1,RE1_PinB,RISING); // set an interrupt on PinB (connected to pin 3 on MEGA), looking for a rising edge signal and executing the "PinB" Interrupt Service Routine (below)
attachInterrupt(5,RE2_PinA,RISING); // set an interrupt on PinA (connected to pin 18 on MEGA), looking for a rising edge signal and executing the "PinA" Interrupt Service Routine (below)
attachInterrupt(4,RE2_PinB,RISING); // set an interrupt on PinB (connected to pin 19 on MEGA), looking for a rising edge signal and executing the "PinB" Interrupt Service Routine (below)
// Check Arduino board type to determine correct mask
#ifdef __AVR_ATmega2560__
#define PIN PINE
#define ABMASK 0b00110000
#define AMASK 0b00010000
#define BMASK 0b00100000
#endif
#ifdef __AVR_ATmega328P__
#define PIN PIND
#define ABMASK 0b00001100
#define AMASK 0b00000100
#define BMASK 0b00001000
#endif
}
void RE1_PinA()
{
RE1_reading = PIN & ABMASK; // read all eight pin values then strip away all but pinA and pinB's values
if(RE1_reading == ABMASK && RE1_aFlag) //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
{
RE1_encoderPos --; //decrement the encoder's position count
RE1_bFlag = 0; //reset flags for the next turn
RE1_aFlag = 0; //reset flags for the next turn
}
else if (RE1_reading == AMASK) RE1_bFlag = 1; //signal that we're expecting pinB to signal the transition to detent from free rotation
}
void RE1_PinB()
{
RE1_reading = PIN & ABMASK; // read all eight pin values then strip away all but pinA and pinB's values
if (RE1_reading == ABMASK && RE1_bFlag) //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
{
RE1_encoderPos ++; //increment the encoder's position count
RE1_bFlag = 0; //reset flags for the next turn
RE1_aFlag = 0; //reset flags for the next turn
}
else if (RE1_reading == BMASK) RE1_aFlag = 1; //signal that we're expecting pinA to signal the transition to detent from free rotation
}
void RE2_PinA()
{
RE2_reading = PIN & ABMASK; // read all eight pin values then strip away all but pinA and pinB's values
if(RE2_reading == ABMASK && RE2_aFlag) //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
{
RE2_encoderPos --; //decrement the encoder's position count
RE2_bFlag = 0; //reset flags for the next turn
RE2_aFlag = 0; //reset flags for the next turn
}
else if (RE2_reading == AMASK) RE2_bFlag = 1; //signal that we're expecting pinB to signal the transition to detent from free rotation
}
void RE2_PinB()
{
RE2_reading = PIN & ABMASK; // read all eight pin values then strip away all but pinA and pinB's values
if (RE2_reading == ABMASK && RE2_bFlag) //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
{
RE2_encoderPos ++; //increment the encoder's position count
RE2_bFlag = 0; //reset flags for the next turn
RE2_aFlag = 0; //reset flags for the next turn
}
else if (RE2_reading == BMASK) RE2_aFlag = 1; //signal that we're expecting pinA to signal the transition to detent from free rotation
}
void loop()
{
if(RE1_oldEncPos != RE1_encoderPos)
{
lcd1.setCursor(13,0); //Set cursor
lcd1.print(" "); //Delete old reading
lcd1.setCursor(13,0); //Set cursor
lcd1.print(RE1_encoderPos); //Print new reading
RE1_oldEncPos = RE1_encoderPos;
}
if(RE2_oldEncPos != RE2_encoderPos)
{
lcd2.setCursor(13,0); //Set cursor
lcd2.print(" "); //Delete old reading
lcd2.setCursor(13,0); //Set cursor
lcd2.print(RE2_encoderPos); //Print new reading
RE2_oldEncPos = RE2_encoderPos;
}
}[code]
I would appreciate any suggestions.
Regards
[/code]