Water Level Indicator

I am a Marine Engineer and electronics hobbyist I was very much impressed by the arduino community who are doing a fantastic job to encourage the students, professional and hobbyist. . I have gone through various arduino programs/posts and wrote this first program. Please help me to resolve the following issues and point out the mistakes in my program

The Sump Tank shall be fitted with a series of resistances & reed switches inside a plastic tube with a magnetic float out side the stem. When the water level rises/falls the float will also rise and fall and the reed switches will make/ break. Thus it will act as a voltage divider.

Issues: 1. When the magnetic float is between Level 1 & 2, the reed switch breaks and hence no display of the level. How to hold/latch the value of the level 2. If in case of power failure it should remember the previous level.

//Tank Level Display int Level1 = 4; int Level2 = 5; int Level3 = 6; int Level4 = 7;

int Level1State=0; int Level2State=0; int Level3State=0; int Level4State=0;

int Sensor =0; float SensorValue=0;

void setup() { // Tank Level Display pinMode(Level1, OUTPUT); pinMode(Level2, OUTPUT); pinMode(Level3, OUTPUT); pinMode(Level4, OUTPUT);

// Control pinMode (pumpRelay, OUTPUT);

void loop () { SensorValue=analogRead(Sensor); SensorValue /=1024; SensorValue *=5;

// Sump Tank Level Display

if(SensorValue >=3.0) { digitalWrite(Level1,HIGH); delay (50); } else { digitalWrite(Level1,LOW); delay (50); }

if (SensorValue >=2.8) { digitalWrite(Level2,HIGH); delay (50); } else { digitalWrite(Level2,LOW); delay (50); }

if (SensorValue >=2.10) { digitalWrite(Level3,HIGH); delay (50); } else { digitalWrite(Level3,LOW); delay (50); }

if (SensorValue >=1.4) { digitalWrite(Level4,HIGH); delay (50); } else { digitalWrite(Level4,LOW); delay (50); { { digitalWrite(otkLevel4,LOW); delay (50); }

How about:

if (SensorValue < 1.4) doOutput(0);
else if (SensorValue < 2.1) doOutput(1);
else if (SensorValue < 2.8) doOutput(3);
else if (SensorValue < 3.0) doOutput(7);
else doOutput(15);

and:

void doOutput(unsigned char val) {
digitalWrite(Level1, (val & 0x8) ? HIGH : LOW);
digitalWrite(Level2, (val & 0x4) ? HIGH : LOW);
digitalWrite(Level3, (val & 0x2) ? HIGH : LOW);
digitalWrite(Level4, (val & 0x1) ? HIGH : LOW);
}

You can also store level information to the EEPROM for persistent storage in case of power failure:


The Gadget Shield: accelerometer, RGB LED, IR transmit/receive, light sensor, potentiometers, pushbuttons

(val & 0x8) ? HIGH : LOW

What does the 0x8 represent?

It is a number that is being used as a mask to remove all but bit 3 from the bit pattern that is in val.

Sir,
Can you explain it in a simple way about this coding .
Sorry to ask this stupid question.

Let’s look at the code again using binary numbers:

if (SensorValue < 1.4) doOutput(0b0000 /* 0 */);
else if (SensorValue < 2.1) doOutput(0b0001 /* 1 */);
else if (SensorValue < 2.8) doOutput(0b0011 /* 3 */);
else if (SensorValue < 3.0) doOutput(0b0111 /* 7 */);
else doOutput(0b1111 /* 15 */);

You see that at every line there are more and more 1’s being sent to the doOutput function. The doOutput function checks each bit position in the 4-bit binary number:

digitalWrite(Level1, (val & 0x8) ? HIGH : LOW);

means:

digitalWrite(Level1, "HIGH if bit 3 of val is '1', else LOW");


The Quick Shield: breakout all 28 pins to quick-connect terminals

Sir,
Please check up this code:

#include <EEPROM.h>
//Tank Level Display
int Level1 = 4;
int Level2 = 5;
int Level3 = 6;
int Level4 = 7;

int Level1State=0;
int Level2State=0;
int Level3State=0;
int Level4State=0;

int Sensor =0;
float SensorValue=0;
int add = 0; //address of EEPROM byte we will be writing to

void setup() {
// Tank Level Display
pinMode(Level1, OUTPUT);
pinMode(Level2, OUTPUT);
pinMode(Level3, OUTPUT);
pinMode(Level4, OUTPUT);

// Control

void loop () {
SensorValue=analogRead(Sensor);
SensorValue /=1024;
SensorValue *=5;

// Sump Tank Level Display
{
if (SensorValue < 1.4) doOutput(0);
EEPROM.write(1,value );
else if (SensorValue < 2.1) doOutput(1);
EEPROM.write(2,value );
else if (SensorValue < 2.8) doOutput(3);
EEPROM.write(3,value );
else if (SensorValue < 3.0) doOutput(7);
EEPROM.write(4,value );
else doOutp
}

void doOutput(unsigned char val) {
digitalWrite(Level1, (val & 0x8) ? HIGH : LOW);
digitalWrite(Level2, (val & 0x4) ? HIGH : LOW);
digitalWrite(Level3, (val & 0x2) ? HIGH : LOW);
digitalWrite(Level4, (val & 0x1) ? HIGH : LOW);
}

You are writing to the EEPROM much too often. The loop() function gets called several thousands of times per second and you will wear out the EEPROM very quickly. I would suggest in the doOutput() function that you compare the new value against the old value (store in a global variable) then only update the EEPROM if the new value is different.

-- The Gadget Shield: accelerometer, RGB LED, IR transmit/receive, light sensor, potentiometers, pushbuttons

  1. If in case of power failure it should remember the previous level.

Consider adding an SDcard and a Real Time Clock, even on a small SDcard one could hold thousands of readings. It could work like a black box in a plane :)

Rob

Sir, I did not understand the Gadget Shield:,I am confused :(can you give me the code for EEPROM for these four levels so that I get an idea how to write and read the value in the EEPROM and my EEPROM remain safe. I am using ATmega 328 and curious to use the EEPROM and Flash memory in my future projects.

unsigned char lastVal = 0xFF;

void doOutput(unsigned char val) {
digitalWrite(Level1, (val & 0x8) ? HIGH : LOW);
digitalWrite(Level2, (val & 0x4) ? HIGH : LOW);
digitalWrite(Level3, (val & 0x2) ? HIGH : LOW);
digitalWrite(Level4, (val & 0x1) ? HIGH : LOW);

if (val != lastVal) {
  lastVal = val;
  EEPROM.write(0, val);
}
}

You can then restore the last value stored before a power failure with EEPROM.read(0).

-- The Quick Shield: breakout all 28 pins to quick-connect terminals

if (SensorValue < 1.4) doOutput(0);
else if (SensorValue < 2.1) doOutput(1);
else if (SensorValue < 2.8) doOutput(3);
else if (SensorValue < 3.0) doOutput(7);
else doOutput(15); In his program he has assigned sensor values >1.4,>2.1,>2.8,>3.0
but in the above mentioned code the values are <,what does it mean?

Sirs,
The following program was compliled and uploaded but this problem
about not displaying the level when the magnetic float is between two levels still exists and there is no display for the fourth level .
Please help me to resolve this problem. :-[

Code:
#include <EEPROM.h>
// Sump Tank (stk) Level Display
int stkLevel1 = 4;
int stkLevel2 = 5;
int stkLevel3 = 6;
int stkLevel4 = 7;
int addr=0;
// Sump Tank (stk) Level Display
int stkLevel1State=0;
int stkLevel2State=0;
int stkLevel3State=0;
int stkLevel4State=0;
int stkSensor =0;
float stkSensorValue=0;
void setup() {
// Sump Tank (stk) Level Display
pinMode(stkLevel1, OUTPUT);
pinMode(stkLevel2, OUTPUT);
pinMode(stkLevel3, OUTPUT);
pinMode(stkLevel4, OUTPUT);
}
void loop () {
stkSensorValue=analogRead(stkSensor);
stkSensorValue /=1024;
stkSensorValue *=5;
if (stkSensorValue < 1.5) doOutput(0);
else if (stkSensorValue < 2.4) doOutput(1);
else if (stkSensorValue < 3.1) doOutput(3);
else if (stkSensorValue < 4.0) doOutput(7);
else doOutput(15);
//delay(500);
}
unsigned char lastVal = 0xFF;
void doOutput(unsigned char val) {
digitalWrite(stkLevel1, (val & 0x8) ? HIGH : LOW);
digitalWrite(stkLevel2, (val & 0x4) ? HIGH : LOW);
digitalWrite(stkLevel3, (val & 0x2) ? HIGH : LOW);
digitalWrite(stkLevel4, (val & 0x1) ? HIGH : LOW);
if (val != lastVal) {
lastVal = val;
EEPROM.write(0, val);
}
}

Add a Serial.begin() statement to setup().

Then, add Serial.print() statements to loop(), after reading the analog pin's value, and after each of the manipulations of stkSensorValue.

Add Serial.print statements to doOutput() to see what was passed in.

One question I have, though. You are passing an integer to doOutput, which is declared to take an unsigned char. Why is doOutput declared to take an unsigned char, rather than an int?

Sirs, Thanks In Serial Monitor the values are OK and checked with the multimeter also. I am a new to arduino. I read this post and tried to complie this program for liquid level display project. I copied it from the codes of Harnam. Please help me to solve this prob.

I don’t know how to help you any more. You say everything is right, but you don’t offer any proof.

The next thing to do is to create a sketch in which you verify, by writing to the Serial Monitor, that you can read the level sensor.

Then, write another sketch that turns each LED on. After a short period of time, turn them off.

Then, add the doOutput function to the LED sketch. Call that function in a loop, from 0 to 15. Verify that the LEDs come on correctly. If not, change the doOutput function until they do.

And, in the future, post code using the # button on the top row, AND answer all questions (except rhetorical ones) that are asked.