Arduino Aquarium Controller

Hello,

As you understand from the subject I am trying to built an aquarium controller, I am working on this project about 2 years starting from scratch because I didn't have any idea about electronics I am just a sailor... and everything I have done is with a lot of research and work, but i am in a dead end now and i would like your help!!!

My controller has an LCD (20x4), a DS1307 as RTC and 3 DS18S20, one is waterproof, for measuring the temperature I am planning to add an 8 channel relay to control multiple devices and some push buttons.

My problem is that the temperature is not very accurate i have a 0,5 degrees difference from my Temperature Controller (Elliwell ic915)and I am wondering if it is a way to calibrate the DS18S20.
And also I can't make my relay to open and close due to the temperature difference.

Here is my code if anyone can help me... (be gentle with me I am very amateur as you will understand :-[ :-[ :-[ )

#include <LiquidCrystal.h>
#include <math.h>
#include "RTClib.h"
#include <Time.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 3

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Assign the addresses of your 1-Wire temp sensors.
DeviceAddress WaterTemperature = { 0x28, 0x62, 0x30, 0xCA, 0x03, 0x00, 0x00, 0xF1 };
DeviceAddress DeviceTemperature = { 0x10, 0x9A, 0x3E, 0x84, 0x02, 0x08, 0x00, 0x4D };
DeviceAddress RoomTemperature = { 0x10, 0xA1, 0xFE, 0x83, 0x02, 0x08, 0x00, 0xFC };

/*
LCD Connections:
rs (LCD pin 4) to Arduino pin 12
rw (LCD pin 5) to Arduino pin 11
enable (LCD pin 6) to Arduino pin 10
LCD pin 15 to Arduino pin 13
LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
*/

LiquidCrystal lcd(12, 11, 4, 5, 6, 7);
RTC_DS1307 RTC;
long previousLCDMillis = 0;    // for LCD screen update
long lcdInterval = 20000;
// screen to show 
int screen = 0;    
int screenMax = 2;
bool screenChanged = true;   // initially we have a new screen,  by definition 
// defines of the screens to show
#define SCREEN1 0
#define SCREEN2       1
#define SCREEN3              2

int ledPinFilter1 = 26;                 // LED connected to digital pin 28 (Filter 1)
int ledPinFilter2 = 27;                 // LED connected to digital pin 31 (Filter 2)
int ledPinHeater = 29;                  // LED connected to digital pin 27 (Heater)
int ledPinFan = 28;
int RelayPinHeater = 24;
int RelayPinFan = 25;

void setup(void) 
{
  pinMode(ledPinFilter1, OUTPUT);      // sets the digital pin as output
  pinMode(ledPinFilter2, OUTPUT);
  pinMode(ledPinHeater, OUTPUT);
  pinMode(ledPinFan, OUTPUT);
  pinMode(RelayPinHeater, OUTPUT);
  pinMode(RelayPinFan, OUTPUT);
  digitalWrite(RelayPinHeater, LOW); // Set the Heater to LOW (off)
  
  // Start up the library
  sensors.begin();  
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(WaterTemperature, 12);
  sensors.setResolution(RoomTemperature, 11);
  sensors.setResolution(DeviceTemperature, 11);
  
  Serial.begin(9600);
Wire.begin();
RTC.begin();
lcd.begin(20, 4);
pinMode(8,OUTPUT);
 
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}  
  lcd.begin(20, 4);              // rows, columns.  use 16,2 for a 16x2 LCD, etc.
  showWelcome();  
  delay(4000);   // to show message on screen}
     
}

void showWelcome()
{
  lcd.clear();
  lcd.setCursor(1, 0);           
  lcd.print("My Amazon Aquarium");
  lcd.setCursor(3, 1);          
  lcd.print("initialising...");
  lcd.setCursor(1, 2);          
  lcd.print("Aquarium Controler");  
}

void showScreen1()
{
  lcd.clear();
  lcd.setCursor(1, 0);// set the cursor to column 1, line 0 (first row)
  lcd.print("My Amazon Aquarium");
  lcd.setCursor(0, 1);       
  lcd.print("Water Temp:");
  printTemperature(WaterTemperature); 
  lcd.print((char)223); 
  lcd.print("C");
  lcd.setCursor(0, 2);
  lcd.print("PH: 6.8");
  lcd.setCursor(0, 3);
  lcd.print("TDS: 150");
  lcd.setCursor(9, 3);
  lcd.print("ms");
}

void showScreen2()
{
  lcd.clear();
  DateTime now = RTC.now();
  lcd.setCursor(1, 0);
  lcd.print("My Amazon Aquarium");
  lcd.setCursor(0, 1);
  lcd.print(now.day(), DEC);
  lcd.print('/');
  lcd.print(now.month(), DEC);
  lcd.print('/');
  lcd.print(now.year(), DEC);
  lcd.setCursor(12, 1);
  if (now.hour()<10)
  lcd.print('0');
  lcd.print(now.hour(), DEC);
  lcd.print(':');
  if (now.minute()<10)
  lcd.print('0');
  lcd.print(now.minute(), DEC);
  lcd.print(':');
  if (now.second()<10)
  lcd.print('0');
  lcd.print(now.second(), DEC);
  lcd.setCursor(0, 2);
  lcd.print("Room Temp:");  
  printTemperature(RoomTemperature);
  lcd.print((char)223);
  lcd.print("C");
  lcd.setCursor(0, 3);
  lcd.print("PH: 6.8");
  lcd.setCursor(8, 3);
  lcd.print("TDS: 150");
  lcd.setCursor(16, 3);
  lcd.print("ms");
  
}

void showScreen3()
{
  lcd.clear();
  DateTime now = RTC.now();
  lcd.setCursor(1, 0);// set the cursor to column 1, line 0 (first row)
  lcd.print("My Amazon Aquarium");
  lcd.setCursor(6, 1);
  if (now.hour()<10)
  lcd.print('0');
  lcd.print(now.hour(), DEC);
  lcd.print(':');
  if (now.minute()<10)
  lcd.print('0');
  lcd.print(now.minute(), DEC);
  lcd.print(':');
  if (now.second()<10)
  lcd.print('0');
  lcd.print(now.second(), DEC);
  lcd.setCursor(0, 2);
  lcd.print("Water Temp:");
  printTemperature(WaterTemperature); 
  lcd.print((char)223); 
  lcd.print("C");
  lcd.setCursor(0, 3);
  lcd.print("Device Temp:");  
  printTemperature(DeviceTemperature);
  lcd.print((char)223);
  lcd.print("C");
 
  
}


void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
  lcd.print("Error");
  } else {
  lcd.print(tempC, 1);
}
}
void loop(void) {
  unsigned long currentLCDMillis = millis();

  // MUST WE SWITCH SCREEN?
  if(currentLCDMillis - previousLCDMillis > lcdInterval)              // save the last time you changed the display 
  {
    previousLCDMillis = currentLCDMillis; 
    screen++;
    if (screen > screenMax) screen = 0;  // all screens done? => start over
    screenChanged = true; 
  }

  // debug Serial.println(screen);


  // DISPLAY CURRENT SCREEN
  {
    screenChanged = false; // reset for next iteration
    switch(screen)
    {
    case SCREEN1: 
      showScreen1(); 
      break;
    case SCREEN2: 
      showScreen2();
      break;
    case SCREEN3:
      showScreen3();
      break;
    default:
      // cannot happen -> showError() ?
      break;
    }
    
    const int TurnHeaterOnTemperature = 27.8;   // The Temperature that sets the Heater on
    const int TurnHeaterOffTemperature = 28.0;   // The Temperature that sets the Heater off
    const int TurnFanOnTemperature = 27.2;  // The Temperature that sets the Fan on
    const int TurnFanOffTemperature = 27.0;  // The Temperature that sets the Fan off

    sensors.requestTemperatures();
   {
    if('WaterTemperature' <= 'TurnHeaterOnTemperature'){
    digitalWrite(RelayPinHeater,HIGH);    // sets the Heater on 
    }
    delay(1000);
    }}}

hi,
my english is not best so i'm not shure if i understand your problem

but the DS18S20 is not verry exact, its tolerance is abou 0.5 K, so i think you can not mesure better using this.

Any suggestion about other Temperature sensor more accurate???

+- .5C is pretty good for the price.

Here's one that +-.25C

Any Help about my code????

Hi, use the "Search the Arduino Forum" window, search for aquarium, it has been done many times before.

Tom......... :slight_smile:

Look in the infamous printTemperature routine and you'll see this:

  float tempC = sensors.getTempC(deviceAddress);

You can use the same construct to get the water temperature in the section where you want to control your relay. What you have currently:

      if('WaterTemperature' <= 'TurnHeaterOnTemperature'){

Is comparing two bizarre constant multibyte characters. Get rid of the single quotes, declare a float called WaterTemperature and read the temperature into it. You'll also want to change your constants such as TurnHeaterOnTemperature to be float too, rather than int.

wildbill:
Look in the infamous printTemperature routine and you'll see this:

  float tempC = sensors.getTempC(deviceAddress);

You can use the same construct to get the water temperature in the section where you want to control your relay. What you have currently:

      if('WaterTemperature' <= 'TurnHeaterOnTemperature'){

Is comparing two bizarre constant multibyte characters. Get rid of the single quotes, declare a float called WaterTemperature and read the temperature into it. You'll also want to change your constants such as TurnHeaterOnTemperature to be float too, rather than int.

Thanks I am going to try it and I will post the results...

Ok now everything is working!!!!!!!!!! :cold_sweat: :grin: :grinning: I found that my relay module at "LOW" is on an at "HIGH" is off and I made also some modifications at my code and everything is working nice here is my new code:

#include <LiquidCrystal.h>
#include <math.h>
#include "RTClib.h"
#include <Time.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 3

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// Assign the addresses of your 1-Wire temp sensors.
DeviceAddress WaterTemperatureSensor = { 0x28, 0x62, 0x30, 0xCA, 0x03, 0x00, 0x00, 0xF1 };
DeviceAddress DeviceTemperatureSensor = { 0x10, 0x9A, 0x3E, 0x84, 0x02, 0x08, 0x00, 0x4D };
DeviceAddress RoomTemperatureSensor = { 0x10, 0xA1, 0xFE, 0x83, 0x02, 0x08, 0x00, 0xFC };

float WaterTemperature = 0;
float DeviceTemperature = 0;
float RoomTemperature = 0;

/*
LCD Connections:
rs (LCD pin 4) to Arduino pin 12
rw (LCD pin 5) to Arduino pin 11
enable (LCD pin 6) to Arduino pin 10
LCD pin 15 to Arduino pin 13
LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
*/

LiquidCrystal lcd(12, 11, 4, 5, 6, 7);
RTC_DS1307 RTC;
long previousLCDMillis = 0;    // for LCD screen update
long lcdInterval = 20000;
// screen to show 
int screen = 0;    
int screenMax = 2;
bool screenChanged = true;   // initially we have a new screen,  by definition 
// defines of the screens to show
#define SCREEN1 0
#define SCREEN2 1
#define SCREEN3 2

int ledPinFilter1 = 26;                 // LED connected to digital pin 28 (Filter 1)
int ledPinFilter2 = 27;                 // LED connected to digital pin 31 (Filter 2)
int ledPinHeater = 29;                  // LED connected to digital pin 27 (Heater)
int ledPinFan = 28;
int RelayPinHeater = 24;
int RelayPinFan = 25;

void setup(void) 
{
  //-------( Initialize Pins so relays are inactive at reset)----
  digitalWrite(RelayPinHeater, HIGH); // Set the Heater to LOW (off)
  
  //---( THEN set pins as outputs )----  
  pinMode(ledPinFilter1, OUTPUT);      // sets the digital pin as output
  pinMode(ledPinFilter2, OUTPUT);
  pinMode(ledPinHeater, OUTPUT);
  pinMode(ledPinFan, OUTPUT);
  pinMode(RelayPinHeater, OUTPUT);
  pinMode(RelayPinFan, OUTPUT);
  delay(4000); //Check that all relays are inactive at Reset

   
  // Start up the library
  sensors.begin();  
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(WaterTemperatureSensor, 12);
  sensors.setResolution(RoomTemperatureSensor, 11);
  sensors.setResolution(DeviceTemperatureSensor, 11);
  
  Serial.begin(9600);
Wire.begin();
RTC.begin();
lcd.begin(20, 4);
pinMode(8,OUTPUT);
 
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}  
  lcd.begin(20, 4);              // rows, columns.  use 16,2 for a 16x2 LCD, etc.
  showWelcome();  
  delay(4000);   // to show message on screen}
     
}

void showWelcome()
{
  lcd.clear();
  lcd.setCursor(1, 0);           
  lcd.print("My Amazon Aquarium");
  lcd.setCursor(3, 1);          
  lcd.print("initialising...");
  lcd.setCursor(1, 2);          
  lcd.print("Aquarium Controler");  
}

void showScreen1()
{
  lcd.clear();
  lcd.setCursor(1, 0);// set the cursor to column 1, line 0 (first row)
  lcd.print("My Amazon Aquarium");
  lcd.setCursor(0, 1);       
  lcd.print("Water Temp:");
  printTemperature(WaterTemperatureSensor); 
  lcd.print((char)223); 
  lcd.print("C");
  lcd.setCursor(0, 2);
  lcd.print("PH: 6.8");
  lcd.setCursor(0, 3);
  lcd.print("TDS: 150");
  lcd.setCursor(9, 3);
  lcd.print("ms");
}

void showScreen2()
{
  lcd.clear();
  DateTime now = RTC.now();
  lcd.setCursor(1, 0);
  lcd.print("My Amazon Aquarium");
  lcd.setCursor(0, 1);
  lcd.print(now.day(), DEC);
  lcd.print('/');
  lcd.print(now.month(), DEC);
  lcd.print('/');
  lcd.print(now.year(), DEC);
  lcd.setCursor(12, 1);
  if (now.hour()<10)
  lcd.print('0');
  lcd.print(now.hour(), DEC);
  lcd.print(':');
  if (now.minute()<10)
  lcd.print('0');
  lcd.print(now.minute(), DEC);
  lcd.print(':');
  if (now.second()<10)
  lcd.print('0');
  lcd.print(now.second(), DEC);
  lcd.setCursor(0, 2);
  lcd.print("Room Temp:");  
  printTemperature(RoomTemperatureSensor);
  lcd.print((char)223);
  lcd.print("C");
  lcd.setCursor(0, 3);
  lcd.print("PH: 6.8");
  lcd.setCursor(8, 3);
  lcd.print("TDS: 150");
  lcd.setCursor(16, 3);
  lcd.print("ms");
  
}

void showScreen3()
{
  lcd.clear();
  DateTime now = RTC.now();
  lcd.setCursor(1, 0);// set the cursor to column 1, line 0 (first row)
  lcd.print("My Amazon Aquarium");
  lcd.setCursor(6, 1);
  if (now.hour()<10)
  lcd.print('0');
  lcd.print(now.hour(), DEC);
  lcd.print(':');
  if (now.minute()<10)
  lcd.print('0');
  lcd.print(now.minute(), DEC);
  lcd.print(':');
  if (now.second()<10)
  lcd.print('0');
  lcd.print(now.second(), DEC);
  lcd.setCursor(0, 2);
  lcd.print("Water Temp:");
  printTemperature(WaterTemperatureSensor); 
  lcd.print((char)223); 
  lcd.print("C");
  lcd.setCursor(0, 3);
  lcd.print("Device Temp:");  
  printTemperature(DeviceTemperatureSensor);
  lcd.print((char)223);
  lcd.print("C");
 
  
}


void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  float WaterTemperaturetempC = sensors.getTempC(WaterTemperatureSensor);
  float DeviceTemperaturetempC = sensors.getTempC(DeviceTemperatureSensor);
  float RoomTemperaturetempC = sensors.getTempC(RoomTemperatureSensor);
  if (tempC == -127.00) {
  lcd.print("Error");
  } else {
  //lcd.print(tempC, 1);
  WaterTemperature = (WaterTemperaturetempC);
  DeviceTemperature = (DeviceTemperaturetempC);
  RoomTemperature = (RoomTemperaturetempC);
  lcd.print(tempC, 1);
}
}
void loop(void) {
  unsigned long currentLCDMillis = millis();

  // MUST WE SWITCH SCREEN?
  if(currentLCDMillis - previousLCDMillis > lcdInterval)              // save the last time you changed the display 
  {
    previousLCDMillis = currentLCDMillis; 
    screen++;
    if (screen > screenMax) screen = 0;  // all screens done? => start over
    screenChanged = true; 
  }

  // debug Serial.println(screen);


  // DISPLAY CURRENT SCREEN
  {
    screenChanged = false; // reset for next iteration
    switch(screen)
    {
    case SCREEN1: 
      showScreen1(); 
      break;
    case SCREEN2: 
      showScreen2();
      break;
    case SCREEN3:
      showScreen3();
      break;
    default:
      // cannot happen -> showError() ?
      break;
    }
    
    sensors.requestTemperatures();
   
    if(WaterTemperature <= 27.8)
    {
    digitalWrite(RelayPinHeater, LOW);    // sets the Heater on     
    }
      
    if(WaterTemperature >= 28.0)
    {
    digitalWrite(RelayPinHeater, HIGH);    // sets the Heater off 
    }
    delay(500);
    }
    
    if(digitalRead(RelayPinHeater) == LOW)
    {    
    digitalWrite(ledPinHeater, HIGH);      // sets the LED on
    }
    else{
    digitalWrite(ledPinHeater, LOW);       // sets the LED off
    }
}