I'm making a custom steering wheel for my racing sim and I encountered an unusual behavior. I am using the interrupt pin on my Pro Micro to read rotary encoders hooked up on two MCP23017 modules. The interrupt seems to be working fine when only a serial output is in the callback function. But as soon as try to get the last interrupt pin or read any of the pins on the expander, the entire code stops. The same methods work fine in the main loop though.
#include <Encoder.h>
#include <Joystick.h>
#include <Adafruit_MCP23X17.h>
Adafruit_MCP23X17 mcp1;
Adafruit_MCP23X17 mcp2;
int mcp1Buttons[8] = {2, 3, 6, 7, 10, 11, 14, 15};
int mcp1LastState[8] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};
int mcp2Buttons[10] = {2, 5, 8, 9, 10, 11, 12, 13, 14, 15};
int mcp2LastState[10] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD,
32, 0, // Button Count, Hat Switch Count
true, true, false, // X and Y, but no Z Axis
true, true, false, // Rx and Ry, but no Rz Axis
false, false, // No rudder or throttle
false, false, false); // No accelerator, brake, or steering
#define DEADZONE 10
void setup() {
Serial.begin(9600);
Serial.println("Serial started");
if (!mcp1.begin_I2C(0x20)) {
Serial.println("Error starting mcp 0x20");
}
if (!mcp2.begin_I2C(0x21)) {
Serial.println("Error starting mcp 0x21");
}
for (int i = 0; i < 16; i++) {
mcp1.pinMode(i, INPUT_PULLUP);
mcp2.pinMode(i, INPUT_PULLUP);
}
Joystick.begin();
Joystick.setXAxisRange(-512, 512);
Joystick.setYAxisRange(-512, 512);
Joystick.setRxAxisRange(-512, 512);
Joystick.setRyAxisRange(-512, 512);
pinMode(7, INPUT_PULLUP);
mcp1.setupInterrupts(true, false, LOW);
mcp1.setupInterruptPin(0, LOW);
mcp1.setupInterruptPin(4, LOW);
mcp1.setupInterruptPin(8, LOW);
mcp1.setupInterruptPin(12, LOW);
mcp1.clearInterrupts();
mcp2.setupInterrupts(true, false, LOW);
mcp2.setupInterruptPin(0, HIGH);
mcp2.setupInterruptPin(3, HIGH);
mcp2.setupInterruptPin(6, HIGH);
mcp2.clearInterrupts();
attachInterrupt(digitalPinToInterrupt(7), pin7Interrupt, CHANGE);
}
void loop() {
int leftX = analogRead(A0) - 512;
int leftY = analogRead(A1) - 512;
int rightX = analogRead(A2) - 512;
int rightY = analogRead(A3) - 512;
if (abs(0 - leftX) <= DEADZONE) {
leftX = 0;
}
if (abs(0 - leftY) <= DEADZONE) {
leftY = 0;
}
if (abs(0 - rightX) <= DEADZONE) {
rightX = 0;
}
if (abs(0 - rightY) <= DEADZONE) {
rightY = 0;
}
Joystick.setXAxis(leftX);
Joystick.setYAxis(leftY);
Joystick.setRxAxis(rightX);
Joystick.setRyAxis(rightY);
for (int i = 0; i < 8; i++) {
int state = mcp1.digitalRead(mcp1Buttons[i]);
if (state != mcp1LastState[i]) {
if (state == LOW) {
Joystick.pressButton(mcp1Buttons[i]);
mcp1LastState[i] = LOW;
}
}
if (state == HIGH) {
Joystick.releaseButton(mcp1Buttons[i]);
mcp1LastState[i] = HIGH;
}
}
for (int i = 0; i < 10; i++) {
int state = mcp2.digitalRead(mcp2Buttons[i]);
if (state != mcp2LastState[i]) {
if (state == LOW) {
Joystick.pressButton(mcp2Buttons[i] + 8);
mcp2LastState[i] = LOW;
}
else if (state == HIGH) {
Joystick.releaseButton(mcp2Buttons[i] + 8);
mcp2LastState[i] = HIGH;
}
}
}
}
void pin7Interrupt() {
Serial.println("Interrupt");
uint8_t lastPin = mcp1.getLastInterruptPin();
if(lastPin != 255) {
if (mcp1.digitalRead(0) != mcp1.digitalRead(1)) {
Serial.println("1");
}
else {
Serial.println("-1");
}
}
}