On my new Arduino Opta I need the RTC. Setting it with setTime(), using the Unix time stamp, works so far. If I set a certain value and read the values RTC->TR and RTC->DR, all TR values are reasonable, from RTC-DR the day also.
But month and year I can't understand:
month: expecting 9, it's 0x89; expecting 10, it's 0xB0 or 0xD0
year: expecting 29, it's 0x61; expecting 30, it's 62
What is the fault in my interpretation? How can I find out the year and the month out of RTC->DR?
// Hardware: Arduino Opta Lite (Finder)
// IDE: Arduino, Version 2.3.4 (on OS Linux Mint)
#include <TimeLib.h> // Library Time by Michael Margolis
#include <mbed.h>
// Variables
int actU;
void setup() {
// setup Serial
Serial.begin(9600);
while (!Serial);
Serial.println();
Serial.println("Serial working");
// set RTC (intern)
actU = 1887117330; // 2029-10-19 15:15:30
set_time(actU);
Serial.print("RTC set to Unix Time "); Serial.print(actU); Serial.println(" (2029-10-19 15:15:30)");
// print raw register values
Serial.print("RTC->TR (HEX): 0x");
Serial.println(RTC->TR, HEX);
Serial.print("RTC->TR (BIN): ");
Serial.println(RTC->TR, BIN);
Serial.print("RTC->DR (HEX): 0x");
Serial.println(RTC->DR, HEX);
Serial.print("RTC->DR (BIN): ");
Serial.println(RTC->DR, BIN);
}
void loop() {
delay(1000);
}
Output (3 examples):
Serial working
RTC set to Unix Time 1918653330 (2030-10-19 15:15:30)
RTC->TR (HEX): 0x151530
RTC->TR (BIN): 101010001010100110000
RTC->DR (HEX): 0x62D019
RTC->DR (BIN): 11000101101000000011001
Serial working
RTC set to Unix Time 1916061330 (2030-09-19 15:15:30)
RTC->TR (HEX): 0x151530
RTC->TR (BIN): 101010001010100110000
RTC->DR (HEX): 0x628919
RTC->DR (BIN): 11000101000100100011001
Serial working
RTC set to Unix Time 1887117330 (2029-10-19 15:15:30)
RTC->TR (HEX): 0x151530
RTC->TR (BIN): 101010001010100110000
RTC->DR (HEX): 0x61B019
RTC->DR (BIN): 11000011011000000011001
Hi @Apus . There are reserved bits inside the register and an addition to year, subtraction from month plus weekday, all in bcd. Check this code that reads the reg to better understand the structure.
Thank you! Coding of the year I understood, coding of the ones of the month number I found out, see code below.
But the relation between the decs of the month and the corresponding Hex number is not clear to me:
month HEX
1 81
12 72
10 B0
11 D1
12 32
1 41
2 62
3 83
9 E9 or 89
10 30 or D0
What's the meccano?
// Hardware: Arduino Opta Lite (Finder)
// IDE: Arduino, Version 2.3.4 (on OS Linux Mint)
#include <TimeLib.h> // Library Time by Michael Margolis
#include <mbed.h>
// Variables
int actU;
void setup() {
// setup Serial
Serial.begin(9600);
while (!Serial);
Serial.println();
Serial.println("Serial working");
// set RTC
actU = 1885507170; // (see line 20)
set_time(actU);
Serial.print("RTC set to Unix Time "); Serial.print(actU); Serial.println(" (30 September 2029 23:59:30)");
}
void loop() {
// print RTC-DR register to find out, how the month is codes
Serial.print("RTC->DR (HEX): 0x");
Serial.println(RTC->DR, HEX);
uint32_t dr = RTC->DR;
uint32_t tr = RTC->TR;
uint8_t myYearOnes = dr >> 16 & 0x0F;
uint8_t myYearDecs = dr >> 20;
uint16_t myYear = myYearOnes + 10 * myYearDecs + 1968;
uint8_t myMonthOnes = dr >> 8 & 0x0F;
uint8_t myMonthDecs = 0; // tbd!!!
uint8_t myMonth = myMonthOnes + 10 * myMonthDecs;
uint8_t myDayOnes = dr & 0x0F;
uint8_t myDayDecs = dr >> 4 & 0x0F;
uint8_t myDay = myDayOnes + 10 * myDayDecs;
uint8_t myHourOnes = tr >> 16 & 0x0F;
uint8_t myHourDecs = tr >> 20;
uint8_t myHour = myHourOnes + 10 * myHourDecs;
uint8_t myMinuteOnes = tr >> 8 & 0x0F;
uint8_t myMinuteDecs = tr >> 12 & 0x0F;
uint8_t myMinute = myMinuteOnes + 10 * myMinuteDecs;
uint8_t mySecOnes = tr & 0x0F;
uint8_t mySecDecs = tr >> 4 & 0x0F;
uint8_t mySec = mySecOnes + 10 * mySecDecs;
Serial.print("RTC->DR and ->TR converted: "); Serial.print(myYear); Serial.print("-");
Serial.print(myMonth); Serial.print("-"); Serial.print(myDay); Serial.print(" ");
Serial.print(myHour); Serial.print(":"); Serial.print(myMinute); Serial.print(":");
Serial.println(mySec); Serial.println();
delay(10000);
}
Thank you, Steve9, now it works perfectly!
My fault was taking bits 15:12 for Month tens in BCD instead of taking only bit 12.
So I could append also the weekday (see following code).
// IDE: Arduino, Version 2.3.4 (on OS Linux Mint)
#include <TimeLib.h> // Library Time by Michael Margolis
#include <mbed.h>
// Variables
int actU;
void setup() {
// setup Serial
Serial.begin(9600);
while (!Serial);
Serial.println();
Serial.println("Serial working");
// set RTC
actU = 1893455980; // (i.e. from https://www.epochconverter.com/)
set_time(actU);
Serial.print("RTC set to Unix Time "); Serial.print(actU); Serial.println(" (31 December 2029 23:59:40)");
}
void loop() {
// print RTC-DR register to find out, how the month is codes
Serial.print("RTC->DR (HEX): 0x");
Serial.println(RTC->DR, HEX);
uint32_t dr = RTC->DR;
uint32_t tr = RTC->TR;
uint8_t myYearUnits = dr >> 16 & 0x0F;
uint8_t myYearTens = dr >> 20;
uint16_t myYear = myYearUnits + 10 * myYearTens + 1968;
uint8_t myMonthUnits = dr >> 8 & 0x0F;
uint8_t myMonthTens = dr >> 12 & 0x1;
uint8_t myMonth = myMonthUnits + 10 * myMonthTens;
uint8_t myDayUnits = dr & 0x0F;
uint8_t myDayTens = dr >> 4 & 0x03;
uint8_t myDay = myDayUnits + 10 * myDayTens;
uint8_t myWeekday = dr >> 13 & 0x7;
uint8_t myHourUnits = tr >> 16 & 0x0F;
uint8_t myHourTens = tr >> 20;
uint8_t myHour = myHourUnits + 10 * myHourTens;
uint8_t myMinuteUnits = tr >> 8 & 0x0F;
uint8_t myMinuteTens = tr >> 12 & 0x0F;
uint8_t myMinute = myMinuteUnits + 10 * myMinuteTens;
uint8_t mySecUnits = tr & 0x0F;
uint8_t mySecTens = tr >> 4 & 0x0F;
uint8_t mySec = mySecUnits + 10 * mySecTens;
Serial.print("RTC->DR and ->TR converted: "); Serial.print(myYear); Serial.print("-");
Serial.print(myMonth); Serial.print("-"); Serial.print(myDay); Serial.print(" ");
Serial.print(myHour); Serial.print(":"); Serial.print(myMinute); Serial.print(":");
Serial.print(mySec); Serial.print(", WD "); Serial.println(myWeekday); Serial.println();
delay(10000);
}
The output for example for 2029-12-31 23:59:40 and following is:
Serial working
RTC set to Unix Time 1893455980 (31 December 2029 23:59:40)
RTC->DR (HEX): 0x613231
RTC->DR and ->TR converted: 2029-12-31 23:59:40, WD 1
RTC->DR (HEX): 0x613231
RTC->DR and ->TR converted: 2029-12-31 23:59:50, WD 1
RTC->DR (HEX): 0x624101
RTC->DR and ->TR converted: 2030-1-1 0:0:0, WD 2
RTC->DR (HEX): 0x624101
RTC->DR and ->TR converted: 2030-1-1 0:0:10, WD 2
So you solved my problem and I can continue with the Arduino Opta. Tank you!