/*
This sketch uses Wire.h library to communicate with DS1307 / DS3231 module without using a dedicated library
See YouTube channel Rudolf - 'Learn everything about the DS3231-SN Real Time Clock | Use without Arduino Library'
DS1307 / DS3231 I2C address is fixed at 0x68
To enable communication, both the SDA and SCL lines should have 4.7K pull-up resistors.
- These are built into the DS1307 / DS3231 RTC module
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>
void setup() {
Wire.begin();
Serial.begin(115200);
}
void loop() {
displayDateTimeTemperatureOnSerial();
delay(1000);
}
void displayDateTimeTemperatureOnSerial() {
// Read the date and time
Wire.beginTransmission(0x68);
Wire.write(0); // Start reading from address 0 (seconds)
Wire.endTransmission();
Wire.requestFrom(0x68, 7); // Request seconds, minutes, hours, day, date, month, year
if (Wire.available()) {
byte seconds = bcdToDec(Wire.read() & 0x7F); // Mask the high bit of seconds
byte minutes = bcdToDec(Wire.read() & 0x7F);
byte hourRegister = Wire.read();
byte hours;
bool isPM = false;
Serial.print(hourRegister, BIN); Serial.print(" ");
Serial.print((20 / 16 * 10)); Serial.print(" + "); Serial.println((20 % 16));
bool is12HourMode = hourRegister & 0x40; // Check if DS3231 is in 12-hour mode
if (is12HourMode) {
Serial.println("12-hour");
isPM = hourRegister & 0x20; // Check if it's PM
hours = bcdToDec(hourRegister & 0x1F); // Mask the high three bits for 12-hour mode
}
else {
Serial.println("24-hour");
hours = bcdToDec(hourRegister & 0x3F); // 24-hour mode, mask the high two bits
}
byte day = bcdToDec(Wire.read());
byte date = bcdToDec(Wire.read());
byte month = bcdToDec(Wire.read());
int year = 2000 + bcdToDec(Wire.read());
// Read the temperature
Wire.beginTransmission(0x68);
Wire.write(0x11); // Start reading from temperature register
Wire.endTransmission();
Wire.requestFrom(0x68, 2);
byte tempMSB = Wire.read();
byte tempLSB = Wire.read();
float temperatureC = (tempMSB << 8 | tempLSB) / 256.0;
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0; // Convert to Fahrenheit
// Print to Serial Monitor
Serial.print("Date: ");
Serial.print(year);
Serial.print("-");
Serial.print(month);
Serial.print("-");
Serial.print(date);
Serial.print(" ");
Serial.println(dayOfWeekToStr(day));
Serial.print("Time: ");
Serial.print(hours);
Serial.print(":");
if (minutes < 10) Serial.print("0");
Serial.print(minutes);
Serial.print(":");
if (seconds < 10) Serial.print("0");
Serial.print(seconds);
Serial.print(is12HourMode ? (isPM ? " PM" : " AM") : ""); // Empty string if in 24-hour mode
Serial.println();
Serial.print("Temp: ");
Serial.print(temperatureC);
Serial.print(" C / ");
Serial.print(temperatureF);
Serial.println(" F");
Serial.println();
Serial.println();
}
}
byte bcdToDec(byte val) {
return ((val / 16 * 10) + (val % 16));
}
String dayOfWeekToStr(byte dayOfWeek) {
switch (dayOfWeek) {
case 1: return "Monday ";
case 2: return "Tuesday ";
case 3: return "Wednesday";
case 4: return "Thursday ";
case 5: return "Friday ";
case 6: return "Saturday ";
case 7: return "Sunday ";
default: return "Err ";
}
}