Do action at certain time using RTC

I'm trying my first hand at Arduino and want to do the same with controlling a fish tank.

Can you provide some help on what sensors and hardware you are using.

Many thanks!

Hello,

Here is my version of aquarium controller based on the examples above.
I will post the hardware used and photos in different post later.

Could anyone have a look at my code and let me know any improvements to simplify it.

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Time.h>
#include <TimeAlarms.h>
#include "virtuabotixRTC.h"
// Creation of the Real Time Clock Object
//CLK -> 12, DAT -> 7, RST -> 8, VCC -> +5v, GND -> GND
virtuabotixRTC myRTC(12, 7, 8);

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
//set device address for DS18B20 sensor
DeviceAddress temp_addr = {0x28, 0xFF, 0x8F, 0x06, 0x66, 0x14, 0x01, 0x18};
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float temperature;
int max_temp = 30; //maximum temperature of aquarium - switch off voltage to heater for safety

// RELAYS
int filterrelay = 9;
int lightsrelay = 6; 
int heaterrelay = 5;
//int pumprelay = 10; // uncomment if the pump relay is to be used

//BUTTONS
int FilterButton = 3;
int LightButton = 11;


//feeding button variables 
int FilterButtonState = LOW; 
int Freading;           // the current reading from the input pin
int Fprevious = HIGH;    // the previous reading from the input pin
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long Ftime = 0;         // the last time the output pin was toggled
long Fdebounce = 100;   // the debounce time, increase if the light output flickers

//light button variables
int LightButtonState = LOW;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = HIGH;    // the previous reading from the input pin
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 100;   // the debounce time, increase if the light output flickers


// the setup routine runs once when you press reset:
void setup() {
     Serial.begin(9600); 
     Wire.begin();
 
     lcd.begin(20,4);// set the colomns to 20 and rows to 4

     sensors.begin();// temp sensor
     sensors.setResolution(temp_addr, 10);
    
// Set the current date, and time in the following format:
// seconds, minutes, hours, day of the week, day of the month, month, year

//myRTC.setDS1302Time(30, 6, 16, 2, 25, 8, 2015);//run once only to set time to RTC // comment when test finished
//myRTC.setDS1302Time(59, 59, 8, 6, 22, 8, 2015);  //for test
  
// initialize the digital pin as an output.
  pinMode(lightsrelay, OUTPUT);     
  pinMode(heaterrelay, OUTPUT);    
 // pinMode(pumprelay, OUTPUT);
  pinMode(filterrelay, OUTPUT); 

  // initialize the feed and light button as INPUT PULLUP (when button is pressed the status is LOW).
  pinMode(FilterButton, INPUT_PULLUP); 
  pinMode(LightButton, INPUT_PULLUP); 

  Serial.println("Startup Completed");  

myRTC.updateTime();
setTime(myRTC.hours,myRTC.minutes,myRTC.seconds,myRTC.dayofmonth,myRTC.month,myRTC.year);
//setTime(8,59,59,1,1,11); //test settime //set time syntax setTime(hour,minutes,secundes,day,month,YY)

  //set initial mode 
    if ((myRTC.hours >= 9) && (myRTC.hours < 12) ) {
       Day ();
    }
    else if ((myRTC.hours >= 12) && (myRTC.hours < 16) ) {
      Afternoon();
    }
     else if ((myRTC.hours >= 16) && (myRTC.hours < 22) ) {
      Day ();
      }
      else {
      Night ();
    } 
    
    HeaterOn();//start heater
    //PumpOn();//start pump
 
    //Alarms schedule
     
    //test
    /*Alarm.alarmRepeat(18,44,5, Feeding);  
    Alarm.alarmRepeat(18,44,15, Day);
    Alarm.alarmRepeat(18,44,25, Afternoon);  
    Alarm.alarmRepeat(18,44,35, Feeding);
    Alarm.alarmRepeat(18,44,45, Day);  
    Alarm.alarmRepeat(18,44,55, Night);*/
    
    //real
    Alarm.alarmRepeat(9,0,0, Feeding);  //start day and feed for 15 min (feeder timer set at 09:05)
    Alarm.alarmRepeat(9,15,0, Day);
    Alarm.alarmRepeat(12,0,0, Afternoon);  //switch off lights in the afternoon
    Alarm.alarmRepeat(16,0,0, Feeding);  //evening feeding for 15 min (feeder timer set at 16:05)
    Alarm.alarmRepeat(16,15,0, Day);
    Alarm.alarmRepeat(22,0,0, Night); //night mode
}

// the loop routine runs over and over again forever:
void loop() {

myRTC.updateTime(); //read time from RTC DS1302

    Serial.print(myRTC.hours, DEC);
    Serial.print(':');
    Serial.print(myRTC.minutes, DEC);
    Serial.print(':');
    Serial.print(myRTC.seconds, DEC);

   
  // Print date/time to the LCD.
   
//lcd.backlight();

  lcd.setCursor(0, 0); 
  lcd.print(myRTC.dayofmonth); lcd.print("/");
  lcd.print(myRTC.month); lcd.print("/");
  lcd.print(myRTC.year); lcd.print(" - ");
  lcd.print(myRTC.hours); lcd.print(":");
  lcd.print(myRTC.minutes); lcd.print(":");
  lcd.print(myRTC.seconds); lcd.print(" ");

  //print on LCD 
  lcd.setCursor(0, 1); 
     lcd.print("Mode:");
lcd.setCursor(10, 2); 
     lcd.print("Temp:");
 lcd.setCursor(0, 2);
   lcd.print("Light:"); 
lcd.setCursor(0, 3);
   lcd.print("Filter:");       
lcd.setCursor(11, 3);
   lcd.print("Heat:"); 
 
  // temp sensor reading
    sensors.requestTemperatures();
    temperature = sensors.getTempC(temp_addr); 
   Serial.print(" temp - ");
   Serial.println(temperature);

   lcd.setCursor(15, 2); 
     lcd.print(temperature);

  //safety precaution - heater off if temperature > 30 C
  if (temperature > max_temp){
    HeaterOff();
  }
  else if (temperature < max_temp - 1){
HeaterOn();
  }
      
   
       //Feeding pushbutton
  Freading = digitalRead(FilterButton);
  if (Freading == HIGH && Fprevious == LOW && millis() - Ftime > Fdebounce) {
    if (FilterButtonState == HIGH){
         FilterOff ();}
    else{
        FilterOn ();}
      Ftime = millis();    
  }
  Fprevious = Freading;
 

       //Light pushbutton:
  reading = digitalRead(LightButton);
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (LightButtonState == HIGH){
         LightsOff ();}
    else{
        LightsOn ();}
      time = millis();    
  }
  previous = reading;

Alarm.delay(100); // wait one second between clock display
}

void Feeding() {
       Serial.println("***Feeding Cycle Started***");  
  FilterOff();
  LightsOn();
// PumpOff();
   lcd.setCursor(5, 1); 
     lcd.print(" FEEDING   ");
    }

void Day () {
  Serial.println("Day mode");
  LightsOn();
  FilterOn();
// PumpOn();
      lcd.setCursor(5, 1); 
     lcd.print(" DAY       ");
}

void Night () {
   Serial.println("***Night mode***");
  LightsOff();
  FilterOn();
  // PumpOff();
       lcd.setCursor(5, 1); 
     lcd.print(" NIGHT     ");
}

void Afternoon () {
  Serial.println("***Afternoon mode***");
  LightsOff();
  FilterOn();
// PumpOn();
       lcd.setCursor(5, 1); 
     lcd.print(" AFTERNOON ");
}

void LightsOn() {
  digitalWrite(lightsrelay, LOW); // Set Lights On
  LightButtonState = HIGH;
  lcd.backlight();// LCD backlight on
   Serial.println("Lights On");
    lcd.setCursor(6, 2);
   lcd.print("ON ");  
}

void LightsOff() {
  digitalWrite(lightsrelay, HIGH); // Set Lights Off
  LightButtonState = LOW;
  lcd.noBacklight(); // LCD backlight off 
   Serial.println("Lights Off"); 
     lcd.setCursor(6, 2);
   lcd.print("OFF");   
}

void FilterOn() {
  digitalWrite(filterrelay, LOW); // Set Filter On
  FilterButtonState = HIGH;
   Serial.println("Filter On");
     lcd.setCursor(7, 3);
   lcd.print("ON ");   
}

void FilterOff() {
  digitalWrite(filterrelay, HIGH); // Set Filter Off
  FilterButtonState = LOW;
   Serial.println("Filter Off"); 
        lcd.setCursor(7, 3);
   lcd.print("OFF");   
}
    
void HeaterOn() {
  digitalWrite(heaterrelay, LOW); // Set Heater On
        lcd.setCursor(16, 3);
   lcd.print("ON ");   
}

void HeaterOff() {
  digitalWrite(heaterrelay, HIGH); // Set Heater Off
        lcd.setCursor(16, 3);
   lcd.print("OFF");     
}

/* uncomment if the pump relay is to be used
 
 void PumpOn() {
   digitalWrite(pumprelay, HIGH); // Set Pump On
   Serial.println("Pump On");  
 }

 void PumpOff() {
   digitalWrite(pumprelay, LOW); // Set Pump Off
   Serial.println("Pump Off");  
 }*/

Make all the variables the appropriate size and make those that refer to Arduino pins const

Alarm.delay(100); // wait one second between clock displayCheck comments and make sure that they reflect what the code does. Use Ctrl/T to format the code consistently.

Are you refering at this

// RELAYS
int filterrelay = 9;
int lightsrelay = 6;
int heaterrelay = 5;
//int pumprelay = 10; // uncomment if the pump relay is to be used

//BUTTONS
int FilterButton = 3;
int LightButton = 11;

To be changed in this

// RELAYS
const filterrelay = 9;
const lightsrelay = 6;
const heaterrelay = 5;
//const pumprelay = 10; // uncomment if the pump relay is to be used

//BUTTONS
const FilterButton = 3;
const LightButton = 11;

What is the reason

Are you refering at this

Yes, but the suggestion was to change them to

// RELAYS
const byte filterrelay = 9;
const byte lightsrelay = 6;
const byte heaterrelay = 5;
//const byte pumprelay = 10; // uncomment if the pump relay is to be used

//BUTTONS
const byte FilterButton = 3;
const byte LightButton = 11;

const because none of the values will change when the program runs. If you do try to change them by accident within the program if you revise it then the compiler will stop you making that mistake.

byte because none of them will ever have a value larger than 255 and ints take twice as much memory as bytes. Not particularly important in this program but it is good practice to use variables of an appropriate size, which can be faster to manipulate and it is always good to save memory. There are other reasons too to do with interrupts but they don't apply unless/until you use them.

Did the modifications and auto format. New sketch is smaller by 10 bytes.

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Time.h>
#include <TimeAlarms.h>
#include "virtuabotixRTC.h"
// Creation of the Real Time Clock Object
//CLK -> 12, DAT -> 7, RST -> 8, VCC -> +5v, GND -> GND
virtuabotixRTC myRTC(12, 7, 8);

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
//set device address for DS18B20 sensor
DeviceAddress temp_addr = {0x28, 0xFF, 0x8F, 0x06, 0x66, 0x14, 0x01, 0x18};
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float temperature;
int max_temp = 30; //maximum temperature of aquarium - switch off voltage to heater for safety

// RELAYS
const byte filterrelay = 9;
const byte lightsrelay = 6;
const byte heaterrelay = 5;
//const byte pumprelay = 10; // uncomment if the pump relay is to be used

//BUTTONS
const byte FilterButton = 3;
const byte LightButton = 11;


//feeding button variables
int FilterButtonState = LOW;
int Freading;           // the current reading from the input pin
int Fprevious = HIGH;    // the previous reading from the input pin
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long Ftime = 0;         // the last time the output pin was toggled
long Fdebounce = 100;   // the debounce time, increase if the light output flickers

//light button variables
int LightButtonState = LOW;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = HIGH;    // the previous reading from the input pin
// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 100;   // the debounce time, increase if the light output flickers


// the setup routine runs once when you press reset:
void setup() {
  Serial.begin(9600);
  Wire.begin();

  lcd.begin(20, 4); // set the colomns to 20 and rows to 4

  sensors.begin();// temp sensor
  sensors.setResolution(temp_addr, 10);

  // Set the current date, and time in the following format:
  // seconds, minutes, hours, day of the week, day of the month, month, year

  //myRTC.setDS1302Time(30, 6, 16, 2, 25, 8, 2015);//run once only to set time to RTC // comment when test finished
  //myRTC.setDS1302Time(59, 59, 8, 6, 22, 8, 2015);  //for test

  // initialize the digital pin as an output.
  pinMode(lightsrelay, OUTPUT);
  pinMode(heaterrelay, OUTPUT);
  // pinMode(pumprelay, OUTPUT);
  pinMode(filterrelay, OUTPUT);

  // initialize the feed and light button as INPUT PULLUP (when button is pressed the status is LOW).
  pinMode(FilterButton, INPUT_PULLUP);
  pinMode(LightButton, INPUT_PULLUP);

  Serial.println("Startup Completed");

  myRTC.updateTime();
  setTime(myRTC.hours, myRTC.minutes, myRTC.seconds, myRTC.dayofmonth, myRTC.month, myRTC.year);
  //setTime(8,59,59,1,1,11); //test settime //set time syntax setTime(hour,minutes,secundes,day,month,YY)

  //set initial mode
  if ((myRTC.hours >= 9) && (myRTC.hours < 12) ) {
    Day ();
  }
  else if ((myRTC.hours >= 12) && (myRTC.hours < 16) ) {
    Afternoon();
  }
  else if ((myRTC.hours >= 16) && (myRTC.hours < 22) ) {
    Day ();
  }
  else {
    Night ();
  }

  HeaterOn();//start heater
  //PumpOn();//start pump

  //Alarms schedule

  //for test
  /*Alarm.alarmRepeat(18,44,5, Feeding);
  Alarm.alarmRepeat(18,44,15, Day);
  Alarm.alarmRepeat(18,44,25, Afternoon);
  Alarm.alarmRepeat(18,44,35, Feeding);
  Alarm.alarmRepeat(18,44,45, Day);
  Alarm.alarmRepeat(18,44,55, Night);*/

  //real
  Alarm.alarmRepeat(9, 0, 0, Feeding); //start day and feed for 15 min (feeder timer set at 09:05)
  Alarm.alarmRepeat(9, 15, 0, Day);
  Alarm.alarmRepeat(12, 0, 0, Afternoon); //switch off lights in the afternoon
  Alarm.alarmRepeat(16, 0, 0, Feeding); //evening feeding for 15 min (feeder timer set at 16:05)
  Alarm.alarmRepeat(16, 15, 0, Day);
  Alarm.alarmRepeat(22, 0, 0, Night); //night mode
}

// the loop routine runs over and over again forever:
void loop() {

  myRTC.updateTime(); //read time from RTC DS1302

  Serial.print(myRTC.hours, DEC);
  Serial.print(':');
  Serial.print(myRTC.minutes, DEC);
  Serial.print(':');
  Serial.print(myRTC.seconds, DEC);


  // Print date/time to the LCD
  //lcd.backlight();

  lcd.setCursor(0, 0);
  lcd.print(myRTC.dayofmonth); lcd.print("/");
  lcd.print(myRTC.month); lcd.print("/");
  lcd.print(myRTC.year); lcd.print(" - ");
  lcd.print(myRTC.hours); lcd.print(":");
  lcd.print(myRTC.minutes); lcd.print(":");
  lcd.print(myRTC.seconds); lcd.print(" ");

  //print on LCD
  lcd.setCursor(0, 1);
  lcd.print("Mode:");
  lcd.setCursor(10, 2);
  lcd.print("Temp:");
  lcd.setCursor(0, 2);
  lcd.print("Light:");
  lcd.setCursor(0, 3);
  lcd.print("Filter:");
  lcd.setCursor(11, 3);
  lcd.print("Heat:");

  // temp sensor reading
  sensors.requestTemperatures();
  temperature = sensors.getTempC(temp_addr);
  Serial.print(" temp - ");
  Serial.println(temperature);

  lcd.setCursor(15, 2);
  lcd.print(temperature);

  //safety precaution - heater off if temperature > 30 C
  if (temperature > max_temp) {
    HeaterOff();
  }
  else if (temperature < max_temp - 1) {
    HeaterOn();
  }


  //Feeding pushbutton
  Freading = digitalRead(FilterButton);
  if (Freading == HIGH && Fprevious == LOW && millis() - Ftime > Fdebounce) {
    if (FilterButtonState == HIGH) {
      FilterOff ();
    }
    else {
      FilterOn ();
    }
    Ftime = millis();
  }
  Fprevious = Freading;


  //Light pushbutton:
  reading = digitalRead(LightButton);
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (LightButtonState == HIGH) {
      LightsOff ();
    }
    else {
      LightsOn ();
    }
    time = millis();
  }
  previous = reading;

  // Alarm.delay(1000); // wait one second between clock display
}

void Feeding() {
  Serial.println("***Feeding Cycle Started***");
  FilterOff();
  LightsOn();
  // PumpOff();
  lcd.setCursor(5, 1);
  lcd.print(" FEEDING   ");
}

void Day () {
  Serial.println("***Day mode***");
  LightsOn();
  FilterOn();
  // PumpOn();
  lcd.setCursor(5, 1);
  lcd.print(" DAY       ");
}

void Night () {
  Serial.println("***Night mode***");
  LightsOff();
  FilterOn();
  // PumpOff();
  lcd.setCursor(5, 1);
  lcd.print(" NIGHT     ");
}

void Afternoon () {
  Serial.println("***Afternoon mode***");
  LightsOff();
  FilterOn();
  // PumpOn();
  lcd.setCursor(5, 1);
  lcd.print(" AFTERNOON ");
}

void LightsOn() {
  digitalWrite(lightsrelay, LOW); // Set Lights On
  LightButtonState = HIGH;
  lcd.backlight();// LCD backlight on
  Serial.println("Lights On");
  lcd.setCursor(6, 2);
  lcd.print("ON ");
}

void LightsOff() {
  digitalWrite(lightsrelay, HIGH); // Set Lights Off
  LightButtonState = LOW;
  lcd.noBacklight(); // LCD backlight off
  Serial.println("Lights Off");
  lcd.setCursor(6, 2);
  lcd.print("OFF");
}

void FilterOn() {
  digitalWrite(filterrelay, LOW); // Set Filter On
  FilterButtonState = HIGH;
  Serial.println("Filter On");
  lcd.setCursor(7, 3);
  lcd.print("ON ");
}

void FilterOff() {
  digitalWrite(filterrelay, HIGH); // Set Filter Off
  FilterButtonState = LOW;
  Serial.println("Filter Off");
  lcd.setCursor(7, 3);
  lcd.print("OFF");
}

void HeaterOn() {
  digitalWrite(heaterrelay, LOW); // Set Heater On
  lcd.setCursor(16, 3);
  lcd.print("ON ");
}

void HeaterOff() {
  digitalWrite(heaterrelay, HIGH); // Set Heater Off
  lcd.setCursor(16, 3);
  lcd.print("OFF");
}

/* uncomment if the pump relay is to be used

 void PumpOn() {
   digitalWrite(pumprelay, HIGH); // Set Pump On
   Serial.println("Pump On");
 }

 void PumpOff() {
   digitalWrite(pumprelay, LOW); // Set Pump Off
   Serial.println("Pump Off");
 }*/

Nick_Pyner:
I use the DS1307 and it is fine for this. You can simply use the standard time display procedure to do something specific. I use the snippet below to change a file name after midnight.

void loop() {

GetClock();
 if (hour == 0 && minute == 0 && second <2)
 {
   getFileName();
 }
myFile = SD.open(filename, FILE_WRITE);//<<<<<<<<<<<<< OPEN

tra la la.....

That's brilliant Nick.

I just got my DS3231. It's supposed to only lose a few minutes per year!!

The code I'm using is a little different.

#include <DS3231.h>

// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);

void setup()
{
  // Setup Serial connection
  Serial.begin(9600);
  
  // Initialize the rtc object
  rtc.begin();
  
}

void loop()
{

  // Print Time
  Serial.println(rtc.getTimeStr());
  
  // Wait one second before repeating :)
  delay (1000);
}

Serial.println(rtc.getTimeStr()); spits out some sort of string array thingy. It looks like this in the Serial Monitor:

17:37:41
17:37:42
17:37:43

Can somebody please tell me how to take rtc.getTimeStr() and put it into a variable called currentTime that is a float? Just want the hours and minutes. ( no colons or seconds) stored as a float.

then I could do something like

if (currentTime => setTime){

//Do Something Cool.

}

Yes. While I wouldn't hear a bad word about the DS1307, I find it is pretty poor in a varying environment. The DS3231 is far superior and only a dollar or so more. I use it with no change to the DS1307 software.

I now use a more elegant(!) time check for midnight.

void loop() {
 GetClock();
  if (today != day)
  {
   today = day;
   getFileName(); 
  }
   ladedah;

I kept say float but what I really meant was int.

The code I'm using:

#include <DS3231.h>

// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);

void setup()
{
  // Setup Serial connection
  Serial.begin(9600);
  
  // Initialize the rtc object
  rtc.begin();
}

void loop()
{
  // Send time
  Serial.println(rtc.getTimeStr());

}

Spits out:

18:32:35
18:32:36
18:32:37
18:32:38
18:32:39

But I don't know how to compare 18:32:37.

if it was stored as an int I could do something like this:

if ( currentTime => setTime) {

// Do Something Cool.

}

I tried :

rtc.getTimeStr().toInt()

lol haHa I have no Idea on the correct syntax. Strings and Arrays are so confusing for me.

I'm afraid I have no idea. I just use
http://bildr.org/2011/03/ds1307-arduino/
no strings, no arrays, and no library.
I thought the DS3231 library had an alarm example included.

Nick_Pyner:
I'm afraid I have no idea. I just use
http://bildr.org/2011/03/ds1307-arduino/
no strings, no arrays, and no library.
I thought the DS3231 library had an alarm example included.

I'm reading your link now....

I just thought if I could get

18:32:36 to be spit out as a simple int (something like 183236), it would be super simple for me to compare against.

You are probably right, but that is a char, and I haven't done that sort of comparison since I retired my Commodore64. The filename procedure uses char

char filename[] = "00000000.CSV";

void loop() {
   
  GetClock();
  if (today != day)
  {
   today = day;
   getFileName(); 


void getFileName(){
sprintf(filename, "%04u%02u%02u.csv", year, month, day);
}

A usable char for date may be

char date[] = "00000000";

loop
getdate();

void getdate(){
sprintf(date, "%04u%02u%02u", year, month, day);
}

I am only interested in action on one event, midnight. If you need something more complicated, you should check the RTC library. There is also a library pair Time and Time Alarms, which may be the ultimate for RTC programming, but I have never needed it.

I was able to figure it out on my own. yay me lol. What I did was I edited the cpp library file to remove the colons and the seconds from the time.

Then, I made 2 global variables

String string;
int currentTime;

Afterwards, I converted the char array into a String like so:

string = (rtc.getTimeStr());

Next, I took that sting and used the "to integer" function like this:

currentTime = (string.toInt());

Later I got all fancy schmancy and turned it into a one liner:

currentTime = ((string = (rtc.getTimeStr())).toInt());

Now I can use currentTime as a condition like this:

if (currentTime >= 2253){ // If currentTime is greater or equal to 10:53pm, Do the following:

Serial.println ("Do Something Amazing");

}

Doesn't that seem way easier than setting RTC alarms?. I'm still learning this stuff so easier is better for me. I only started learning maybe 4 or 5 weeks ago. I go for the low hanging fruit.

Where did this rtc.getTimeStr() come from, exactly? Where did you hear about it?

You don't need any rtc.getTimeStr() to get the time, especially if you are just trying to get at numbers. Here is a demonstration:

#include <Wire.h>

byte ss=0, mi=0, hh=0, wd=6, dd=1, mo=1, yy=0;
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
 
  // clear /EOSC bit
  // Sometimes necessary to ensure that the clock
  // keeps running on just battery power. Once set,
  // it shouldn't need to be reset but it's a good
  // idea to make sure.
//  Wire.beginTransmission(0x68); // address DS3231
//  Wire.write(0x0E); // select register
//  Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC
//  Wire.endTransmission();
}
 
void loop()
{
  // ask RTC for the time
  // send request to receive data starting at register 0
  Wire.beginTransmission(0x68); // 0x68 is DS3231 device address
  Wire.write((byte)0); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(0x68, 7); // request seven bytes (ss, mi, hh, wd, dd, mo, yy)
  // check for a reply from the RTC, and use it if we can
  if (Wire.available() >= 7) { 
    // if we're here, we got a reply and it is long enough
    // so now we read the time
    ss = bcd2bin(Wire.read()); // get seconds
    mi = bcd2bin(Wire.read()); // get minutes
    hh = bcd2bin(Wire.read()); // get hours
    wd = bcd2bin(Wire.read());
    dd = bcd2bin(Wire.read());
    mo = bcd2bin(Wire.read());
    yy = bcd2bin(Wire.read());
    // show that we successfully got the time
    Serial.print("Got the time: ");
    printTime();
  }
  else {
    // if we're here, that means we were unable to read the time
    Serial.println("Unable to read time from RTC"); 
  }
  delay(500);
}

byte bcd2bin(byte x) {
  // converts from binary-coded decimal to a "regular" binary number
  return ((((x >> 4) & 0xF) * 10) + (x & 0xF)) ;
}

void printTime() {
  // just like it says on the tin
  Serial.print ("\'");
  if (yy<10) Serial.print("0"); Serial.print(yy,DEC); Serial.print("-");
  if (mo<10) Serial.print("0"); Serial.print(mo,DEC); Serial.print("-");
  if (dd<10) Serial.print("0"); Serial.print(dd,DEC); Serial.print("(");
  switch (wd) {
    case 1: Serial.print("Mon"); break;
    case 2: Serial.print("Tue"); break; 
    case 3: Serial.print("Wed"); break; 
    case 4: Serial.print("Thu"); break; 
    case 5: Serial.print("Fri"); break; 
    case 6: Serial.print("Sat"); break; 
    case 7: Serial.print("Sun"); break;
    default: Serial.print("Bad");  
  }
  Serial.print(") ");
  if (hh<10) Serial.print("0"); Serial.print(hh,DEC); Serial.print(":");
  if (mi<10) Serial.print("0"); Serial.print(mi,DEC); Serial.print(":");
  if (ss<10) Serial.print("0"); Serial.print(ss,DEC); Serial.println("");
}

Try it and see what appears on your Serial monitor.

odometer:
Where did this rtc.getTimeStr() come from, exactly? Where did you hear about it?

You don't need any rtc.getTimeStr() to get the time, especially if you are just trying to get at numbers. Here is a demonstration:

Try it and see what appears on your Serial monitor.

It's just a library I picked up for my DS3231 RTC I got from google. The official website is Rinkydinkelectronics.com/library.php

I'm using the DS3231.zip from that site.

The reason I like it is that there is not much code and it keeps my main sketch uncluttered.

Keypel:
I was able to figure it out on my own........Doesn't that seem way easier than setting RTC alarms?.

If you get what you want, then OK, but I'm not sure it was worth the effort, and I would only fiddle with a library myself as an absolutely last resort.

The link I referred to previously, which doesn't use a library, is the only method that I use. It doesn't have the colons in the first place. If you want them, or whatever, you have to insert them yourself. It is in fact more or less the same code as that from odometer.

your code needs to call Alarm.delay regularly because this function checks the state of all the sheduled events. failing to call Alarm.delaywill result in the alarms not being trigerred. you can call Alarm.delay(0) if you need to service the sheduler without a delay.

Hi MattHadfield

Did you get the relay to work with the RTC
I am very new to this and im in to deep

I have a similar project under way and am trying to work through it :confused:

If you are able to show your final sketch that would be great. :slight_smile:

Thanks

MattHadfield:
Hey everyone,

Ive just started with arduino and am slowly getting my head around it, im currently trying to build a Fishtank controller that is automated with a manual switch that can be pressed to enable feeding.

Now i have the basics in place, the switch works and activates the feeding cycle, but i am struggling to find any readup on how to program an RTC, what i want it to do is at X time turn on the lights and at x time turn them off, but then i also need this for the other relays as well.

Heres my current sketch -

/*

Blink
  Turns on an LED on for one second, then off for one second, repeatedly.

This example code is in the public domain.
*/

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:

// RELAYS

int pumprelay = 3;
int filterrelay = 4;
int lightsrelay = 5;
int heaterrelay =6;

//BUTTONS

int FeedingButton = 7;
int HeaterButton = 18;

//LEDS

int lightsled = 8;
int pumpled = 9;
int filterled = 10;
int FeedingLED = 11;
int heaterled = 12;

// variables will change:
int buttonState = 0;        // variable for reading the pushbutton status

// the setup routine runs once when you press reset:
void setup() {               
  // initialize the digital pin as an output.
  pinMode(lightsrelay, OUTPUT);
  pinMode(lightsled, OUTPUT);   
  pinMode(heaterrelay, OUTPUT);
  pinMode(heaterled, OUTPUT); 
  pinMode(pumprelay, OUTPUT);
  pinMode(pumpled, OUTPUT); 
  pinMode(filterrelay, OUTPUT);
  pinMode(filterled, OUTPUT);   
  pinMode(FeedingButton, INPUT);
  pinMode(FeedingLED, OUTPUT);
 
}

// the loop routine runs over and over again forever:
void loop() {
 
    // read the state of the pushbutton value:
  buttonState = digitalRead(FeedingButton);

// check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {   
    // Start Feeding Cyle   
      Feeding();
  }
  else {
    // Continue Normal Program

}
}

void Feeding() {
  digitalWrite(FeedingLED, HIGH); // Set Feeding LED On
  LightsOn();
  PumpOff();
  FilterOff();
  delay(600000);
  digitalWrite(FeedingLED, LOW); // Set Feeding LED Off
  LightsOff();
  PumpOn();
  FilterOn();
  delay(1000);

}

void LightsOn() {
digitalWrite(lightsrelay, HIGH); // Set Lights On
digitalWrite(lightsled, HIGH); // Set LED On
}

void LightsOff() {
digitalWrite(lightsrelay, LOW); // Set Lights Off
digitalWrite(lightsled, LOW); // Set LED Off
}

void PumpOn() {
digitalWrite(pumprelay, HIGH); // Set Pump On
digitalWrite(pumpled, HIGH); // Set LED On
}

void PumpOff() {
digitalWrite(pumprelay, LOW); // Set Pump Off
digitalWrite(pumpled, LOW); // Set LED Off
}

void FilterOn() {
digitalWrite(filterrelay, HIGH); // Set Filter On
digitalWrite(filterled, HIGH); // Set LED On
}

void FilterOff() {
digitalWrite(filterrelay, LOW); // Set Filter Off
digitalWrite(filterled, LOW); // Set LED Off
}




Anyone know of any really good guides for RTC at all ?

did you end up figuring this out, im also in the same boat as i need to make lights flash from 11:30pm to 5:30am for a school project whose date has been changed to tomorrow