I am using an Arduino Uno and an MCP23008 GPIO pin expander, I have a momentary button connected to GPIO 2 on the MCP23008 and an LED light connected to GPIO 1 on the MCP23008. What I want is for the LED to turn on when the button is pressed down, and off otherwise. The code I currently have is this:
#include "Wire.h" //import Wire library
byte inVal; //declare byte variable
void setup() {
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(0x20); //MCP23008 i2c addr
Wire.write(0x00); //MCP23008 internal register addr for I.O.dir
Wire.write(00000010); //set all pins as output, except for #2 as input
Wire.endTransmission();
}
void loop() {
Wire.begin();
Wire.beginTransmission(0x20); //MCP23008 i2c addr
Wire.write(0x09); //MCP23008 internal register addr for GPIO access
//Wire.write(0xFF); //set all output pins to HIGH, commented out for now.
Wire.endTransmission();
Wire.requestFrom(0x20,1); //get one byte of input input from MCP23008
inVal=Wire.read(); //set pyte as variable
//Serial.println(inVal,BIN); //output byte to serial monitor, commented out for now
Serial.println(bitRead(inVal, 1)); //output second bit from byte(1 or 0, for HIGH or LOW, depending on the press of the momentary button.
if((bitRead(inVal, 1)==1)) //if the bit from the button is high,
{
Wire.beginTransmission(0x20);
Wire.write(0x09);
Wire.write(0xFF); //then set all output pins as HIGH
Wire.endTransmission();
}
else if((bitRead(inVal, 1)==0)) //if the bit from the button is low,
{
Wire.beginTransmission(0x20);
Wire.write(0x09);
Wire.write(0x00); //then set all output pins as LOW
Wire.endTransmission();
}
}
I don't know as much Arduino as I do Python, and I have even less experience with i2c connections and the Wire library, but this looks to me like it should be working.
The bit printed on the serial monitor is HIGH, until I press the button once, then it stays LOW forever until I modify and re-upload the code to the Arduino. Not sure what's going wrong here. Anything helps, thanks.
1 Answer 1
I see one major thing wrong at first glance:
Wire.write(00000010); //set all pins as output, except for #2 as input
That doesn't set GPIO 1 (which you call number 2 - counting starts at 0 not 1) to be an input, that sets GPIO 3 (number 4) as an input. Numbers starting with 0
are octal, not binary. For binary the prefix is 0b
:
Wire.write(0b00000010); //set all pins as output, except for #2 as input
And then you read using:
bitRead(inVal, 1)
which would have read GPIO 1 which is configured as an output.
So you have a switch on GPIO 1 which is an output, which you then drive high (causing a short internally which can damage the pin), and as a result you drive the pin HIGH internally. Now it's always high, so a read of the pin sees the HIGH you are driving from it. Hence it gets stuck at 1.
Fixing your IODIR write should help solve that problem.
-
1I changed the IODir to Binary, but it still isn't working, and in the same way. (At one point, the led started blinking every second, I don't know why, and I have been unable to replicate this. What I want is to get high/low input from pin 1, if it is high, set pin 0 out as high, if it is low, set pin 0 out low. Been stuck on this for weeks now, and I don't get why. What am I missing? Thanks.E. Pence– E. Pence2017年09月11日 03:01:57 +00:00Commented Sep 11, 2017 at 3:01
Explore related questions
See similar questions with these tags.