Code Version 2.5
From Reef Projects
Code is fairly well commented. (12688 bytes)
Current Features:
- Controls lights/timer function
If lights are killed because of restart (power fail) or overheating, there is a delay before turning onbuilt into ballast
* Controls heater & fan
- If temp is too low, lights come on to raise temp
- Controls heater in normal range
- Turns on fan if too hot
- Turns off lights if fan is unable to cool the tank
- Feed mode button
ATOATO will be separate- Alarm when temp is out of range
- Countdown to when pumps will resume in feed mode
PH monitor- Prints to LCD
- Shows relays that are active
- Displays high/low/current temp
- Displays time
- Keypad Controls
- Normal Running mode
- Set time and date from keypad
- Feed mode with countdown timer
- Skimmer stays off for 30 minutes after powerheads come back on
- Includes updates by Mattotone
- Works with Arduino 0015 with keypad() function modified v.1 and LCDtoI2C Library
#include <OneWire.h>
#include <LCDI2C.h>
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>
/*
To do:
* integrate keypad
A-normal mode
B-set time
*Set hours and minutes
C-feed mode
*turn off pumps/skimmer for 5 min
D-Reset High / Low temp
Arduino Reef Controller
Analog Pin 0 =
Analog Pin 1 = PH Probe
Analog Pin 2 = **ORP Probe?
Analog Pin 3 =
Analog Pin 4 = SDA for I2C
Analog Pin 5 = SCL for I2C
Digital Pin 0 = RX
Digital Pin 1 = TX
Digital Pin 2 = Temp Sensor
Digital Pin 3 = Alarm
Digital Pin 4 =
Digital Pin 5 =
Digital Pin 6 = Relay 1 Heater
Digital Pin 7 = Relay 2 Day Light
Digital Pin 8 = Relay 3 Moon Light
Digital Pin 9 = Relay 4 Fan
Digital Pin 10 = Relay 5 Skimmer
Digital Pin 11 = Relay 6 Power Head #1
Digital Pin 12 = Relay 7 Power Head #2
Digital Pin 13 = Relay 8
*/
LCDI2C lcd = LCDI2C(4,20,0x4C,1); //[# of lines on LCD],[address of serial LCD controller on I2C]
OneWire ds(2); // Temp Sensor on pin 2
int day_light = 7;
int moon_light = 8;
int fan = 9;
//int ato = 10;
int ph_1 = 11;
int ph_2 = 12;
int skimmer = 10;
int alarm = 3;
int fuge_light = 5;
int heater = 6;
int heater_on_temp = 7750; //Turn on the heater at this temp ex 78 degrees = 7800, 78.5 degrees = 7850
int heater_off_temp = 7800; //Turn off heater at this temp
int fan_on_temp = 8100; //Turn on fan at this temp
int fan_off_temp = 8050; //turn fan off once below this temp
int lights_off_temp = 8300; //Turn off the lights if the temp rises above this temp
int alarm_low_temp = 7600; //alarm will begin if temp falls below this value & lights will turn on to raise the temperature
int alarm_high_temp = 8300; //alarm will begin if temp is above this value
int lights_on_time_1 = -100; //Turn day lights on at this time (military time)
int lights_off_time_1 = -100; //Turn day lights off at this time
int lights_on_time_2 = 1200; //Turn day lights on at this time (military time)
int lights_off_time_2 = 2000; //Turn day lights off at this time
int wait_time = 0; //how long to wait before turning on lights if they are turned off due to power loss or overheating
int lights_out = -100; //placeholder --don't change
int moonl_on_time = 2100; //Turn on moon lights at this time
int moonl_off_time = 700; //Turn off moon lights at this time
int fuge_on_time = 2000; //Turn on refugium lights at this time
int fuge_off_time = 1000; //Turn off refugium lights at this time
int feed_time = 5; //Turn off power heads for this amount of time when feed mode button is pressed.
int pumps_off = -10; //placeholder --don't change
int skimmer_off = -10; //placeholder ---don't change
int pumps_off_second, pumps_off_minute, pumps_on_minute, pumps_off_hour, pumps_on_second, pumps_on_hour, pumps_on, skimmer_on_hour, skimmer_on_minute, skimmer_on_second;
//int ato_time = 3; //Number of seconds for teh ATO to run each time the switch is on.
#define NUMREADINGS 10
int readings[NUMREADINGS]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int keypad_delay = 15; //necessary delay to keep from having scrambled characters on the display
void setup(void) {
Wire.begin(); //initialize the I2C bus
lcd.init(); //initialize LCD
/*Un-comment to set the time
RTC.stop();
RTC.set(DS1307_SEC,01); //set the seconds
RTC.set(DS1307_MIN,51); //set the minutes
RTC.set(DS1307_HR,20); //set the hours (military)
RTC.set(DS1307_DOW,7); //set the day of the week
RTC.set(DS1307_DATE,29); //set the date
RTC.set(DS1307_MTH,3); //set the month
RTC.set(DS1307_YR,9); //set the year
RTC.start();
//****** initialize inputs/outputs ************************************/
pinMode(day_light, OUTPUT); // digital pin for day light as output
pinMode(moon_light, OUTPUT); // digital pin for moon light as output
pinMode(fan, OUTPUT); // digital pin for fan as output
//pinMode(ato, OUTPUT); // digital pin for auto top off as output
pinMode(ph_1, OUTPUT); // digital pin for power head 1 as output
pinMode(ph_2, OUTPUT); // digital pin for power head 2 as output
pinMode(skimmer, OUTPUT); // digital pin for skimmer as output
pinMode(alarm, OUTPUT); // digital pin for alarm as output
pinMode(heater, OUTPUT); //digital pin for heater output
digitalWrite(day_light, LOW);
for (int i = 0; i < NUMREADINGS; i++)
readings[i] = 0;
}
int High = 0;
int Low = 10000;
int on_minute = 1; //indicates that this is the first time through the program.
void loop(void){
int mode = 100; //Check for keypad input
if(lcd.keypad() != -1){
mode = lcd.keypad();
}
//***********Mode B Set Time*************************************************************************************************
if(mode == 101){
int minute, hour, second, date, month, year, tens, ones, key;
int set_time = 0;
while(set_time == 0){
lcd.clear();
hour = RTC.get(DS1307_HR,true); //This is in military time [0,23]
minute = RTC.get(DS1307_MIN,false);
second = RTC.get(DS1307_SEC,false);
date = RTC.get(DS1307_DATE,false);
month = RTC.get(DS1307_MTH,false);
year = RTC.get(DS1307_YR,false);
lcd.setCursor(0,0);
if(hour < 10){
lcd.print(" ");
delay(keypad_delay);
}
lcd.print(hour);
delay(keypad_delay);
lcd.print(":");
delay(keypad_delay);
if(minute < 10){
lcd.print("0");
delay(keypad_delay);
}
lcd.print(minute);
delay(keypad_delay);
/* Don't print seconds
lcd.print(":");
delay(keypad_delay);
if(second < 10){
lcd.print("0");
delay(keypad_delay);
}
lcd.print(second);
delay(keypad_delay);
*/
lcd.setCursor(1,0);
if(month < 10){
lcd.print(" ");
delay(keypad_delay);
}
lcd.print(month);
delay(keypad_delay);
lcd.print("/");
delay(keypad_delay);
if(date < 10){
lcd.print(" ");
delay(keypad_delay);
}
lcd.print(date);
delay(keypad_delay);
lcd.print("/");
delay(keypad_delay);
if(year < 10){
lcd.print("0");
delay(keypad_delay);
}
lcd.print(year);
delay(keypad_delay);
lcd.setCursor(0,0);
lcd.cursor_on();
//**************Set Hour*********************************************************************************************
for (;;){
key = lcd.keypad();
if(key >= 0 && key <= 2){tens = key; break;}
}
for (;;){
key = lcd.keypad();
if(key == -1){break;}
}
lcd.print(tens);
delay(keypad_delay);
for (;;){
key = lcd.keypad();
if(key >= 0 && key <= 9){ones = key; break;}
}
for (;;){
key = lcd.keypad();
if(key == -1){break;}
}
lcd.right();
RTC.stop();
RTC.set(DS1307_HR,tens * 10 + ones);
RTC.start();
lcd.setCursor(0,0);
hour = RTC.get(DS1307_HR,true);
if(hour < 10){
lcd.print(" ");
delay(keypad_delay);
}
lcd.print(hour);
delay(keypad_delay);
lcd.right();
//**************Set Minute*********************************************************************************************
for (;;){
key = lcd.keypad();
if(key >= 0 && key <= 6){tens = key; break;}
}
for (;;){
key = lcd.keypad();
if(key == -1){break;}
}
lcd.print(tens);
delay(keypad_delay);
for (;;){
key = lcd.keypad();
if(key >= 0 && key <= 9){ones = key; break;}
}
for (;;){
key = lcd.keypad();
if(key == -1){break;}
}
lcd.right();
RTC.stop();
RTC.set(DS1307_MIN,tens * 10 + ones);
RTC.start();
lcd.setCursor(0,3);
minute = RTC.get(DS1307_MIN,true);
if(minute < 10){
lcd.print("0");
delay(keypad_delay);
}
lcd.print(minute);
delay(keypad_delay);
//**************Set Month*********************************************************************************************
lcd.setCursor(1,0);
for (;;){
key = lcd.keypad();
if(key == 0 || key == 1){tens = key; break;}
}
for (;;){
key = lcd.keypad();
if(key == -1){break;}
}
lcd.print(tens);
delay(keypad_delay);
for (;;){
key = lcd.keypad();
if(key >= 0 && key <= 9){ones = key; break;}
}
for (;;){
key = lcd.keypad();
if(key == -1){break;}
}
lcd.right();
RTC.stop();
RTC.set(DS1307_MTH,tens * 10 + ones);
RTC.start();
lcd.setCursor(1,0);
month = RTC.get(DS1307_MTH,true);
if(month < 10){
lcd.print(" ");
delay(keypad_delay);
}
lcd.print(month);
delay(keypad_delay);
//**************Set Date*********************************************************************************************
lcd.setCursor(1,3);
for (;;){
key = lcd.keypad();
if(key >= 0 && key <= 3){tens = key; break;}
}
for (;;){
key = lcd.keypad();
if(key == -1){break;}
}
lcd.print(tens);
delay(keypad_delay);
for (;;){
key = lcd.keypad();
if(key >= 0 && key <= 9){ones = key; break;}
}
for (;;){
key = lcd.keypad();
if(key == -1){break;}
}
lcd.right();
RTC.stop();
RTC.set(DS1307_DATE,tens * 10 + ones);
RTC.start();
lcd.setCursor(1,3);
date = RTC.get(DS1307_DATE,true);
if(date < 10){
lcd.print(" ");
delay(keypad_delay);
}
lcd.print(date);
delay(keypad_delay);
//**************Set Year*********************************************************************************************
lcd.setCursor(1,8);
for (;;){
key = lcd.keypad();
if(key >= 0 && key <= 9){tens = key; break;}
}
for (;;){
key = lcd.keypad();
if(key == -1){break;}
}
lcd.print(tens);
delay(keypad_delay);
for (;;){
key = lcd.keypad();
if(key >= 0 && key <= 9){ones = key; break;}
}
for (;;){
key = lcd.keypad();
if(key == -1){break;}
}
lcd.right();
RTC.stop();
RTC.set(DS1307_YR,tens * 10 + ones);
RTC.start();
lcd.setCursor(1,6);
year = RTC.get(DS1307_YR,true);
if(year < 10){
lcd.print(" ");
delay(keypad_delay);
}
lcd.print(year);
delay(keypad_delay);
//**************Finish Up*********************************************************************************************
for (;;){
lcd.cursor_off();
lcd.setCursor(2,0);
lcd.print("Time & Date Set");
delay(keypad_delay);
lcd.setCursor(3,0);
lcd.print("Choose Mode A or B");
delay(keypad_delay);
if(lcd.keypad() == 100){set_time = 1; break;}
if(lcd.keypad() == 101){break;}
}
lcd.clear();
} //end while
} //end mode 101
//*************Normal Mode 100 and Feed Mode 102*************************************************************************************************
if(mode == 100 || mode == 102 || mode == 103){
byte i;
byte present = 0;
byte data[12];
byte addr[8];
long ph_val;
int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract, minute, hour, second, date, month, year, mil_time;
//int ph_read;
//Get time from DS1307**********************************************************************************************
hour = RTC.get(DS1307_HR,true); //This is in military time [0,23]
minute = RTC.get(DS1307_MIN,false);
second = RTC.get(DS1307_SEC,false);
// date = RTC.get(DS1307_DATE,false);
// month = RTC.get(DS1307_MTH,false);
// year = RTC.get(DS1307_YR,false);
mil_time = (hour * 100) + minute; //create military time output [0000,2400)
//Get temp data from DS18B20 ***************************************************************************************
if ( !ds.search(addr)) {
ds.reset_search();
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
LowByte = data[0];
HighByte = data[1];
TReading = (HighByte << 8) + LowByte;
SignBit = TReading & 0x8000; // test most sig bit
if (SignBit) // negative
{
TReading = (TReading ^ 0xffff) + 1; // 2's comp
}
Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25
Tc_100 = (Tc_100 * 9/5) + 3200; //Convert to fahrenheit, comment this out to display in celcius
//Display current temperature*****************************************************************************
lcd.setCursor(0,0);
Whole = (Tc_100 / 100); // separate off the whole and fractional portions
Fract = (Tc_100 % 100);
lcd.print(Whole, DEC);
delay(keypad_delay);
lcd.print(".");
delay(keypad_delay);
if (Fract < 10)
{
lcd.print("0");
delay(keypad_delay);
}
lcd.print(Fract, DEC);
delay(keypad_delay);
lcd.write(0xDF);
delay(keypad_delay);
lcd.print("F ");
delay(keypad_delay);
//Alarm if temp is out of bounds**************************************************************************
if(alarm_low_temp > Tc_100 || alarm_high_temp < Tc_100){
digitalWrite(alarm, HIGH);
delay(300);
digitalWrite(alarm, LOW);
}
//Display Time******************************************************************************************
lcd.setCursor(0,10);
if((hour < 10 && hour > 0) || (hour > 12 && hour - 12 < 10)){
lcd.print(" ");
delay(keypad_delay);
}
if(hour > 12){
lcd.print(hour - 12, DEC);
delay(keypad_delay);
}
if(hour == 0){
lcd.print(12, DEC);
delay(keypad_delay);
}
if(hour > 0 && hour < 13){
lcd.print(hour, DEC);
delay(keypad_delay);
}
lcd.print(":");
delay(keypad_delay);
if(minute < 10){
lcd.print("0");
delay(keypad_delay);
}
lcd.print(minute, DEC);
delay(keypad_delay);
lcd.print(":");
delay(keypad_delay);
if(second < 10){
lcd.print("0");
delay(keypad_delay);
}
lcd.print(second, DEC);
delay(keypad_delay);
if(hour < 12 || hour == 0){
lcd.print("AM");
delay(keypad_delay);
}
else{
lcd.print("PM");
delay(keypad_delay);
}
//Display High Temp***********************************************************************************
if(on_minute == 0){ //used so if bad data is sent for the first reading, it is not saved
lcd.setCursor(1,0);
if(Tc_100 > High){
High = Tc_100;
}
Whole = (High / 100); // separate off the whole and fractional portions
Fract = (High % 100);
lcd.print("H= ");
delay(keypad_delay);
lcd.print(Whole, DEC);
delay(keypad_delay);
lcd.print(".");
delay(keypad_delay);
if (Fract < 10)
{
lcd.print("0");
delay(keypad_delay);
}
lcd.print(Fract, DEC);
delay(keypad_delay);
lcd.write(0xDF);
delay(keypad_delay);
lcd.print(" ");
delay(keypad_delay);
}
//Display Low Temp***************************************************************************************
if(on_minute == 0){ //used so if bad data is sent for the first reading, it is not saved
if(Tc_100 < Low){
Low = Tc_100;
}
Whole = (Low / 100); // separate off the whole and fractional portions
Fract = (Low % 100);
lcd.print("L= ");
delay(keypad_delay);
lcd.print(Whole, DEC);
delay(keypad_delay);
lcd.print(".");
delay(keypad_delay);
if (Fract < 10)
{
lcd.print("0");
delay(keypad_delay);
}
lcd.print(Fract, DEC);
delay(keypad_delay);
lcd.write(0xDF);
delay(keypad_delay);
lcd.print(" ");
delay(keypad_delay);
}
//Relay Controls ***************************************************************************************
//****************Heater***************************************************************************
if(Tc_100 < heater_on_temp){ // turn heater on if temp is below heater_on_temp
digitalWrite(heater, HIGH);
}
if(Tc_100 > heater_off_temp){ //turn heater off if temp is above heater_off_temp
digitalWrite(heater, LOW);
}
//****************Day Lights****************************************************************************
// Two On/off cycles no waiting to turn the light on, ballast has internal switch
if((lights_on_time_1 < mil_time && lights_off_time_1 >= mil_time && lights_off_temp > Tc_100) || (lights_on_time_2 < mil_time && lights_off_time_2 >= mil_time && lights_off_temp > Tc_100) || (alarm_low_temp > Tc_100)) {
digitalWrite(day_light, HIGH);
}
else{
digitalWrite(day_light, LOW);
}
//****************Moon Lights*******************************************************************************
if( ((moonl_off_time < moonl_on_time) && (moonl_on_time <= mil_time || moonl_off_time > mil_time)) || (moonl_on_time <= mil_time && moonl_off_time > mil_time) ) {
digitalWrite(moon_light, HIGH);
}
else{
digitalWrite(moon_light, LOW);
}
//****************Refugium Lights*******************************************************************************
if(fuge_on_time <= mil_time || fuge_off_time > mil_time){
digitalWrite(fuge_light, HIGH);
}
else{
digitalWrite(fuge_light, LOW);
}
//****************Fan****************************************************************************************
if(Tc_100 > fan_on_temp){ // turn fan on if temp is above fan_on_temp
digitalWrite(fan, HIGH);
}
if(Tc_100 < fan_off_temp){ //turn fan off if temp is below fan_off_temp
digitalWrite(fan, LOW);
}
/****************Auto top off********************************************************************************
if(digitalRead(ato_input) == LOW && ato_hour != hour){
digitalWrite(ato, HIGH);
delay(ato_time * 1000); //Turn on ATO pump for the number of seconds defined by ato_time
digitalWrite(ato, LOW); //Turn off ATO Pump
ato_hour = hour; //only allow the ATO to run once per hour.
lcd.setCursor(3,0); //Display the last time the ATO ran
lcd.print("ATO ");
delay(keypad_delay);
if(hour < 10 || (hour > 12 && hour - 12 < 10)){
lcd.print(" ");
delay(keypad_delay);
}
if(hour > 12){
lcd.print(hour - 12, DEC);
delay(keypad_delay);
}
if(hour == 0){
lcd.print(12, DEC);
delay(keypad_delay);
}
if(hour > 0 && hour < 13){
lcd.print(hour, DEC);
delay(keypad_delay);
}
lcd.print(":");
delay(keypad_delay);
if(minute < 10){
lcd.print("0");
delay(keypad_delay);
}
lcd.print(minute, DEC);
delay(keypad_delay);
if(hour < 12){
lcd.print("AM ");
delay(keypad_delay);
}
else{
lcd.print("PM ");
delay(keypad_delay);
}
}
*/
//***********PH Probe**********************************************************************************************
/* To calibrate ph probe set 7ph to 2V and 10PH to 1V
total -= readings[index]; // subtract the last reading
readings[index] = analogRead(ph_probe); // read from the sensor
total += readings[index]; // add the reading to the total
index = (index + 1); // advance to the next index
if (index >= NUMREADINGS) // if we're at the end of the array...
index = 0; // ...wrap around to the beginning
average = total / NUMREADINGS; // calculate the average
ph_val = (-1.47 * average + 1300); //ph is stored 100 times value
Whole = (ph_val / 100); // separate off the whole and fractional portions
Fract = (ph_val % 100);
lcd.setCursor(3,12);
lcd.print("PH ");
delay(keypad_delay);
if (Whole < 10){
lcd.print(" ");
delay(keypad_delay);
}
lcd.print(Whole, DEC);
delay(keypad_delay);
lcd.print(".");
delay(keypad_delay);
if (Fract < 10){
lcd.print("0");
delay(keypad_delay);
}
lcd.print(Fract, DEC);
delay(keypad_delay);
*/
//****************Power heads and skimmer feed mode 102******************************************************************
if(mode == 102 && digitalRead(skimmer) == LOW){
pumps_off = -10;
skimmer_off = -10;
}
if(mode == 102 && digitalRead(ph_1) == HIGH){
pumps_off = 10;
skimmer_off = 10;
pumps_on_second = second;
if(minute + feed_time > 59){
pumps_on_minute = (minute + feed_time) % 60;
pumps_on_hour = hour + 1;
}
else{
pumps_on_minute = minute + feed_time;
pumps_on_hour = hour;
}
if(pumps_on_hour > 23){
pumps_on_hour = pumps_on_hour - 24;
}
skimmer_on_second = second;
if(minute + feed_time + 30 > 59){
skimmer_on_minute = (minute + feed_time + 30) % 60;
skimmer_on_hour = hour + 1;
}
else{
skimmer_on_minute = minute + feed_time + 30;
skimmer_on_hour = hour;
}
if(skimmer_on_hour > 23){
skimmer_on_hour = skimmer_on_hour - 24;
}
}
if((pumps_on_hour == hour && pumps_on_minute == minute && pumps_on_second <= second) || pumps_off == -10){
digitalWrite(ph_1, HIGH);
digitalWrite(ph_2, HIGH);
pumps_off = -10;
}
else{
digitalWrite(ph_1, LOW);
digitalWrite(ph_2, LOW);
}
if((skimmer_on_hour == hour && skimmer_on_minute == minute && skimmer_on_second <= second) || skimmer_off == -10){
digitalWrite(skimmer, HIGH);
skimmer_off = -10;
}
else{
digitalWrite(skimmer, LOW);
}
//Display when normal operation will resume*******************
if(pumps_off != -10){
lcd.setCursor(3,0);
if(pumps_on_minute >= minute){
pumps_off_second = pumps_on_second - second + feed_time * 60 + pumps_on_minute * 60 - minute * 60 - feed_time * 60;
}
else{
pumps_on = minute - 60;
pumps_off_second = pumps_on_second - second + feed_time * 60 + pumps_on_minute * 60 - pumps_on * 60 - feed_time * 60;
}
pumps_off_minute = pumps_off_second / 60;
if(pumps_off_minute < 10){
lcd.print(" ");
delay(keypad_delay);
}
lcd.print(pumps_off_minute); //minutes until pumps turn on
delay(keypad_delay);
lcd.print(":");
delay(keypad_delay);
if(pumps_off_second % 60 < 10){
lcd.print("0");
delay(keypad_delay);
}
lcd.print(pumps_off_second % 60); //seconds until pumps turn on
delay(keypad_delay);
}
else{
lcd.setCursor(3,0);
lcd.print(" ");
delay(keypad_delay);
}
//Display what relays are on******************************************************************************************
lcd.setCursor(2,0);
if(digitalRead(fuge_light) == HIGH){lcd.print("S1 ");delay(keypad_delay);}
else{lcd.print("S0 ");delay(keypad_delay);}
if(digitalRead(heater) == HIGH){lcd.print("H1 ");delay(keypad_delay);}
else{lcd.print("H0 ");delay(keypad_delay);}
if(digitalRead(day_light) == HIGH){lcd.print("L1 ");delay(keypad_delay);}
else{lcd.print("L0 ");delay(keypad_delay);}
if(digitalRead(moon_light) == HIGH){lcd.print("M1 ");delay(keypad_delay);}
else{lcd.print("M0 ");delay(keypad_delay);}
if(digitalRead(fan) == HIGH){lcd.print("F1 ");delay(keypad_delay);}
else{lcd.print("F0 ");delay(keypad_delay);}
if(digitalRead(ph_1) == HIGH){lcd.print("P1 ");delay(keypad_delay);}
else{lcd.print("P0 ");delay(keypad_delay);}
//Mode D (103) Reset temps********************************************************************************************
if(mode == 103){
High = Tc_100;
Low = Tc_100;
}
on_minute = 0; //signals that the program has been run once
} //end mode 100 & 102 &103
} //end loop
