Using a DS3231 RTC as recommended by so many as the DS1307 looses time dramatically.
Unsoldered the charging resistor and used a CR2032 battery.
Changed nothing in the code as reference to the new RTC unit, also as recommended somewhere in the forum.
Originally had a strange year (2543 or similar) on startup but was going to reset anyhow.
Uncommented the manual adjust setting, set to 2534.
Thai year for 2022 is 2565 but had to set 31 years less to get it to show 2565 and all ok.
Recommented the adjust and uploaded again.
Then had second thoughts, perhaps the year set as Thai format would not cover leap years etc. so tried to revert back to year 2022.
Have never set it to this previously and it simply will not change from the 2565.
Dates times all change but not the year.
Any thoughts?.............broke something perhaps...??
Even tried the "adjust to pc time" but no change in the year there either.
Removed the memory battery and refitted but again no change.
/* Birthday Clock uses DS1307 RTC ....maybe replace later with DS3231 for better time keeping but seems ok for now
Arduino pro mini with LEDs on pin 8 and the scan switch on pin 9
I2C to 16 x 2 LCD display and to the rtc
Can add extra birthdays if required in the "People birthdays[]" ..order is their name then the day then month of their birthday
In the "scan" there probably is a better way to look and the month number in People birthdays[] but I used simple "if"
So the program runs the "clock" showing current date on the top line and time on the bottom line
When a birthday comes up, it switches over to print "Happy Birthday" top line and their name on the second line
The LEDs flash at the beginning and end of this section and then goes back to the clock display for approx 8 seconds.
If the "scan" button " is pressed and held for a few seconds, the display will run through all the names and their day and month of their birthdate.
commented out serial prints were used during testing
rtc adjust can be un-commented for adjusting the time etc. either manually as I did for Thailand or automatically for your local time via PC
So uncomment whichever, adjust and upload, then comment out and reload again (with a battery in the rtc naturally)
Changes 1/8/2022....changed char to const char in 2 places
Adding code to update the RTC each day at say 3:00AM....have to find out how much compensation is required
RTC currently running fast...................................................................................
// Start RTC drift compensation
if (time.hour == 3 && time.minute == 1 && time.second == 0) { // run daily at exactly 3:01 A.M.
delay(7000); // wait 7.0 seconds (that's 6.0 secs drift plus 1 second then reset seconds to 3:01:01 see below)
RTCTime newValue;
newValue.hour = 3;
newValue.minute = 1;
newValue.second = 1;
setTime.setValue(newValue);
}
// Time drift is approx 6 seconds gain per 24 hours. The extra one second is to prevent the program from being stuck
// in an endless loop. Formula is time drift <in seconds> + 1 second leeway + set time to 1 min, 1 second past the hour.
// This will result in the clock being put back 6 seconds at 3:00:01 every morning. Adjust formula accordingly..............THIS DIDNT WORK ......came up with compile error on time.hour
Another approach perhaps try this........RTC.adjust( RTC.now() + 60 ) ;1 minute forward perhaps.....not yet done ...still pissing around with the idea
Changes 3/8/2022....include hd44780 library...much better choice for LCD's....commented out old code with date
44780 library here...... https://github.com/duinoWitchery/hd44780 ...stored with birthdays code
8/10/2022...modoified to use DS3231 RTC....no changes in code except uncomment adjust section to adjust time manually...re-comment after use
Battery recommended rechargable LIR2032 but I take out the charge diode and use CR2032 (10 year life so that will suffice)
NOTE*****some problem when using DS3231 with the year setting......details below "adjust" line
*/
#include <Wire.h>
//#include <LiquidCrystal_I2C.h> //comment out....change to hd44780
#include <hd44780.h> // added these 2 lines
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
#include "RTClib.h"
RTC_DS1307 rtc;
//LiquidCrystal_I2C lcd(0x27, 16, 2); //comment out....change to hd44780 ...
hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip......change to hd44780.... 3/8/2022
// ************ LCD geometry ....also added these 2 lines 3/8/2022
const int LCD_COLS = 16;
const int LCD_ROWS = 2;
byte adjustButton = 10;// experiment time adjust 3/8/2022
byte adjustbuttonState;// ....added for time adjust experiment 3/8/2022
byte scanButton = 9;
byte buttonState;
byte ledPin = 8;
byte testButton = 7;
byte tbState;
//int ledState = 0;
const long interval (200);
const char daysOfTheWeek[7][12] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; // changed char to const char to move from SRAM....1/8/2022
const char monthOfYear[13][5] = {" ", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEPT", "OCT", "NOV", "DEC"};// changed char to const char to move from SRAM....1/8/2022
struct People { // set up the struct
char name[10];
byte day;
byte month;
};
const People birthdays[] = {
{"OPO", 21, 9}, // my people name, day and month of birthday
{"GRANDMA", 14, 4},
{"NAD", 20, 1},
{"TON", 1, 6},
{"TOOSAFE", 12, 5},
{"JACKPOT", 7, 3},
{"SAWITA", 3, 6},
{"JEFF", 25, 2}
};
void setup ()
{
Serial.begin(9600); // for serial monitor
pinMode(scanButton, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
pinMode(testButton, INPUT_PULLUP);
pinMode(adjustButton, INPUT_PULLUP); // experiment with time adjust 3/8/2022
//lcd.init (); // initialize the lcd
//lcd.begin();
lcd.begin(LCD_COLS, LCD_ROWS); // added this for LCD...hd44780 3/8/2022 ...end of added/changed code for hd44780 library
lcd.backlight(); // to power ON the back light
if (! rtc.begin()) // real time clock check
{
lcd.print("Couldn't find RTC");
while (1);
}
if (! rtc.isrunning())
{
lcd.print("RTC is NOT running!");
}
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));//auto update from computer time
//rtc.adjust(DateTime(2022, 10, 9, 6, 28, 0));// to set the time manually............ year (Thai plus 543...month....day.....hour(24) ...minute...second)
// ******* NOTE that I had to set year to less 31 as above to give year display of 2565 ....no idea why at this stage....possibly because of " RTC_DS1307 rtc; " ....???????
// ******** SET back to 2022...seems there may be a limit (2100) to the clock and self adjust for leap years may not work properly using extra 543 years.
digitalWrite(ledPin, LOW); // make sure led is off to begin with
}
void loop() {
adjustbuttonState = digitalRead(adjustButton); //experiment time adjust 3/8/2022
buttonState = digitalRead(scanButton); // check if scan button changed
if (buttonState == LOW) {
scanBirthdays();
}
tbState = digitalRead(testButton); //check if test button has been pressed
if (tbState == LOW) {
testButtonCode();
}
DateTime now = rtc.now(); // check rtc
// Serial.print("The year now is ");
// Serial.println(now.year());
// Serial.print("The month now is ");
// Serial.println(now.month());
// Serial.print("The day now is " );
// Serial.println(now.day());
for (uint8_t x = 0; x < sizeof (birthdays) / sizeof(birthdays[0]); x++) { // loop through list ....const People birthdays
//Serial.print ("Checking ");
//Serial.println(birthdays[x].name);
if ( birthdays[x].month == now.month() &&
birthdays[x].day == now.day()) { // see if any birthdays match todays day and month
for (int j = 0; j < 10; j++) {
digitalWrite(ledPin, HIGH); // flash LED 10 times
delay(interval);
digitalWrite(ledPin, LOW);
delay(interval);
}
//Serial.print("Happy Birthday ");
//Serial.println(birthdays[x].name);
lcd.setCursor(0, 0); //if they do then show on the LCD display
lcd.print(" HAPPY BIRTHDAY ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
lcd.print(birthdays[x].name);
lcd.print(" ");
for (int i = 0; i < 10; i++) { //flash LED 10 times again
digitalWrite(ledPin, HIGH);
delay(interval);
digitalWrite(ledPin, LOW);
delay(interval);
}
}
else {
Clock(); // jump to display clock
} // placing clock here gives 8 second clock display
// if above for loop operates
}
}
//*************************************end of loop**************************************************
void Clock() {
// print bottom line on 16 x 2 display
DateTime now = rtc.now(); // check time on real time clock
lcd.setCursor(1, 1); // display on LCD
lcd.print("TIME");
lcd.print(" ");
if (now.hour() < 10) {
lcd.print("0");
}
lcd.print(now.hour());
lcd.print(':');
if (now.minute() < 10) { // "0" leading if less than 10
lcd.print("0");
}
lcd.print(now.minute());
lcd.print(':');
if (now.second() < 10) {
lcd.print("0");
}
lcd.print(now.second());
lcd.print(" ");
//print top line on 16 x 2 display
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);
lcd.print(" ");
lcd.print(now.day());
lcd.print('/');
lcd.print(now.month());
lcd.print('/');
int thaiYear = now.year() + 543; // Thai year = +543 years
lcd.print(thaiYear);
lcd.print(" ");
delay(1000);
}
//*******************************end of "clock"******************************************************
void scanBirthdays() {
for (uint8_t x = 0; x < sizeof (birthdays) / sizeof(birthdays[0]); x++) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(birthdays[x].name); //scan the struct and look for names
lcd.print(" BIRTHDAY");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.print(birthdays[x].day); //select the one that co-incides with the number through the for loop
lcd.print(" of ");
int monthValue = birthdays[x].month;
switch (monthValue) {
case 1:
lcd.print("JANUARY");
break;
case 2:
lcd.print("FEBRUARY");
break;
case 3:
lcd.print("March ");
break;
case 4:
lcd.print("April ");
break;
case 5:
lcd.print("MAY ");
break;
case 6:
lcd.print("JUNE ");
break;
case 7:
lcd.print("JULY ");
break;
case 8:
lcd.print("AUGUST ");
break;
case 9:
lcd.print("SEPTEMBER");
break;
case 10:
lcd.print("OCTOBER ");
break;
case 11:
lcd.print("NOVEMBER ");
break;
case 12:
lcd.print("DECEMBER");
break;
default:
lcd.print("ERROR ");
break;
}
delay(4000);
}
}
void testButtonCode() {
lcd.print(" HAPPY ");
lcd.setCursor (0, 1);
lcd.print(" BIRTHDAY TEST ");
for (int i = 0; i < 20; i++) { //flash LED 20 times
digitalWrite(ledPin, HIGH);
delay(interval);
digitalWrite(ledPin, LOW);
delay(interval);
}
}
//************************************program end***********************************************