/*
This sketch uses Wire.h library to communicate with DS3231 module without using a dedicated DS3231 library
See YouTube channel Rudolf - 'Learn everything about the DS3231-SN Real Time Clock | Use without Arduino Library'
See https://lastminuteengineers.com/ds3231-rtc-arduino-tutorial/ for DS3231 specs and instruction
DS3231 I2C address is fixed at 0x68
24C32 EEPROM I2C address is adjustable, default is 0x57
To enable communication, both the SDA and SCL lines should have 4.7K pull-up resistors.
- These are built into the DS3231 RTC module
Battery - CR2032 (3V coin) or ML2032, LIR2032 (rechargeable)
!! NOTE !! If board uses recharging circuit. Remove resistor if you're using a CR2032 battery.
To use 24C32 EEPROM, install uEEPROMLib library.
Set date and time to 11:23:47 PM, Saturday, October 28, 2024, Alarm-1: 11:50:00 PM 28th of each month
The simulated DS1307 is automatically initialized to the current system time when starting the simulation.
It then keeps counting the time. You can override the initial time by setting the initTime attribute
to a different value. The value can be either a valid ISO 8601 date string (e.g. "2019-11-19T11:41:56Z"),
or one of the following special values:
"0" - Set the initial time to "2000-01-01T00:00:00Z"
"now" - Set the initial time to the current system time
Note that "Z" at the end of the date string indicates that the time is in UTC, and not in the local time zone. If you omit the "Z", the time will be interpreted as local time.
*/
#include <Wire.h>
#define DS1307_ADDR 0x68
// dayofWeek 1,Monday 2,Tuesday 3,Wednesday 4,Thursday 5,Friday 6,Saturday 7,Sunday
uint8_t seconds = 47, minutes = 23, hours = 11, dayofWeek = 6, dayofMonth = 28, month = 10, year = 24;
uint8_t hoursAMPM;
bool isPM = true; // 0x02 Hour regester, Bit 5 is set low(0) for AM and set high(1) for PM
void setup() {
Serial.begin(9600);
Wire.begin(); // initialize I2C communication
hoursAMPM = dectoBcd(hours); // 1st: set the hour, in this example 11 or 00001011 in BCD
// 2nd: Set the DS3231 12-hour format bit settings
// 0x02 Hour address, Bit 6 is set high(1) for 12 hour format or set low(0) for 24 hour format
hoursAMPM = hoursAMPM | 0b01000000; // or write 64, or 0x40, OR's 01000000 | 00010001 (11)
// 3rd: Is PM set to 'true'?
if (isPM) {
hoursAMPM = hoursAMPM | 0b00100000; // or write 32, or 0x20, OR's 010010001 | 00100000
}
// Set-Time by writing to DS3231
Wire.beginTransmission(DS1307_ADDR); // start communication using DS3231 hex address
Wire.write(0x00); // write to register address 0x00 the seconds register
Wire.write(dectoBcd(seconds)); // write seconds in BCD format, 0100(MSB) and 0111(LSB)
Wire.write(0x01); // write to 0x01 minutes register, not required - DS1307 moves to next register by itself
Wire.write(dectoBcd(minutes));
Wire.write(hoursAMPM);
Wire.write(dayofWeek);
Wire.write(dectoBcd(dayofMonth));
Wire.write(dectoBcd(month));
Wire.write(dectoBcd(year));
Wire.endTransmission();
}
void loop() {
Serial.print(dectoBcd(seconds), BIN);
Serial.println(" Writing " + String(seconds) + " to seconds register");
Serial.print(dectoBcd(minutes), BIN);
Serial.println(" Writing " + String(minutes) + " to minutes register");
Serial.print(hoursAMPM, BIN);
Serial.println(" bit 6, 12 hr: bit 5, PM: Writing " + String(hours) + " to hours register");
Serial.print(dayofWeek, BIN);
Serial.println(" Writing " + String(dayofWeek) + " to dayofWeek register");
Serial.print(dectoBcd(dayofMonth), BIN);
Serial.println(" Writing " + String(dayofMonth) + " to date register");
Serial.print(dectoBcd(month), BIN);
Serial.println(" Writing " + String(month) + " to month register");
Serial.print(dectoBcd(year), BIN);
Serial.println(" Writing " + String(year) + " to year register");
while(true) {
delay(1000);
}
}
// BCD (Binary Coded Decimal) Example: 47 / 10 = 4 or 00000100, shift left 4 places = 01000000
// 47 % 10 returns remainder which is 7, or 00000111
// Combined this will be 0100 + 0111 (see DS1307 datasheet)
byte dectoBcd(byte val) {
return ((val / 10 * 16) + (val % 10)); // This works the same as below
//return ((val / 10 << 4) + (val % 10)); // This works the same as above
}
// Need a fuction to turn BCD to DEC
byte bcdtoDec(byte value) {
return ((value / 16 * 10) + (value % 16));
}