Interfacing MCP23017 E/SP with arrays in Arduino IDE

Hi,

I am new to Arduino and currently working on my first ever project which is a continuity tester with some other small functionality. The project will accommodate 10 different types of cables to test with some of them ranging up to 116 IO therefore I am using 8 MCP23017 E/SP to expand my IO requirements to cover this.

I am having trouble interfacing these chips with some existing code I found on another thread. I have attached the code below of which I am trying to replace the array elements in "pinsCableBegin" and "pinsCableEnd" with my own pin addresses for 1 of my 10 separate tests.

`

// Cable Tester by "jurs" for Arduino forum
enum {PASS, FAIL_NOTCONNECTED, FAIL_WRONGCONNECTED, FAIL_SHORTENED };

// pin numbers for use at begin and end of cable
const byte pinsCableBegin[]= { 2, 3, 4, 5,  };
const byte pinsCableEnd[]  = {11,12,13,A0 };
const byte NUMCABLES=sizeof(pinsCableBegin);

void setup() {
  Serial.begin(9600);
  if (sizeof(pinsCableBegin)!=sizeof(pinsCableEnd))
  {
    Serial.println("Wrong cable pin configuration!");
    Serial.println("Fix declaration of pinsCableBegin[] and pinsCableEnd[] arrays!");
    while(1); // error stop with endless loop
  }  
  Serial.println();
  Serial.println("################################################");
  Serial.println("#                CABLE TESTER                  #");
  Serial.println("################################################");
  Serial.println();
}

void allPinsInputHigh()
{ // set all pins to INPUT_PULLUP in a for-loop
  for (byte i=0;i<NUMCABLES;i++)
  {
    pinMode(pinsCableBegin[i],INPUT_PULLUP);
    pinMode(pinsCableEnd[i],INPUT_PULLUP);
  }
}


void DoOneTest()
{
  byte result;
  Serial.println();
  Serial.println("### TEST ###");
  for (byte i=0;i<NUMCABLES;i++) // test each pin 
  {
    result= PASS; // initially there is no error found, assume PASS
    allPinsInputHigh();
    // first test is for continuity and OUTPUT/HIGH
    pinMode(pinsCableBegin[i], OUTPUT);
    if (digitalRead(pinsCableEnd[i])!=HIGH)
    {
        bitSet(result,FAIL_NOTCONNECTED);
    }
    // then check for continuity and OUTPUT/LOW
    digitalWrite(pinsCableBegin[i], LOW);
    if (digitalRead(pinsCableEnd[i])!=LOW)
    {
        bitSet(result,FAIL_NOTCONNECTED);
    }
    
    // next test: check for wrong connections to other pins
    for (byte j=0;j<NUMCABLES;j++)
    {
      if (j!=i && digitalRead(pinsCableEnd[j])==LOW)
      {
        bitSet(result, FAIL_WRONGCONNECTED);
      }  
    }
    // final test for short circuit against other pins
    for (byte j=0;j<NUMCABLES;j++)
    {
      if (j!=i && digitalRead(pinsCableBegin[j])==LOW)
      {
        bitSet(result, FAIL_SHORTENED);
      }  
    }
    Serial.print("Line ");
    Serial.print(i+1);
    if (result== PASS) Serial.print(" PASS");
    else Serial.print(" FAIL");
    if (bitRead(result,FAIL_NOTCONNECTED)) Serial.print(" BREAK");
    if (bitRead(result,FAIL_WRONGCONNECTED)) Serial.print(" WRONG");
    if  (bitRead(result,FAIL_SHORTENED)) Serial.print(" SHORT");
    Serial.println();
  }
  Serial.println("Test finished.");
  Serial.println();
}

void loop() {
  if (Serial.available())
  {
    DoOneTest();
    delay(20);
    while (Serial.available()) Serial.read(); // clear Serial input buffer
  }
}

`

Specifically, I am unsure what syntax to use to call up a specific pin of one of the chips inside the array elements. For example, I have attached a schematic of one of the continuity tests (the simplest) below. I was wondering how I would declare 2 arrays for this test for the pins at either end of the cable as I'm unsure of how to address intended connections inside an array.

I have read about declaring each pin as an object then putting all the objects inside an array but I don't really understand any of the explanations around this or how to do it myself.

Any help with this would be greatly appreciated!

Thanks in advance.

Please post a link to that thread.

https://forum.arduino.cc/t/continuity-tester-pass-or-fail-outcome-only/353166

Your topic does not seem to have much to do with the communication between a PC and an Arduino and hence has been moved to a more suitable location on the forum.

I don't see that the code from the other topic will be of any real help other than explaining about the four different tests that he did.
I think it may be easier if you start from scratch rather than trying to adapt that code to fit your MCP23017 design.
Maybe first learn how to use the MCP32017 and the libraries

Its not really got anything to do with the code in the other topic I just put that in as a reference to what I'm doing and linked it. I think you may have misunderstood me slightly but to clarify, I'm simply trying to call external chip pins in an array.

I know how to use the library and MCP23017 chips but cannot find a function in the library/ datasheet or anything online about declaring the pins as objects which is preventing me from interfacing the chips with the Arduino and what I need help with.

I'm not a C++ expert so can't help with Classes and Objects but I would think a simple array would suffice.

Yes that's what I originally tried to do but the difficulty comes in naming each pin on an MCP23017 chip as if I want to address pins 5 through 10 on the Arduino I simply declare:

const byte pinsCableBegin[]= { 5, 6, 7, 8, 9,10 };

However when I want to declare MCP23017 pins I assumed it looked something like the below:

#include "Adafruit_MCP23X17.h"

Adafruit_MCP23X17 mcp1;
Adafruit_MCP23X17 mcp2;
Adafruit_MCP23X17 mcp3;
Adafruit_MCP23X17 mcp4;
Adafruit_MCP23X17 mcp5;
Adafruit_MCP23X17 mcp6;
Adafruit_MCP23X17 mcp7;
Adafruit_MCP23X17 mcp8;


const byte pinsCableBegin[]= { mcp1(0), mcp2(3), 4, 5, 6, 7, 8, 9,10 }
//This would theoretically declare pin1 on chip 1 and pin 4 on chip 2 if the syntax were correct

void setup() { ...

Obviously this doesn't compile as the array function doesn't recognise the mcp pins so my general question is how do I write in MCP pins to an array so I can use it in something like the code from #1?

You said you knew how to use the library and the ICs, so why are you using the instance name with an argument.
Do you really understand how to use the library?

I'm not "using" anything yet I have simply put some really basic code to give the gist of what I'm trying to do.

If you are unable to help, that's fine. I would prefer if you could stop cluttering up the feed though so that if someone who does know about this topic sees this they can help.

Thank you.

I'm able to help and trying to help but if you think that my help is just clutter, then I will do as you wish and leave.

Apologies, I didn't mean to cause offence however your comment about your inexperience in C++ and questions regarding unrelated topics to the initial question led me to believe you haven't any experience relating to this particular issue.

Nonetheless, thank you for trying to help.

@chimney12 ,

Your other topic on the same subject deleted.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

Well, you've had the necessary time to read the advice given.

Here's a thought - an array of pin numbers is just an array of integers, nothing more, nothing less. The pin numbers could be, for example, from 0-127; If you divide the pin number by 16, you get the number of the MCP that pin might be found on, numbered from 0-7; add 0x20 to that, and you have the address of the MCP.
Does that provide you with an idea?

This pile of hardware

#include "Adafruit_MCP23X17.h"

Adafruit_MCP23X17 mcp1;
Adafruit_MCP23X17 mcp2;
Adafruit_MCP23X17 mcp3;
Adafruit_MCP23X17 mcp4;
Adafruit_MCP23X17 mcp5;
Adafruit_MCP23X17 mcp6;
Adafruit_MCP23X17 mcp7;
Adafruit_MCP23X17 mcp8;

will be easier to work with if you use an array of Adafruit_MCP23X17s, viz:

# include "Adafruit_MCP23X17.h"

Adafruit_MCP23X17 myMCP[8];

and shoukd work nicely with the kinda thing @camsysca is getting at.

a7

1 Like

@chimney12 If you're still out there, how about asking questions about what you still don't understand? We're still waiting to hear back from you.

Hi,

Apologies, I have been away on holiday but yes I think I understand what you're getting at. Would providing the syntax "0x20 0x21 0x22 etc..." allow me to refence individual pins inside the array then I have tried messing around with this but I cant quite find the right way of referencing the pins.

# include "Adafruit_MCP23X17.h"

Adafruit_MCP23X17 myMCP[8];


const byte pinsCableBegin[]= { 10x20, 20x21, 30x21, 40x21};
//trying to address pin 1 on chip 1 and pins 2-4 on chip 2



void setup() { ...

I assumed it would look something like above but I'm unsure how exactly to "add 0x20" onto the end of the pins?

Many ways to approach that, but that's not one of them.
Consider. If you have 100 pins, organize them in series. First 16 on first MCP, next 16 on 2nd, etc. So pin # 69 would be on the fifth MCP, 6th pin. like this
0-15 first MCP
16-31 second
32-47 third
48-63 fourth
64-79, so 64, 65, 66, 67, 68, 69 means 69 is the 6th pin on the 5th MCP.
So,
MCP index = pin#/16 (whole number remanant is the MCP number.
pin index = pin#%16 (remainder is the answer)

Clearer? Now, your code knows how to interpret pin # 69 in the pin array.

I understand what you're getting at but I think I would need to start at a higher pin value as I am using almost all the other 70 pins on the Arduino.

The issue I am specifically facing is not working out what pin on what chip the signal came from, but actually predefining that pin inside an array so I can use it for continuity testing.

When you mentioned adding 0x20 onto the end of my desired pin, how would I format that inside the code to get it to work in an array as the below obviously doesn't compile so I'm unsure of the syntax?

const byte pinsCableBegin[]= { 10x20, 20x21, 30x21, 40x21};

Thank you.

Literally add.

So 0 .. 7 become 0x20, 0x21, 0x22 and so forth.

0x prefixes a number expressed in hexadecimal. Used here so you can see the bits, once you've done this for awhile. The lower bits are the original number, and adding 0x20 (32 decimal) is setting one of the higher order bits.

These numbers can be pulled apart when necessary using bit masks and shifting, something you will sooner later want to be all over.

a7