The following sketch is my failed attempt to read MCP23S17 pin values using the Arduino SPI library.
The setup is four normally open buttons connected to MCP23S17 port B input pins 0-3.
link to picture of hardware
When a button is pressed, Serial.print is supposed to display what button was pressed.
The expected output is:
1 //button 1 pressed
10 //button 2 pressed
100 //button 3 pressed
1000 //button 4 pressed
1111 //all four buttons pressed
In reality the sketch always prints 1 for all pins; no matter what the pin values are:
11111111
11111111
11111111
11111111
sketch:
#include <SPI.h>
const uint8_t ADDR = 0x20; //MCP23S17 address, all ADDR pins are grounded
const uint8_t OPCODE_WRITE = (ADDR << 1 | 0x00); //MCP23S17 opcode write has LSB clear
const uint8_t OPCODE_READ = (ADDR << 1 | 0x01); //MCP23S17 opcode read has LSB set
const uint8_t IODIRB = 0x01; //buttons are on port B
const uint8_t GPIOB = 0x13;
uint8_t buttonState = 0; //bit wise
uint8_t IOERead(const uint8_t REGISTER_ADDR)
{
uint8_t data;
SPI.beginTransaction(SPISettings (SPI_CLOCK_DIV8, MSBFIRST, SPI_MODE0)); //gain control of SPI bus
digitalWrite(SS, LOW); //enable Slave Select
SPI.transfer(OPCODE_READ); //read command
SPI.transfer(REGISTER_ADDR); //register address to read data from
data = SPI.transfer(0); //save the data (0 is dummy data to send)
digitalWrite(SS, HIGH); //disable Slave Select
SPI.endTransaction(); //release the SPI bus
return data;
}
void setup()
{
Serial.begin(9600);
pinMode(SS, OUTPUT); //configure controller's Slave Select pin to output
digitalWrite(SS, HIGH); //disable Slave Select
SPI.begin();
//IODIRB register is already configured to input by default
}
void loop()
{
buttonState = IOERead(GPIOB);
if (buttonState > 0) //if a button was pressed
{
Serial.println(buttonState, BIN);
delay(200);
}
}
Buttons are active high with external pull-down resistors.
The pin's voltage is normally low.
When a button is pressed, the pin's voltage is pulled high.
I confirmed the pin voltages with a multi-meter.
The controller is Teensy LC (3.3 volts) on Arduino 1.6.7.
Teensy LC pin out: https://www.pjrc.com/teensy/card6a_rev2.png
MCP23S17 datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/20001952C.pdf
SPI library: SPI - Arduino Reference
I have read the datasheet, the Arduino SPI library reference, and some SPI examples.
Please tell me what I am missing.