Hi, I use an arduino R4 wifi to display messages on the led matrix. But every 6 messages, I want it to be used as a clock and request it to display the current time, which comes from the ArduinoCloud.getLocalTime() function.
Before each run (so roughly 1x/minute or so) , the time is imported via the ArduinoCloud.getLocalTime() function.
It seems to work well in the beginning but after a few hours I see that the time is no longer in sync, experiencing a drift of approx 10 minutes a day ( the arduino clock ticking too quickly). I read in other posts that the R4 RTC clock is far from super accurate, but I thought that importing new time from the ArduinoCloud.getLocalTime(); function - instead of relyin gon the internal RTC - would solve this.
I'm having a similar problem (Also on R4 WiFi) where the value of ArduinoCloud.getLocalTime() will increment by 1 hour every time I call RTC.setTime !
I suspect this is the timezone offset (I'm GMT+1) but it's super freaky that any function can interfere with the time retrieved from the cloud.
I have tried everything to work around this but I'm out of ideas and can't solve it.
I have read this in another topic on this forum:
"All Arduino boards are using internal RTC to store the time after the first request to the NTP server"
If that's true, we are screwed with the drifting RTC in the R4
The comment was made by Arduino them member @pennam
Maybe he can give us a fix to override the internal RTC and get the real time from the NTP server.
Hmmm, Not sure this is the same issue, as I do not use the RTC.setTime function. The drift I encounter is a few minutes per hour, which seem unrelated to a timezone issue.
What @pennam means is that only the first call to ArduinoCloud.getLocalTime() will call the NTP server and all following calls will use the internal RTC to get the time. This will explain the drift you are experiencing.
I'm rewriting my code to use the NTPclient.h library to sync internal RTC every minute. It's a shame that it has to be done this way but I don't see any other solution for now. My R4 WiFi RTC drifts 2 seconds each minute !
Thank you @pennam , this looks indeed promising.
Could you explain how to use the setSyncInterval() function? I tried to add a command setSyncInterval(10*60) in the setup function but the arduino editor did not enjoy it. Should I include a specific library for it to work?
Here my full sketch:
/*
Sketch generated by the Arduino IoT Cloud Thing "Untitled 4"
https://create.arduino.cc/cloud/things/33b5abdd-5b4b-40e8-b57c-d5e911e30de9
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
String SendText;
int compteur;
bool syncLed;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
Code wifi:
GSM:
NBB-IOS-M5W3165CFP
qca4g2zdyddm2
Maison:
Mobistar-4ac4
471088FCF66FFA672752EA365A
*/
#include "thingProperties.h"
#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"
#include "WiFiS3.h"
#define Buzzer D11 //buzzer pin
#define DEBUG 0 // set 1 for debugging; mremoves debuggibg code before compiling if not required
#if DEBUG ==1
#define debug(x) Serial.print(x)
#define debugln(x) Serial.println(x)
#else
#define debug(x)
#define debugln(x)
#endif
//unsigned long previousMillis = 0;
unsigned long previousMillis2 = 0;
const unsigned long TextInterval = 2500; //definit le temps entre 2 messages (en millisecondes)
String XXXToSendXXX;
String XXXTimeToSendXXX;
const bool DebugToggle = 0;
ArduinoLEDMatrix matrix;
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(Buzzer, OUTPUT);
digitalWrite(Buzzer, LOW);
Buzz();
matrix.begin();
//ArduinoCloud.setSyncInterval(600); //is not accepted by the arduino IDE
initProperties(); // Defined in thingProperties.h
ArduinoCloud.begin(ArduinoIoTPreferredConnection); // Connect to Arduino IoT Cloud
MatrixWrite(F(" Booting R4 Messenger OtA v1... "));
Serial.println(F("Booting Messenger OtA v1..."));
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
void loop() {
ArduinoCloud.update();
//syncingLed();
sendText();
}
void sendText() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis2 > TextInterval) //toutes les 10 secondes
{
if (compteur % 6 == 0) {
time_t UnixTime;
UnixTime = ArduinoCloud.getLocalTime();
String SentTime = ctime(&UnixTime);
debugln(SentTime);
SentTime = SentTime.substring(4, 19);
XXXTimeToSendXXX = " " + SentTime + " ";
MatrixWrite(XXXTimeToSendXXX);
}
else
{
MatrixWrite(XXXToSendXXX);
}
debug(F("compteur:"));
debugln(compteur);
compteur++;
previousMillis2 = millis();
digitalWrite(LED_BUILTIN, syncLed);
syncLed = 1 - syncLed;
}
}
void MatrixWrite(String text) //texte qui défile
{
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
matrix.textScrollSpeed(25);
matrix.textFont(Font_5x7);
matrix.beginText(0, 1, 0xFFFFFF);
matrix.println(text);
matrix.endText(SCROLL_LEFT);
matrix.endDraw();
debugln(text);
}
void Buzz() {
for (int i = 0; i < 3; i++)
{
digitalWrite(Buzzer, HIGH);
delay(50);
digitalWrite(Buzzer, LOW);
delay(50);
}
debugln(F("Buzz!"));
}
void onSendTextChange() { //qd un nouveau message est reçu...
compteur = 0;
debugln(SendText);
if (SendText == "") XXXToSendXXX = SendText;
else XXXToSendXXX = " " + SendText + " ";
Buzz();
}
void onCompteurChange() {
}
I was having a lot of trouble with the RTC and it would seem the solution lies here.
After setting the RTC using the ntpClient library (adjusting for timezone and daylight saving) the time on my project would often revert to GMT time and I'd have to call the NTP again.
Is there a way to disable the IoT TimeService? I'd like my code to keep running with my local GMT offset and DST.