Hello, everyone.
I am trying to do a small project using few i2c peripherials.
First of all, I am using I2C connected LCD display (16x2), works just fine.
Additionally, I am using MCP23017 for handling the input buttons and output pins.
My code follows:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define LCD_I2C_ADDR 0x27
#define MCP 0x20
#define MCPenable 4
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
#define LED 13
LiquidCrystal_I2C lcd(LCD_I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
byte intValue = 0;
byte inputs = 1;
byte intState = 0;
void setup()
{
Wire.begin();
lcd.begin (16,2);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.clear();
Wire.begin();
// first we reset MCP
pinMode(MCPenable, OUTPUT);
digitalWrite(MCPenable, LOW);
delay(10);
digitalWrite(MCPenable, HIGH);
delay(10);
I2Csend(MCP, 0x01, 0x00); // set all of bank B to OUTPUTS
I2Csend(MCP, 0x00, 0xFF); // set all of bank A to INPUTS
I2Csend(MCP, 0x0C, 0xFF); // set pullup ON for bank A
I2Csend(MCP, 0x02, 0xFF); // invert inputs of bank A
I2Csend(MCP, 0x04, 0xFF); // enable interrupt for all pins of bank A
pinMode(LED, OUTPUT);
attachInterrupt(1, intControl, RISING);
}
void loop()
{
Wire.beginTransmission(MCP);
Wire.write(0x12); // GPIOA
Wire.endTransmission();
Wire.requestFrom(MCP, 1);
inputs = Wire.read();
//I2Csend(MCP, 0x13, inputs);
lcd.setCursor(0,0);
lcd.print("Inputs: ");
lcd.print(inputs);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Int: ");
lcd.print(intValue / 2);
lcd.print(" ");
lcd.print(intState);
lcd.print(" ");
delay(50); // for debounce
}
void I2Csend(byte I2Caddress, byte memAddr, byte memValue) {
Wire.beginTransmission(I2Caddress);
Wire.write(memAddr); // IODIRA register
Wire.write(memValue); // set all of bank A to INPUTS
Wire.endTransmission();
}
void intControl() {
detachInterrupt(1);
// this works no problem
intValue++;
digitalWrite(LED, !digitalRead(LED));
//problem code - trying to get the interrupt register value from MCP port A (reg. 0x10)
Wire.begin();
Wire.beginTransmission(MCP);
Wire.write(0x10);
Wire.endTransmission();
Wire.requestFrom(MCP, 1);
intState = Wire.read();
I2Csend(MCP, 0x13, intState);
// end of problem code
delay(100); // debounce?
attachInterrupt(1, intControl, RISING);
}
The problem is, that without interrupt handling, all acts well.
As soon as I wired the interrupt pin to the Arduino pin 3, the code works, but only when I disable the problematic part within the interrupt handling.
I assume the timing interrupts, relevant for i2c communication, are not working when external interrupt occur, but that's just my guess.
Anyone have any example for me or an advice, what am I doing wrong?
Thanks.