Go Down

Topic: Need some direction for controlling relays using RTC (Read 1 time) previous topic - next topic

mtmcghee

Ok,

So im trying to build a simple timer... ok not super simple but simple enough.

I am using a Duemilanove and RTC_DS1307 the RTC is connected to Analog pins 4-sda 5-scl and the relays are connected to digital ports 1-8 to match relay 1-8  the code that came with the RTC isnt good at all... but im not familiar enough with programing to understand much of it...

all i want to do is specify a time that the relays open and then when they close and have it repeat every day... simple right??/


thanks


matt

CrossRoads

Sounds simple enough when you put it that way.

Will likely need a transistor for each relay to drive them, 40mA from arduino usually not enough.
Or a part like ULN2803, 8 transistors nicely packaged up.
See the right side of the drawing.

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

mtmcghee

i have the relays working they are on a board and i can make them click using the Blink sketch and but i have no idea how to write the code involed in making the rest of it work...

mtmcghee

#3
Mar 10, 2011, 06:37 am Last Edit: Mar 10, 2011, 07:22 am by mtmcghee Reason: 1
ok i found some i guess better code, it actually uploaded, and if it works the person that wrote it thankyou!!!

Code: [Select]

/*
* RTC Control v.01
* by <http://www.combustory.com> John Vaughters
* Credit to:
* Maurice Ribble - http://www.glacialwanderer.com/hobbyrobotics for RTC DS1307 code
*
* With this code you can set the date/time, retreive the date/time and use the extra memory of an RTC DS1307 chip.  
* The program also sets all the extra memory space to 0xff.
* Serial Communication method with the Arduino that utilizes a leading CHAR for each command described below.
* Commands:
* T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99) - T(sec)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(year) - T Sets the date of the RTC DS1307 Chip.
* Example to set the time for 02-Feb-09 @ 19:57:11 for the 3 day of the week, use this command - T1157193020209
* Q(1-2) - (Q1) Memory initialization  (Q2) RTC - Memory Dump
*/

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68  // This is the I2C address


// Global Variables

int command = 0;       // This is the command char, in ascii form, sent from the serial port    
int i;
long previousMillis = 0;        // will store last time Temp was updated
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
byte test;

// 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) );
}

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock
// Assumes you're passing in valid numbers, Probably need to put in checks for valid numbers.

void setDateDs1307()                
{

  second = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result.  
  minute = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  hour  = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  dayOfWeek = (byte) (Serial.read() - 48);
  dayOfMonth = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  month = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  year= (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0x00);
  Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
  Wire.send(decToBcd(minute));
  Wire.send(decToBcd(hour));      // If you want 12 hour am/pm you need to set
                                  // bit 6 (also need to change readDateDs1307)
  Wire.send(decToBcd(dayOfWeek));
  Wire.send(decToBcd(dayOfMonth));
  Wire.send(decToBcd(month));
  Wire.send(decToBcd(year));
  Wire.endTransmission();
}

// Gets the date and time from the ds1307 and prints result
void getDateDs1307()
{
 // Reset the register pointer
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.send(0x00);
 Wire.endTransmission();

 Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

 // A few of these need masks because certain bits are control bits
 second     = bcdToDec(Wire.receive() & 0x7f);
 minute     = bcdToDec(Wire.receive());
 hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
 dayOfWeek  = bcdToDec(Wire.receive());
 dayOfMonth = bcdToDec(Wire.receive());
 month      = bcdToDec(Wire.receive());
 year       = bcdToDec(Wire.receive());

 Serial.print(hour, DEC);
 Serial.print(":");
 Serial.print(minute, DEC);
 Serial.print(":");
 Serial.print(second, DEC);
 Serial.print("  ");
 Serial.print(month, DEC);
 Serial.print("/");
 Serial.print(dayOfMonth, DEC);
 Serial.print("/");
 Serial.print(year, DEC);

}


void setup() {
 Wire.begin();
 Serial.begin(57600);

}

void loop() {
    if (Serial.available()) {      // Look for char in serial que and process if found
     command = Serial.read();
     if (command == 84) {      //If command = "T" Set Date
      setDateDs1307();
      getDateDs1307();
      Serial.println(" ");
     }
     else if (command == 81) {      //If command = "Q" RTC1307 Memory Functions
       delay(100);    
       if (Serial.available()) {
        command = Serial.read();
        if (command == 49) {      //If command = "1" RTC1307 Initialize Memory - All Data will be set to 255 (0xff).  Therefore 255 or 0 will be an invalid value.  
         Wire.beginTransmission(DS1307_I2C_ADDRESS); // 255 will be the init value and 0 will be considered an error that occurs when the RTC is in Battery mode.
         Wire.send(0x08); // Set the register pointer to be just past the date/time registers.
        for (i = 1; i <= 27; i++) {
            Wire.send(0xff);
           delay(100);
        }  
        Wire.endTransmission();
        getDateDs1307();
        Serial.println(": RTC1307 Initialized Memory");
        }
        else if (command == 50) {      //If command = "2" RTC1307 Memory Dump
         getDateDs1307();
         Serial.println(": RTC 1307 Dump Begin");
         Wire.beginTransmission(DS1307_I2C_ADDRESS);
         Wire.send(0x00);
         Wire.endTransmission();
         Wire.requestFrom(DS1307_I2C_ADDRESS, 64);
         for (i = 1; i <= 64; i++) {
            test = Wire.receive();
            Serial.print(i);
            Serial.print(":");
            Serial.println(test, DEC);
         }
         Serial.println(" RTC1307 Dump end");
        }
       }  
      }
     Serial.print("Command: ");
     Serial.println(command);     // Echo command CHAR in ascii that was sent
     }

     command = 0;                 // reset command
     delay(100);
   }
//*****************************************************The End***********************


CrossRoads

For your relay, see if it will turn on an LED - if not, the clicking is not actually closing the contacts.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

mtmcghee


For your relay, see if it will turn on an LED - if not, the clicking is not actually closing the contacts.


ok i just double checked and they are contacting i connected an 120v 60w lamp and it blinks on and off with the relay so i know that it will work, now how do i write a code to work with the RTC? and how can i check to see if i set the RTC correctly?
Thanks

Matt

mtmcghee

ok when i set my time per the instructions in the code it kicks back this

0:56:30  1/31/57
Command: 84

then when i enter "Time" it kicks back this

29:65:39  9/29/69
Command: 84


whats going on??


CrossRoads

ok, first go back and modify your entry with the code listing.
put [ code ] in front (no spaces th) and [ /code ] after it, makes it a lot easier to get around.

Read the listing:
"* With this code you can set the date/time, retreive the date/time and use the extra memory of an RTC DS1307 chip. "

So you're going to want to perhaps  modify this function to retrieve the time (you don't need to print it, do you?)
Code: [Select]

// Gets the date and time from the ds1307 and prints result
void getDateDs1307()
{
 // Reset the register pointer
 Wire.beginTransmission(DS1307_I2C_ADDRESS);
 Wire.send(0x00);
 Wire.endTransmission();

 Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

 // A few of these need masks because certain bits are control bits
 second     = bcdToDec(Wire.receive() & 0x7f);
 minute     = bcdToDec(Wire.receive());
 hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
 dayOfWeek  = bcdToDec(Wire.receive());
 dayOfMonth = bcdToDec(Wire.receive());
 month      = bcdToDec(Wire.receive());
 year       = bcdToDec(Wire.receive());

 Serial.print(hour, DEC);
 Serial.print(":");
 Serial.print(minute, DEC);
 Serial.print(":");
 Serial.print(second, DEC);
 Serial.print("  ");
 Serial.print(month, DEC);
 Serial.print("/");
 Serial.print(dayOfMonth, DEC);
 Serial.print("/");
 Serial.print(year, DEC);

}

Then in void loop() ,
You're going to call it and take action when the data is what you want.
Code: [Select]

getDateDs1307();
if (hour == 22 && done_flag = 0){
//do something
done_flag = 1;
}  
getDateDs1307();
if (hour == 23){
done_flag = 0; // reset for next day
}

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

mtmcghee

thanks for the help and the tip posting the code...
i wont need to print it just verify that it set correctly...

but i have no idea what to change the code to...

mtmcghee

#9
Mar 11, 2011, 05:37 am Last Edit: Mar 11, 2011, 06:39 am by mtmcghee Reason: 1
ok i think i have my code right for this part, can someone please take a look at it ???

Im Still Not Having Any Luck With The RTC...

Code: [Select]


{

pinMode(1,  OUTPUT); // fan
pinMode(2,  OUTPUT); // moon
pinMode(3,  OUTPUT); // pc a
pinMode(4,  OUTPUT); // pc b
pinMode(5,  OUTPUT); // mh a
pinMode(6,  OUTPUT); // mh b


}

void loop()
{  // need matching }  at the end of loop - maybe it just wasn't pasted in
  // ***** read rtc *****
  year = RTC.get(DS1307_YR,false);             
  month = RTC.get(DS1307_MTH,false); 
  date = RTC.get(DS1307_DATE,false);
  hour = RTC.get(DS1307_HR,true);                     
  minute = RTC.get(DS1307_MIN,false);
  second = RTC.get(DS1307_SEC,false);
  time = (hour * 100) + minute;                       
  Serial.println("rtc");
  Serial.println(date && "." && month && "." && year);
  }
 
  // ***** Sch *****

if ( (time >0800) && (time <+ 2030) ){digitalWrite (1, HIGH);} else {digitalWrite (1, LOW);}
if ( (time >2000) && (time <+ 2200) ){digitalWrite (2, HIGH);} else {digitalWrite (2, LOW);}
if ( (time >0800) && (time <+ 1845) ){digitalWrite (3, HIGH);} else {digitalWrite (3, LOW);}
if ( (time >0805) && (time <+ 1900) ){digitalWrite (4, HIGH);} else {digitalWrite (4, LOW);}
if ( (time >0800) && (time <+ 1845) ){digitalWrite (5, HIGH);} else {digitalWrite (5, LOW);}
if ( (time >0805) && (time <+ 1900) ){digitalWrite (6, HIGH);} else {digitalWrite (6, LOW);}
 

PaulS

Code: [Select]
  time = (hour * 100) + minute;
On large parts of this planet, there are 60 minutes in an hour.

Code: [Select]
if ( (time >0800) && (time <+ 2030) ){digitalWrite (1, HIGH);} else {digitalWrite (1, LOW);}
Supposing that hour had held a value of 9 and minute had held a value of 20, time should contain the value of 930. This is greater than 800 and less than 2030, so you set digital pin 1 to HIGH. Well, that just screwed up your serial communications. Digital pins 0 and 1 are the serial port on the non-Mega Arduinos, and one of 4 serial ports on the Mega. Those pins can not ALSO be used for GPIO.

Quote
Im Still Not Having Any Luck With The RTC...

There Is No Luck Required. Either You Can Read The Time From The RTC Or You Can't. wHICH iS iT?

If you can't get the time, why are you trying to use it? If you can get the time, what is the problem?

Code: [Select]
  year = RTC.get(DS1307_YR,false);             
  month = RTC.get(DS1307_MTH,false); 
  date = RTC.get(DS1307_DATE,false);
  hour = RTC.get(DS1307_HR,true);                     
  minute = RTC.get(DS1307_MIN,false);
  second = RTC.get(DS1307_SEC,false);

Get the year, month, and date from the last time those values were fetched from the clock, then fetch new values, and get the hour, minute, and second values. Makes sense. Not.

Is the time on your RTC set? You are using hour and minute, but printing only day, month, and year. Why not print the values that you actually use?

mtmcghee

ok, so i dont need to use digital pin 1 for a relay, As for the RTC i have tried about 15 differnt codes to try and set it but there is either some problem in the code and it wont up load or the code at that is post 4 will upload and i cant set the time but if i wait and recheck the time it has kiced back to its default and im not sure why...

this cant be that complicated...

orbitalair

Am I right the DS1307 does not have an alarm?
This is far easier if you use a chip with an alarm, like a pcf8563 or another DS part.

Then you just set the bit you want, and when the alarm trips you get an interrupt.
easy-peesy.

With just a clock you have to always calc times, convert to seconds(midnite being 0) and compare.

mtmcghee


Am I right the DS1307 does not have an alarm?
This is far easier if you use a chip with an alarm, like a pcf8563 or another DS part.

Then you just set the bit you want, and when the alarm trips you get an interrupt.
easy-peesy.

With just a clock you have to always calc times, convert to seconds(midnite being 0) and compare.


I have no idea if it has an alarm or not...

PaulS

Quote
I have no idea if it has an alarm or not...

It does not. It is simply a clock.

Go Up