I'm using the 'ELEGOO the most complete starter kit' and I am aware that the DS1307RTC isn't the most accurate RTC, however, I'm trying to make a data logger that is synced with the time on my computer. The RTC is around 10 seconds behind my computer time, so I was just wondering if I could add a bit of code to change that so the RTC is in sync with my computer clock.
Yes, most example code for use with RTC will let you do that.
There’s a couple of ways…
In the example code, you may have seen some (// commented lines) in setup(), whicb pre-set the clock to the compile date & time.
OR
If you’re skilled enough, you can set the date & time using the serial terminal… this requires extra code in your program to interact with the serial console.
OR
If you have a network or cellular connection, you can use NTP to re- sync the clock.
All these methods are applicable to any RTC module.
The problem is that there is nothing built into the IDE that allows a connected Arduino to ask for the current time from the computer through the serial monitor. At least that's the case for v1.8.xx of the IDE. Has that changed in v2 of the IDE?
Today's understatement for sure.
Best if you use a DS3231 RTC otherwise any setting you make will be inaccurate within the day.
In the Elegoo Most Complete Starter Kit (V2), the RTC example you have shows these lines...
// Send sketch compiling time to Arduino
clock.setDateTime(__DATE__, __TIME__);
... which, if you trigger those lines every hour, should take the 10 seconds daily creep down to 0.5 second (per hour).
But then you would have to recompile and upload the sketch every hour.
If it's running slow 10 seconds per day, maybe the sketch could just increment the seconds register of the RTC once every 8,640,000 millis().
Yes, you can do some code and is easy!
Here I'm using the Ds1302, I took the example code for Serial Event and changed it a bit. The way I'm updating the minutes and seconds are by sending a command like this through the serial monitor:
M12\nS34\n Where it sets the minutes to 12 and seconds to 34
The \n is a NewLine character.
#include <Ds1302.h>
Ds1302 rtc(A5, A4, A3);
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
void setup() {
// initialize serial:
Serial.begin(9600);
// reserve 200 bytes for the inputString:
inputString.reserve(200);
rtc.init();
if (rtc.isHalted())
{
Serial.println("RTC is halted.");
}
}
void loop() {
// print the string when a newline arrives:
if (stringComplete) {
Serial.print(inputString);
//Get the current time
Ds1302::DateTime now;
rtc.getDateTime(&now);
//Get the message from the PC
String sub_string = inputString.substring(1); //get the next characters after the command
int value = sub_string.toInt();
switch(inputString[0]) { //swich to the command
case 'M':
now.minute=value;
rtc.setDateTime(&now);
break;
case 'S':
now.second=value;
rtc.setDateTime(&now);
break;
//And so on for hours, days, etc.
}
//print updated time:
if (now.hour < 10) Serial.print('0');
Serial.print(now.hour); // 00-23
Serial.print(':');
if (now.minute < 10) Serial.print('0');
Serial.print(now.minute); // 00-59
Serial.print(':');
if (now.second < 10) Serial.print('0');
Serial.print(now.second); // 00-59
Serial.println(' ');
// clear the string:
inputString = "";
stringComplete = false;
}
}
/*
SerialEvent occurs whenever a new data comes in the hardware serial RX. This
routine is run between each time loop() runs, so using delay inside loop can
delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
You can update the clock manually by typing the time on the serial monitor, but if you want something more automated you could do some computer code like the next one, I just wrote it quickly and I didn't test it, but it gives you an idea.
#include <stdio.h>
#include <time.h>
#include <Windows.h> //for sleep function
#include "rs232.h"
time_t now;
struct tm *tm;
int main()
{
now = time(0); //isn't this redundant?
if ((tm = localtime (&now)) == NULL)
{
printf("Error extracting time stuff\r\n");
}
printf("Today is %04d/%02d/%02d %02d:%02d:%02d\r\n", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
send_time();
}
void send_time()
{
int comport_number=0;
RS232_OpenComport(comport_number, 9600, "8N1", 0);
Sleep(1000); //Wait 1 second for the arduino to exit the bootloader mode
unsigned char buf[10];
snprintf(buf,10,"M=%d\nS=%d\n",tm->tm_min, tm->tm_sec);
RS232_SendBuf(comport_number, buf, strlen(buf));
}
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.