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;
}