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 :
[code language=”cpp”]///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();
}
}
[/code]
Comments are closed.