Using PCF8574 GPIO extender sensing water levels

Hi,
I want to sense water levels using eight PCF8574 GPIO extenders. Here I want to control the IO extender reading using dip switches. One extender measures one water level. So, I used 8 dip switches (Interactive DIP Switch 8 common elements) connected with 8 extenders.
As an example, after I HIGH one switch of the first dip switch, the first I/O extender's P0 should be able to read the pin satate and give a serial print "increasing water level 1". Likewise for all the first switch of the 8 dip switches go HIGH P0 pin should read the satae and give a serial print " Increasing water level 2, increasing water level 3"..etc. Like that when all the P6 goes to LOW it should give " decreasing water level" on serial monitor. Other remaining P1 to P7 I/O pins using to on and off leds.

In my code I got all the serial prints and led outputs without the control of dip switches. I want to get those conditions under the manipulation of dip switches. In other words,they should work only if I on or off the dip switches. Due to exceeding word limit I couldnt be able to attach the decreasing functions.

#include <Wire.h>
#include "Arduino.h"
#include "PCF8574.h"

//Set the I2C HEX address
int addr1 = 0x20; //PCF8574 device 1
int addr2 = 0x21; //PCF8574 device 2
int addr3 = 0x22; //PCF8574 device 3
int addr4 = 0x23; //PCF8574 device 4
int addr5 = 0x24; //PCF8574 device 5
int addr6 = 0x25; //PCF8574 device 6
int addr7 = 0x26; //PCF8574 device 7
int addr8 = 0x27; //PCF8574 device 8


bool ISR_FLAG1 = false;//interrupt triggered flag
bool ISR_FLAG2 = false;//interrupt triggered flag
bool ISR_FLAG3 = false;//interrupt triggered flag
bool ISR_FLAG4 = false;//interrupt triggered flag
bool ISR_FLAG5 = false;//interrupt triggered flag
bool ISR_FLAG6 = false;//interrupt triggered flag
bool ISR_FLAG7 = false;//interrupt triggered flag
bool ISR_FLAG8 = false;//interrupt triggered flag

int OutPins[] = {13, 12, 11, 10, 9, 8, 7, 6}; //led pins
int s;//Array element's parameter of OutPins[] array

byte abc = 0;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  //pcf8574.begin();

  //Assign the interrupt routine using Mega pins
  //Interrupt is triggered when a GPIO input changes from LOW to HIGH
  pinMode(22, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(22), ISR_PROC, FALLING);
  pinMode(47, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(47), ISR_PROC, FALLING);
  pinMode(48, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(48), ISR_PROC, FALLING);
  pinMode(49, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(49), ISR_PROC, FALLING);
  pinMode(50, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(50), ISR_PROC, FALLING);
  pinMode(51, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(51), ISR_PROC, FALLING);
  pinMode(52, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(52), ISR_PROC, FALLING);
  pinMode(53, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(53), ISR_PROC, FALLING);


  setupOutPins();//set the pinMode() function to LEDs

  digitalWrite ( OutPins[0], 1);

}

void setupOutPins() {
  for (s = 0; s < 8; s++) {
    pinMode (OutPins[s], OUTPUT);
    delayMicroseconds (100);
  }
}


void loop() {

  InsetIncRead1 (); //Gives the output when the water level increasing in dip switch one
  InsetIncRead2 (); //Gives the output when the water level increasing in dip switch two
  InsetIncRead3 (); //Gives the output when the water level increasing in dip switch three
  InsetIncRead4 (); //Gives the output when the water level increasing in dip switch four
  InsetIncRead5 (); //Gives the output when the water level increasing in dip switch five
  InsetIncRead6 (); //Gives the output when the water level increasing in dip switch six
  InsetIncRead7 (); //Gives the output when the water level increasing in dip switch seven
  InsetIncRead8 (); //Gives the output when the water level increasing in dip switch eight

  //ISR_PROC();//Set a flag if an interrupt is triggered

  InsetDecRead8 (); //Gives the output when the water level decreasing in dip switch eight
  InsetDecRead7 (); //Gives the output when the water level decreasing in dip switch seven
  InsetDecRead6 (); //Gives the output when the water level decreasing in dip switch six
  InsetDecRead5 (); //Gives the output when the water level decreasing in dip switch five
  InsetDecRead4 (); //Gives the output when the water level decreasing in dip switch four
  InsetDecRead3 (); //Gives the output when the water level decreasing in dip switch three
  InsetDecRead2 (); //Gives the output when the water level decreasing in dip switch two
  InsetDecRead1 (); //Gives the output when the water level decreasing in dip switch one

}

void InsetIncRead1 () {

  Wire.requestFrom (addr1, 1);
  if (Wire.available()) {
    abc = Wire.read();
  }

  if (abc & 0b00000001) {
    Serial.println("Increasing water level 1");
  }

  if (abc & 0b01111111) {
    digitalWrite(OutPins[1], 1);
  }

  delay(500);
}

void InsetIncRead2  () {

  Wire.requestFrom (addr2, 1);
  if (Wire.available()) {
    abc = Wire.read();
  }

  if (abc & 0b00000001) {
    Serial.println("Increasing water level 2");
  }

  if (abc & 0b00000011) {
    digitalWrite (OutPins[0], 0);
  }

  if (abc & 0b01111111) {
    digitalWrite(OutPins[2], 1);
  }

  delay(500);

}

int InsetIncRead3 () {

  Wire.requestFrom (addr3, 1);
  if (Wire.available()) {
    abc = Wire.read();
  }

  if (abc & 0b00000001) {
    Serial.println("Increasing water level 3");
  }


  if (abc & 0b00000011) {
    digitalWrite (OutPins[1], 0);
  }

  if (abc & 0b01111111) {
    digitalWrite(OutPins[3], 1);
  }

  delay(500);

}
int InsetIncRead4 () {

  Wire.requestFrom (addr4, 1);
  if (Wire.available()) {
    abc = Wire.read();
  }

  if (abc & 0b00000001) {
    Serial.println("Increasing water level 4");
  }

  if (abc & 0b00000011) {
    digitalWrite (OutPins[2], 0);
  }

  if (abc & 0b01111111) {
    digitalWrite(OutPins[4], 1);
  }

  delay(500);

}

void InsetIncRead5 () {

  Wire.requestFrom (addr5, 1);
  if (Wire.available()) {
    abc = Wire.read();
  }

  if (abc & 0b00000001) {
    Serial.println("Increasing water level 5");
  }

  if (abc & 0b00000011) {
    digitalWrite (OutPins[3], 0);
  }

  if (abc & 0b01111111) {
    digitalWrite(OutPins[5], 1);
  }

  delay(500);

}

void InsetIncRead6 () {

  Wire.requestFrom (addr6, 1);
  if (Wire.available()) {
    abc = Wire.read();
  }

  if (abc & 0b00000001) {
    Serial.println("Increasing water level 6");
  }

  if (abc & 0b00000011) {
    digitalWrite (OutPins[4], 0);
  }

  if (abc & 0b01111111) {
    digitalWrite(OutPins[6], 1);
  }

  delay(500);
}

void InsetIncRead7 () {

  Wire.requestFrom (addr7, 1);
  if (Wire.available()) {
    abc = Wire.read();
  }

  if (abc & 0b00000001) {
    Serial.println("Increasing water level 7");
  }

  if (abc & 0b00000011) {
    digitalWrite (OutPins[5], 0);
  }

  if (abc & 0b01111111) {
    digitalWrite(OutPins[7], 1);
  }

  delay(500);

}

void InsetIncRead8 () {

  Wire.requestFrom (addr8, 1);
  if (Wire.available()) {
    abc = Wire.read();
  }

  if (abc & 0b00000001) {
    Serial.println("Increasing water level 8");
  }

  if (abc & 0b00000011) {
    digitalWrite (OutPins[6], 0);
  }

  if (abc & 0b01111111) {
    digitalWrite(OutPins[8], 1);
  }

  delay(500);

}

//Set a flag if an interrupt is triggered
void ISR_PROC() {
  ISR_FLAG1 = true;
  ISR_FLAG2 = true;
  ISR_FLAG3 = true;
  ISR_FLAG4 = true;
  ISR_FLAG5 = true;
  ISR_FLAG6 = true;
  ISR_FLAG7 = true;
  ISR_FLAG8 = true;

  if (ISR_FLAG1 == true) {
    InsetDecRead1 ();
    ISR_FLAG1 = false; //clear interrupt flag
  }

  delay(200);

  if (ISR_FLAG2 == true) {
    InsetDecRead2 ();
    ISR_FLAG2 = false; //clear interrupt flag
  }

  delay(200);

  if (ISR_FLAG3 == true) {
    InsetDecRead3 ();
    ISR_FLAG3 = false; //clear interrupt flag
  }

  delay(200);

  if (ISR_FLAG4 == true) {
    InsetDecRead4 ();
    ISR_FLAG4 = false; //clear interrupt flag
  }

  delay(200);

  if (ISR_FLAG5 == true) {
    InsetDecRead5 ();
    ISR_FLAG5 = false; //clear interrupt flag
  }

  delay(200);

  if (ISR_FLAG6 == true) {
    InsetDecRead6 ();
    ISR_FLAG6 = false; //clear interrupt flag
  }

  delay(200);

  if (ISR_FLAG7 == true) {
    InsetDecRead7 ();
    ISR_FLAG7 = false; //clear interrupt flag
  }

  delay(200);

  if (ISR_FLAG8 == true) {
    InsetDecRead8 ();
    ISR_FLAG8 = false; //clear interrupt flag
  }

  delay(200);

}

That is an impressive number of PCF8574 port expanders.

How are you measuring the water level, and what sensors are you using, and how many sensors have you ?

To determine if the water level is rising or falling, you have to some how store the last state, so you can determine the change (if any).

If you want to use interrupts, you'll have to look at pin change interrupts. You can only use the following technique with a few of the mega's pins:

attachInterrupt(digitalPinToInterrupt(49), ISR_PROC, FALLING);

See: attachInterrupt() - Arduino Reference

Hi,
Ops circuit;


You will need current limit resistors on the LEDs.

Tom... :slight_smile:

Hi,
Why do you want to use interrupts?
Wouldn't it be simpler and just a quick to poll each expander?

How often must you check each tank level?

Have you actually made at least one expander port circuit and checked some basic code before going full into the code you have presented?

Thanks.. Tom.... :slight_smile: