Hello,
I'm setting up a series of libraries for my own project, interfacing a matrix keyboard to an arduino nano (for the moment) using an mcp23008, and reading the pressed key as suggested in the AN1081 application note.
the problem is that I cannot use the component in an interrupt. Here is a sample code (I can expand it if it is necessary). Please do mind that the code works if outside of the interrupt
#include <Wire.h>
#include <mcp23008.h>
#include <i2ckeyboard.h>
const static char *keys[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#"};
// i2c address
i2ckeyboard keyboard(0x27);
void setup() {
// Just sets up the registrs
keyboard.setup();
//Serial if later needed
Serial.begin(9600);
// Sets up the INT0 interrupt pin port as input
DDRD &= ~(1 << DDD2);
PORTD &= ~(1 << PORTD2);
// Sets up port B1 as inactive output to flash LED when interrupt
DDRB |= (1 << DDB1);
PORTB &= ~(1 << PORTB1);
// Interrupt setup
cli();
// Activate interrupt on falling edge of INT0
EICRA|=(1<<ISC01);
EICRA&=~(1<<ISC00);
// Enabling INT0 interrupt mask
EIMSK |= (1 << INT0);
// Enabling interrupts
sei();
}
// Interrupt
ISR(INT0_vect) {
// Clears interrupt - TBD see if really needed
cli();
// Flashing led
PORTB |= (1 << PORTB1);
// Reads the key
uint8_t c = keyboard.readKey();
// Shuts down LED
PORTB &= ~(1 << PORTB1);
sei();
//;
}
void loop() {
// put your main code here, to run repeatedly:
//Serial.println(100);
delay(500);
}
Currently the code stops with the led on. The content of the setup function basically… sets up the registers of the component just as said in the aforementioned application note.
The readKey function has been now reduced to
uint8_t i2ckeyboard::readKey(void){
uint8_t startCapture=readByte(0x08);
return startCapture;
}
(yes I do have defined constants for registers)
And "readByte" is defined in an internal library as
uint8_t data;
Wire.beginTransmission(_address);
Wire.write(adr);
Wire.endTransmission();
Wire.requestFrom((uint8_t)_address,(uint8_t)1);
while (Wire.available()) data=Wire.read();
return data;
and I have used it successfully in interrupts before (eg. on a attiny25v while interfacing to an mcp79410 RTC).
So my question is:
what am I doing wrong?
As remarked before the code works outside the interrupt, but I really would like to be able to read the values during the interrupt execution. Do you have enough info from the code I posted or do you need more?
Thanks