I am testing an MCP23S17 with one rotary encoder for a bigger project. My intention is to Serial.print the inputs of the rotary encoder as a first step of testing. Unfortunately I get nothing, and therefore I'd be grateful for feedback where I'm going wrong, in particular the configuration of the MCP... Thanks in advance!
The wiring looks like this:
The wiring looks like this:
Code:
#include <Arduino.h>
#include <SPI.h>
// MCP23S17 registers
constexpr uint8_t IODIRA = 0x00; // IO direction (0 = output, 1 = input (Default))
constexpr uint8_t IPOLA = 0x02; // IO polarity (0 = normal, 1 = inverse)
constexpr uint8_t GPINTENA = 0x04; // Interrupt on change (0 = disable, 1 = enable)
constexpr uint8_t DEFVALA = 0x06; // Default comparison for interrupt on change (interrupts on opposite)
constexpr uint8_t INTCONA = 0x08; // Interrupt control (0 = interrupt on change from previous, 1 = interrupt on change from DEFVAL)
constexpr uint8_t IOCON = 0x0A; // IO Configuration: bank/mirror/seqop/disslw/haen/odr/intpol/notimp
constexpr uint8_t GPPUA = 0x0C; // Pull-up resistor (0 = disabled, 1 = enabled)
constexpr uint8_t INFTFA = 0x0E; // Interrupt flag (read only) : (0 = no interrupt, 1 = pin caused interrupt)
constexpr uint8_t INTCAPA = 0x10; // Interrupt capture (read only) : value of GPIO at time of last interrupt
constexpr uint8_t GPIOA = 0x12; // Port value. Write to change, read to obtain value
constexpr uint8_t OLLATA = 0x14; // Output latch. Write to latch output.
constexpr uint8_t csPin = 10;
constexpr uint8_t ports = 0x20;
constexpr uint8_t interruptPin = 20;
volatile bool interrupted = false;
// ISR functions
void handleInterrupt() {
interrupted = true;
}
// Write to expander
void expanderWrite(const uint8_t port, const uint8_t reg, const uint8_t data) {
digitalWrite(csPin, LOW);
SPI.transfer(port << 1); // Write mode
SPI.transfer(reg);
SPI.transfer(data);
digitalWrite(csPin, HIGH);
}
// Read from expander
uint8_t expanderRead(const uint8_t port, const uint8_t reg) {
uint8_t data = 0;
digitalWrite(csPin, LOW);
SPI.transfer((port << 1) | 1); // Read mode
SPI.transfer(reg);
data = SPI.transfer(0);
digitalWrite(csPin, HIGH);
return data;
}
void setup() {
Serial.begin(115200);
SPI.begin();
pinMode(csPin, OUTPUT);
digitalWrite(csPin, HIGH);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
// Config MCP:
// Banks segregated = 1
// mirror interrupts = 1
// disable sequential mode = 1
// slew rate disabled = 0
// no hardware adressing = 0
// no interrupt pin open drain = 0
// interrupt active high = 1
// not used = 0
expanderWrite(ports, IOCON, 0b11100010);
// Set PORT A registers
expanderWrite(ports, IODIRA, 0b11111111); // IO direction, 1 = input
expanderWrite(ports, GPPUA, 0b11111111); // Pull-up resistor, 1 = enabled
expanderWrite(ports, IPOLA, 0b11111111); // IO polarity, 1 = inverse
expanderWrite(ports, GPINTENA, 0b11111111); // Interrupt on change, 1 = enable
expanderWrite(ports, INTCONA, 0b11111111); // Interrupt control, 1 = interrupt on change compared with DEFVAL bits
expanderWrite(ports, DEFVALA, 0b11111111); // Interrupt comparison value 1 = interrupt on != 1
}
void loop() {
if (interrupted == true) {
interrupted = false;
uint8_t portA = expanderRead(ports, GPIOA);
for (uint8_t bit = 0; bit < 8; ++bit) {
Serial.print(String(bitRead(portA, bit)));
}
Serial.println();
}
}