Swimming Pool Auto Controller Project 1

June 6, 2013 § 5 Comments

Explanation of the codes :

The ON and Off is defined here because those used in codes for better understanding.

And the pin definitions are arduino pin definitions that you can understand more better which pin is used for what purposes.

#define ON 1
#define OFF 0
#define TEMPERATURE_LIMIT 31

///PIN DEFINITIONS
#define OVERFLOW_LEVEL 0
#define LOW_LEVEL 1
#define HIGH_LEVEL 2
#define PUMP 3
............
...........

Then including the header files, and declaring and initializing the variables required.

TimeRoutine[8][2] is a integer two dimensional array that holds the value of predefined time routine(the time when the pool will be cleaned on different weekdays) in it. later we will use a function to retrieve the times and compare with current time and do the pool water cleaning event.

printWeekday is a easy function that will print to 16×2 character LCD the weekday of the integer parameter that will be provided when calling.

checkButtons is a function that is used to debounce the buttons and set the current time(weekday, hour, minute). And the function is somewhat crappy. I need to work on it in the future.

getTemperature is a function that is used to read the temperature value from the one-wire temperature sensor DS18B20 in hexadecimal value. then convert it to decimal degree celcious value and store in in the temp variable. I have not personally written the codes. The function and its corresponding library (onewire.h) is downloaded from the net.

WaterFillingMode is a function that have the statements of the behavior of the pool when water is filling in it.

WaterCleaningMode is a function that have the statements of the behavior of the pool when water cleaning/draining.

ReadyMode is a function that have the statements of the behavior of the pool when pool is ready for swimming.

Ok, enough, if u r a programmer, u can understand the further codes and if u r not, the flowcharts will come later for your better understanding of the codes.

Swimming Pool Auto Controller Project(start)

June 4, 2013 § 7 Comments

I am helping my classmates to do their Thesis Project : Swimming Pool Auto Controller.

So, for the starting, here are some small description.

The project was finished, it took approx 1 month(total of 15 hour work) to finish that project. I have worked on my free times as i have a job.

The project was easy, but it needs 2 times code rewriting, 1 atmega8 has damaged and burnt out its some I/O pin for accidentally short-circuit. And the funniest thing is, we got shocked several times by the poor quality water heater.

The pump we have used was a Reverse-Osmosis 80 GPD pump(we needed a small pump for our project). We have used a solenoid valve to control the water draining. The temperature sensor is the most common DS18B20 temperature sensor that we have used in this project.

The Features Was

  • Water Temperature Control.
  • Water Level Control.
  • Automatic Water Recycling Each Day.
  • Show Temperature on the LCD.
  • Swimming Pool dancing light control(When Pool Is Ready).

We have used Atmega8 microcontroller to our project as the hex file is less than 7 kilobyte. And the code for this project is :

///constants
#define ON 1
#define OFF 0
#define TEMPERATURE_LIMIT 31

///PIN DEFINITIONS
#define OVERFLOW_LEVEL 0
#define LOW_LEVEL 1
#define HIGH_LEVEL 2
#define PUMP 3
#define HEATER 4
#define VALVE 5
#define LIGHT1 6
#define LIGHT2 7
#define LIGHT3 8
#define LIGHT4 9
///THE DS18B20 IS ON PIN 10
#define weekdayPin 11
#define hourPin 12
#define minutePin 13    /*
LCD-D7 14
LCD-D6 15
LCD-D5 16
LCD-D4 17
LCD-ENABLE 18
LCD-RESET 19   */
///ALL PINS ARE USED UP
//-----------------------------------------
#include <OneWire.h>
OneWire ds(10);  // ds18b20 is on pin 10
#define MAX_DS1820_SENSORS 2
byte addr[MAX_DS1820_SENSORS][8];
#define DS18S20_ID 0x10
#define DS18B20_ID 0x28
//---------------------------------------
#include <LiquidCrystal.h>
#define LCD_WIDTH 16
#define LCD_HEIGHT 2
LiquidCrystal lcd(19, 18, 17, 16, 15, 14);
//------------------------------------------
byte second=0, minute=0, hour=0, weekday=1; // declare time variables
// these time variables are declared globally so they can be used ANYWHERE in your program
//---------------------------------------------
uint8_t Light=0;
uint8_t MODE=0; //1=water filling, 2=water cleaning, 0=pool ready check everytimewater level
float temp=0.00;

byte TimeRoutine[8][2]={
//start water cleaning times
//h|m|
{0, 0},//not used
{9,20},//saturday
{9,20},//sunday
{9,20},//monday
{9,20},//tuesday
{9,20},//wednesday
{9,20},//thursday
{9,20},//friday
};

void printWeekday (int dayNum) {
// print a weekday, based on the day number
switch (dayNum) {
case 1:
lcd.print ("Sat ");
break;
case 2:
lcd.print ("Sun ");
break;
case 3:
lcd.print ("Mon ");
break;
case 4:
lcd.print ("Tue ");
break;
case 5:
lcd.print ("Wed ");
break;
case 6:
lcd.print ("Thu ");

break;
case 7:
lcd.print ("Fri ");
break;
}
}

void checkButtons()
{
static boolean secPressed=false, minPressed=false, hourPressed=false, wkdayPressed=false; //track button state

if (digitalRead (minutePin)==LOW && minPressed == false) {
minute++;//when minute pin is low, increase minute once
minPressed = true;
}
if (digitalRead (minutePin)==HIGH) minPressed = false;

if (digitalRead (hourPin)==LOW && hourPressed == false) {
hour++;//when our pin is low, increase hour once
hourPressed = true;
}
if (digitalRead (hourPin)==HIGH) hourPressed = false;

if (digitalRead (weekdayPin)==LOW && wkdayPressed == false) {
weekday++;//when weekday pin is low, increase weekday once
secPressed = true;
}
if (digitalRead (weekdayPin)==HIGH) wkdayPressed = false;
}

///code for ds18b20 library
boolean getTemperature(){
byte i;
byte present = 0;
byte data[12];
byte addr[8];
//find a device
if (!ds.search(addr)) {
ds.reset_search();
return false;
} if (
OneWire::crc8( addr, 7) != addr[7]) {
return false;
} if (
addr[0] != DS18S20_ID && addr[0] != DS18B20_ID) {
return false;
} ds.reset();
ds.select(addr);
// Start conversion
ds.write(0x44, 1);
// Wait some time...
delay(400);
present = ds.reset();
ds.select(addr);
// Issue Read scratchpad command
ds.write(0xBE);
// Receive 9 bytes
for ( i = 0; i < 9; i++) {
data[i] = ds.read();
} // Calculate temperature value
temp = ( (data[1] << 8) + data[0] )*0.0625;
return true;
}

void WaterFillingMode()
{
digitalWrite(LIGHT1, OFF);
digitalWrite(LIGHT2, OFF);
digitalWrite(LIGHT3, OFF);
digitalWrite(LIGHT4, OFF);
digitalWrite(HEATER,OFF);
/////WATER FILLING MODE
lcd.clear();
lcd.setCursor(0,0);
lcd.print("  Water Filling");
delay (400);
if (digitalRead(HIGH_LEVEL)==ON)
{
digitalWrite(PUMP,OFF);
lcd.setCursor(0,0);
lcd.print("  Water Is Full");
MODE=0;//change to pool ready mode
}
else
{
digitalWrite(PUMP,ON);
}

if (digitalRead(LOW_LEVEL)==OFF)
{
digitalWrite(PUMP,ON);
}
}

void WaterCleaningMode()
{
lcd.clear();

digitalWrite(LIGHT1, OFF);
digitalWrite(LIGHT2, OFF);
digitalWrite(LIGHT3, OFF);
digitalWrite(LIGHT4, OFF);
digitalWrite(HEATER,OFF);
lcd.setCursor(0,0);
lcd.clear();
lcd.print("Water Recycling");
digitalWrite(VALVE, ON);
delay(400);
if (digitalRead(LOW_LEVEL)==OFF)
{
lcd.setCursor(0,0);
lcd.print("  Water Cleaned");
lcd.setCursor(8,1);
//5 sec.delay routine
digitalWrite(VALVE, OFF);
MODE=1;//change to water filling mode
}
}

void ReadyMode()
{


//lcd.print("    Pool Is Ready");
//first check the upper level sensors, if it is low then
//goto water filling mode
if (digitalRead(LOW_LEVEL)==OFF)
{
MODE=1;
}
//lighting code
//date time showin code
// first 8 digits=current time and add a space
lcd.setCursor(0, 0);
lcd.print(hour, DEC); // the hour, sent to the screen in decimal format
lcd.print(":"); // a colon between the hour and the minute
lcd.print(minute, DEC); // the minute, sent to the screen in decimal format
lcd.print(":"); // a colon between the minute and the second
lcd.print(second, DEC); // the second, sent to the screen in decimal format

lcd.print(" T-"); // a separator to separate time and temperature

//temperature control+showing code
if (getTemperature())
{
//lcd.clear();
//lcd.setCursor(2,1);
//lcd.print("Temp ");
lcd.print(temp);
lcd.print("\337C");
//temperature control code
}

if (temp<=TEMPERATURE_LIMIT)
{
digitalWrite(HEATER,ON);
}
else
{
digitalWrite(HEATER,OFF);
}
//lcd.print("Temp ");

//show the next water recycling day &time
lcd.setCursor(0, 1);
if (weekday<7)
{
printWeekday(weekday+1);
lcd.print(TimeRoutine[weekday][0]);
lcd.print(":");
lcd.print(TimeRoutine[weekday][1]);
}
else
{
printWeekday(1);
lcd.print(TimeRoutine[1][0]);
lcd.print(":");
lcd.print(TimeRoutine[1][1]);
}

//count untill reached the date time from table
//then go to mode=2 //water cleaning mode
if (TimeRoutine[weekday][0]==hour)
{
if (TimeRoutine[weekday][1]==minute)
{
if (second==0)
{
//EXECUTE WATER CLEANING MODE
MODE=2;
}
}
}



Light++;
if (Light>7)
{
Light=0;
}
if (Light==0)
{
digitalWrite(LIGHT1, ON);
digitalWrite(LIGHT2, OFF);
digitalWrite(LIGHT3, OFF);
digitalWrite(LIGHT4, OFF);
}
else if (Light==2)
{
digitalWrite(LIGHT1, OFF);
digitalWrite(LIGHT2, OFF);
digitalWrite(LIGHT3, ON);
digitalWrite(LIGHT4, OFF);
}
else if (Light==4)
{
digitalWrite(LIGHT1, OFF);
digitalWrite(LIGHT2, ON);
digitalWrite(LIGHT3, OFF);
digitalWrite(LIGHT4, OFF);
}
else if (Light==6)
{
digitalWrite(LIGHT1, OFF);
digitalWrite(LIGHT2, OFF);
digitalWrite(LIGHT3, OFF);
digitalWrite(LIGHT4, ON);
}
}


void setup(void)//this code section runs once
{

lcd.begin(LCD_WIDTH, LCD_HEIGHT,1);
lcd.print("Initializing");

pinMode(OVERFLOW_LEVEL, INPUT);
pinMode(LOW_LEVEL, INPUT);
pinMode(HIGH_LEVEL, INPUT);
pinMode(PUMP, OUTPUT);
pinMode(HEATER, OUTPUT);
pinMode(VALVE, OUTPUT);
pinMode(LIGHT1, OUTPUT);
pinMode(LIGHT2, OUTPUT);
pinMode(LIGHT3, OUTPUT);
pinMode(LIGHT4, OUTPUT);
pinMode(minutePin, INPUT);
pinMode(hourPin, INPUT);
pinMode(weekdayPin, INPUT);

lcd.setCursor(0,0);
lcd.print("Initializing.");

digitalWrite(OVERFLOW_LEVEL, LOW);
digitalWrite(LOW_LEVEL, LOW);
digitalWrite(HIGH_LEVEL, LOW);
digitalWrite(PUMP, LOW);
digitalWrite(HEATER, LOW);
digitalWrite(VALVE, LOW);
digitalWrite(LIGHT1, LOW);
digitalWrite(LIGHT2, LOW);
digitalWrite(LIGHT3, LOW);
digitalWrite(LIGHT4, LOW);
digitalWrite(minutePin, HIGH);
digitalWrite(hourPin, HIGH);
digitalWrite(weekdayPin, HIGH);

lcd.setCursor(0,0);
lcd.print("Initializing..");
//INITIALIZE THE TIMING VARIABLES
second=50;
minute=19;
hour=9;
weekday=1;
delay(300);
lcd.setCursor(0,0);
lcd.print("Initializing...");
delay(500);
lcd.setCursor(0,0);
lcd.print("Initializing....");
}


void loop(void)
{
static unsigned long lastTick = 0; // set up a local variable to hold the last time we moved forward one second
// (static variables are initialized once and keep their values between function calls)
// move forward one second every 1000 milliseconds
if (millis() - lastTick >= 1000) {
lastTick = millis();
//LcdOutput();
second++;
}

// move forward one minute every 60 seconds
if (second > 59) {
minute++;
second = 0; // reset seconds to zero
}
// move forward one hour every 60 minutes
if (minute > 59) {
hour++;
minute = 0; // reset minutes to zero
}
// move forward one weekday every 24 hours
if (hour > 23) {
weekday++;
hour = 0; // reset hours to zero
}
// reset weekdays on Saturday
if (weekday > 7) {
weekday = 1;
}

checkButtons(); // runs a function that checks the setting buttons

if (MODE==0)
{
// pool is ready
ReadyMode();
}
else if (MODE==1)
{
//WATER FILLING MODE
WaterFillingMode();
}
else if (MODE==2)
{
//WATER RECYCLING MODE
WaterCleaningMode();
}

}

Where Am I?

You are currently browsing the Swimming Pool Controller category at khairulhasanmd.

%d bloggers like this: