MCP23017

Hello,
I have been having some issues using MCP23017 I/O expanders to check the status of GPIOs. Here is a brief overview of the heavily commented code: I check 128 GPIOs through the bused MCP23017s, and then check pins 22-54 on an Arduino Mega 2560. The status of all these pins is recorded in a array of 160 (arry), which is then recorded back. This all works, if i print the individual status of the pins, where i put voltage, i can see the status of them. However, in order to be useful for the project i need the absolute pin number, which is Absolute-Pin = (Card-Number * 160) + Card-Pin + 1. The absolute pin works, however if i excite the digital pin on the Arduino Mega, then try to change the status of one of the pins on the MCP23017s, the value doesn't get reported back. However, the individual pin status is updated, and can be reported back.

Any help would be much appreciated.

#include <Adafruit_MCP23017.h>  //Library for MCP23017 I/O expander. Available from GitHub: https://github.com/kasperskaarhoj/MCP23017-Arduino-Library/blob/master/MCP23017.h
#include <String.h>             // string library

#include "Wire.h"               //wire class, for serial communication 

//Global Variables, to be changed by programer
int SLAVE_ID = 1;          //Slave Is, change this while programming the boards, to corrispond to their address in the verifier
bool arry[160];

//Global Variables, to not be changed by the user


long ABSOLUTE_VALUE = 0;




//Class for checking the local master selection of MCP23017 i/O expanders, don't fuck with this class
class LocalMaster 
{
  Adafruit_MCP23017 mcps[];

  int totalChips = 8; //Total number of MCP_23017 
  
  public:
  LocalMaster() 
  {
    //Nothing in the public domain, b/c reasons
  }

  /**
   * int totalChips A number from 1 to 8
   */
  //Chip assignments    
  //addr 0 = A2 low , A1 low , A0 low  000
  //addr 1 = A2 low , A1 low , A0 high 001
  //addr 2 = A2 low , A1 high , A0 low  010
  //addr 3 = A2 low , A1 high , A0 high  011
  //addr 4 = A2 high , A1 low , A0 low  100
  //addr 5 = A2 high , A1 low , A0 high  101
  //addr 6 = A2 high , A1 high , A0 low  110
  //addr 7 = A2 high, A1 high, A0 high 111

  void start(int totalChips) //this funciton fully addressing and communicates with the MCP23017 chips, using the Adafruit_MCP23017 library
  {
    if (totalChips > 0 && totalChips <= 8) //error checking, to make sure you aren't trying to address more than 8 chips
    {
      this->totalChips = totalChips;       //passes the memory location, of the correct object
      
      for (int i = 0; i < totalChips; i++) //Iterating over a loop. Notice the number of chips fully addressed by this loop changes based on the size of totalChip, thus for troubling shooting, the number of totalChips can be changed
      {
        mcps[i] = Adafruit_MCP23017();    //creating an object within the MCP23017 library
        
        mcps[i].begin(i);                 //beginning communication
        for (int pinNumber = 0; pinNumber <= 15; pinNumber++) //interating over the 16 GPIOs that each I/O expander has
        {
          mcps[i].pinMode(pinNumber, INPUT);  //setting the pins to input, as required
        }
      }
    }
  }

  /**
   * int chipNumber A number from 1 to 8
   * int pinNumber A number from 0 to 15
   */
  bool scan(int chipNumber, int pinNumber)  //this function scans the pins for their respective digital status. 
  {
    if (chipNumber <= totalChips+1 || chipNumber >= 1 || pinNumber <= 15 || pinNumber >= 0) //Error checking, this acts as the try-catch loop, however it only exits if an error, no handling. 
    {
      mcps[chipNumber-1].pinMode(pinNumber, INPUT);     //sets to an input, incase it was in sourcing mode
      return mcps[chipNumber-1].digitalRead(pinNumber); //returns the status of the digitalread of the pinnumber 
    }
    return false;
  }

  /**
   * int chipNumber A number from 1 to 8
   * int pinNumber A number from 0 to 15
   */
  void source(int chipNumber, int pinNumber)  //this function sources voltage across the pin, up to 25mA
  {
    if (chipNumber <= totalChips+1 || chipNumber >= 1 || pinNumber <= 15 || pinNumber >= 0)
    {
      mcps[chipNumber-1].pinMode(pinNumber, OUTPUT);
      mcps[chipNumber-1].digitalWrite(pinNumber, HIGH);

      // Some constant delay stuff
      delay(1000); //look at taking this out
    }
  }
};

LocalMaster localMaster;


void setup() 
{
  localMaster.start(8); //starts all of the I/O expanders


  Serial.begin(9600);
  Wire.begin(SLAVE_ID); //begin communmciation based on the slave ID
}

void loop()
{ 
  //int ABSOLUTE_VALUE = 0;
//bool arry[160]; //array that will hold all the info about pin status. 

  //loop that iterates, using the local master class 
  for (int chipNumber = 1; chipNumber <= 8; chipNumber++)
  {
    for (int pinNumber = 0; pinNumber <= 15; pinNumber++) 
    {
     arry[(chipNumber-1)*15 + pinNumber] = localMaster.scan(chipNumber, pinNumber);
      /*
      Serial.print(chipNumber);
      Serial.print(" : ");
      Serial.print(pinNumber);
      Serial.print(" : ");
      Serial.println(localMaster.scan(chipNumber, pinNumber));
      */
    }
/*
if(input="A")
{
  localMaster.source(input_board,input_pin);
}
*/
   
  }
  delay(200);

 for(int pinNum = 128; pinNum <= 159; pinNum++) //this while looper will cycle through the lower and upper pins, scanning and reporting the state of each pin, printing across the serial communication port. 
  {
    int myPin = pinNum-106;
     //arry[pinNumber] = myLogic.scan(pinNumber-106); //"myLogic" is a declared object of class "processLogic", which then is calls class function "detect", passing it integer "i". detect will call scan inside of itself. 
     pinMode(myPin, INPUT);
    arry[pinNum] = digitalRead(myPin);//assigned the "myState" to hold the memory of the read pin
      //pinMode(myPin, OUTPUT);
      //digitalWrite(myPin, LOW);
    
  }

delay(200);

  for (int i = 0; i<160; i++)
  {
    if(arry[i] == 1)
    {
      ABSOLUTE_VALUE = ((SLAVE_ID*160) + i + 1);

      
     Serial.print ("Iterator Number");
      Serial.print (":");
      Serial.print(i, DEC);
      Serial.print(" : ");
      Serial.print ("Absolute_value");
      Serial.print (":");
      Serial.println(ABSOLUTE_VALUE, DEC);
     
      
      
    }
    
  }

  //printing directly over the COMport, can be used for error checking. 
  Serial.print ("TOTAL_Absolute_value");
  Serial.print (":");
  Serial.println(ABSOLUTE_VALUE, DEC);
     
  
  ABSOLUTE_VALUE = 0; //Zeroing the Absolute_value, as it is a global variable. 
      
  Wire.onRequest(handleMasterRequest);

  
}

void handleMasterRequest() {
  for (int i = 0; i < sizeof(arry); i++) {
    Wire.write(arry[i]);

  }
}

Here is an imagine of the boards, with pull down resistors. We used 1M ohm.

Any ideas guys?

flytyer232:
Hello,
I have been having some issues using MCP23017 I/O expanders to check the status of GPIOs. Here is a brief overview of the heavily commented code: I check 128 GPIOs through the bused MCP23017s, and then check pins 22-54 on an Arduino Mega 2560. The status of all these pins is recorded in a array of 160 (arry), which is then recorded back. This all works, if i print the individual status of the pins, where i put voltage, i can see the status of them. However, in order to be useful for the project i need the absolute pin number, which is Absolute-Pin = (Card-Number * 160) + Card-Pin + 1. The absolute pin works, however if i excite the digital pin on the Arduino Mega, then try to change the status of one of the pins on the MCP23017s, the value doesn't get reported back. However, the individual pin status is updated, and can be reported back.

Any help would be much appreciated.

This makes no sense to me.

I have no idea what you are trying to do.

Explain it again more clearly.

And fewer run-on sentences.