I was following a tutorial and I ran the code for displaying the date and time from a DS3231 RTC. However, it seems that the Arduino is not able to properly display these values on the serial monitor. I'm not sure what is causing this issue. I assume maybe the problem is with the decimal to binary conversion functions. How do I go about making the date & time display correctly as intended? For example the original version of the code tried to print a weekday directly from an array based on its index value, which gave a very long line of "???????????????????????????????????????????????" on the serial monitor. In order to fix it, I created a variable to store the value of whatever index was chosen from the array to be the weekday. This got rid of the long string question marks, but still does not output anything legible.
link to the tutorial: Here
#include "Wire.h"
/*
* DS3231 I2C address is:
* 1101000 R/W'
* = 0x68
*
* The Wire.h library will append the R/W' bit.
* So we only specify the first 7 bits
*/
#define DS3231_I2C_ID 0x68 //I2C address for the DS3231 RTC chip
void setup() {
Serial.begin(115200);
Wire.begin();
//the parameters are: Second, Minute, Hour, WeekDay, Day, Month, Year
//the following sets: second=45, minute=59, hour=3, weekday=Wednesday, day=29, month=April, year=2017
setDate(45, 59, 3, 4, 29, 4, 17); // 24 hour format; Sun=1
}
void loop() {
readDate();
delay(1000);
}
void setDate(byte Second, byte Minute, byte Hour, byte WeekDay, byte Day, byte Month, byte Year) {
Wire.beginTransmission(DS3231_I2C_ID);
Wire.write(0x0); // register address for the time and date
Wire.write(dec2bcd(Second));
Wire.write(dec2bcd(Minute));
// Hour must be in 24h format
bool h12 = 1; // set 12 hour mode
if(h12){ // 12 hour mode
if(Hour >= 12){
Hour = dec2bcd(Hour-12) | 0b01100000; // bit5(PM)=1; bit6(12 hour)=1
}else{
Hour = dec2bcd(Hour) & 0b11011111 | 0b01000000; // bit5(PM)=0; bit6(12 hour)=1
}
}else{ // 24 hour mode
Hour = dec2bcd(Hour) & 0b10111111;
}
Wire.write(Hour);
Wire.write(dec2bcd(WeekDay));
Wire.write(dec2bcd(Day));
Wire.write(dec2bcd(Month));
Wire.write(dec2bcd(Year));
Wire.endTransmission();
}
void readDate() {
Wire.beginTransmission(DS3231_I2C_ID);
Wire.write(0x0); // register address for the time and date
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ID, 7); // get 7 bytes
byte Second = bcd2dec(Wire.read() & 0b1111111);
byte Minute = bcd2dec(Wire.read() & 0b1111111);
byte Hour = Wire.read();
bool h12 = Hour & 0b01000000;
bool PM;
if (h12) { // 12 hour clock
PM = Hour & 0b00100000;
Hour = bcd2dec(Hour & 0b00011111);
} else { // 24 hour clock
Hour = bcd2dec(Hour & 0b00111111);
}
byte WeekDay = bcd2dec(Wire.read()); // 1=Sunday
byte Day = bcd2dec(Wire.read());
byte Month = bcd2dec(Wire.read());
byte Year = bcd2dec(Wire.read());
const char* days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
String wDay = days[WeekDay-1];
Serial.print(wDay);
Serial.print(" ");
Serial.print(Month);
Serial.print("/");
Serial.print(Day);
Serial.print("/20");
Serial.print(Year);
Serial.print(" ");
Serial.print(Hour);
Serial.print(":");
Serial.print(Minute);
Serial.print(":");
if (Second < 10) Serial.print("0");
Serial.print(Second);
if (PM) Serial.print("P");
else Serial.print("A");
Serial.println();
}
// Convert binary coded decimal (BCD) to nrmal decimal numbers
byte bcd2dec(byte val) {
return ((val/16*10) + (val%16));
}
// Convert normal decimal number to binary coded decimal
byte dec2bcd(byte val) {
return ((val/10*16) + (val%10));
}
⸮⸮ 165/165/20
165/165/20165 25:85:85P
165/165/20165 25:85:85P
165/165/20165 25:85:85P
165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P
⸮⸮ 165/165/20165 25:85:85P