Why are MCP23017 (port extender) input pins high by default?

Consider the following sketch.

With nothing connected to the input ports, this prints "1111111111111111".
If I apply 3v to the first port, it still prints "1111111111111111".
If I apply ground to the first port, it prints "0111111111111111".

I would like it to be the opposite. With nothing connected it should be "0000000000000000" and when 3v is applied to the first pin it should be "10000000000000000".

#include <Adafruit_MCP23017.h> //port extender

Adafruit_MCP23017 mcp;

void setup() {
  // Setup port extender
  Wire.begin();
  mcp.begin(0);
  
  for (int i = 0; i <= 15; i++) {
    mcp.pinMode(i, INPUT);
  }

  for (int i = 0; i <= 15; i++) {
    Serial.print(mcp.digitalRead(i));
  }
  Serial.println("");
}

void loop() {

}

With nothing connected it should be ...l

Look at the data sheet. You have to enable the pull up resistors and set the bytes to read inverted.

They are not high by default, they float by default any reading will not be reliable.

so can it be handled in code?or a resistor required?

MCP23017 (port extender) output pins are unpredictable while booting.once booted it settles to what I have set as initial values.

I am not sure if it can be handled in code or any resistor required between pin and positive +.(what should be the value of resistor)

or a resistor required

Yes.

thanks for clarification,can we use any resistor between 1k to 10k ohm?

In above link i can see piece of code as below which enables pullup.so by reducding external/physical resistor.

Will it work.

//--------ENABLE PULLUPS (default is off)-------------------
mcp.setGPIOABPullUp(0xFFFF); //all enabled
temp = mcp.getRegister( MCP23017_GPPUB );
Serial.print("GPPUB: ");
Serial.print(temp, BIN); //0 = pull up disabled, 1=pull up enabled
Serial.println();

What has this got to do with the original question?

Yes you can enable pull up resistors in code. But then the default value is all ones not all zeros as there is no internal pull down resistors.

Which Arduino? Which pins are you using? Post your code between code tags, like this:

[code]
Your
  code
    here.
[/code]

:astonished: Alert, alert! XY Problem detected! :astonished:

Grumpy_Mike:
Look at the data sheet. You have to enable the pull up.

I was confused with this answer because I have the same issue as original question i wanted default value 00....but you mentioned like we need to enable pull up.

so now i have to enable pull down for all 16 additional gpios by adding resistor between pin and ground,right?

I was confused with this answer because I have the same issue as original question i wanted default value 00....but you mentioned like we need to enable pull up.

The suggestion to use pull-ups was so that you had valid inputs. Without an active sensor, pull-up or pull-down, the input pin(s) are floating and are invalid, unknown logic levels.

Why do you need inputs to be zero? You’ve not explained anything about your inputs other than you’re using 3 volts to test. Is that the supply voltage of the MCP23017? Is that the system voltage?

i have to enable pull down for all 16 additional gpios by adding resistor between pin and ground,right?

Yes, if you need pull-downs for some unknown, unexplained reason, you must must add external resistors. Most times though, you would just enable the internal pull-up and you’re done. If you’re reading a switch and you want the logic reversed so the the input is a zero with the button released and a one with the button pressed, let the compiler do it for you by reading the input like this:

inputPushbutton = ! digitalRead(pin);

so now i have to enable pull down for all 16 additional gpios by adding resistor between pin and ground,right?

Yes if you want the period between the power up or reset, to the code running to have the value of zero. This is sometimes needed if those pins are eventually going to be outputs and you have wired the outputs to be active high ( a common rookie mistake ). Then you might need a pull down resistor on those pins but more commonly you would design the system so that peripherals are active low.

I am not sure if it can be handled in code

No, because the problem is before any code is run so there is nothing code can do to affect this.

or any resistor required between pin and positive +.(what should be the value of resistor)

Yes a resistor from 10K to 30K should ensure you have a weak logic one from power up. If you want a weak logic zero then connect it to ground.

However, I will agree with the others that knowing context would remove all the guess work from answers.

Grumpy_Mike:
Yes if you want the period between the power up or reset, to the code running to have the value of zero. This is sometimes needed if those pins are eventually going to be outputs and you have wired the outputs to be active high ( a common rookie mistake ). Then you might need a pull down resistor on those pins but more commonly you would design the system so that peripherals are active low.

Outputs are routinely designed to be active high with pull-down resistor... especially if there's a MOSFET connected to them.

As a separate note, it'd probably be a good idea to have this discussion not split over two threads.

wvmarle:
Outputs are routinely designed to be active high with pull-down resistor... especially if there's a MOSFET connected to them.

Or also routinely designed to be active low with pull-up resistor... especially if there's a logic-level device connected to them.

Having the source voltage contained within the device receiving the control signal tends to make the interconnection more "fail-safe" in terms of accidental shorts.

@vijayvikma, do not cross-post. Threads merged.