| Arduino Cloc: A Maxim DS1307/MAX7221 Based Clock with Auto Daylight Savings Adjustment | ![]() |
| I have been busying myself recently with some experiments into programming the Arduino prototyping platform. I have already created some hardware, a Maxim DS1307 Real Time Clock shield and a Serially Interfaced, 8 digit 7 Segment Display based on a MAX7221 IC. So far I have created test routines to test my hardware but I wanted to really get my teeth into creating some more practical code. And here it is, A more or less functioning LED clock. I have included a download of the sketch (Arduino speak for program) that I wrote so that Arduino owners can examine and play with my code, There is a cheesy video blog at the end of the article as well if you want to see the clock in action… Time and date are input into the clock via a rotary encoder which is attached to the digital pins 2,3 and 4 of the Arduino. As I am fairly recent to Arduino programming I had a look around for some guidance on using the Arduino alongside the DS1307 Real Time Clock and it is clearly a popular choice with builders. As a starting point I used code from this this tutorial from John Boxall, and with what I had already learned in building my 24 Hour Countdown Sketch I managed to put together a functioning clock with relative ease. Although I did not use them Adafruit also have a good tutorial on using the DS1307 as well as a library that simplifies somewhat setting and fetching the time from the DS1307 clock. As well as finding excellent tutorials on interfacing an Arduino with a Maxim DS1307 real time clock I also uncovered quite a few projects from people using this hardware, it would appear a popular choice. What I did not see in any of the examples that I found was a clock that catered for Daylight Savings Time. (British Summer Time here in the UK). Having had a lot of the code for my clock spoon fed to me already, I thought it would be interesting to build on it a bit so my Arduino sketch has that extra trick up it’s sleeve. British Summer Time is slightly complicated to program for as the clocks do not go forwards and backwards on the same date each year. The clocks go forwards at 1am on the last Sunday of the month of March each year and back on the Last Sunday of October at the same time. Adjusting the time on the correct day was going to require a more complex formula than I initially predicted. You can see in the code below how I calculate it, basically its through a set of AND and OR statements. To calculate the correct date you need to take the day of the month and subtract the day of the week (Sunday == 1, Saturday ==7). The result of this will be greater than 24 in March if we have passed from Winter Time into Summer Time. The formula is similar for the October changeover.
To add a photo-resistor you also need a resistor of around 10k value, You can see how I connected them in the diagram to the left. The other thing that you will find in my sketch is a small collection of animations that I programmed. There are various fades, wipes and other animations. Some are used in the startup sequence the clock goes through. Some I used during the clock setting routine. Some did not make the final cut at all but I decided to leave them in the sketch for use later or if anyone else thinks that they are cool. Please feel free to use any of my code if it helps you out. Just be aware that it is probably not the best optimised code out there as it represents pretty much all of my knowledge at this moment in time! // ***************************************************************** // * Arduino Cloc Ver 1 * // * A Maxim DS1307 based clock which displays on a Maxim MAX7221/ * // * MAX9219 based Serially Interfaced, 8-Digit, 7-Segment, LED * // * Display for Arduino. The clock is set via a cheap mechanical * // * rotary encoder with push switch. Display brightness is set * // * based on the value returned by a Photo-Resistor. No alarm * // * function in this version, but lots of eye candy! * // * ----------------------------------------------------------- * // * Written by Blair Thompson www.justblair.co.uk * // * Thanks to John Boxal for his tutorial at * // * http://tronixstuff.wordpress.com/ * // * and to Sunbox for posting his rotary encoder library here * // * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1205879808 * // * I modified his library only to add keyword higlighting * // ***************************************************************** // ************************** Includes ***************************** #include <LedControl.h> // Adds DS7221/7219 function #include "Wire.h" // We use this library to talk to the DS1307 #include "RotaryEncoder.h" // This is a library for cheap mechanical rotary encoders // it debounces the switch contacts of the encoder // ******************* Declare Some Constants ********************** //Lets start with the pinouts to the Max72xx led driver const byte DIN = 12; // Pin 1 on the Max72xx const byte CLK = 11; // Pin 13 on the Max72xx const byte LOADCS = 10; // Pin 12 on the Max72xx // select the pin for the LED, we will flash the lights to show that we are in set mode const byte led_pin = 13; // Its the built in LED on the Arduino // Now the pins of the Rotary Encoder... It's one of those with the push buttons const byte DATA_A = 3; const byte DATA_B = 4; const byte PUSH = 2; const byte pot_pin = 0; // Photo-resistor const int DS1307_I2C_ADDRESS = 0x68; // This is the address of the DS1307 on the I2C bus // *********** define the RotaryEncoder instance ********************* RotaryEncoder rotary(DATA_A, DATA_B, PUSH); // declare pins(data A, data B, Push Button) // ************* define the LedControl instance ********************** // if I want more I can setup lc2, lc3 etc LedControl lc=LedControl(DIN,CLK,LOADCS,1); // DIN, CLK, Load/CS, 1 = only one chip MAX chip attached. // ***************** We need a few variables as well***************** // Need some variables to store the time byte second, minute, hour, day_of_week, day_of_month, month, year, sqwe, bst_flag; byte serial_debug = 1; // if "1" it switches on the debug messages to the serial port byte serial_show_time = 1; // If "1" it switches on time updates to the serial port byte chip_id = 0; // This is not strictly reqd, but if using more than one display this will be needed byte led_brightness = 10; // range is 0-15. 0=lowest, 15 = full power byte row = 0; // Set the starting position int val = 0; // Variable to store the data from the serial port byte test_delay = 50; // Sets the speed of the animations int photo_value = 0; // Variable to store the data from the photo-resistor // **************************************************************** // * Lets do the setup for one time only * // **************************************************************** void setup() // once only, lets make the pins outputs { pinMode(led_pin, OUTPUT); pinMode(DIN, OUTPUT); pinMode(CLK, OUTPUT); pinMode(LOADCS, OUTPUT); // take pins out of power save mode. No updates otherwise. for(int index=0;index<lc.getDeviceCount();index++) { lc.shutdown(index,false); } lc.setIntensity(0,led_brightness ); //set the brightness Wire.begin(); rotary.minimum(0); rotary.maximum(60); rotary.position(30); Serial.begin(9600); LEDTest(); // Before we get started, we will call the current time into the Arduino get_date_DS1307(&second, &minute, &hour, &day_of_week, &day_of_month, &month, &year, &sqwe, &bst_flag); } // **************************************************************** // * The Main Loop... This just keeps going round and round * // **************************************************************** void loop() { // here comes the good stuff, the main loop! // First lets find out if the clocks need to go forward? // Check to see if it's the last Sunday in March with an IF/AND statement if (bst_flag == 0 && month == 3 && day_of_week == 1 && day_of_month >24 && hour >0){ bst_start (); } // Second, perhaps they need to go back? // Something similar to before if (bst_flag == 1 && month == 10 && day_of_week == 1 && day_of_month >23 && hour >0){ bst_end (); } // We will measure the photoresistor and adjust the display brightness // read the photo_value of the potentiometer (photo_valueue between 0 and 1023) // and then use the map command to inverse/scale the result and set brightness. photo_value = analogRead(pot_pin); // Read led_brightness = map(photo_value, 0, 1023, 15, 0); // Map lc.setIntensity( 0, led_brightness); // Set the brightness // Now a quick check to see if the Rotary Encoders Button has been pressed if (rotary.pressed()){ Set(); // Go to the "Set" routine and set the time and date } // We can also run the test routine by typing "t" from the serial monitor if( Serial.available() ) { val = Serial.read(); // read the serial port if(val =='t'){ // If "t" is pressed in the Serial Monitor, LEDTest(); // run the test. } if(val =='s'){ // If "s" is pressed in the Serial Monitor, scrolling_marque(); // Scroll "Arduino Cloc" on the LED } } // On the 5th second of each minute, we will display the date if (second == 5){ led_print(day_of_month, 6); // Print the hour lc.setChar(chip_id, 5, '-', false); // Print the divider led_print(month, 3); // Now the minutes lc.setChar(chip_id, 2, '-', false); // Another divider led_print(year, 0); // And the year delay (2000); // And pause for 2 seconds if (serial_debug == 1){ // Print to the Serial Port Serial.print (day_of_month); // if debug is on. Serial.print ('-'); Serial.print (month); Serial.print ('-'); Serial.println (year); } } // ************************************************************** // * Display the time, this just keeps looping unless * // * there is an event such as a serial message recd * // * or the rotary encoder is pressed * // ************************************************************** get_date_DS1307(&second, &minute, &hour, &day_of_week, &day_of_month, &month, &year, &sqwe, &bst_flag); // Captures the current time from the Maxim clock IC led_print(hour, 6); // Print the hour lc.setChar(chip_id, 5, '-', false); // Print the divider led_print(minute, 3); // Now the minutes lc.setChar(chip_id, 2, '-', false); // Another divider led_print(second, 0); // And the seconds just to make it look exciting! // This bit sends the time to the serial port if (serial_show_time == 1){ Serial.print(hour, DEC);// convert the byte variable to a decimal number when being displayed Serial.print(":"); if (minute<10){ Serial.print("0"); } Serial.print(minute, DEC); Serial.print(":"); if (second<10){ Serial.print("0"); } Serial.print(second, DEC); Serial.print(" "); Serial.print(day_of_month, DEC); Serial.print("/"); Serial.print(month, DEC); Serial.print("/"); Serial.print(year, DEC); Serial.print(" Day of week:"); switch(day_of_week){ case 1: Serial.print("Sunday"); break; case 2: Serial.print("Monday"); break; case 3: Serial.print("Tuesday"); break; case 4: Serial.print("Wednesday"); break; case 5: Serial.print("Thursday"); break; case 6: Serial.print("Friday"); break; case 7: Serial.print("Saturday"); break; } } if (serial_debug == 1){ Serial.print(" - Summertime? "); Serial.println(bst_flag, DEC); delay(100); } } // ***************************************************************** // * This function can be called to set the time via Encoder * // * It is a little long winded, but as well as setting the time * // * it checks to see if it's Summer-Time as well and records it * // ***************************************************************** void Set(){ digitalWrite(led_pin, HIGH); // Sets a LED to on to indicate we are in set mode byte set_second, set_minute, set_hour, set_day_of_week, set_day_of_month, set_month, set_year, set_bst_flag; // set variables that we can store the newly inputted dates. I could have reused the variables // from the time routine, but I decided that having new ones might be more flexible if I want to // reuse this routine in other projects set_second = second; // moves the current time over into my "set" variables. set_minute = minute; // I do this because I dont want to set the time from set_hour = hour; // scratch each time... for instance in a set_day_of_week = day_of_week; set_day_of_month = day_of_month; set_month = month; set_year = year; wipe_led_down(false); // A brief transition which also doubles up as debounce to the rotary encoders push switch byte set_progress = 0; // This just controls the progress of the set routine rotary.minimum(0); // This sets the max and min values the rotary rotary.maximum(23); // encoder can return when we set the hours rotary.position(set_hour); // Set the rotary encoder starting position to match prev time while (set_progress ==0){ lc.setChar(0, 7, '5',false); // If you squint your eyes, the first three digits lc.setChar(0, 6, 'e',false); // almost read "SET" lc.setRow(0, 5, 70); // That makes a "T" led_print (rotary.position(), 3); // The rotary encoder position will be displayed on the LED lc.setChar(chip_id, 2, '-', false); // Print the divider led_print(minute, 0); // Pop the minutes in positions 0 and 1 if (rotary.pressed()){ // We have selected the value we want, store the value set_hour = rotary.position(); set_progress++; // ....and progress to the next level if (serial_debug == 1){ // Send a message to make sure! Serial.print ("Hour Set to "); Serial.println (set_hour, DEC); } } } wipe_led_rl(false); // Another transition which also doubles up as debounce to the rotary encoders push switch rotary.minimum(0); // This sets the max and min values the rotary rotary.maximum(59); // encoder can return when we set the minutes rotary.position(set_minute); // Set the rotary encoder starting position to match prev time while (set_progress == 1){ lc.setChar(0, 7, '5',false); // If you squint your eyes, the first three digits lc.setChar(0, 6, 'e',false); // almost read "SET" lc.setRow(0, 5, 70); // That makes a "T" led_print (set_hour, 3); lc.setChar(chip_id, 2, '-', false); // Print the divider led_print(rotary.position(), 0); if (rotary.pressed()){ set_minute = rotary.position(); set_progress++; if (serial_debug == 1){ // Send a message to make sure! Serial.print ("Min Set to "); Serial.println (set_minute, DEC); } } } wipe_led_rl(false); // Another transition which also doubles up as debounce to the rotary encoders push switch rotary.minimum(0); // This sets the max and min values the rotary rotary.maximum(31); // encoder can return when we set the minutes rotary.position(set_day_of_month); // Set the rotary encoder starting position to match prev date while (set_progress ==2){ led_print(rotary.position(), 6); lc.setChar(chip_id, 5, '-', false); // Print the divider led_print(month, 3); lc.setChar(chip_id, 2, '-', false); // Another divider led_print(year, 0); if (rotary.pressed()){ set_day_of_month = rotary.position(); set_progress++; if (serial_debug == 1){ // Send a message to make sure! Serial.print ("Day Set to "); Serial.println (set_day_of_month, DEC); } } } wipe_led_rl(false); rotary.minimum(0); rotary.maximum(12); rotary.position(set_month); while (set_progress ==3){ led_print(set_day_of_month, 6); lc.setChar(chip_id, 5, '-', false); // Print the divider led_print(rotary.position(), 3); lc.setChar(chip_id, 2, '-', false); // Another divider led_print(year, 0); if (rotary.pressed()){ set_month = rotary.position(); set_progress++; } } wipe_led_rl(false); rotary.minimum(0); rotary.maximum(12); rotary.position(set_month); while (set_progress ==3){ led_print(set_day_of_month, 6); lc.setChar(chip_id, 5, '-', false); // Print the divider led_print(rotary.position(), 3); lc.setChar(chip_id, 2, '-', false); // Another divider led_print(year, 0); if (rotary.pressed()){ set_month = rotary.position(); set_progress++; } } wipe_led_rl(false); rotary.minimum(0); rotary.maximum(99); rotary.position(set_year); while (set_progress ==4){ led_print(set_day_of_month, 6); lc.setChar(chip_id, 5, '-', false); // Print the divider led_print(set_month, 3); lc.setChar(chip_id, 2, '-', false); // Another divider led_print(rotary.position(), 0); if (rotary.pressed()){ set_year = rotary.position(); set_progress++; } } wipe_led_rl(false); rotary.minimum(1); rotary.maximum(7); rotary.position(set_day_of_week); while (set_progress == 5){ lc.setChar(chip_id, 7, 'd', false); lc.setChar(chip_id, 6, 'a', false); // Another divider lc.setRow(0, 5, 59); led_print(rotary.position(), 0); if (rotary.pressed()){ set_day_of_week = rotary.position(); set_progress++; } } if (set_month > 10 || set_month < 3 || (set_month == 10 && (set_day_of_month - set_day_of_week) > 22) || (set_month == 3 && (set_day_of_month - set_day_of_week)<24)){ Serial.println ("Winter"); set_bst_flag = 0; } else{ Serial.println ("Summer"); set_bst_flag =1; } wipe_led_lr(true); second = 0; // not going to bother with a user input for seconds setDateDs1307(second, set_minute, set_hour, set_day_of_week, set_day_of_month, set_month, set_year, set_bst_flag); val=0; digitalWrite(led_pin, LOW); } // ***************************************************************** // * Special Effects Functions * // * Just some eye candy really to handle transisitons on the * // * MAX7221/MAX7219 based display. Not all are used in the * // * sketch, but I left them in so that you can play with them * // ***************************************************************** // ************ Cause we have to show off sometimes **************** void LEDTest (){ word_arduino (); wipe_led_lr(false); word_cloc(); wipe_led_lr(false); wipe_led_one_by_one(true); wipe_led_rl(false); wipe_led_lr(true); wipe_led_up(false); wipe_led_down(true); val=0; } // ****************** Display the word "Arduino" ******************* void word_arduino (){ lc.clearDisplay(chip_id); lc.setRow(chip_id, 7, 119); // "A" delay(test_delay); lc.setRow(chip_id, 6, 5); // "r" delay(test_delay); lc.setRow(chip_id, 5, 61); // "d" delay(test_delay); lc.setRow(chip_id, 4, 28); // "u" delay(test_delay); lc.setRow(chip_id, 3, 4); // "i" delay(test_delay); lc.setRow(chip_id, 2, 21); // "n" delay(test_delay); lc.setRow(chip_id, 1, 29); // "0" delay(test_delay); lc.setRow(chip_id, 0, 0); // " " delay(1000); } // ******************* Display the word "cloc" ********************* void word_cloc(){ lc.clearDisplay(chip_id); lc.setRow(chip_id, 5, 78); // "C" delay(test_delay); lc.setRow(chip_id, 4, 6); // "l" delay(test_delay); lc.setRow(chip_id, 3, 29); // "o" delay(test_delay); lc.setRow(chip_id, 2, 13); // "c" delay(1000); } // ****************** Scrolling Marque ***************************** void scrolling_marque(){ byte title_text[] = { 0,0,0,0,0,0,0,119, 5, 61, 28, 4, 21, 29, 0, 78, 6, 29, 13, 0,0,0,0,0,0,0,0 }; byte digit_count = 8; for (byte count = 0; count < 20; count++){ int this_digit = 0; lc.setRow (chip_id, 7, title_text[count]); lc.setRow (chip_id, 6, title_text[count+1]); lc.setRow (chip_id, 5, title_text[count+2]); lc.setRow (chip_id, 4, title_text[count+3]); lc.setRow (chip_id, 3, title_text[count+4]); lc.setRow (chip_id, 2, title_text[count+5]); lc.setRow (chip_id, 1, title_text[count+6]); lc.setRow (chip_id, 0, title_text[count+7]); delay(test_delay*4); } } // *************** Wipe the screen to empty or full **************** // Right to Left void wipe_led_rl (boolean on){ for (int r=0; r<=7; r++){ lc.setRow(chip_id, r, on); delay(test_delay); } } // ******************** Left to Right ***************************** void wipe_led_lr (boolean on){ for (int r=7; r>=0; r--){ int x=0; if(on==true){ x=255; } lc.setRow(chip_id, r, x); delay(test_delay); } } // ************************ Top to Bottom ************************** void wipe_led_down (boolean on){ int x=0; if(on==true){ x=255; } lc.setColumn(chip_id, 1, x); delay(test_delay); lc.setColumn(chip_id, 2, x); lc.setColumn(chip_id, 6, x); delay(test_delay); lc.setColumn(chip_id, 7, x); delay(test_delay); lc.setColumn(chip_id, 5, x); lc.setColumn(chip_id, 3, x); delay(test_delay); lc.setColumn(chip_id, 4, x); lc.setColumn(chip_id, 0, x); delay(test_delay); } // ******************* Bottom to Top ******************************* void wipe_led_up (boolean on){ int x=0; if(on==true){ x=255; } lc.setColumn(chip_id, 4, x); lc.setColumn(chip_id, 0, x); delay(test_delay); lc.setColumn(chip_id, 3, x); lc.setColumn(chip_id, 5, x); delay(test_delay); lc.setColumn(chip_id, 7, x); delay(test_delay); lc.setColumn(chip_id, 6, x); lc.setColumn(chip_id, 2, x); delay(test_delay); lc.setColumn(chip_id, 1, x); delay(test_delay); } // ***************** Super Duper, Led by Led *********************** void wipe_led_one_by_one(boolean on){ for (int r=7; r>=0; r--){ lc.setLed(chip_id, r, 0, on); delay(test_delay); } for (int r=0; r<=7; r++){ lc.setLed(chip_id, r, 1, on); delay(test_delay); } for (int r=7; r>=0; r--){ lc.setLed(chip_id, r, 2, on); delay(test_delay); } for (int r=0; r<=7; r++){ lc.setLed(chip_id, r, 3, on); delay(test_delay); } for (int r=7; r>=0; r--){ lc.setLed(chip_id, r, 4, on); delay(test_delay); } for (int r=0; r<=7; r++){ lc.setLed(chip_id, r, 5, on); delay(test_delay); } for (int r=7; r>=0; r--){ lc.setLed(chip_id, r, 6, on); delay(test_delay); } for (int r=0; r<=7; r++){ lc.setLed(chip_id, r, 7, on); delay(test_delay); } } // ****************** Fade Bright or Dull *********************** void fade_led (boolean on){ if(on==true){ int brightlevel = 0; while (brightlevel<led_brightness){ lc.setIntensity(0,brightlevel ); //set the brightness delay(test_delay*2); Serial.println(brightlevel); brightlevel++; } } else{ int brightlevel = led_brightness; while (brightlevel>=0){ lc.setIntensity(0,brightlevel ); //set the brightness delay(test_delay*2); Serial.println(brightlevel); brightlevel--; } } if (serial_debug == 1){ Serial.print("fade"); } } // ***************************************************************** // * Print the numbers function * // * This function takes 2 digit numbers, turns them into a pair * // * of 1 digit numbers and sends them to the MAX7221 * // ***************************************************************** void led_print(int time_int, int pos){ // Ask for the number and the position to print byte ones, tens; // A couple of variables to fill with digits ones=time_int%10; // %10 divides by ten and extracts the remainder tens=time_int/10%10; // Handy for splitting the digits in two for printing lc.setDigit(chip_id, pos, (byte) ones, false); // These two lines send the digits to the Max7221 lc.setDigit(chip_id, pos+1, (byte) tens, false); // one by one } // ***************************************************************** // * These functions talk to the DS1307 * // * Based on code from tronixstuff.com/tutorials in turn based * // * based on code by Maurice Ribble 17-4-2008 - * // * http://www.glacialwanderer.com/hobbyrobotics * // ***************************************************************** // Convert normal decimal numbers to binary coded decimal // The DS1307 stores most of the units it uses in this format byte dec_to_bcd(byte val){ return ( (val/10*16) + (val%10) ); } // Convert binary coded decimal to normal decimal numbers byte bcd_to_dec(byte val){ return ( (val/16*10) + (val%16) ); } // Gets the date and time from the ds1307 void get_date_DS1307( byte *second, byte *minute, byte *hour, byte *day_of_week, byte *day_of_month, byte *month, byte *year, byte *sqwe, byte *bst_flag) { // Reset the register pointer, this tells the DS1307 where we want to // start reading from (ie, where the time is stored on the chip) Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.send(0); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 9); // Ask for 9 bytes from the DS1307 // A few of these need masks because certain bits are control bits *second = bcd_to_dec(Wire.receive() & 0x7f); *minute = bcd_to_dec(Wire.receive()); *hour = bcd_to_dec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm *day_of_week = bcd_to_dec(Wire.receive()); *day_of_month= bcd_to_dec(Wire.receive()); *month = bcd_to_dec(Wire.receive()); *year = bcd_to_dec(Wire.receive()); *sqwe = Wire.receive(); // I was lazy here, I'm reading the Square Wave control so I dont have to address the Ram // in a seperate read cycle *bst_flag = Wire.receive(); // This is a flag to tell the arduino if we are in Summer-time or Standard-time if (serial_debug == 1){ // Send a message to make sure! Serial.println ("Time Read"); } // Nothing left to do, all requested bytes are read and understood } //Sends the date and time to the DS1307 void setDateDs1307( byte second, // 0-59 byte minute, // 0-59 byte hour, // 1-23 byte day_of_week, // 1-7 byte day_of_month, // 1-28/29/30/31 byte month, // 1-12 byte year, // 0-99 byte bst_flag) // 0-1 { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.send(0); // Reset the register pointer like before Wire.send(dec_to_bcd(second)); // 0 to bit 7 starts the clock (ie if there are seconds stored Wire.send(dec_to_bcd(minute)); // in the DS1307 then we are telling the time Wire.send(dec_to_bcd(hour)); Wire.send(dec_to_bcd(day_of_week)); Wire.send(dec_to_bcd(day_of_month)); Wire.send(dec_to_bcd(month)); Wire.send(dec_to_bcd(year)); Wire.send(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on 1hz square wave Wire.send(bst_flag); // 0 == standard-time 1 == summer-time Wire.endTransmission(); // Time sent to DS1307, this functions work is done if (serial_debug == 1){ // Send a message to make sure! Serial.println ("Time Sent"); } } // ***************************************************************** // * British Summer Time Correction Functions * // ***************************************************************** void bst_start (){ // Lets put the clock forward change_bst_flag(1); // Change the BST flag to Summer-time Wire.beginTransmission(DS1307_I2C_ADDRESS); // Begins talking to the DS1307 Wire.send(0x2); // Points the DS1307 to the internal address for hour Wire.send(dec_to_bcd(hour+1)); // Puts the clocks forward Wire.endTransmission(); // That's it, an hour of sleep lost in a function } void bst_end (){ // Lets put the clock back change_bst_flag(0); // Change the BST flag to Standard-time Wire.beginTransmission(DS1307_I2C_ADDRESS); // Begins talking to the DS1307 Wire.send(0x2); // Points the DS1307 to the internal address for hour Wire.send(dec_to_bcd(hour-1)); // Puts the clocks back Wire.endTransmission(); // That's it, an hour longer in bed tonight } void change_bst_flag (byte state){ // A mini function for changing the BST flag Wire.beginTransmission(DS1307_I2C_ADDRESS); // Begins talking to the DS1307 Wire.send(0x8); // Points the DS1307 to the first internal address for RAM Wire.send(state); // sets flag to say if we are in or out of summertime Wire.endTransmission(); // Thats it done, the flag is set if (serial_debug == 1){ // Send a message to make sure! Serial.println ("Flag Set"); } } So there you have it, Ver 1 laid bare. There is a little more mork still to do. The Summer Time correction functions are still pretty crude. At the moment for instance you really want your clock to be on on the key changeover dates (or within a day of them anyway depending on what day of the month Sunday lies. I would also like to add more function to the clock, an Alarm would seem to be an obvious addition Dim lights Embed Embed this video on your site |

