Measure Water Rise Speed

Hi, I'm making a new system that can detect the water level of my water tank. Say my tank is 3 feet. And I have 6 pcs of float switches, normally closed.

So there will be a float switch in the body of my system for EVERY 0.5 feet. It is definitely easy to make the arduino tell me what level the water is. But my question is: How can I compute for the speed of water rise?

TYIA.
Glenn

Record the time a switch is triggered...

static unsigned long mark1;
static unsigned long mark2;

if ( digitalRead( PIN_LEVEL1 ) )
{
  mark1 = millis();
}

Record the time a different switch is triggered...

if ( digitalRead( PIN_LEVEL2 ) )
{
  mark2 = millis();
}

It is now trivial to calculate the rate (feet per millisecond)...

float rate = 0.5 / (mark2 - mark1);

Thank you so much! I will reply to this topic of mine if I have further queries. THANKS!!!!

G

if you can get a a submersible pressure sensor, you can monitor the level continuously.
there have been a few on here that have used these for monitoring the level of watering tanks for livestock.

use ping ultrasonic level sensor

Hi all, why is it that the rate returns 0.00 using the formula given by codingbadly ?
Also, when I try to print each millis of each switches, at first they are different, but eventually they became equal.

Check my codes:

/*
  Float Switch Program.
 To be integrated to other programs.
 */

// constants won't change. They're used here to 
// set pin numbers:
const int floatSwitch1 = 2;     // the 0.5ft float switch
const int floatSwitch2 = 3;     // the 1ft float switch
const int floatSwitch3 = 4;     // the 0.5ft float switch
const int floatSwitch4 = 5;     // the 1ft float switch
const int floatSwitch5 = 6;     // the 0.5ft float switch
const int floatSwitch6 = 7;     // the 1ft float switch

static unsigned long time1; // record the time of switch1
static unsigned long time2; // record the time of switch2
static unsigned long time3; // record the time of switch1
static unsigned long time4; // record the time of switch2
static unsigned long time5; // record the time of switch1
static unsigned long time6; // record the time of switch2


unsigned floatSwitch1State = 0;
unsigned floatSwitch2State = 0;
unsigned floatSwitch3State = 0;
unsigned floatSwitch4State = 0;
unsigned floatSwitch5State = 0;
unsigned floatSwitch6State = 0;

String currentInfo = "";

float rate;

void setup() 
{
  // initialize the LED pin as an output:
  pinMode(13, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(floatSwitch1, INPUT);
  digitalWrite(floatSwitch1, HIGH); // pull up the floatSwitch1  

  pinMode(floatSwitch2, INPUT);
  digitalWrite(floatSwitch2, HIGH); // pull up the floatSwitch2  

  pinMode(floatSwitch3, INPUT);
  digitalWrite(floatSwitch3, HIGH); // pull up the floatSwitch2  

  pinMode(floatSwitch4, INPUT);
  digitalWrite(floatSwitch4, HIGH); // pull up the floatSwitch2  

  pinMode(floatSwitch5, INPUT);
  digitalWrite(floatSwitch5, HIGH); // pull up the floatSwitch2  

  pinMode(floatSwitch6, INPUT);
  digitalWrite(floatSwitch6, HIGH); // pull up the floatSwitch2  

  Serial.begin(9600);
}

void loop()
{
  // read the state of the pushbutton value:
  floatSwitch1State = digitalRead(floatSwitch1); 
  floatSwitch2State = digitalRead(floatSwitch2); 
  floatSwitch3State = digitalRead(floatSwitch3); 
  floatSwitch4State = digitalRead(floatSwitch4); 
  floatSwitch5State = digitalRead(floatSwitch5); 
  floatSwitch6State = digitalRead(floatSwitch6); 
  
  // if floatSwitch1 is DOWN, meaning is not being touched by water,
  // then it will output 0, since the switch is normally CLOSED - LOW.
  if ( floatSwitch1State == HIGH && floatSwitch2State == LOW && floatSwitch3State == LOW && floatSwitch4State == LOW && floatSwitch5State == LOW && floatSwitch6State == LOW) 
  {     
    time1 = millis();
    currentInfo = "Water Level is currently at 0.5 ft";
  } 

  if ( floatSwitch1State == HIGH && floatSwitch2State == HIGH && floatSwitch3State == LOW && floatSwitch4State == LOW && floatSwitch5State == LOW && floatSwitch6State == LOW)
  {
    time2 = millis();
    currentInfo = "Water Level is currently at 1 ft";
    rate = 0.5/(time2-time1);
  }

  if ( floatSwitch1State == HIGH && floatSwitch2State == HIGH && floatSwitch3State == HIGH && floatSwitch4State == LOW && floatSwitch5State == LOW && floatSwitch6State == LOW)
  {
    time3 = millis();
    currentInfo = "Water Level is currently at 1.5 ft";
    rate = 0.5/(time3-time2);

  }
  

  //-----continue up to 3ft.
  
    Serial.println(currentInfo);
    delay(500);
    Serial.println("");
    Serial.print("RATE: ");
    Serial.println(rate);
    delay(500);
}

If it's always 0 then your not making it through the if statements for some reason. I've had problems with really long if statements like that. Just as an experiment, break it down. See what happens.

if ( floatSwitch1State == HIGH ){

if (floatSwitch3State == LOW) {

if (floatSwitch4State == LOW) {
...etc
time1 = millis();
currentInfo = "Water Level is currently at 0.5 ft";
}}}}}}

To use the pullups, just call:

pinMode(floatSwitch1, INPUT_PULLUP);

You won't need the digital write statement. Saves you some memory.

static unsigned long time1; // record the time of switch1

You should initialize that. I hate risking a null value. The code is actually OK, just a personal pet peeve with me.

tl;dr

Short on arrays, short on debug prints.

static unsigned long time1; // record the time of switch1

You should initialize that.

Why?
It's both static and has global scope; it is by definition initialized to zero.

I know, Why I put "The code is actually OK, just a personal pet peeve with me." Just my personal preference really. It's fine and will work the way it is. I just like it to be obviously stated in the program what a var is initialized to.

I just like it to be obviously stated in the program what a var is initialized to

More obvious than "static"?

hi Keith, thank you so much for your reply. INPUT_PULLUP apparently doesn’t work in my IDE or in my board. that’s why I’m pulling it up manually. Alright, I’m going to try your suggestions. Thanks.

Been thinking too. Your zeroing problem might be because it is doing the calc every loop. Your redoing the check and checking the time difference. And setting the time to the current time every loop.

An idea would be to check them all to see if they have changed. Save that in a marker. And only do the time difference calc if it switched from last loop.
You could put all of them in an arrays and just for loop through them.

for(int x = 0; x < 5; x++)

thisReading[x]= digitalRead(floatSwitch[x]); //change float switch to an array too, will make it easier

if (thisReading[x] != lastReading[x]){

  do your stuff;

lastReading[x] = thisReading[x];
}

That would help all the if statements. If it changed, you really only need to check what changed last to figure out if it’s going up or down. Above, below or itself. Not sure if this works (mechanicly) in both directions or only one.