Cheap aquarium project

hello everybody , a few weeks ago i bought my first arduino ( Arduino uno R3 ) ,so i started reading and experimenting so i figured out the basics , then i wanted do more so now i started a new aquarium controller but i am stuck for the moment .
i am using the folowing parts for my project :

-arduino uno R3

  • temperature sensor : ds18b20

  • 8 relay module

-ds1307 RTC

-LCD Display 1602 / HD44780

-IR led

i started working on he code but i can`t get the light to turn on and off at the specific times.
i have no errors but it does not work either. after i get this part done i plan to :

-add a alarm for the heater to turn on and off at specified temperatures
-add the LCD for displaying temperature and time
-add the ir reciver to turn on and off the lights , pump , heater

but for now can somebody look at my code and tell me where is the mistake with those allarms ?

//#include <IRremote.h> //for later use
//#include <IRremoteInt.h> //for later use

#include <Wire.h>

#include <Time.h>
#include <TimeAlarms.h>

#include <DS1307RTC.h>

#include <OneWire.h>

#include <DallasTemperature.h>



#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

int lights = A0; // lights for first aquarium
int heater = A1; // heater for first aquarium
int pump = A2; // pump for first aquarium
int lights2 = A3; // lights for second aquarium

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  delay(200);
  pinMode(heater, OUTPUT);
  pinMode(pump, OUTPUT);
  pinMode(lights2, OUTPUT);
  pinMode(lights, OUTPUT);
  digitalWrite(lights, HIGH); //test the lights
  Serial.println("Light test : on");
  delay(500);
  digitalWrite(lights, LOW);
  Serial.println("Light test : off");

  sensors.begin();
  Alarm.alarmRepeat(7,30,0,lightsON );  // 7:30am turn on the lights
  Alarm.alarmRepeat(22,00,0,lightsOFF);  // 22:00pm turn lights off 
  //  Alarm.alarmRepeat(dowSaturday,12,00,30,WeeklyAlarm);  // 8:30:30 every Saturday
  Alarm.timerOnce(10, OnceOnly);
}


void loop() {
  sensors.requestTemperatures(); 
  Serial.print("temp is =  ");
  Serial.print(sensors.getTempCByIndex(0));
  Serial.println("  degrees celsius");
  Serial.println("                               ");

  //Alarm.delay(1000);

  tmElements_t tm;

  if (RTC.read(tm)) {
    Serial.print("time is  ");
    print2digits(tm.Hour);
    Serial.write(':');
    print2digits(tm.Minute);
    Serial.write(':');
    print2digits(tm.Second);
    Serial.print(" , Date is ");
    Serial.print(tm.Day);
    Serial.write('/');
    Serial.print(tm.Month);
    Serial.write('/');
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.println();
    Serial.println(" ---------------------------");
  } 
  else {
    if (RTC.chipPresent()) {
      Serial.println("The DS1307 is stopped.  Please run the SetTime");
      Serial.println("example to initialize the time and begin running.");
      Serial.println();
    } 
    else {
      Serial.println("DS1307 read error!  Please check the circuitry.");
      Serial.println();
    }
    delay(9000);
  }
  delay(1000);
}

void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}


void lightsON()
{
  Serial.println("Lights ON");
  digitalWrite(lights, HIGH);
digitalWrite(lights2, HIGH);  
}

void lightsOFF()
{
  Serial.println("lights OFF");
  digitalWrite(lights, LOW);
digitalWrite(lights2, LOW);  
}
void OnceOnly(){
  Serial.println("This timer only triggers once");  
}
void Repeats(){
  Serial.println("15 second timer");         
}

clock_with_thermomether_and_relay.ino (2.53 KB)

also sorry if my english is bad

Hi,
I too hope to build something for my Aquarium…

Heres the code for my seed propagator which uses a DS1307 for time keeping and a 2 relay module similar to yours. The thing I discovered about these is they need a LOW input to activate the relay/s which is a bit like inverted logic and I don’t really like it but it works.

You will have to pick your way through the code for what you need, but it’s a start…

You may have to change some pins too.

#include <FastIO.h>
#include <I2CIO.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
 
// DS18b20 Data line is plugged into pin 12 on the Arduino
#define ONE_WIRE_BUS 12
 
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
 
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire); 
/*
Connections:
Heater1 pin 3 //Relay-1
Heater2 pin 4 //Relay-2
SDA to Arduino Analog pin 4
SCL to Arduino Analog pin 5
LightPin Analog pin A7
TempPin pin 12 //DS18b20
*/

#define DS1307_I2C_ADDRESS 0x68
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE);  // Set the LCD I2C address 

//*****constants*****
int Light,LightPin=A7,TargetTemp,Heater1=3,Heater2=4,TempPin=12;
int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
float TEMP;
void setup()
//----------------Start of Set up---------------------
{
TargetTemp=23;  //Set Normal/Target temp to 23c
pinMode(Heater1,OUTPUT);
pinMode(Heater2,OUTPUT);
pinMode(13,OUTPUT);
Wire.begin();
lcd.begin(20,4); // tells Arduino the LCD dimensions
// start serial port
Serial.begin(9600);
//Serial.println("Dallas Temperature IC Control Library Demo"); 
// Start up the library
sensors.begin(); // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement
}
//------------End of Setup loop------------------------
//--------------Start of Main loop------------------
void loop()  
{
  GetTime();
  GetTemp();
  TestIt();
  digitalWrite(13,HIGH);    //Flash LED
  delay(100);               //For 100mS
  digitalWrite(13,LOW);     //LED off
}
//------------End of main loop-----------------------------
void GetTime()
{
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
//if (second <=5)
{
//lcd.clear(); // clear LCD screen
lcd.setCursor(0,0);
lcd.print(" ");
lcd.print(hour, DEC);
lcd.print(":");
if (minute<10)
{
lcd.print("0");
}
lcd.print(minute, DEC);
lcd.print(":");
if (second<10)
{
lcd.print("0");
}
lcd.print(second, DEC);
lcd.print(" ");
lcd.print(dayOfMonth, DEC);
lcd.print("/");
lcd.print(month, DEC);
lcd.print("/");
lcd.print("20");
lcd.print(year, DEC);
//delay(1000);
}
}
//------------------------------------------------------------------------------------------
void GetTemp()
{
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
sensors.requestTemperatures(); // Send the command to get temperatures
TEMP=(sensors.getTempCByIndex(0)); // Why "byIndex"? You can have more than one IC on the same bus. 0 refers to the first IC on the wire
}
//-----------------------------------------------------------------------------------------------------------
void TestIt()
 {
  Light=analogRead(LightPin);
  Light=Light/4;
  if(Light>200)
  {TargetTemp=25;}
  if(Light>160 && Light<200)
  {TargetTemp=18;}
  if(Light<160)
  {TargetTemp=14;}
// Set Temp******
 
   lcd.setCursor(1,1);
   lcd.print("Target Temp:");
   lcd.print(TargetTemp);
   lcd.print(".00c ");
   lcd.setCursor(1,2);
   lcd.print("Current Temp:");
   lcd.print(TEMP); 
   lcd.print("c ");
   
   if (TEMP < TargetTemp)
  {
   digitalWrite(Heater1,LOW);    //Heater ON
   digitalWrite(Heater2,LOW);
   lcd.setCursor(1,3);
   lcd.print("Heater ON ");
   lcd.print("Lite=");
   lcd.print(Light);
   lcd.print("  ");
  }
  if (TEMP > TargetTemp)
  {
    digitalWrite(Heater1,HIGH);
   digitalWrite(Heater2,HIGH);  //Heater OFF
   lcd.setCursor(1,3);
   lcd.print("Heater OFF ");
   lcd.print("Lite=");
   lcd.print(Light);
   lcd.print("  ");
 //lcd.clear();
}
}
//*************************************************************************************************************

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
//-----------------------------------------------------------------
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
//------------------------------------------------------------------
// Gets the date and time from the ds1307
void getDateDs1307
(
byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f); // Need to change this if 12 hour am/pm
*dayOfWeek = bcdToDec(Wire.read() &0x07);
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
//==================================================================================

Hope it helps.
Regards

Mel.

thank`s mel , looking through your code( "if(Light>200)" ) also gave me another ideea :

add a photocell to measure the amount of natural light and if its too much then .... digitalWrite(lights, LOW); so i dont end up with a aquarium full of algae :)

Hi Becone, Yes did'ent think of that! I use it because there's no point in keeping seedlings warm when it's dark! (They grow leggy) and we all like Leggy. How will you test the time to switch things on/off.

Regards

Mel.

Cactusface: Hi Becone, Yes did'ent think of that! I use it because there's no point in keeping seedlings warm when it's dark! (They grow leggy) and we all like Leggy. How will you test the time to switch things on/off.

Regards

Mel.

are u asking how will i know when to turn off the lights when the natural light is enough ?

i dont know yet , i think i will try different values untill i dont get more algae. i will also try to find out more about algae growth , maybe i find something that will help.

temperature will be measured by the ds18b20 and based on that heater will turn on when temp is lower then 25 degrees celsius (farenheit......not my thing) and then turn of when it reaches 25 degrees

the pump will turn on in the morning and off at night because it makes some noise from the air bubbles that it sends through the water

also i will use a old remote control to manualy turn everything on or off

still cant get the alarm to turn on/off the lights but i got to write the thermostat function and tested it for 2 days , works well for now :slight_smile:

#include <DS1307RTC.h>

#include <Time.h>

#include <TimeAlarms.h>

#include <IRremote.h>
#include <IRremoteInt.h>

#include <DallasTemperature.h>

#include <OneWire.h>

#include <Wire.h>

#define lights A0
#define heater A1
#define pump A2
#define ONE_WIRE_BUS 8
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
DeviceAddress Probe01 = {  
  0x28, 0xFF, 0x69, 0x73, 0x3B, 0x04, 0x00, 0xAE };


void setup() {
  // put your setup code here, to run once:
  pinMode(lights, OUTPUT);
  pinMode(heater, OUTPUT);
  pinMode(pump, OUTPUT);

  digitalWrite(lights, HIGH);
  digitalWrite(heater, HIGH);
  digitalWrite(pump, HIGH);

  Serial.begin(9600);
  Alarm.alarmRepeat(20,10,0, MorningAlarm);  // 8:30am every day
  Alarm.alarmRepeat(20,15,0, EveningAlarm);  // 5:45pm every day 
  Alarm.alarmRepeat(dowSaturday,8,30,30,WeeklyAlarm);  // 8:30:30 every Saturday 


  Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
  Alarm.timerOnce(10, OnceOnly);             // called once after 10 seconds 

  sensors.begin();
  sensors.setResolution(Probe01, 10);

  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet)
    Serial.println("Unable to sync with the RTC");
  else
    Serial.println("RTC has set the system time");
}

void loop() {
  // put your main code here, to run repeatedly: 
  sensors.requestTemperatures(); // Send the command to get temperatures
  displayTemperature(Probe01);
  float temperature1 = sensors.getTempCByIndex(0);

  if(temperature1 <= 26)
  {
    digitalWrite(heater, LOW);
    Serial.println("Heater ON");
  }
     else
      {
        digitalWrite(heater, HIGH);
    Serial.println("Heater OFF");
  }
  {
    digitalClockDisplay(); 
    Alarm.delay(1000); // wait one second between clock display;
  }
}

// functions to be called when an alarm triggers:
void MorningAlarm(){
  Serial.println("Alarm: - turn lights off");
  digitalWrite(lights, LOW);  
}

void EveningAlarm(){
  Serial.println("Alarm: - turn lights on"); 
  digitalWrite(lights, HIGH);   
}

void WeeklyAlarm(){
  Serial.println("Alarm: - its Monday Morning");      
}

void ExplicitAlarm(){
  Serial.println("Alarm: - this triggers only at the given date and time");       
}

void Repeats(){
  Serial.println("15 second timer");
digitalWrite(lights, LOW);  
}

void OnceOnly(){
  Serial.println("This timer only triggers once");
digitalWrite(lights, LOW);   
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  //Serial.print(dow());
  Serial.print(" ");
  Serial.print(day());
  Serial.print("/");
  Serial.print(month());
  Serial.print("/");
  Serial.print(year());
  Serial.println();
}

void printDigits(int digits)
{
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

void displayTemperature(DeviceAddress deviceAddress)
{

  float tempC = sensors.getTempC(deviceAddress);

  if (tempC == -127.00) // Measurement failed or no device found
  {
    Serial.println("Temperature Error");
  } 
  else
  {
    Serial.print("Temp =");
    Serial.print(tempC);
    Serial.println(" C");
  }
}// End printTemperature

so the part of the thermostat is this :

sensors.requestTemperatures(); // Send the command to get temperatures
  displayTemperature(Probe01);
  float temperature1 = sensors.getTempCByIndex(0);

  if(temperature1 <= 26)
  {
    digitalWrite(heater, LOW);
    Serial.println("Heater ON");
  }
     else
      {
        digitalWrite(heater, HIGH);
    Serial.println("Heater OFF");
  }

Guy’s. I would like to join in if I may (newbie as well). I to am building a (somewhat) cheap aquarium controller based on the 18B20, D1307 RTC. I can share the code but I still needs allot more work. The controller will be used to heat the tank as well as control the light (LEDs). I have everything mounted in the top cover of the aquarium (30 gallon unit). an OLED and encoder is mounted in the cover to set the temperature, time, light on/off sequence. So far I’ve got the temperature to display and the encoder to work. I also have a PIR to turn off the display when no one is present to prevent OLED burn-in. Next is the temp control and finally the menu. (See attached pictures). Note this is my first time ever working with Arduino and "C’ type language so I know only about 10% of what I’m doing. All suggestions are welcome, (but please be kind).

Teensy_Temp1.jpg

Teensy_Temp2.jpg

Temp_89_Test_w_TenSec_Delay9.ino (10.3 KB)