0

Reading Dipswitches from MCP23017 I2C
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Reading Dipswitches from MCP23017 I2C

by larrywal32 on Sun Aug 18, 2019 1:01 am

Hi folks - I've been following this tutorial: https://medium.com/@wilko.vehreke/more- ... 9f5e15cde3

...to get a nodeMCU working with an MCP23017 for IO expansion.

I have the whole tutorial working for a basic blink done through the MCP23017 and using the adafruit library.

Now I'm trying to use the MCP23017 to read values of dipswitches. Here's what I did so far:
    *I declared Adafruit pin 1 (physical pin 22) as an OUTPUT pin, and I connected it to each dipswitch input in parallel. (My goal is to use this to send a signal through all the dipswitches).

    *I declared Adafruit pins 8 through 11 (physical pins 1 through 4) as INPUT pins, and I connected each to the negative side of a dipswitch.

    *I then am using the below code to try to continuously read the values of the dipswitches.


However, when I look at the serial monitor, every now and then it appears to read the proper values, but over time the values seem to change at random and then after a minute or so the values simply report back 1 1 1 1, with the occasional 1 1 1 0. I'm sure I must be doing something wrong...or misunderstanding how to read data.

Here is an example from the serial output I just ran - didn't change anything in the dipswitches on any iteration. 0100 was the correct reading.

Direct Read Values: 1 1 1 1
Direct Read Values: 1 1 1 1
Direct Read Values: 1 1 1 0
Direct Read Values: 0 1 0 0
Direct Read Values: 1 1 1 1
Direct Read Values: 1 1 1 1
Direct Read Values: 1 1 1 1


Thanks so much in advance for your help. I'm at a loss.

Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>
#include "Adafruit_MCP23017.h"
// Instance of MCP23017 library
Adafruit_MCP23017 mcp;
void setup() { 
  // Initialize the MCP23017
  mcp.begin();
 
  // Define GPA0 (physical pin 21) as output pin
  mcp.pinMode(0, OUTPUT);

  // Define GPA1 (physical pin 22) as output pin
  mcp.pinMode(1, OUTPUT);

  //Define GPB0, 1, 2, 3 as input pins (physical pins 1, 2, 3, 4)
  mcp.pinMode(8, INPUT);
  mcp.pinMode(9, INPUT);
  mcp.pinMode(10, INPUT);
  mcp.pinMode(11, INPUT);

  Serial.begin(9600);
 
}

void loop() {
 
  int dipNum = 0;
  int dip1=0;
  int dip2=0;
  int dip3=0;
  int dip4=0;

  //read the dip switches
  mcp.digitalWrite(1, HIGH);

  Serial.print("Direct Read Values: ");
  Serial.print(mcp.digitalRead(8));
  Serial.print(" ");
  Serial.print(mcp.digitalRead(9));
  Serial.print(" ");
  Serial.print(mcp.digitalRead(10));
  Serial.print(" ");
  Serial.print(mcp.digitalRead(11));
  Serial.println();

  mcp.digitalWrite(1, LOW);
 
  delay(7000);
}

[/list]

larrywal32
 
Posts: 4
Joined: Sun Aug 18, 2019 12:53 am

Re: Reading Dipswitches from MCP23017 I2C

by kcl1s on Sun Aug 18, 2019 6:33 am

Your inputs are 'floating' in no definite state because when the switch is open there is no connection. The way you have it wired and coded you need to add 10k resistors between each pin and ground. These will pull the pins low when the dip switch is open.

Another option is to wire the other side of the dip switches to ground then set the pins to input pullup mode by adding this code
mcp.pullUp(8, HIGH); for each input. This sets the internal pull up resistors to pull the pin high when the switch is open. This way you don't have to use external pull down resistors. This makes wiring easier but when using the input pull up your logic will be reversed (switch closed = LOW, switch open = HIGH) so you have to change your code to reflect this.

The MCP23017 library example code named button shows how the code works.

These are the same options you use on the regular Arduino digital pins.

Fellow hobbyist
Keith

kcl1s
 
Posts: 1248
Joined: Tue Aug 30, 2016 12:06 pm

Re: Reading Dipswitches from MCP23017 I2C

by larrywal32 on Sun Aug 18, 2019 7:25 pm

Thank you - this is fantastic. I got it working - didn't know the examples existed.

One question - why 10k for the resistor value? How was 10k calculated? Is that specific to the NodeMCU?

larrywal32
 
Posts: 4
Joined: Sun Aug 18, 2019 12:53 am

Re: Reading Dipswitches from MCP23017 I2C

by kcl1s on Sun Aug 18, 2019 8:57 pm

larrywal32 wrote:Thank you - this is fantastic. I got it working - didn't know the examples existed.

One question - why 10k for the resistor value? How was 10k calculated? Is that specific to the NodeMCU?

Glad you got it working.

The 10k value allows the pin to be pulled low when the switch is open but will not pass a lot of current when the switch is closed. This is standard Arduino practice no matter which processor you are using. The value is not critical as long as it is in this range. You would not want to use a 220 ohm LED current limiting resistor for pull down.

In addition to the library examples there are other builtin examples in the Arduino IDE that help you learn some of the basic functions. Most examples will apply to the 8266 boards as well. You can find tutorials on them on arduino.cc https://www.arduino.cc/en/Tutorial/BuiltInExamples This tutorial explains the button wiring. https://www.arduino.cc/en/Tutorial/DigitalReadSerial

By the way in the tutorial link you provided the author does not use current limiting resistors for the LED circuits. This is not a good practice as it may blow the MCP23017, the LED or both. The expander digital I/O should be treated the same as regular micro controller pins. This tutorial shows the proper LED wiring https://www.arduino.cc/en/Tutorial/Blink

Hope this helps
Keith

kcl1s
 
Posts: 1248
Joined: Tue Aug 30, 2016 12:06 pm

Please be positive and constructive with your questions and comments.