Cable tester with MCP23017

hi I'm new here, im trying to build my first project with a arduino, but i'm not succeeding with writing the code for the MCP23017.

I used as a base for my project existing cable tester project, that is using the local GPIO on the arduino.
in want to connect 5x a mcp23017 because I need te test cables with 40 in and 40 out.

the original project that I want to adjust:

I already succeed in changing the display from serial to an I2c display and it is working.

I hooked up 1 mcp23017 and im able to switch a led on and off with it so I have a i2c connection.

does anybody has some advice about how to use the gpis of the MCP23017 for this?

here is a link to the datasheet of the MCP23017:

here is my code:



#include <LiquidCrystal_I2C.h>
#include <MCP23017.h>
#define MCP23017_I2C_ADDRESS 0x20  // I2C address of the MCP23017 IC

MCP23017 mcp23017 = MCP23017(MCP23017_I2C_ADDRESS);  // instance of the connected MCP23017 IC

const uint8_t OUT0 = 0;      // GPA0 (21) of the MCP23017
const uint8_t OUT1 = 1;      // GPA1 (22) of the MCP23017
const uint8_t OUT2 = 2;      // GPA2 (23) of the MCP23017
const uint8_t OUT3 = 3;      // GPA3 (24) of the MCP23017
const uint8_t OUT4 = 4;      // GPA4 (25) of the MCP23017
const uint8_t OUT5 = 5;      // GPA5 (26) of the MCP23017
const uint8_t OUT6 = 6;      // GPA6 (27) of the MCP23017
const uint8_t OUT7 = 7;      // GPA7 (28) of the MCP23017


const int input[4] = {A0,A1,A2,A3 };
const uint8_t output[4] = {0,1,2,3 };
const int green = 2;  
const int yellow = 3; 
const int red = 4;    
const int reset = 5;  
bool reset_state;
const int num_pin = 4;
bool readings[4][4];
bool init_readings[4];
int encoder0PinA = 6;
int encoder0PinB = 7; 
int encoder0Pos = 0;
int encoder0PinALast = LOW;
int n = LOW;
LiquidCrystal_I2C lcd(0x38, 16, 2); // I2C address 0x38, 16 column and 2 rows
void setup() {
  lcd.init(); // initialize the lcd
  lcd.backlight();
  
  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(reset, INPUT);
  for (int i = 0; i < num_pin; i++) {
    pinMode(input[i], INPUT);
    //pinMode(output[i], OUTPUT);
    //pinMode(input[i], INPUT_PULLUP);
    pinMode(output[i], INPUT_PULLUP);
  }
}



void loop() {
  unsigned long cT = millis();
  // startup(cT);
  bool start_complete = true;
  unsigned long last_motion;
  int display_enc_value = 0;
  bool error_detected = false;
  bool last_display_state;
  while (start_complete)
  {
    cT = millis();
    read_inputs();

    if (reset_state == HIGH) {
      save_readings();
      error_detected = false;
    }

    if (motion_detection(cT, last_motion )) { // changes enc_val
      last_motion = cT;
      lcd.clear();
    }

    bool lds = last_display_state;
    if (cT - last_motion < 1000) {  //what to display
      lcd_display(true);
      last_display_state = true;
    } else {
      lcd_display(false);
      last_display_state = false;
    }

    if (lds != last_display_state) {  // change of state
      lcd.clear();
    }

    bool alright =  evaluate_readings(encoder0Pos, false);
    if (alright == false) {
      error_detected = true;
    }

    lights(alright, error_detected);



  }

}


void lcd_display(bool display_encoder) {
  if (display_encoder == true) {
    lcd.setCursor(0, 0);
    lcd.print("pin count: ");
    lcd.print(encoder0Pos);
  } else if (display_encoder == false) {
    lcd.setCursor(0, 0);
    for (int i = 0; i < num_pin; i++) {
      if (i < encoder0Pos) {
        lcd.setCursor(i, 0);
        lcd.print("1");
      } else {
        lcd.setCursor(i, 0);
        lcd.print("0");
      }
      lcd.setCursor(i, 1);
      lcd.print(readings[i][i]);
    }
  }
}




void save_readings() {

  for (int in = 0; in < num_pin; in++) {
    init_readings[in] = digitalRead(input[in]);
  }

}

bool encoder_read() {   //changes encoder0Pos and returns true if motion detected
  bool motion_detect = false;
  n = digitalRead(encoder0PinA);
  if ((encoder0PinALast == LOW) && (n == HIGH)) {

    if (digitalRead(encoder0PinB) == LOW) {
      motion_detect = true;
      encoder0Pos--;
    } else {
      encoder0Pos++;
      motion_detect = true;
    }

  }
  if (encoder0Pos > 16)
    encoder0Pos = 16;

  if (encoder0Pos < 1)
    encoder0Pos = 1;

  encoder0PinALast = n;

  return motion_detect;
}





void startup(unsigned long sT) {
  unsigned long cT = millis();
  bool tick_on = false;
  unsigned long last_tick;
  byte blinkOn = 0;
  while (cT - sT < 2000)
  {
    cT = millis();
    if (cT - last_tick > 250) {
      last_tick = cT;
      tick_on = true;
    }
    unsigned long tick = millis();
    lcd.setCursor(0, 1);
    lcd.print("    andurils");
    lcd.setCursor(1, 1);
    lcd.print("  kabeltester");

    if (tick_on) {
      blinkOn = (blinkOn + 1) % 3;
      tick_on = false;
    }
    digitalWrite(red, LOW);
    digitalWrite(green, LOW);
    digitalWrite(yellow, LOW);
    digitalWrite(2 + blinkOn, HIGH);


  }
  lcd.clear();
  digitalWrite(green, LOW);
  digitalWrite(yellow, LOW);
  digitalWrite(red, LOW);
}
void lights(bool readings_ok, bool error_detected ) {
  if (readings_ok && !error_detected) { // no error, and nothing detected
    digitalWrite(green, HIGH);
    digitalWrite(yellow, LOW);
    digitalWrite(red, LOW);
  } else if (readings_ok && error_detected) {
    digitalWrite(green, LOW);
    digitalWrite(yellow, HIGH);
    digitalWrite(red, LOW);
  } else if (!readings_ok && error_detected) {
    digitalWrite(green, LOW);
    digitalWrite(yellow, LOW);
    digitalWrite(red, HIGH);
  }
}

bool evaluate_readings(int pins, bool special) { //returns true if ..etc (for straight connections (1-1,2-2..)
  bool correct = true;
  if (!special) {
    for (int out = 0; out < num_pin; out++) {
      for (int in = 0; in < num_pin; in++) {
        if (out < encoder0Pos) {//cares only about pins that are selected
          if (out == in) {
            if (readings[out][in] != 1) {
              correct = false;
            }
          }
          if (out != in) {
            if (readings[out][in] == 1) {
              correct = false;
            }
          }
        } else {

        }
      }
    }
  } else if (special) {
    for (int i = 0; i < num_pin; i++) {
      if (readings[i][i] != init_readings[i]) {
        correct = false;
      }
    }
  }
  return correct;
}

void read_inputs() {  // reads all inputs always
  reset_state = digitalRead(reset);
  for (int out = 0; out < num_pin; out++) {
    digitalWrite(output[out], HIGH);
    for (int in = 0; in < num_pin; in++) {
      readings[out][in] = digitalRead(input[in]);
    }
    digitalWrite(output[out], LOW);
  }
}
bool motion_detection(unsigned long cT, unsigned long last_motion) {
  bool motion_detect = encoder_read();
  if (motion_detect) {
    last_motion = cT;
  }
  return motion_detect;
}

If You provide a link to the datasheet more helpers will be interested.

thanx for the the tip @railroader I will ad it to the original post

Use the A0, A1 and A2. They provide 8 combinations, well enough for Your 5 devices.

yes , I already found out how the change the I2C address by putting jumpers on A0 -A1-A2 on the MCP23017.
but the problem is mostly writing the code to get it work.
in my code I tried to use 1 MCP23017 to start with but I cannot get it working .

What are you testing for, simple continuity for pins one through 40? Or are you also looking for crossconnects/shorts?

Note the pin 7, chip select! It needs to be connected to GND.
My guess is that the device has a base I2C adress working when A0 - A2 are all low. Binary coding the different units, A0 - A2, the will have their adresses like base + 0, base + 1, ..... base + 7.

the code posted above is for continuity test, but I also would like to add crossconnects/shorts

Post this library link.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.