On/Off pin at set time help?

Hi All,

I have a DS1307 RTC, Uno, and LCD, trying to get a on/off result on a pin at a set time.

The background is 4 relay channels on pin 5, 6, 7, 8 which I want to be able to independantly switch on and of at set times.

I have the RTC set up and working as it should, and got my relays all hooked up and working on test, however can somone give me an example code of how to switch on and off a pin at a set time...

Im using the wire.h and liquidcrystal libraries at present...

i.e.

read the RTC and...

at 08.00 turn pin 5 on, at 18.00 turn pin 5 off
at 10.00 turn pin 6 on, at 19.00 turn ping 6 off...

if you get the gist of it...

As said, a piece of example code doing one of the above operations would be perfect so I can tweak and get the function integrated in to my code.

What have you tried?

I haven't tried anything yet as I don't now where to start, or even how to do it, hence asking if anyone has an example I can work from there to get the multiple switches at once etc...

Even a good point in the "right direction" would help...

I'm not asking somone to do it for me, hence not posting my code, but I need to be able to see a working example for me to base it on... anyone?

How would YOU turn the pin on at a specific time? If you are to turn the pin on at 5:37:18, you need to know the current time. If hour equals 5 and minutes equal 37 and seconds equal 18, it's time to do something.

Strangely enough, the Arduino works exactly the same way.

Ok, right, this is the problem...

If I wanted to switch something on my arm would do what my brain wanted, I dont have to code my brain....

I get that people may know how to do this, and all this makes sense, but I have only just got this thing, and as much as I want to try as much as I can, Im stumped.

I've tried cutting about various examples from the universal KB, however nothing ties in to what I am trying to get, or does it work, this is why IUm after some help, from somone who will probably now this very quick, and be willing to help me out, wihtout sounding rude, everyone starts somewhere, so turning the question back with another question isn't really that helpfull...

So here I am...

I have the RTC on, it works, I have the LCD on it works, I have the relays hooked up, and yes albeit on a weird timing, they work...

This is where I am stuck, can somone please help me out here, as said, all Im trying to do is get 1 example that works with what I have to turn relay0pin on at x time and off at y time...

I will want expandability to the 4 relays, but thats the bit I'll work out, I just need the first one to help me on my way.... This is where I am so far....

//LCD Realy test 1.2.0.3 //Arduino SYNCS with RTC

#include <LiquidCrystal.h>
#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
#include <Time.h>
#include <DS1307RTC.h>


LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

const int relay0pin =  6; 
const int relay1pin =  7; 
const int relay2pin =  8; 
const int relay3pin =  9; 

int relay0state = LOW; 
int relay1state = LOW;  
int relay2state = LOW;  
int relay3state = LOW;  

long previousMillis0 = 1;        // will store last time relay0 was updated
long previousMillis1 = 1;        // will store last time relay1 was updated     
long previousMillis2 = 1;        // will store last time relay1 was updated    
long previousMillis3 = 1;        // will store last time relay1 was updated    

long interval0 = 400;           // interval at which to switch (milliseconds)
long interval1 = 800;           // interval at which to switch (milliseconds)
long interval2 = 1600;           // interval at which to switch (milliseconds)
long interval3 = 3200;           // interval at which to switch (milliseconds)

    byte decToBcd(byte val)
 {
    return ( (val/10*16) + (val%10) );
 }

 

    byte bcdToDec(byte val)
 {
    return ( (val/16*10) + (val%16) );
 }

 void setDateDs1307(byte second, 
 byte minute,
 byte hour, 
 byte dayOfWeek,
 byte dayOfMonth, 
 byte month, 
 byte year)
 
 {

    Wire.beginTransmission(DS1307_I2C_ADDRESS);
    Wire.write(0);
    Wire.write(decToBcd(second)); 
    Wire.write(decToBcd(minute));
    Wire.write(decToBcd(hour));
    Wire.write(decToBcd(dayOfWeek));
    Wire.write(decToBcd(dayOfMonth));
    Wire.write(decToBcd(month));
    Wire.write(decToBcd(year));
    Wire.write(0x10); 
    Wire.endTransmission();
  
 }



 void getDateDs1307(byte *second,
 byte *minute,
 byte *hour,
 byte *dayOfWeek,
 byte *dayOfMonth,
 byte *month,
 byte *year)

 {

   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.write(0);
   Wire.endTransmission();
   Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
 
   *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());
   *dayOfMonth = bcdToDec(Wire.read());
   *month = bcdToDec(Wire.read());
   *year = bcdToDec(Wire.read());
  
  }

void setup() 

  {
    
 

     pinMode(relay0pin, OUTPUT);   
     pinMode(relay1pin, OUTPUT);     
     pinMode(relay2pin, OUTPUT);
     pinMode(relay3pin, OUTPUT);
 
     byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
     Wire.begin();
     Serial.begin(9600);

     second = 00;
     minute = 00  ;
     hour = 18;
     dayOfWeek = 7;
     dayOfMonth = 20;
     month = 4;
     year = 13;
 
//setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

    lcd.begin(16, 2); // tells Arduino the LCD dimensions

  
  
  Serial.begin(9600);
  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()
  
  {{
 
    lcd.begin(16, 2);
    lcd.setCursor(11, 0);
    lcd.print("Light");
    lcd.setCursor (11,1);
    lcd.print("*");
    
    if (relay0state == HIGH)
  
  {
  
    lcd.setCursor(12,2);
    lcd.print("*");

  }
  
    if (relay1state == HIGH)
  
  {
  
    lcd.setCursor(13,2);
    lcd.print("*");

  } 
  
    if (relay2state == HIGH)
  
  {
  
    lcd.setCursor(14,2);
    lcd.print("*");

  } 
   
   if (relay3state == HIGH)
  
  {
  
    lcd.setCursor(15,2);
    lcd.print("*");

  }  
 byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
 getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
 
 lcd.setCursor(0,0);
 if (hour<10)
 
   {
   
     lcd.print("0");
   
   }
 
 lcd.print(hour, DEC);
 lcd.print(":");
 if (minute<10)
 
   {
 
     lcd.print("0");
 
   }
 
 lcd.print(minute, DEC);

 if (second<10)
 
   {
   
     lcd.print("");
   
   }
 
 lcd.setCursor(0,1);

 switch(dayOfWeek)
   
   {
 
     case 1:
     lcd.print("Sun");
     break;
     case 2:
     lcd.print("Mon");
     break;
     case 3:
     lcd.print("Tue");
     break;
     case 4:
     lcd.print("Wed");
     break;
     case 5:
     lcd.print("Thu");
     break;
     case 6:
     lcd.print("Fri");
     break;
     case 7:
     lcd.print("Sat");
     break;
 
   }
delay(250);
  }
  
unsigned long currentMillis0 = millis();
unsigned long currentMillis1 = millis();
unsigned long currentMillis2 = millis();
unsigned long currentMillis3 = millis();
 
if(currentMillis0 - previousMillis0 > interval0) 
  
  {
    
    previousMillis0 = currentMillis0;   
 
    if (relay0state == LOW)
    
    relay0state = HIGH;
      
    else
    
    relay0state = LOW;
  
    digitalWrite(relay0pin, relay0state);
       
  }
    
if(currentMillis1 - previousMillis1 > interval1) 

  {
    
     previousMillis1 = currentMillis1;   
   
     if (relay1state == LOW)
     
     relay1state = HIGH; 
      
     else
     
     relay1state = LOW;
   
     digitalWrite(relay1pin, relay1state);
   
  }
  
if(currentMillis2 - previousMillis2 > interval2) 
  
  {
   
      previousMillis2 = currentMillis2;   
  
      if (relay2state == LOW)

      relay2state = HIGH;
      
      else

      relay2state = LOW;
  
      digitalWrite(relay2pin, relay2state);
       
  }
  
  if(currentMillis3 - previousMillis3 > interval3) 
  
  {
   
      previousMillis3 = currentMillis3;   
  
      if (relay3state == LOW)

      relay3state = HIGH;
      
      else

      relay3state = LOW;
  
      digitalWrite(relay3pin, relay3state);
       
  }
  
  
  
    if(Serial.available())
  {
     time_t t = processSyncMessage();
     if(t >0)
     {
        RTC.set(t);   // set the RTC and the system time to the received value
        setTime(t);          
     }
  }
   digitalClockDisplay();  
  // delay(1000);
}

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

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

/*  code to process time sync messages from the serial port   */
#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message

time_t processSyncMessage() {
  // return the time if a valid sync message is received on the serial port.
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    char c = Serial.read() ; 
    Serial.print(c);  
    if( c == TIME_HEADER ) {       
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){   
        c = Serial.read();          
        if( c >= '0' && c <= '9'){   
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }   
      return pctime; 
    }  
  }
  return 0;
  }

Obviously this timer bit I'm after will replace my test of (which can be disreagarded).

So here I am...

I have the RTC on, it works

How do you know it works? By what process have you concluded that it "works"?

You really need to make that code LOOK better. Functions start in column 1 not in the middle of the page.

 void setDateDs1307(byte second, 
 byte minute,
 byte hour, 
 byte dayOfWeek,
 byte dayOfMonth, 
 byte month, 
 byte year)
 
 {

There should NOT be a blank line between the function and the {. The arguments should all be lined up, not jammed in column 1.

void setup() 

  {

I get tired of scrolling before the code in the function appears.

    void loop()
  
  {{

Functions need ONE curly brace at the start, not two.

Anyway, I finally found what I was looking for:

 getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

This is where you get the time from the RTC. This is how you know that the RTC works.

Now, how hard is this:

if(hour == 5 && minute == 37 && second == 18)
{
   // turn a relay on
}

Thanks,

I'll give that a shot.

I know it works, as all through and despite power cycling the device it has consistenly been relaying a print through serial of the current time/date, which has been consistently correct.

As said, I'll give the above a go and see how I fair...

So,

I have cut out all the bits that at present dont relate to this problem, but still cant get it running, getting:

sketch_apr21a.ino: In function 'void loop()':
sketch_apr21a:84: error: invalid operands of types '' and 'int' to binary 'operator=='
sketch_apr21a:84: error: invalid operands of types '' and 'int' to binary 'operator=='
sketch_apr21a:84: error: invalid operands of types '' and 'int' to binary 'operator=='

the code is:

#include <DS1307RTC.h>

#include <Time.h>
#include <Wire.h>
#include <LiquidCrystal.h>
#define DS1307_I2C_ADDRESS 0x68


LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)

{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second)); 
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.write(0x10); 
  Wire.endTransmission();
}

void getDateDs1307(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year)

{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  *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());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}

void setup() 

{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  Serial.begin(9600);

  second = 00;
  minute = 00  ;
  hour = 18;
  dayOfWeek = 7;
  dayOfMonth = 20;
  month = 4;
  year = 13;

//setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

  Serial.begin(9600);
  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");

  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
}

void loop ()
  
{
  if(hour == 5 && minute == 37 && second == 18)
{
     Serial.println("TIME NOW TEST 5:37.8");
}
}

I have cut out all the bits that at present dont relate to this problem

I don't see how the setDateDs1307() function is relevant, since we've already established that it works, but, OK.

I copied and pasted your code into the 1.0.3 IDE.
Same errors. Because hour, minute, and second are function names in the RTC class. This compiles, though:

void loop ()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

  if(hour == 5 && minute == 37 && second == 18)
  {
    Serial.println("TIME NOW TEST 5:37.8");
  }
}

Using names for the variables that are different from the function names is a better idea, though.

You haven't declared the variables second, minute, hour, dayOfWeek, dayOfMonth, month, year globally, so they are not accessible throughout your code, the only reason it is compiling is that hour,minute,second are also declared in the Time library, but they are function types. Change their name to avoid name collisions and declare them globally and that should fix those errors.