Adding Code For Daylight Savings Time

Then what is it, and what is it for?

It's a help desk.

I presume he means he is using a 3D printer to manufacture the casing for the clock. :grin:

He omitted the obligatory Web link to the project in the first post. :roll_eyes:

Here is the link to the project. Link
And yes, print time is 3D print time.

In one of my clock projects, I have inserted a switch for DST. I have written code such that, when the DST switch is turned off, the display shows the hour from the RTC; but when the DST switch is turned on, the Arduino adds 1 to the hour from the RTC and then displays the result. Sure, there is a bit more fiddly business so that the hours stay in the range 1 to 12, but that is the main idea.

My suggestion is that, after this line,

int firstHourDigit = MyDateAndTime.Hour;

you put in something like

if (digitalRead(DST_SWITCH_PIN) == LOW) {  // read DST switch
  firstHourDigit = firstHourDigit + 1;  // add 1 to the hours
  if (firstHourDigit >= 24) {  // deal with midnight
    firstHourDigit = 0;
  }
}

Of course, this isn't the complete code. You would also have to declare DST_SWITCH_PIN equal to the number of whatever pin you are using for the switch. You would also need a pinMode statement to declare that pin as an INPUT or INPUT_PULLUP. And I haven't even gotten started on the code for secondHourDigit. But this should be enough to get you started.

Oh, and one last thing. Make sure that you are using a toggle switch, which you can flick on and off, and which stays that way (either on or off) until you flick it again. Don't just use a push-button switch which turns off as soon as you let go of it.

There are now some places that are talking about making DST time permanent. I'm thinking about adding more control options for it, in case the system changes in my country.

If you use a manual toggle switch, all you have to do is turn it on and leave it on.

1 Like

If you're interested, I have made several functions that automatically adjust the time coming from a DS3231. I am not connected to Internet and need no switches. Instead, I use the TimeLib library to convert from DS3231 format using yr/month/day/hr/min/seconds to Unix time in seconds since 1970. Then, I add 60*60 seconds during DST and reconvert back to yr/month/day/hr/min/seconds format. I also use this library to find the last Sunday in March and October to know when I adjust, or not. Here's my code:

#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
#include <TimeLib.h> //for Clockdate() t_unix_time conversion
tmElements_t te;  //Time elements structure
unsigned long int summerseconds,winterseconds;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  // set the initial time here: ONLY DO THIS ONCE!
  // Note Sunday is 1, Monday is 2 etc
  // Note put hours=ActualHours-1 if already in summer or else hours=ActualHours in winter
  // DS3231        seconds, minutes, hours, day, date, month, year
  //setDS3231time     (15,     48,      3,     2,   31,   10,    22);   
  
}

void loop() {
  unsigned long int Currentseconds;
  byte yr;
  yr=readDS3231year();
  summerseconds=findlastSunday(2000+yr,3); //summer
  winterseconds=findlastSunday(2000+yr,10); //winter  
  Currentseconds=readDS3231time();
  Currentseconds=CheckDST(Currentseconds);
  displayTime(Currentseconds);
} 

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

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

void setDS3231time(byte sec, byte Min, byte hr, byte wkday, byte monthday, byte MOnth, byte Yr)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(sec)); // set seconds
  Wire.write(decToBcd(Min)); // set minutes
  Wire.write(decToBcd(hr)); // set hours
  Wire.write(decToBcd(wkday)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(monthday)); // set date (1 to 31)
  Wire.write(decToBcd(MOnth)); // set month
  Wire.write(decToBcd(Yr)); // set year (0 to 99)
  Wire.endTransmission();
}

byte readDS3231year()
{
  byte Year;
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  // request seven bytes of data from DS3231 starting from register 00h
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  for (int i=0;i<6;i++)Wire.read();
  Year = bcdToDec(Wire.read());
  return Year;
}

unsigned long int readDS3231time()
{
  unsigned long currentseconds;
  byte DayOfWeek;
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();

  // request seven bytes of data from DS3231 starting from register 00h
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  
  te.Second = bcdToDec(Wire.read() & 0x7f);
  te.Minute = bcdToDec(Wire.read());
  te.Hour = bcdToDec(Wire.read() & 0x3f);
  DayOfWeek = bcdToDec(Wire.read());
  te.Day =  bcdToDec(Wire.read());
  te.Month = bcdToDec(Wire.read());
  te.Year = bcdToDec(Wire.read())+2000 - 1970;;
  currentseconds =  makeTime(te);
  return currentseconds;
}

void displayTime(unsigned long int CURrentseconds)
{
  int DayOfWeek=weekday(CURrentseconds);
  switch (DayOfWeek) {
    case 1:
      Serial.print("dimanche");
      break;
    case 2:
      Serial.print("lundi   ");
      break;
    case 3:
      Serial.print("mardi   ");
      break;
    case 4:
      Serial.print("mercredi");
      break;
    case 5:
      Serial.print("jeudi   ");
      break;
    case 6:
      Serial.print("vendredi");
      break;
    case 7:
      Serial.print("samedi  ");
      break;
    default:
      Serial.print(DayOfWeek);
  }
  Serial.print(day(CURrentseconds), DEC);
  Serial.print("/");
  Serial.print(month(CURrentseconds), DEC);
  Serial.print("/");
  Serial.println(year(CURrentseconds)-2000, DEC);
  

  if (hour(CURrentseconds) < 10)
  {
    Serial.print("0");
  }
  Serial.print(hour(CURrentseconds), DEC);
  Serial.print(":");
  if (minute(CURrentseconds) < 10)
  {
    Serial.print("0");
  }
  Serial.print(minute(CURrentseconds), DEC);
  Serial.print(":");
  if (second(CURrentseconds) < 10)
  {
    Serial.print("0");
  }
  Serial.println(second(CURrentseconds), DEC);
}


unsigned long int CheckDST(unsigned long int CUrrentseconds)
{
  if ((CUrrentseconds>summerseconds)&&(CUrrentseconds<winterseconds)) 
    return (CUrrentseconds+3600UL);
  else
    return(CUrrentseconds);
}


unsigned long int findlastSunday(int Year,int Month)
{
  unsigned long currentseconds;
  int Weekday,delta;
  int retval;
  te.Second = 0;
  te.Hour = 2; 
  te.Minute = 0;
  te.Month=Month+1;
  te.Year=Year - 1970;
  te.Day=1;
  currentseconds =  makeTime(te);
  Weekday=weekday(currentseconds);
  if (Weekday==1) delta=7;
  else delta=Weekday-1;
  currentseconds=currentseconds-(unsigned long)delta*(unsigned long)24*(unsigned long)3600; //back up to last Sunday of previous month
  return currentseconds;
}

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.