# Programming question: Detect the changes in these switches.

Hi this should be easy for others. And this would be easier in event-driven programming language. :) I have 6 switches, in this current code of mine I have 3 only... I need to know if the switches current state change.

So basically, I'm building a new project. A small flood monitoring device. I have to compute the speed of the water rise. The idea is already here. I need to get the millis() of each switch. But the RATE variable returns 0 because....

If for example the switch1 becomes HIGH (meaning the water touches the switch), we should get the time when the switch1 touches the water. and then the water rises to switch2, switch2 becomes HIGH. we need to get the millis of switch2. At first the computation is okay, but as soon as the program returns to the top of the loop, it gets the millis() again of the 2 high switches. do you get me? I just need to get the millis() of a certain switch IF and ONLY IF its current state changes. Please help.

Thank you!

I have here my code:

``````/*
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:

// 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);
}
``````

I just need to get the millis() of a certain switch IF and ONLY IF its current state changes.

Look at the StateChangeDetection example in the IDE to see how to detect when a switch [u]becomes[/u] pressed rather than [u]is[/u] pressed.

Following from @UKHeliBob's comments I would have a variable that records the state of the water height.

So if no sensor is touched waterHeight = 0 if sensor1 is touched waterHeight = 1 if sensor2 is touched waterHeight = 2

...R

hi guys, I can't make it work.

``````/*
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

// Variables will change:
unsigned floatSwitch1State = 0;
unsigned floatSwitch2State = 0;
unsigned floatSwitch3State = 0;
unsigned floatSwitch4State = 0;
unsigned floatSwitch5State = 0;
unsigned floatSwitch6State = 0;

unsigned floatSwitch1LastState = 0;
unsigned floatSwitch2LastState = 0;
unsigned floatSwitch3LastState = 0;
unsigned floatSwitch4LastState = 0;
unsigned floatSwitch5LastState = 0;
unsigned floatSwitch6LastState = 0;

String currentInfo = "";

float rate;

void setup()
{
// 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:

// compare the buttonState to its previous state
if (floatSwitch1State != floatSwitch1LastState)
{
// if the state has changed, increment the counter
if (floatSwitch1State == HIGH && floatSwitch2State == LOW && floatSwitch3State == LOW && floatSwitch4State == LOW && floatSwitch5State == LOW && floatSwitch6State == LOW) {
// if the current state is HIGH then the button
// went from off to on:
// state has changed!
time1 = millis();
currentInfo = "Water Level is currently at 0.5 ft";
}
else
{
// if the current state is LOW then the switch state changed.
//Serial.println("SWITCH1 CHANGED!");
}
}
// save the current state as the last state,
//for next time through the loop
floatSwitch1LastState = floatSwitch1State;

/**************2nd*********************/
// compare the buttonState to its previous state
if (floatSwitch2State != floatSwitch2LastState)
{
// if the state has changed, increment the counter
if (floatSwitch1State == HIGH && floatSwitch2State == HIGH && floatSwitch3State == LOW && floatSwitch4State == LOW && floatSwitch5State == LOW && floatSwitch6State == LOW) {
// if the current state is HIGH then the button
// went from off to on:
// state has changed!
time2 = millis();
currentInfo = "Water Level is currently at 1 ft";
rate = 0.5/(time2-time1);
}
else
{
// if the current state is LOW then the switch state changed.
//Serial.println("SWITCH1 CHANGED!");
}
}
// save the current state as the last state,
//for next time through the loop
floatSwitch2LastState = floatSwitch2State;

/**************3rd*********************/
// compare the buttonState to its previous state
if (floatSwitch3State != floatSwitch3LastState)
{
// if the state has changed, increment the counter
if (floatSwitch1State == HIGH && floatSwitch2State == HIGH && floatSwitch3State == HIGH && floatSwitch4State == LOW && floatSwitch5State == LOW && floatSwitch6State == LOW) {
// if the current state is HIGH then the button
// went from off to on:
// state has changed!
time3 = millis();
currentInfo = "Water Level is currently at 1.5 ft";
rate = 0.5/(time3-time2);
}
else
{
// if the current state is LOW then the switch state changed.
//Serial.println("SWITCH1 CHANGED!");
}
}
// save the current state as the last state,
//for next time through the loop
floatSwitch3LastState = floatSwitch3State;

/**************4th*********************/
// compare the buttonState to its previous state
if (floatSwitch4State != floatSwitch4LastState)
{
// if the state has changed, increment the counter
if (floatSwitch1State == HIGH && floatSwitch2State == HIGH && floatSwitch3State == HIGH && floatSwitch4State == HIGH && floatSwitch5State == LOW && floatSwitch6State == LOW) {
// if the current state is HIGH then the button
// went from off to on:
// state has changed!
time4 = millis();
currentInfo = "Water Level is currently at 2.0 ft";
rate = 0.5/(time4-time3);
}
else
{
// if the current state is LOW then the switch state changed.
//Serial.println("SWITCH1 CHANGED!");
}
}
// save the current state as the last state,
//for next time through the loop
floatSwitch4LastState = floatSwitch4State;

/**************5th*********************/
// compare the buttonState to its previous state
if (floatSwitch5State != floatSwitch5LastState)
{
// if the state has changed, increment the counter
if (floatSwitch1State == HIGH && floatSwitch2State == HIGH && floatSwitch3State == HIGH && floatSwitch4State == HIGH && floatSwitch5State == HIGH && floatSwitch6State == LOW) {
// if the current state is HIGH then the button
// went from off to on:
// state has changed!
time5 = millis();
currentInfo = "Water Level is currently at 2.5 ft";
rate = 0.5/(time5-time4);
}

}
// save the current state as the last state,
//for next time through the loop
floatSwitch5LastState = floatSwitch5State;

/**************6th*********************/
// compare the buttonState to its previous state
if (floatSwitch6State != floatSwitch6LastState)
{
// if the state has changed, increment the counter
if (floatSwitch1State == HIGH && floatSwitch2State == HIGH && floatSwitch3State == HIGH && floatSwitch4State == HIGH && floatSwitch5State == HIGH && floatSwitch6State == HIGH) {
// if the current state is HIGH then the button
// went from off to on:
// state has changed!
time6 = millis();
currentInfo = "Water Level is currently at 3.0 ft";
rate = 0.5/(time6-time5);
}
else
{
// if the current state is LOW then the switch state changed.
//Serial.println("SWITCH1 CHANGED!");
}
}
// save the current state as the last state,
//for next time through the loop
floatSwitch6LastState = floatSwitch6State;

Serial.println(currentInfo);
delay(500);
Serial.println("");
Serial.print("RATE: ");
Serial.println(rate);
delay(500);

}
``````

0.00 rate, and when the level is in 2ft, I bring down the 4th switch, it never goes back to 1.5ft.

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

This turns on the internal pullup resistor so the state of the pin will be HIGH when the switch is open

``````    if (floatSwitch1State == HIGH && floatSwitch2State == LOW && floatSwitch3State == LOW && floatSwitch4State == LOW && floatSwitch5State == LOW && floatSwitch6State == LOW) {
// if the current state is HIGH then the button
// went from off to on:
// state has changed!
``````

So this comment cannot be true. How are the switches wired ? They should take the pin LOW when the switch is closed.

hi, the float switches are normally closed. one wire is attached to digital pins, and the other is to GND. So if the water touches the float switch, it will be opened, thus HIGH. right? Sorry for the confusing comment in my last code...

``````/*
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

// Variables will change:
unsigned floatSwitch1State = 0;
unsigned floatSwitch2State = 0;
unsigned floatSwitch3State = 0;
unsigned floatSwitch4State = 0;
unsigned floatSwitch5State = 0;
unsigned floatSwitch6State = 0;

unsigned floatSwitch1LastState = 0;
unsigned floatSwitch2LastState = 0;
unsigned floatSwitch3LastState = 0;
unsigned floatSwitch4LastState = 0;
unsigned floatSwitch5LastState = 0;
unsigned floatSwitch6LastState = 0;

String currentInfo = "";

float rate;

void setup()
{
// 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:

// compare the buttonState to its previous state
if (floatSwitch1State != floatSwitch1LastState)
{
// if the state has changed, increment the counter
if (floatSwitch1State == HIGH && floatSwitch2State == LOW && floatSwitch3State == LOW && floatSwitch4State == LOW && floatSwitch5State == LOW && floatSwitch6State == LOW) {
// FROM LOW TO HIGH
time1 = millis();
currentInfo = "Water Level is currently at 0.5 ft";
}
else if ((floatSwitch1State == LOW && floatSwitch2State == LOW && floatSwitch3State == LOW && floatSwitch4State == LOW && floatSwitch5State == LOW && floatSwitch6State == LOW))
{
currentInfo = "Water Level is currently BELOW 0.5 ft";
}
}
// save the current state as the last state,
//for next time through the loop
floatSwitch1LastState = floatSwitch1State;

/**************2nd*********************/
// compare the buttonState to its previous state
if (floatSwitch2State != floatSwitch2LastState)
{
// if the state has changed, increment the counter
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);
}
else if ((floatSwitch1State == HIGH && floatSwitch2State == LOW && floatSwitch3State == LOW && floatSwitch4State == LOW && floatSwitch5State == LOW && floatSwitch6State == LOW))
{
currentInfo = "Water Level is currently at 0.5 ft";
}
}
// save the current state as the last state,
//for next time through the loop
floatSwitch2LastState = floatSwitch2State;

Serial.println(currentInfo);
delay(500);
Serial.println("");
Serial.println(time1);
Serial.println(time2);
Serial.print("RATE: ");
Serial.println(rate);
delay(500);

}
``````

You want the water to close the switch and make it low. Otherwise a loose wire could break the connection and cause the pump to come on when you don't want it to.

Thanks Delta_G… It’s hassle for me to rewire the switches firght now. :3
It’s now working, this is the best state so far. But the rate is still 0.00, although the time variables are okay. hmmmm

sample output:

3003 <<---- time1
9012 <<— time2
RATE: 0.00
Water Level is currently at 0.5 ft

``````/*
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

// Variables will change:
unsigned floatSwitch1State = 0;
unsigned floatSwitch2State = 0;
unsigned floatSwitch3State = 0;
unsigned floatSwitch4State = 0;
unsigned floatSwitch5State = 0;
unsigned floatSwitch6State = 0;

unsigned floatSwitch1LastState = 0;
unsigned floatSwitch2LastState = 0;
unsigned floatSwitch3LastState = 0;
unsigned floatSwitch4LastState = 0;
unsigned floatSwitch5LastState = 0;
unsigned floatSwitch6LastState = 0;

String currentInfo = "Water Level is currently BELOW 0.5 ft";

float rate;

void setup()
{
// 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:

// compare the buttonState to its previous state
if (floatSwitch1State != floatSwitch1LastState)
{
// if the state has changed, increment the counter
if (floatSwitch1State == 1 && floatSwitch2State == 0 && floatSwitch3State == 0 && floatSwitch4State == 0 && floatSwitch5State == 0 && floatSwitch6State == 0) {
// FROM LOW TO HIGH
time1 = millis();
currentInfo = "Water Level is currently at 0.5 ft";
}
else if ((floatSwitch1State == 0 && floatSwitch2State == 0 && floatSwitch3State == 0 && floatSwitch4State == 0 && floatSwitch5State == 0 && floatSwitch6State == 0))
{
currentInfo = "Water Level is currently BELOW 0.5 ft";
}
}
// save the current state as the last state,
//for next time through the loop
floatSwitch1LastState = floatSwitch1State;

/**************2nd*********************/
// compare the buttonState to its previous state
if (floatSwitch2State != floatSwitch2LastState)
{
// if the state has changed, increment the counter
if (floatSwitch1State == 1 && floatSwitch2State == 1 && floatSwitch3State == 0 && floatSwitch4State == 0 && floatSwitch5State == 0 && floatSwitch6State == 0) {
time2 = millis();
currentInfo = "Water Level is currently at 1 ft";
rate = 0.5/(time2-time1);
}
else if ((floatSwitch1State == 1 && floatSwitch2State == 0 && floatSwitch3State == 0 && floatSwitch4State == 0 && floatSwitch5State == 0 && floatSwitch6State == 0))
{
currentInfo = "Water Level is currently at 0.5 ft";
}
}
// save the current state as the last state,
//for next time through the loop
floatSwitch2LastState = floatSwitch2State;

Serial.println(currentInfo);
delay(500);
Serial.println("");
Serial.println(time1);
Serial.println(time2);
Serial.print("RATE: ");
Serial.println(rate);
delay(1000);

}
``````

I think the output is soooo small.

I think the problem is that you are dividing 0.5 by 6009 - in other words you have your units mixed up. Maybe it should be 0.5 * 1000 / (t2 -t1) to allow for the fact that the time is in millisecs. And, better still 500.0 / (t2 - t1)

...R

If your float switches are bobbing up and down you will get " make...break..make...break...", you have to make provisions for this. Also, what kind of rate are you looking for? Feet per hour, inches per min, feet per second?

``````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

// Variables will change:
unsigned floatSwitch1State = 0;
unsigned floatSwitch2State = 0;
unsigned floatSwitch3State = 0;
unsigned floatSwitch4State = 0;
unsigned floatSwitch5State = 0;
unsigned floatSwitch6State = 0;

unsigned floatSwitch1LastState = 0;
unsigned floatSwitch2LastState = 0;
unsigned floatSwitch3LastState = 0;
unsigned floatSwitch4LastState = 0;
unsigned floatSwitch5LastState = 0;
unsigned floatSwitch6LastState = 0;
``````

What's the objection to using arrays?

``````      rate = 0.5/(time2-time1);
``````

``````3003 <<---- time1
9012 <<--- time2
RATE: 0.00
``````

My calculations:

``````9012 - 3003 = 6009
0.5 / 6009 = 0.00008320852
``````

Since Serial.print prints two decimal places by default, seeing 0.00 is exactly what you expect.

Robin2 - hi, thank you for your reply. Why should I multiply 0.5 feet to 1000? Should it be (time2-time/1000) to get its equivalent in seconds?

klubfingers - hello, thank you also for your reply. I think feet per hour would be the best measurement of speed of water rise.

Nick Gammon - hi sir. I can use array, but for the sake of simplicity, I did the code in that way. After I solve this problem, I will have to simplify/enhance the code and combine it with temboo IOT.

What you call “simplicity” I call “complexity”.

Isn’t this simpler?

``````const int floatSwitch [6] = { 2, 3, 4, 5, 6, 7 };
...
void setup ()
{
for (int i = 0; i < 6; i++)
pinMode (floatSwitch [i], INPUT_PULLUP);
...
``````

glenn_boy13: Robin2 - hi, thank you for your reply. Why should I multiply 0.5 feet to 1000? Should it be (time2-time/1000) to get its equivalent in seconds?

I could easily have made a mistake but it would take you 10 seconds with a calculator to check.

...R

Well, let's see. One hours worth of milliseconds would be 60 seconds per minute x 60 minutes per hour = 3600 x 1000 millis = 3,600,000 x 0.5 feet = 1,800,000.

So 1800000 / (Time2 - Time1) would be feet / hour.

Say the water rose from switch 1 to switch 2 in 16 minutes, that would be 16 x 60 x 1000 millis, so 1800000 / 960000 millis = 1.875 feet /hour. Correct me if I'm wrong (A distinct possibility).

hi klubfingers.

1,800,000. , this number's unit would be MILLIS-FT, because you multiplied millis to feet. so for example, the total time in millis (t2-t1) is 960,000 the unit of this would be millis.

If we divide the 1,800,000 millis-ft / 960,000 millis, the answer's unit would be feet only. we need feet per hour or feet per second. :)

I guess 0.5/(t2-t1) is correct, I just need to make the distance of one switch to another longer if I want a large value of RATE. Please someone correct me if I'm wrong. thanks. and thanks to Robin as well.