outputs with rtc

I have not had my arduino long and so far its going well with the basic stuff but i have come to a bit of a dead end.

I cant seem to find any reference of how to switch outputs at certain times by using the rtc.

I not sure if i have explained well, What im after is something like

if (hour > 21 && minute > 15)
digitalWrite (13, HIGH);

Only problem with this is at 22:00 the output goes off

I’m sure there’s an easy way.

Thanks Adam

An easy way to handle such a task is to pick an absolute reference frame and count in only one unit.

For example, why not convert the hours to minutes, and then count minutes from the start of the day. ie. 0100 hrs = 60 minutes and 0200 hrs = 120 minutes.

Now you can specify a range for which you’d like the output to be on. For example:

if (minute >= 60 && minute <= 120) //Turns on the output at 0100 hrs and turns off at 0200 hrs
 digitalWrite (13, HIGH);

Not sure i can do that as the time is also output to a lcd disply so the code is in hours and minutes

I know the code is a bit messy

#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(49, 48, 47, 53, 52, 51, 50);



int fan = 13; // fan on pin 13
int pin = 0; // analog pin
int tempc = 0,tempf=0; // temperature variables
int samples[8]; // variables to make a better precision
int maxi = -100,mini = 100; // to start max/min temperature
int i; // temp varialbe

#define DS1307      0xD0 >> 1                   // shift required by Wire.h (silly...)


// DS1307 clock registers

#define R_SECS      0
#define R_MINS      1
#define R_HRS       2

byte second = 0x00;                             // default to 01 JAN 2007, midnight
byte minute = 0x00;
byte hour = 0x00;
byte wkDay = 0x02;
byte day = 0x01;
byte month = 0x01;
byte year = 0x07;
byte ctrl = 0x00;



void setup()


{ 
 pinMode(fan, OUTPUT);  // digital pin for fan as output
 Wire.begin();
 lcd.clear();
 //second = 0x45;                                // remove to set time then replace
 //minute = 0x31;
 //hour   = 0x17;
 //wkDay  = 0x07;
 //day    = 0x13;
 //month  = 0x04;
 //year   = 0x09;
 //ctrl   = 0x00;                                // disable SQW output
 //setClock();
 
 

}
void loop()


{   
for(i = 0;i<=7;i++){ // gets 8 samples of temperature
  samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
  tempc = tempc + samples[i];
  delay(1000);
}
tempc = tempc/8.0; // better precision
tempf = (tempc * 9)/ 5 + 32; // converts to fahrenheit
//{
// if (tempc > 21)           // value for fan on pin 13
//digitalWrite(13, HIGH);    // fan on
// if (tempc < 21)           // value for fan off on pin 13
// digitalWrite(13, LOW);    // fan off
//}


{
  if (hour > 21 && minute > 01)
  digitalWrite (13, HIGH);
  delay (1000);
}


lcd.setCursor(0,1);
lcd.print(tempc,DEC);
lcd.println(" Celsius        ");
lcd.setCursor(0,0);
tempc = 0;
delay(0000); // delay before loop


 getClock();
 printHex2(hour);
 lcd.print(":");
 printHex2(minute);
 lcd.print(" ");
 lcd.print("  ");
 printHex2(day);
 lcd.print("/");
 printMonthName(bcd2Dec(month));
 lcd.print("/");
 printHex2(year);
 lcd.println();
 delay(1000);
}
void setClock()
{
 Wire.beginTransmission(DS1307);
 Wire.send(R_SECS);
 Wire.send(second);
 Wire.send(minute);
 Wire.send(hour);
 Wire.send(wkDay);
 Wire.send(day);
 Wire.send(month);
 Wire.send(year);
 Wire.send(ctrl);
 Wire.endTransmission();
}
void getClock()
{
 Wire.beginTransmission(DS1307);
 Wire.send(R_SECS);
 Wire.endTransmission();
 Wire.requestFrom(DS1307, 8);
 second = Wire.receive();
 minute = Wire.receive();
 hour   = Wire.receive();
 wkDay  = Wire.receive();
 day    = Wire.receive();
 month  = Wire.receive();
 year   = Wire.receive();
 ctrl   = Wire.receive();
}
byte bcd2Dec(byte bcdVal)
{
 return bcdVal / 16 * 10 + bcdVal % 16;
}
void printHex2(byte hexVal)
{
 if (hexVal < 0x10)
   lcd.print("0");
 lcd.print(hexVal, HEX);
}
void printDec2(byte decVal)
{
 if (decVal < 10)
   lcd.print("0");
 lcd.print(decVal, DEC);
}
void printMonthName(byte m)
{
 switch (m) {
   case 1:
     lcd.print("01");
     break;
   case 2:
     lcd.print("02");
     break;
   case 3:
     lcd.print("03");
     break;
   case 4:
     lcd.print("04");
     break;
   case 5:
     lcd.print("05");
     break;
   case 6:
     lcd.print("06");
     break;
   case 7:
     lcd.print("07");
     break;
   case 8:
     lcd.print("08");
     break;
   case 9:
     lcd.print("09");
    
     break;
   case 10:
     lcd.print("10");
     break;
   case 11:
     lcd.print("11");
     break;
   case 12:
     lcd.print("12");   
 }
}

Not sure i can do that as the time is also output to a lcd disply so the code is in hours and minutes

The conversion from one reference frame to another will be quite trivial. In your case, lets assume that minutes was an int which contains the number of minutes since the start of the day.

int hours_to_display = minutes / 60; //will truncate the decimal points, but stores whole hours in hours_to_display
int minutes_to_display = minutes % 60; //will store remaining minutes into minutes_to_display

Ah i see where your coming from,

Thanks for that, im now going back and trying again

Ok i have tried this

int hourmin = (hour * 60) //hours * 60 = variable hourmin
if (hourmin + minute > 1500) // hourmin + minute > 1500 minutes
digitalWrite (13, HIGH);

I know its about right but i just cant get it to work

Any ideas, please

Thanks Adam

Can you post all your revised code please:

Also are you resetting minute every midnight? If you are then you will never reach 1500 minutes as there are only 1440 minutes in a day.

The 1500 was me forcing the time, I was trying at 1300,1400 and 1500 trying to sort out were i was going wrong.

#include <Wire.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(49, 48, 47, 53, 52, 51, 50);



int fan = 13; // fan on pin 13
int pin = 0; // analog pin
int tempc = 0,tempf=0; // temperature variables
int samples[8]; // variables to make a better precision
int maxi = -100,mini = 100; // to start max/min temperature
int i; // temp varialbe


#define DS1307      0xD0 >> 1                   // shift required by Wire.h (silly...)


// DS1307 clock registers

#define R_SECS      0
#define R_MINS      1
#define R_HRS       2

byte second = 0x00;                             // default to 01 JAN 2007, midnight
byte minute = 0x00;
byte hour = 0x00;
byte wkDay = 0x02;
byte day = 0x01;
byte month = 0x01;
byte year = 0x07;
byte ctrl = 0x00;



void setup()


{ 
 pinMode(fan, OUTPUT);  // digital pin for fan as output
 Wire.begin();
 lcd.clear();
 //second = 0x45;                                // remove to set time then replace
 //minute = 0x31;
 //hour   = 0x17;
 //wkDay  = 0x07;
 //day    = 0x13;
 //month  = 0x04;
 //year   = 0x09;
 //ctrl   = 0x00;                                // disable SQW output
 //setClock();
 
 

}
void loop()


{   
for(i = 0;i<=7;i++){ // gets 8 samples of temperature
  samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
  tempc = tempc + samples[i];
  delay(1000);
}
tempc = tempc/8.0; // better precision
tempf = (tempc * 9)/ 5 + 32; // converts to fahrenheit
//{
// if (tempc > 21)           // value for fan on pin 13
//digitalWrite(13, HIGH);    // fan on
// if (tempc < 21)           // value for fan off on pin 13
// digitalWrite(13, LOW);    // fan off
//}


{
  int hourmin = (hour * 60)              //hours * 60 = variable hourmin
  if (hourmin + minute > 1500)      // hourmin + minute  > 1500 minutes
  digitalWrite (13, HIGH);
}


lcd.setCursor(0,1);
lcd.print(tempc,DEC);
lcd.println(" Celsius        ");
lcd.setCursor(0,0);
tempc = 0;
delay(0000); // delay before loop



 


 getClock();
 printHex2(hour);
 lcd.print(":");
 printHex2(minute);
 lcd.print(" ");
 lcd.print("  ");
 printHex2(day);
 lcd.print("/");
 printMonthName(bcd2Dec(month));
 lcd.print("/");
 printHex2(year);
 lcd.println();
 delay(1000);
}
void setClock()
{
 Wire.beginTransmission(DS1307);
 Wire.send(R_SECS);
 Wire.send(second);
 Wire.send(minute);
 Wire.send(hour);
 Wire.send(wkDay);
 Wire.send(day);
 Wire.send(month);
 Wire.send(year);
 Wire.send(ctrl);
 Wire.endTransmission();
}
void getClock()
{
 Wire.beginTransmission(DS1307);
 Wire.send(R_SECS);
 Wire.endTransmission();
 Wire.requestFrom(DS1307, 8);
 second = Wire.receive();
 minute = Wire.receive();
 hour   = Wire.receive();
 wkDay  = Wire.receive();
 day    = Wire.receive();
 month  = Wire.receive();
 year   = Wire.receive();
 ctrl   = Wire.receive();
}
byte bcd2Dec(byte bcdVal)
{
 return bcdVal / 16 * 10 + bcdVal % 16;
}
void printHex2(byte hexVal)
{
 if (hexVal < 0x10)
   lcd.print("0");
 lcd.print(hexVal, HEX);
}
void printDec2(byte decVal)
{
 if (decVal < 10)
   lcd.print("0");
 lcd.print(decVal, DEC);
}
void printMonthName(byte m)
{
 switch (m) {
   case 1:
     lcd.print("01");
     break;
   case 2:
     lcd.print("02");
     break;
   case 3:
     lcd.print("03");
     break;
   case 4:
     lcd.print("04");
     break;
   case 5:
     lcd.print("05");
     break;
   case 6:
     lcd.print("06");
     break;
   case 7:
     lcd.print("07");
     break;
   case 8:
     lcd.print("08");
     break;
   case 9:
     lcd.print("09");
    
     break;
   case 10:
     lcd.print("10");
     break;
   case 11:
     lcd.print("11");
     break;
   case 12:
     lcd.print("12");   
 }
}
{
  int hourmin = (hour * 60)              //hours * 60 = variable hourmin
  if (hourmin + minute > 1500)      // hourmin + minute  > 1500 minutes
  digitalWrite (13, HIGH);
}

Not sure why you have braces around those lines of code.

Try this code. I just made a minor modification. I added a few lines which print the current value of int hourmin to the serial terminal. Monitor serial and see if you can figure out what the issue is. Post back with the results.

I had to include c stdlib for the itoa function which converts an int to a string, used to print hourmin.

#include <Wire.h>
#include <LiquidCrystal.h>
#include <stdlib.h> //used for itoa. Feel free to remove if not using that function

LiquidCrystal lcd(49, 48, 47, 53, 52, 51, 50);



int fan = 13; // fan on pin 13
int pin = 0; // analog pin
int tempc = 0,tempf=0; // temperature variables
int samples[8]; // variables to make a better precision
int maxi = -100,mini = 100; // to start max/min temperature
int i; // temp varialbe


#define DS1307      0xD0 >> 1                   // shift required by Wire.h (silly...)


// DS1307 clock registers

#define R_SECS      0
#define R_MINS      1
#define R_HRS       2

byte second = 0x00;                             // default to 01 JAN 2007, midnight
byte minute = 0x00;
byte hour = 0x00;
byte wkDay = 0x02;
byte day = 0x01;
byte month = 0x01;
byte year = 0x07;
byte ctrl = 0x00;



void setup()


{
 pinMode(fan, OUTPUT);  // digital pin for fan as output
 Wire.begin();
 lcd.clear();
 //second = 0x45;                                // remove to set time then replace
 //minute = 0x31;
 //hour   = 0x17;
 //wkDay  = 0x07;
 //day    = 0x13;
 //month  = 0x04;
 //year   = 0x09;
 //ctrl   = 0x00;                                // disable SQW output
 //setClock();

      Serial.begin(9600);

}
void loop()


{
for(i = 0;i<=7;i++){ // gets 8 samples of temperature
  samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
  tempc = tempc + samples[i];
  delay(1000);
}
tempc = tempc/8.0; // better precision
tempf = (tempc * 9)/ 5 + 32; // converts to fahrenheit
//{
// if (tempc > 21)           // value for fan on pin 13
//digitalWrite(13, HIGH);    // fan on
// if (tempc < 21)           // value for fan off on pin 13
// digitalWrite(13, LOW);    // fan off
//}


  int hourmin = (hour * 60)              //hours * 60 = variable hourmin
  
  char string_buffer[12]; //used to store hourmin when converted to string
  Serial.printLn(itoa(hourmin, string_buffer, 10)) //convert hourmin to decimal (base 10), and store into string_buffer. Also print to serial
  
  if (hourmin + minute > 1500)      // hourmin + minute  > 1500 minutes
      digitalWrite (13, HIGH);



lcd.setCursor(0,1);
lcd.print(tempc,DEC);
lcd.println(" Celsius        ");
lcd.setCursor(0,0);
tempc = 0;
delay(0000); // delay before loop






 getClock();
 printHex2(hour);
 lcd.print(":");
 printHex2(minute);
 lcd.print(" ");
 lcd.print("  ");
 printHex2(day);
 lcd.print("/");
 printMonthName(bcd2Dec(month));
 lcd.print("/");
 printHex2(year);
 lcd.println();
 delay(1000);
}
void setClock()
{
 Wire.beginTransmission(DS1307);
 Wire.send(R_SECS);
 Wire.send(second);
 Wire.send(minute);
 Wire.send(hour);
 Wire.send(wkDay);
 Wire.send(day);
 Wire.send(month);
 Wire.send(year);
 Wire.send(ctrl);
 Wire.endTransmission();
}
void getClock()
{
 Wire.beginTransmission(DS1307);
 Wire.send(R_SECS);
 Wire.endTransmission();
 Wire.requestFrom(DS1307, 8);
 second = Wire.receive();
 minute = Wire.receive();
 hour   = Wire.receive();
 wkDay  = Wire.receive();
 day    = Wire.receive();
 month  = Wire.receive();
 year   = Wire.receive();
 ctrl   = Wire.receive();
}
byte bcd2Dec(byte bcdVal)
{
 return bcdVal / 16 * 10 + bcdVal % 16;
}
void printHex2(byte hexVal)
{
 if (hexVal < 0x10)
   lcd.print("0");
 lcd.print(hexVal, HEX);
}
void printDec2(byte decVal)
{
 if (decVal < 10)
   lcd.print("0");
 lcd.print(decVal, DEC);
}
void printMonthName(byte m)
{
 switch (m) {
   case 1:
     lcd.print("01");
     break;
   case 2:
     lcd.print("02");
     break;
   case 3:
     lcd.print("03");
     break;
   case 4:
     lcd.print("04");
     break;
   case 5:
     lcd.print("05");
     break;
   case 6:
     lcd.print("06");
     break;
   case 7:
     lcd.print("07");
     break;
   case 8:
     lcd.print("08");
     break;
   case 9:
     lcd.print("09");

     break;
   case 10:
     lcd.print("10");
     break;
   case 11:
     lcd.print("11");
     break;
   case 12:
     lcd.print("12");
 }
}

Well its partly working, The serial print hour all ways shows 1440.

I have altered the byte,hour from 00 to 01 and the serial shows

60
1440
1440

I think im not using the right “hour” for the calculations, only problem now is i cant seem to find the right “hour” and i will probably have the same problem with the minutes when i get the hours sorted.

Any ideas ?

  Serial.print("hour: ");
  Serial.printLn(hour);
  
  Serial.print("minute: ");
  Serial.printLn(minute);

  int hourmin = (hour * 60)              //hours * 60 = variable hourmin
  
  char string_buffer[12]; //used to store hourmin when converted to string
  Serial.print("hourmin: ");
  Serial.printLn(itoa(hourmin, string_buffer, 10)) //convert hourmin to decimal (base 10), and store into string_buffer. Also print to serial
  
  Serial.printLn(); //prints a carriage return

  if (hourmin + minute > 1500)      // hourmin + minute  > 1500 minutes
      digitalWrite (13, HIGH);

As you can see above, ive added more debugging messages. Give that a shot and see if you can figure out whats funky.

Full code can be found below:

#include <Wire.h>
#include <LiquidCrystal.h>
#include <stdlib.h> //used for itoa. Feel free to remove if not using that function

LiquidCrystal lcd(49, 48, 47, 53, 52, 51, 50);



int fan = 13; // fan on pin 13
int pin = 0; // analog pin
int tempc = 0,tempf=0; // temperature variables
int samples[8]; // variables to make a better precision
int maxi = -100,mini = 100; // to start max/min temperature
int i; // temp varialbe


#define DS1307      0xD0 >> 1                   // shift required by Wire.h (silly...)


// DS1307 clock registers

#define R_SECS      0
#define R_MINS      1
#define R_HRS       2

byte second = 0x00;                             // default to 01 JAN 2007, midnight
byte minute = 0x00;
byte hour = 0x00;
byte wkDay = 0x02;
byte day = 0x01;
byte month = 0x01;
byte year = 0x07;
byte ctrl = 0x00;



void setup()


{
 pinMode(fan, OUTPUT);  // digital pin for fan as output
 Wire.begin();
 lcd.clear();
 //second = 0x45;                                // remove to set time then replace
 //minute = 0x31;
 //hour   = 0x17;
 //wkDay  = 0x07;
 //day    = 0x13;
 //month  = 0x04;
 //year   = 0x09;
 //ctrl   = 0x00;                                // disable SQW output
 //setClock();

      Serial.begin(9600);

}
void loop()


{
for(i = 0;i<=7;i++){ // gets 8 samples of temperature
  samples[i] = ( 5.0 * analogRead(pin) * 100.0) / 1024.0;
  tempc = tempc + samples[i];
  delay(1000);
}
tempc = tempc/8.0; // better precision
tempf = (tempc * 9)/ 5 + 32; // converts to fahrenheit
//{
// if (tempc > 21)           // value for fan on pin 13
//digitalWrite(13, HIGH);    // fan on
// if (tempc < 21)           // value for fan off on pin 13
// digitalWrite(13, LOW);    // fan off
//}

  Serial.print("hour: ");
  Serial.printLn(hour);
  
  Serial.print("minute: ");
  Serial.printLn(minute);

  int hourmin = (hour * 60)              //hours * 60 = variable hourmin
  
  char string_buffer[12]; //used to store hourmin when converted to string
  Serial.print("hourmin: ");
  Serial.printLn(itoa(hourmin, string_buffer, 10)) //convert hourmin to decimal (base 10), and store into string_buffer. Also print to serial
  
  Serial.printLn(); //prints a carriage return

  if (hourmin + minute > 1500)      // hourmin + minute  > 1500 minutes
      digitalWrite (13, HIGH);



lcd.setCursor(0,1);
lcd.print(tempc,DEC);
lcd.println(" Celsius        ");
lcd.setCursor(0,0);
tempc = 0;
delay(0000); // delay before loop






 getClock();
 printHex2(hour);
 lcd.print(":");
 printHex2(minute);
 lcd.print(" ");
 lcd.print("  ");
 printHex2(day);
 lcd.print("/");
 printMonthName(bcd2Dec(month));
 lcd.print("/");
 printHex2(year);
 lcd.println();
 delay(1000);
}
void setClock()
{
 Wire.beginTransmission(DS1307);
 Wire.send(R_SECS);
 Wire.send(second);
 Wire.send(minute);
 Wire.send(hour);
 Wire.send(wkDay);
 Wire.send(day);
 Wire.send(month);
 Wire.send(year);
 Wire.send(ctrl);
 Wire.endTransmission();
}
void getClock()
{
 Wire.beginTransmission(DS1307);
 Wire.send(R_SECS);
 Wire.endTransmission();
 Wire.requestFrom(DS1307, 8);
 second = Wire.receive();
 minute = Wire.receive();
 hour   = Wire.receive();
 wkDay  = Wire.receive();
 day    = Wire.receive();
 month  = Wire.receive();
 year   = Wire.receive();
 ctrl   = Wire.receive();
}
byte bcd2Dec(byte bcdVal)
{
 return bcdVal / 16 * 10 + bcdVal % 16;
}
void printHex2(byte hexVal)
{
 if (hexVal < 0x10)
   lcd.print("0");
 lcd.print(hexVal, HEX);
}
void printDec2(byte decVal)
{
 if (decVal < 10)
   lcd.print("0");
 lcd.print(decVal, DEC);
}
void printMonthName(byte m)
{
 switch (m) {
   case 1:
     lcd.print("01");
     break;
   case 2:
     lcd.print("02");
     break;
   case 3:
     lcd.print("03");
     break;
   case 4:
     lcd.print("04");
     break;
   case 5:
     lcd.print("05");
     break;
   case 6:
     lcd.print("06");
     break;
   case 7:
     lcd.print("07");
     break;
   case 8:
     lcd.print("08");
     break;
   case 9:
     lcd.print("09");

     break;
   case 10:
     lcd.print("10");
     break;
   case 11:
     lcd.print("11");
     break;
   case 12:
     lcd.print("12");
 }
}

Its odd that hourmin is printing 1440 when hour has been set to 01. It appears to print 60 minutes correctly for the first cycle, but printing 1440 after those cycles is odd.