Hi everybody,
I want to use a Seeeduino XIAO-board which has a SAMD21-µC to create one-time-passwords ( OTP )
There is a demo-code for OTPs that uses the library swRTC which is written for AVR-boards.
The TOTP-library needs the time in this format
long GMT = rtc.getTimestamp();
This is the complete demo-code
// GetCode.ino
//
// Basic example for the TOTP library
//
// This example uses the opensource SwRTC library as a software real-time clock
// you can download from https://github.com/leomil72/swRTC
// for real implementation it's suggested the use of an hardware RTC
#include "sha1.h"
#include "TOTP.h"
#include "swRTC.h"
// The shared secret is MyLegoDoor
uint8_t hmacKey[] = {0x4d, 0x79, 0x4c, 0x65, 0x67, 0x6f, 0x44, 0x6f, 0x6f, 0x72};
TOTP totp = TOTP(hmacKey, 10);
swRTC rtc;
char code[7];
void setup() {
Serial.begin(9600);
rtc.stopRTC();
// Adjust the following values to match the current date and time
// and power on Arduino at the time set (use GMT timezone!)
rtc.setDate(27, 8, 2013);
rtc.setTime(21, 25, 00);
rtc.startRTC();
}
void loop() {
long GMT = rtc.getTimestamp();
char* newCode = totp.getCode(GMT);
if(strcmp(code, newCode) != 0) {
strcpy(code, newCode);
Serial.println(code);
}
}
The swRTC-function getTimestamp() is defined like this.
The comment
//returns a timestamp giving the number of seconds since a part year
is not really clear to me
//returns a timestamp giving the number of seconds since a part year (default=1970)
unsigned long swRTC::getTimestamp(int yearT){
unsigned long time=0;
//check the epoch
if (yearT == 0) {
yearT = 1970;
} else if (yearT < 1900) {
yearT = 1900;
} else if (yearT > 1970) {
yearT = 1970;
} else if ((yearT != 1900) && (yearT != 1970)) {
yearT = 1970;
}
//One revolution of the Earth is not 365 days but accurately 365.2422 days.
//It is leap year that adjusts this decimal fraction. But...
time += (getYear() - yearT) * 365.2422;
for (byte i = 0; i < getMonth() - 1; i++){
time += daysPerMonth[i]; //find day from month
}
time = (time + getDay()) * 24UL; //find hours from day
time = (time + getHours()) * 60UL; //find minutes from hours
time = (time + getMinutes()) * 60UL; //find seconds from minute
time += getSeconds(); // add seconds
if (time > 951847199UL) { time += 86400UL; } //year 2000 is a special leap year, so 1 day must be added if date is greater than 29/02/2000
//the code below checks if, in case of a leap year, the date is before or past the 29th of februray:
//if no, the leap day hasn't been yet reached so we have to subtract a day
if (isLeapYear(getYear())) {
if (getMonth() <= 2 ) {
time -= 86400UL;
}
}
return (time - 86400UL); //because years start at day 0.0, not day 1.
}
I'm not familiar with unix-time-things like epoc etc.
looks like number of seconds since 1970??
The software RTC for the SAMD21
has different functions so this is no drop-in replacement.
what is the name of this timeformat that the function
swRTC::getTimestamp(int yearT)
returns?
Which libraries / functions do I have to use to transform the time-format delivered by the RTC_SAMD21.h-library to get the swRTC-time-format?
or as a different approach:
How could I transform the swRTC.h with all its functions into a hardware-independent version that counts up time based on the universal available function millis()?
I want to explain a bit more on that:
I mean not an independant running RTC that is able to work in the backround. This is what makes it hardware-dependant through the use if timer-interrupts.
I mean a version where I the user is responsible to code in a way to call a tick-function often enough that the RTC-variables keep track of time on a precisionlevel of seconds.
For creating one time passwords a precision of a second is enough.
best regards Stefan