Hello, I'm new to arduino and to code...
I've been trying to figure out how to use interrupt encoders using an MCP23017 module on Arduino pro micro (clone) for several days without success.
I tested my circuit with the example code from Adafruit_MCP23017_Arduino_Library (mcp23xxx_interrupt) and it works.
But when I use a code I've found on internet, it doesn't work. Nothing happens in the serial.
It's supposed to be a debugging code so it should work and I must have a problem in my setup...
Here is the original code:
And more, after uploading the code, my ardiuno pro micro is blocked. I have to disconnect the SDA and SCL connections and re-upload an empty code to get it back.
Here's my schematic:
here are the codes I use:
-mcp23xxx_interrupt, it works : mcp23xxx_interrupt - Pastebin.com
-Encoders_interrupt (Adapted from the link above), does not work:
/*
Made by Gustavo Silveira, 2023.
http://www.musiconerd.com
http://www.youtube.com/musiconerd
http://facebook.com/musiconerdmusiconerd
http://instagram.com/musiconerd/
http://www.gustavosilveira.net
gustavosilveira@musiconerd.com
*/
//#include <Wire.h>
#include <Adafruit_MCP23X17.h> // Include the Adafruit_MCP23X17 library
Adafruit_MCP23X17 mcp; // Create an instance of the Adafruit_MCP23X17 class
const int I2C_ADDRESS = 0x20; // MCP23017 I2C address
int INT_PIN = 7;
byte encIndex;
const int ENCODER_N = 2; // Number of encoders used
int encoderPin[ENCODER_N][2] = {{0, 1}, {2, 3}}; // Pin numbers for the A and B channels of each encoder
// const int encoderPin[ENCODER_N][2] = {{8, 9}, {0, 1}, {12, 13}, {10, 11}, {2, 3}, {14, 15}}; // Pin numbers for the A and B channels of each encoder
int count[ENCODER_N] = {0}; // Current count of each encoder
int lastCount[ENCODER_N] = {0}; // Previous count of each encoder
int encoderA[ENCODER_N] = {0}; // Current state of the A channel of each encoder
int encoderB[ENCODER_N] = {0}; // Current state of the B channel of each encoder
int lastEncoderA[ENCODER_N] = {HIGH}; // Previous state of the A channel of each encoder
int lastEncoderB[ENCODER_N] = {HIGH}; // Previous state of the B channel of each encoder
void setup() {
Serial.begin(9600);
while (!Serial) {
Serial.println("waiting...");
}
Serial.println();
// uncomment appropriate mcp.begin
if (!mcp.begin_I2C(I2C_ADDRESS, &Wire)) { // Wire1 or Wire
//if (!mcp.begin_SPI(CS_PIN)) {
Serial.println("MCP23017 Error.");
while (1)
;
} else {
Serial.println("MCP23017 Success.");
}
// configure MCU pin that will read INTA/B state
pinMode(INT_PIN, INPUT_PULLUP);
for (int i = 0; i < ENCODER_N; i++) {
for (int j = 0; j < 2; j++) {
mcp.pinMode(encoderPin[i][j], INPUT_PULLUP);
mcp.setupInterruptPin(encoderPin[i][j], CHANGE);
}
}
// OPTIONAL - call this to override defaults
// mirror INTA/B so only one wire required
// active drive so INTA/B will not be floating
// INTA/B will be signaled with a LOW
mcp.setupInterrupts(true, false, CHANGE);
//attachInterrupt(digitalPinToInterrupt(INT_PIN), getLastInterrupt, CHANGE); // gets the MCP23017 pin that was "interrupted"
attachInterrupt(digitalPinToInterrupt(INT_PIN), readEncoder, CHANGE); // reads the encoder in the MCP23017
mcp.clearInterrupts(); // clearInterrupts
//Serial.println("oi...");
}
void loop() {
}
void readEncoder() {
byte interruptPin = mcp.getLastInterruptPin();
if (interruptPin >= 0 && interruptPin <= 16) {
// Serial.print("interruptPin: ");
// Serial.println(interruptPin);
updateEncIndex(interruptPin);
// Serial.print("encIndex: ");
// Serial.println(encIndex);
int encoderA = mcp.digitalRead(encoderPin[encIndex][0]); // Read the state of the A channel of the current encoder
int encoderB = mcp.digitalRead(encoderPin[encIndex][1]); // Read the state of the B channel of the current encoder
if (encoderA != lastEncoderA[encIndex]) { // Check if the state of the A channel has changed
if (encoderA == LOW) { // If the state of the A channel is LOW
if (encoderB == LOW) { // If the state of the B channel is also LOW
count[encIndex]--; // Decrement the count for this encoder
} else {
count[encIndex]++; // Otherwise, increment the count for this encoder
}
}
lastEncoderA[encIndex] = encoderA; // Update the previous state of the A channel
}
if (count[encIndex] != lastCount[encIndex]) { // If the count has changed
Serial.print("Encoder ["); // Print the encoder number
Serial.print(encIndex);
Serial.print("]: ");
Serial.println(count[encIndex]); // Print the current count
lastCount[encIndex] = count[encIndex]; // Update the previous count
}
}
mcp.clearInterrupts(); // clear
}
void updateEncIndex(int _interruptPin) {
// Loop through each subarray in encoderPin
for (int i = 0; i < ENCODER_N; i++) {
// Check if _interruptPin matches either value in the current subarray
if (_interruptPin == encoderPin[i][0] || _interruptPin == encoderPin[i][1]) {
// If a match is found, set encIndex to the current index i and exit the loop
encIndex = i;
break;
}
}
}
void getLastInterrupt() {
byte interruptPin = mcp.getLastInterruptPin();
if (interruptPin >= 0 && interruptPin < 16) {
Serial.println(interruptPin);
//Serial.println(Serial.print(interruptPin));
// Serial.print("Interrupt detected on pin: ");
// Serial.println(interruptPin);
// Serial.print("Pin states at time of interrupt: 0b");
// Serial.println(mcp.getCapturedInterrupt(), 2);
delay(25); // debounce
// NOTE: If using DEFVAL, INT clears only if interrupt
// condition does not exist.
// See Fig 1-7 in datasheet.
}
mcp.clearInterrupts(); // clear
}
Thanks for your help!

