RGB LCD Backpack - Interrupt
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- robreeves49
- Posts: 26
- Joined: Sun Mar 13, 2011 7:51 pm
RGB LCD Backpack - Interrupt
I saw an earlier post where you explained using polling instead of interrupts for button detection, but I'm wondering if there is a way to trigger an interrupt when any button is pushed? My sketch could be off doing whatever when I push the button, and I'd want to interrupt whatever to poll the buttons.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: RGB LCD Backpack - Interrupt
The arduino library supports two interrupts: one on digital pin 2, and the other on digital pin 3. You can read about the attachInterrupt function here:
http://arduino.cc/en/Reference/AttachInterrupt
The ATMega328 chip also supports pin-change interrupts. These are not directly supported by any arduino libraries, but you can still use them. Chapter 13 of the ATmega328 datasheet describes both the two external interrupts used by arduino, and the pin-change interrupts available on the other digital pins
http://arduino.cc/en/Reference/AttachInterrupt
The ATMega328 chip also supports pin-change interrupts. These are not directly supported by any arduino libraries, but you can still use them. Chapter 13 of the ATmega328 datasheet describes both the two external interrupts used by arduino, and the pin-change interrupts available on the other digital pins
-
- Posts: 1645
- Joined: Sat Nov 10, 2007 12:59 am
Re: RGB LCD Backpack - Interrupt
yes. the mcp23017 is capable of generating pin change interrupts. you'll have to enable interrupts on the pins used for the buttons. this will involve hacking the library a little to enable and configure interrupts on the button pins and installing a wire jumper between pin 20 of the mcp23017 and whichever arduino pin you'd like the interrupt to occur on. this will likely be pin 2 or pin 3, because they can be used with the attachInterrupt function.
have a read of the mcp23017 datasheet.
no doubt a fun and worthwhile project.
have a read of the mcp23017 datasheet.
no doubt a fun and worthwhile project.
- robreeves49
- Posts: 26
- Joined: Sun Mar 13, 2011 7:51 pm
Re: RGB LCD Backpack - Interrupt
So, tie pin 20 to an Arduino interrupt pin and hack the library so that a button push triggers an interrupt (a state change) on pin 20, right?
-
- Posts: 1645
- Joined: Sat Nov 10, 2007 12:59 am
Re: RGB LCD Backpack - Interrupt
that should be it.
i ordered a second lcd shield for hacking and it arrived yesterday. this is one of the things i wanted to try along with moving the buttons off board, playing with the other 4 i/o lines and replacing the chip with a micro controller to give it some local intelligence.
as driverblock pointed out, you can use any i/o pin on the arduino to generate a pin change interrupt. it's not any more difficult than using attachInterrupt once you've done a little reading in the datasheet. there are third party libraries available, too.
i ordered a second lcd shield for hacking and it arrived yesterday. this is one of the things i wanted to try along with moving the buttons off board, playing with the other 4 i/o lines and replacing the chip with a micro controller to give it some local intelligence.
as driverblock pointed out, you can use any i/o pin on the arduino to generate a pin change interrupt. it's not any more difficult than using attachInterrupt once you've done a little reading in the datasheet. there are third party libraries available, too.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: RGB LCD Backpack - Interrupt
Whether you you arduino pin-change interrupts or mcp23017 pin chance interrupts, remember that one interrupt line serves up to 8 port pins.
If you have more than one button, you'll have to figure out which button caused the interrupt. The mcp23017 helps you out with this a little bit by providing the INTCAP register, which will tell you which pin caused the interrupt. But that's not necessarily foolproof, because other pin changes can accumulate while you're processing the first interrupt. So, while it may not be likely, it's *possible* to get more than one pin change in an interrupt.
Arduino pin change interrupts don't have an INTCAP register, so it's up to you to keep track of the state of the port register so that you can figure out what's changed when you get an interrupt. If you always remember the state of the port every time you read it, you can XOR the remembered state with the current state to get the equivalent of the INTCAP register. Again, it's *possible* to get more than one pin change in an interrupt.
Once you have your change flags, remember that you will get one interrupt when a button is pressed, and another interrupt when the button is released. The INTCAP will look the same for both events, since it is simply flagging which pins changed state. You'll have to examine the port register to determine if the change(s) were caused by a press or a release.
If you have more than one button, you'll have to figure out which button caused the interrupt. The mcp23017 helps you out with this a little bit by providing the INTCAP register, which will tell you which pin caused the interrupt. But that's not necessarily foolproof, because other pin changes can accumulate while you're processing the first interrupt. So, while it may not be likely, it's *possible* to get more than one pin change in an interrupt.
Arduino pin change interrupts don't have an INTCAP register, so it's up to you to keep track of the state of the port register so that you can figure out what's changed when you get an interrupt. If you always remember the state of the port every time you read it, you can XOR the remembered state with the current state to get the equivalent of the INTCAP register. Again, it's *possible* to get more than one pin change in an interrupt.
Once you have your change flags, remember that you will get one interrupt when a button is pressed, and another interrupt when the button is released. The INTCAP will look the same for both events, since it is simply flagging which pins changed state. You'll have to examine the port register to determine if the change(s) were caused by a press or a release.
- robreeves49
- Posts: 26
- Joined: Sun Mar 13, 2011 7:51 pm
Re: RGB LCD Backpack - Interrupt
Maybe I'm oversimplifying, but my plan was to call the LCD library readbuttons() method after detecting the interrupt, and let it do the work of figuring out what button was pushed. Anyway, won't know until I try it.
- adafruit_support_rick
- Posts: 35092
- Joined: Tue Mar 15, 2011 11:42 am
Re: RGB LCD Backpack - Interrupt
readButtons just returns a bitmap of of the current state of the buttons. You'll still have to figure out which buttons changed state.
For instance, if you press and hold button 1, you'll get your interrupt, and readButtons will tell you that button 1 is pressed.
Now, press and release button 2. You'll get an interrupt for the press, and readButtons will tell you that buttons 1 and 2 are pressed. Then you'll get another interrupt for the release, and readButtons will tell you that button 1 is pressed.
Maybe, in your application, it's not important for you to be able to tell the difference between the first and third interrupt. Maybe it's also not important for you to know that button 1 was only pressed once.
But in many applications, it's critical to disambiguate those three interrupt states in order to know what the user is doing and how to respond.
For instance, if you press and hold button 1, you'll get your interrupt, and readButtons will tell you that button 1 is pressed.
Now, press and release button 2. You'll get an interrupt for the press, and readButtons will tell you that buttons 1 and 2 are pressed. Then you'll get another interrupt for the release, and readButtons will tell you that button 1 is pressed.
Maybe, in your application, it's not important for you to be able to tell the difference between the first and third interrupt. Maybe it's also not important for you to know that button 1 was only pressed once.
But in many applications, it's critical to disambiguate those three interrupt states in order to know what the user is doing and how to respond.
-
- Posts: 1645
- Joined: Sat Nov 10, 2007 12:59 am
Re: RGB LCD Backpack - Interrupt
the falling edge should be easy to identify since it will happen only after you read the register on the mcp23017. debouncing still ought to be a lot of fun. the shield library doesn't address it at all. it might be amusing to write a little sketch that continually reads the buttons to see how many changes are detected per press.
also it looks like it might be worthwhile to do a thorough rewrite of the library. it appears to be a pretty straightforward adaptation of the existing lcd library and uses analogs of pinMode and digitalWrite to do a lot of things one bit at a time that it would make a whole lot more sense to do in parallel when the lcd is connected through a port expander.
also it looks like it might be worthwhile to do a thorough rewrite of the library. it appears to be a pretty straightforward adaptation of the existing lcd library and uses analogs of pinMode and digitalWrite to do a lot of things one bit at a time that it would make a whole lot more sense to do in parallel when the lcd is connected through a port expander.
-
- Posts: 4
- Joined: Thu Jul 19, 2012 3:11 pm
Re: RGB LCD Backpack - Interrupt
OK - got it working - not polished yet, but you'll be off to the races with this...
Add to Adafruit_MCP23017.h:
Adafruit_MCP23017.cpp:
digitalwrite is rewritten ( write to OLAT. DO NOT read first - interrupt will be reset. Declare gpio static ). Functions are added
Adafruit_RGBLCDShield.h:
Adafruit_RGBLCDShield.cpp:
Adafruit_RGBLCDShield::begin ( fragment )
write4bits speedup disabled
readbuttons changed:
Ugly Arduino example - switches bounce like crazy - must keep reading OLAT until pin resets
Add to Adafruit_MCP23017.h:
Code: Select all
uint16_t readInterrupts();
void interruptEnable(uint8_t p, uint8_t d);
void defaultvalue(uint8_t p, uint8_t d);
void interruptControl(uint8_t p, uint8_t d);
void interruptMirror(uint8_t d);
void interruptPolarity(uint8_t d);
digitalwrite is rewritten ( write to OLAT. DO NOT read first - interrupt will be reset. Declare gpio static ). Functions are added
Code: Select all
void Adafruit_MCP23017::digitalWrite(uint8_t p, uint8_t d) {
static uint8_t gpio;
uint8_t gpioaddr, olataddr;
// only 16 bits!
if (p > 15)
return;
if (p < 8) {
olataddr = MCP23017_OLATA;
gpioaddr = MCP23017_GPIOA;
} else {
olataddr = MCP23017_OLATB;
gpioaddr = MCP23017_GPIOB;
p -= 8;
}
// read the current GPIO output latches
//Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
//wiresend(olataddr);
//Wire.endTransmission();
//Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 1);
// gpio = wirerecv();
// set the pin and direction
if (d == HIGH) {
gpio |= 1 << p;
} else {
gpio &= ~(1 << p);
}
// write the new GPIO
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(olataddr);
wiresend(gpio);
Wire.endTransmission();
}
//read interrupt
uint16_t Adafruit_MCP23017::readInterrupts() {
uint16_t ba = 0;
uint8_t a;
// read the interrupt capture buffers
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(MCP23017_INTCAPA);
Wire.endTransmission();
Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 2);
a = wirerecv();
ba = wirerecv();
ba <<= 8;
ba |= a;
return ba;
}
// interrupt enable
void Adafruit_MCP23017::interruptEnable(uint8_t p, uint8_t d) {
uint8_t gpinten;
uint8_t gpintenaddr;
// only 16 bits!
if (p > 15)
return;
if (p < 8)
gpintenaddr = MCP23017_GPINTENA;
else {
gpintenaddr = MCP23017_GPINTENB;
p -= 8;
}
// read the current interrupt enable set
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(gpintenaddr);
Wire.endTransmission();
Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 1);
gpinten = wirerecv();
// set the pin enabled state
if (d == HIGH) {
gpinten |= 1 << p;
} else {
gpinten &= ~(1 << p);
}
// write the new INTEN
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(gpintenaddr);
wiresend(gpinten);
Wire.endTransmission();
}
// interrupt enable end
// interrupt default value compare
void Adafruit_MCP23017::defaultvalue(uint8_t p, uint8_t d) {
uint8_t gpdefval;
uint8_t gpdefvaladdr;
// only 16 bits!
if (p > 15)
return;
if (p < 8)
gpdefvaladdr = MCP23017_DEFVALA;
else {
gpdefvaladdr = MCP23017_DEFVALB;
p -= 8;
}
// read the current interrupt enable set
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(gpdefvaladdr);
Wire.endTransmission();
Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 1);
gpdefval = wirerecv();
// set the pin enabled state
if (d == HIGH) {
gpdefval |= 1 << p;
} else {
gpdefval &= ~(1 << p);
}
// write the new DEFVAL
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(gpdefvaladdr);
wiresend(gpdefval);
Wire.endTransmission();
}
// interrupt default value compare end
// interrupt control
void Adafruit_MCP23017::interruptControl(uint8_t p, uint8_t d) {
uint8_t gpintcon;
uint8_t gpintconaddr;
// only 16 bits!
if (p > 15)
return;
if (p < 8)
gpintconaddr = MCP23017_INTCONA;
else {
gpintconaddr = MCP23017_INTCONB;
p -= 8;
}
// read the current interrupt enable set
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(gpintconaddr);
Wire.endTransmission();
Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 1);
gpintcon = wirerecv();
// set the pin enabled state
if (d == HIGH) {
gpintcon |= 1 << p;
} else {
gpintcon &= ~(1 << p);
}
// write the new INTCON
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(gpintconaddr);
wiresend(gpintcon);
Wire.endTransmission();
}
// interrupt control end
// Interrupt mirror bit
void Adafruit_MCP23017::interruptMirror(uint8_t d) {
uint8_t iocon;
uint8_t ioconaddr;
ioconaddr = MCP23017_IOCONA;
// read the current interrupt enable set
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(ioconaddr);
Wire.endTransmission();
Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 1);
iocon = wirerecv();
// set the interrupt mirror state
if (d == HIGH) {
iocon |= 1 << 6; // bit 6 = mirror
} else {
iocon &= ~(1 << 6);
}
// write the new IOCON
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(ioconaddr);
wiresend(iocon);
Wire.endTransmission();
}
// Interrupt mirror bit end
// Interrupt polarity bit
void Adafruit_MCP23017::interruptPolarity(uint8_t d) {
uint8_t iocon;
uint8_t ioconaddr;
ioconaddr = MCP23017_IOCONA;
// read the current interrupt enable set
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(ioconaddr);
Wire.endTransmission();
Wire.requestFrom(MCP23017_ADDRESS | i2caddr, 1);
iocon = wirerecv();
// set the interrupt polarity state
if (d == HIGH) {
iocon |= 1 << 1; // bit 1 = polarity
} else {
iocon &= ~(1 << 1);
}
// write the new IOCON
Wire.beginTransmission(MCP23017_ADDRESS | i2caddr);
wiresend(ioconaddr);
wiresend(iocon);
Wire.endTransmission();
}
// Interrupt polarity bit end
Code: Select all
uint16_t readButtons();
Adafruit_RGBLCDShield::begin ( fragment )
Code: Select all
if (_i2cAddr != 255) {
//_i2c.begin(_i2cAddr);
//Wire.begin();
_i2c.begin();
_i2c.pinMode(8, OUTPUT);
_i2c.pinMode(6, OUTPUT);
_i2c.pinMode(7, OUTPUT);
setBacklight(0x7);
if (_rw_pin)
_i2c.pinMode(_rw_pin, OUTPUT);
_i2c.pinMode(_rs_pin, OUTPUT);
_i2c.pinMode(_enable_pin, OUTPUT);
_i2c.interruptMirror(1);
_i2c.interruptPolarity(1);
for (uint8_t i=0; i<4; i++)
_i2c.pinMode(_data_pins[i], OUTPUT);
for (uint8_t i=0; i<5; i++) {
_i2c.pinMode(_button_pins[i], INPUT);
_i2c.pullUp(_button_pins[i], 1);
_i2c.defaultvalue(_button_pins[i], 1);
_i2c.interruptControl(_button_pins[i], 1);
_i2c.interruptEnable(_button_pins[i], 1);
}
}
Code: Select all
void Adafruit_RGBLCDShield::write4bits(uint8_t value) {
// if (_i2cAddr != 255) {
if (1 != 1) {
uint16_t out = 0 ;
out = _i2c.readGPIOAB();
// speed up for i2c since its sluggish
for (int i = 0; i < 4; i++) {
out &= ~_BV(_data_pins[i]);
out |= ((value >> i) & 0x1) << _data_pins[i];
}
// make sure enable is low
out &= ~ _BV(_enable_pin);
_i2c.writeGPIOAB(out);
// pulse enable
delayMicroseconds(1);
out |= _BV(_enable_pin);
_i2c.writeGPIOAB(out);
delayMicroseconds(1);
out &= ~_BV(_enable_pin);
_i2c.writeGPIOAB(out);
delayMicroseconds(100);
} else {
for (int i = 0; i < 4; i++) {
// _pinMode(_data_pins[i], OUTPUT);
_digitalWrite(_data_pins[i], (value >> i) & 0x01);
}
pulseEnable();
}
}
Code: Select all
uint16_t Adafruit_RGBLCDShield::readButtons(void) {
uint16_t reply ;
//for (uint8_t i=0; i<5; i++) {
// reply &= ~((_i2c.digitalRead(_button_pins[i])) << i);
//}
reply = _i2c.readInterrupts();
return reply;
}
Code: Select all
/*********************
Example code for the Adafruit RGB Character LCD Shield and Library
This code displays text on the shield, and also reads the buttons on the keypad.
When a button is pressed, the backlight changes color.
**********************/
//include the library code:
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore
// However, you can connect other I2C sensors to the I2C bus and share
// the I2C bus.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
// These #defines make it easy to set the backlight color
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7
volatile uint16_t buttons, b2, test , test2;
volatile boolean bRead;
unsigned long tnow;
void setup() {
// Debugging output
Serial.begin(9600);
// set up the LCD's number of rows and columns:
lcd.begin(20, 4);
// Print a message to the LCD. We track how long it takes since
// this library has been optimized a bit and we're proud of it :)
int time = millis();
lcd.print("Hello, world!");
time = millis() - time;
Serial.print("Took "); Serial.print(time); Serial.println(" ms");
lcd.setBacklight(0);
pinMode(1,INPUT); //set the pin to input
digitalWrite(1, LOW);
//Enable Pin Change Interrupt
PCMSK1 |= (1 << PCINT9);
PCICR |= (1 << PCIE1); // 8 - 15
test = 255;
tnow = millis();
}
ISR(PCINT1_vect)
{
if (digitalRead(1) == HIGH){
buttons += 1;
b2 +=1;
bRead = true;
}
}
void loop() {
if (bRead == true )
{
while (digitalRead(1) == HIGH){
test = lcd.readButtons();
b2 --;
}
bRead = false;
// buttons = 0;
}
if (millis() - tnow >= 1000 ) {
tnow = millis();
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis()/1000);
lcd.setCursor(0, 2);
lcd.print(buttons);
lcd.setCursor(0, 3);
lcd.print(test);
// if (buttons) {
//lcd.clear();
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(0,0);
if (~test & BUTTON_UP) {
lcd.print("UP ");
Serial.println("UP ");
// lcd.setBacklight(RED);
}
if (~test & BUTTON_DOWN) {
lcd.print("DOWN ");
Serial.println("DOWN ");
// lcd.setBacklight(YELLOW);
}
if (~test & BUTTON_LEFT) {
lcd.print("LEFT ");
Serial.println("LEFT ");
// lcd.setBacklight(GREEN);
}
if (~test & BUTTON_RIGHT) {
lcd.print("RIGHT ");
Serial.println("RIGHT ");
// lcd.setBacklight(TEAL);
}
if (~test & BUTTON_SELECT) {
lcd.print("SELECT ");
Serial.println("SELECT ");
// lcd.setBacklight(VIOLET);
}
// }
}
}
-
- Posts: 4
- Joined: Thu Jul 19, 2012 3:11 pm
Re: RGB LCD Backpack - Interrupt
The I2C speedup to 400 KHZ helps hugely, too!
-
- Posts: 1
- Joined: Sun Dec 19, 2010 12:58 am
Re: RGB LCD Backpack - Interrupt
tedcool, I tried to use your code but I haven't had any success. The LCD flashes on and then off again quickly.
I haven't made any changes to the wiring, it looks like pin 20 on the MCP23017 should go to pin 1 on the arduino? I didn't want to make any physical changes unless I had to, not sure if this is why it is crashing?
I've double checked that I made the changes correct but maybe if you could upload your files? Or maybe this is an incompatibility with new Arduino? I'm running 1.0.3
thanks,
I haven't made any changes to the wiring, it looks like pin 20 on the MCP23017 should go to pin 1 on the arduino? I didn't want to make any physical changes unless I had to, not sure if this is why it is crashing?
I've double checked that I made the changes correct but maybe if you could upload your files? Or maybe this is an incompatibility with new Arduino? I'm running 1.0.3
thanks,
-
- Posts: 27
- Joined: Tue Oct 30, 2012 6:57 am
Re: RGB LCD Backpack - Interrupt
I don't know if you've solved the issue but I've followed instructions in post
http://www.adafruit.com/forums/viewtopi ... 31&t=32813
and it worked for me. Well explained, maybe a complete example sketch could be better but after figuring how it works I've been able to use the code in my application. I post here the code, derived from the HelloWorld example in Adafruit library:
I hope to help !!!
But I also have some doubts, because if attachInterrupt uses mode LOW or CHANGE, the sketch hangs. Any idea ?
Regards,
Joan
http://www.adafruit.com/forums/viewtopi ... 31&t=32813
and it worked for me. Well explained, maybe a complete example sketch could be better but after figuring how it works I've been able to use the code in my application. I post here the code, derived from the HelloWorld example in Adafruit library:
Code: Select all
/*********************
Example code for the Adafruit RGB Character LCD Shield and Library
This code displays text on the shield, and also reads the buttons on the keypad.
When a button is pressed, the backlight changes color.
**********************/
// include the library code:
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore
// However, you can connect other I2C sensors to the I2C bus and share
// the I2C bus.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
// These #defines make it easy to set the backlight color
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7
// Interruptons: pin 3 = interrupt 1 in Arduino Uno & Mega
volatile boolean isTriggered = false;
void setup() {
// Debugging output
Serial.begin(9600);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD. We track how long it takes since
// this library has been optimized a bit and we're proud of it :)
int time = millis();
lcd.print("Hello, world!");
time = millis() - time;
Serial.print("Took "); Serial.print(time); Serial.println(" ms");
lcd.setBacklight(WHITE);
//Catch the external interrupt from the button input
attachInterrupt(1,ISR_Button, FALLING);
//Tell the MCP23017 to start making interrupts
lcd.enableButtonInterrupt();
}
uint8_t i=0;
void loop() {
uint8_t buttons;
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis()/1000);
if (isTriggered) {
//while (!digitalRead(3)) {
isTriggered = false;
buttons = lcd.readButtons();
//}
if (buttons) {
lcd.clear();
lcd.setCursor(0,0);
if (buttons & BUTTON_UP) {
lcd.print("UP ");
lcd.setBacklight(RED);
}
if (buttons & BUTTON_DOWN) {
lcd.print("DOWN ");
lcd.setBacklight(YELLOW);
}
if (buttons & BUTTON_LEFT) {
lcd.print("LEFT ");
lcd.setBacklight(GREEN);
}
if (buttons & BUTTON_RIGHT) {
lcd.print("RIGHT ");
lcd.setBacklight(TEAL);
}
if (buttons & BUTTON_SELECT) {
lcd.print("SELECT ");
lcd.setBacklight(VIOLET);
}
}
}
}
//ISR to service the button interrupt
void ISR_Button() {
isTriggered = true;
}
But I also have some doubts, because if attachInterrupt uses mode LOW or CHANGE, the sketch hangs. Any idea ?
Regards,
Joan
- GeertVc
- Posts: 1
- Joined: Mon Mar 02, 2015 2:22 pm
Re: RGB LCD Backpack - Interrupt
adafruit_support_rick wrote:The mcp23017 helps you out with this a little bit by providing the INTCAP register, which will tell you which pin caused the interrupt.
You're right... I meant the INTF register, but mistakenly wrote the INTCAP register. Sorry for the confusion caused...adafruit_support_rick wrote:This is not correct. The INTCAP register only "snapshots" the state of the IO pins the moment the interrupt happens. There's another register, INTF or Interrupt Flag Register, that indicates exactly which pin(s) have caused the interrupt. That register must be used to know the origin of the interrupt.
Last edited by GeertVc on Thu Mar 03, 2016 2:09 am, edited 1 time in total.
-
- Posts: 4
- Joined: Thu Jul 19, 2012 3:11 pm
Re: RGB LCD Backpack - Interrupt
I forgot to explain that I am using the interrupt pins from the mcp23017 connected to the arduino - see my ugly code example where I set the pin change interrupt.
I connected 19 and 20 together - I'm happy to use 1 interrupt service routine for both porta and portb.
pinMode(1,INPUT); //set the pin to input
digitalWrite(1, LOW);
//Enable Pin Change Interrupt
PCMSK1 |= (1 << PCINT9);
PCICR |= (1 << PCIE1); // 8 - 15
I connected 19 and 20 together - I'm happy to use 1 interrupt service routine for both porta and portb.
pinMode(1,INPUT); //set the pin to input
digitalWrite(1, LOW);
//Enable Pin Change Interrupt
PCMSK1 |= (1 << PCINT9);
PCICR |= (1 << PCIE1); // 8 - 15
Please be positive and constructive with your questions and comments.