I need to synchronize two separate circuit boards working with Arduino Nano. The need is to activate one relay using Arduino-1 after 45 minutes, and another relay using Arduino-2 after 45.36 seconds. The time starts from the point of reception of input from an external switch common to both.
With ref toThis question, and from the advice ofedgar-bonet I have used one temperature-compensated RTC for timing the Arduinos externally(DS3231). I am using it's 32kHz pin from the chip for counting the ticks and in the Arduino using the interrupt to count the ticks.
The program is shown below.
float _sec = 1;float secTime = _sec * 1000UL; // second->millisuint32_t coilTime = 5 * 1000UL; // second->millisvolatile uint32_t count = 0;/* * 32768 ticks in 1 sec * 0.032768 tick in 1 us */float _multiplier = 0.032768; // 32768 Hzuint32_t _delay = secTime * _multiplier * 1000UL ;volatile bool onFlag = false;ISR(INT1_vect, ISR_NOBLOCK) { count = count + 1UL; if (_delay == count) { PORTC |= (1 << 5); onFlag = true; EIMSK = 0; }}ISR(INT0_vect) { /* INTERRUPT re-initalization */ EIMSK = 0; EICRA = B00001100; // INT0 - clear ; INT1 - set EIFR = 0; PORTB ^= (1 << 0) | (1 << 1); // setting Green off and red on count = 0; EIMSK = B00000010; // INT0 - inactive ; INT1 - active} void setup() { Serial.begin(115200); /* PIN initialization */ DDRB |= (1 << 0) | (1 << 1); // red led and green led pinMode(3, INPUT_PULLUP); // timer unit pinMode(2, INPUT); // interrupt unit DDRC |= (1 << 3) | (1 << 4) | (1 << 5); // relay, OUT_1, OUT_2 /* LEDs state update */ PORTB &= ~(1 << 1); // red off. PORTB |= (1 << 0); // green on. PORTC &= ~(1 << 3); // A3-off /* INTERRUPT initalization */ EICRA = B00000011; // INT0 - set ; INT1 - not set EIMSK = B00000001; // INT0 - active ; INT1 - inactive EIFR = 0;}void loop() { if (onFlag) { PORTB |= (1 << 0); // setting green on delay(500); PORTC ^= (1 << 5); // PORTB ^= (1 << 0) | (1 << 1); PORTB ^= (1 << 1); // setting red off while (true) { TCCR2B = 0; count = 0; PORTB ^= (1 << 0); delay(500); } }}When running the program, the result I am expecting is the accuracy of microseconds but for:
input -> Measured value1 sec -> 1.0003877922 sec -> 2.00078420850 sec -> 50.020926833250 sec -> 250.104557792
How do I make the clock more precise? In the data sheet it is said that the clock is accurate to +- 2ppm.
- I'm not completely sure I understand your use case because, at least for the initial synchronisation, there is a connection between the 2 devices.
volatile uint32_t count . . . count = 0;beware of asynchronous non-atomic operations on multi-byte variables on an 8bit MCU. For high precision calculations, float may have limitations:float _multiplier = 0.032768;2ppm is about one second every five days.6v6gt– 6v6gt2023-01-26 12:24:35 +00:00CommentedJan 26, 2023 at 12:24 - Can you please advise me on the correct variables to be used? In the initial case, I have a common switch connected to my devices and I use that as the interrupt signal.Lawliet– Lawliet2023-01-26 15:36:33 +00:00CommentedJan 26, 2023 at 15:36
1.0000000 / (1.000387792 / 32768 ) = 32755.29776.... that makes 32755 ticks in 1 secondjsotola– jsotola2023-01-26 17:04:41 +00:00CommentedJan 26, 2023 at 17:04- 1
after 45 min and another relay using Arduino-2 after 45.36 secondsdoes not declare the necessary precision ... for example, 45.36 can be anywhere between 44.355000... and 45.364999...jsotola– jsotola2023-01-26 17:17:20 +00:00CommentedJan 26, 2023 at 17:17 - 1Instead of using floats to specify the time interval, why not specify say 1 second as 32768? At a quick glance, the loss of ticks (in comparison to your reference) seems linear at around 13 per second. Maybe try switching off timer 0 to inhibit its possibly clashing interrupts and then you'll have to find another solution for delay().6v6gt– 6v6gt2023-01-27 06:58:40 +00:00CommentedJan 27, 2023 at 6:58
2 Answers2
This may not be a proper answer to your question. Instead of telling youhow to improve the accuracy, I will show you how to measure it. Theissue is that the code you posted is doing too much stuff, and it is notclear how it could be measuring the clock accuracy. So, instead Isuggest you try the code below:
- connect a push button between pin 2 and GND
- connect the 32768 Hz signal to pin 5
- watch the built-in LED blink
const uint8_t input_pin = 5; // 32768 Hz on digital 5 = T1const uint8_t clear_pin = 2; // button to clear timervoid setup() { pinMode(input_pin, INPUT_PULLUP); pinMode(clear_pin, INPUT_PULLUP); pinMode(LED_BUILTIN, OUTPUT); // Configure Timer 1 as a counter. TCCR1A = 0; TCCR1B = _BV(CS11) | _BV(CS12); // count falling edges of T1}void loop() { // Display bit 14 of the counter on the builtin LED. if (TCNT1 & (1 << 14)) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } // Clear the counter on button press. if (digitalRead(clear_pin) == LOW) { TCNT1 = 0; }}What this sketch does is use Timer/counter 1 as a counter in order tocount the falling edges of the 32768 Hz signal. Bit 14 of the countershould then toggle at 1 Hz. This bit is output on the built-in LED tolet you check its frequency. You can use the push button to reset thephase of the blinks.
If you have a very accurate clock at hand, you can use the push buttonto synchronize the blinks with the ticks of that clock, and then see howlong it takes to get visibly out of phase. You can also synchronise theblinks of two Arduinos and see for how long they stay in sync. If youhave a scope, you could measure a tiny offset between the edges of thetwo Arduino's LEDs, then see how this offset evolves with time.
It looks like you have a drift problem (?) Some of the DS3231 RTC modules on the market have significantly more drift than the datasheet spec and the only way to know if you have one of those is to tune the aging register and test it. In a stable temperature environment you can usually get a -SN to a millisecond per day of clock drift.
This can be done with an Uno and a cheap GPS module:https://thecavepearlproject.org/2024/10/22/setting-accurate-rtc-time-with-a-gps-the-ds3231-aging-offset-to-reduce-drift/
Explore related questions
See similar questions with these tags.

