1

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.

asked Aug 28, 2017 at 20:36
0

1 Answer 1

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.

answered Aug 29, 2017 at 9:01
1
  • 1
    I 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. Commented Sep 11, 2017 at 3:01

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.