user66713: I am in need to synchronize two separate circuit boards working with Arduino nano. The need is to activate one relay using Arduino-1 after 45 min 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 to This question and from the advice of edgar-bonet I have used one temperature-compensated RTC for timing the Arduino s externally (DS3231). I am using its 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->millis
uint32_t coilTime = 5 * 1000UL; // second->millis

volatile uint32_t count = 0;
/*
 * 32768 ticks in 1 sec
 * 0.032768 tick in 1 us
 */

float _multiplier = 0.032768; // 32768 Hz

uint32_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 the accuracy of microseconds
but
for
input -> Measured value
1 sec -> 1.000387792
2 sec -> 2.000784208
50 sec -> 50.020926833
250 sec -> 250.104557792
How to make the clock more precise, In the datasheet it is said that the clock is accurate to +- 2ppm.
datasheet-ds3231

user7508: This may not be a proper answer to your question. Instead of telling you
how to improve the accuracy, I will show you how to measure it. The
issue is that the code you posted is doing too much stuff, and it is not
clear how it could be measuring the clock accuracy. So, instead I
suggest 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 = T1
const uint8_t clear_pin = 2;  // button to clear timer

void 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 to
count the falling edges of the 32768 Hz signal. Bit 14 of the counter
should then toggle at 1 Hz. This bit is output on the built-in LED to
let you check its frequency. You can use the push button to reset the
phase of the blinks.
If you have a very accurate clock at hand, you can use the push button
to synchronize the blinks with the ticks of that clock, and then see how
long it takes to get visibly out of phase. You can also synchronise the
blinks of two Arduinos and see for how long they stay in sync. If you
have a scope, you could measure a tiny offset between the edges of the
two Arduino's LEDs, then see how this offset evolves with time.

66713: <p>I am in need to synchronize two separate circuit boards working with Arduino nano. The need is to activate one relay using Arduino-1 after 45 min 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.</p>
<p>with ref to <a href="https://arduino.stackexchange.com/questions/91915/arduino-nano-timing-precision">This question</a> and from the advice of <a href="https://arduino.stackexchange.com/users/7508/edgar-bonet">edgar-bonet</a> I have used one temperature-compensated RTC for timing the Arduino s externally <strong>(DS3231)</strong>. I am using its 32kHz pin from the chip for counting the ticks and in the Arduino using the interrupt to count the ticks.</p>
<p>The program is shown below.</p>
<pre><code>

float _sec = 1;


float secTime =  _sec * 1000UL; // second-&gt;millis
uint32_t coilTime = 5 * 1000UL; // second-&gt;millis

volatile uint32_t count = 0;
/*
 * 32768 ticks in 1 sec
 * 0.032768 tick in 1 us
 */

float _multiplier = 0.032768; // 32768 Hz

uint32_t _delay = secTime * _multiplier * 1000UL ;

volatile bool onFlag = false;

ISR(INT1_vect, ISR_NOBLOCK) {
  count = count + 1UL;
  if (_delay == count) {
    PORTC |= (1 &lt;&lt; 5);
    onFlag = true;
    EIMSK = 0;
  }
}

ISR(INT0_vect) {
  /* INTERRUPT re-initalization */
  EIMSK = 0;
  EICRA = B00001100; // INT0 - clear ; INT1 -  set
  EIFR  = 0;
  PORTB ^=  (1 &lt;&lt; 0) | (1 &lt;&lt; 1); // setting Green off and red on
  count = 0;
  EIMSK = B00000010; // INT0 - inactive ; INT1 - active
} 


void setup() {
  Serial.begin(115200);

  /* PIN initialization */
  DDRB |= (1 &lt;&lt; 0) | (1 &lt;&lt; 1); // red led and green led

  pinMode(3, INPUT_PULLUP); // timer unit
  pinMode(2, INPUT); // interrupt unit

  DDRC |= (1 &lt;&lt; 3) | (1 &lt;&lt; 4) | (1 &lt;&lt; 5); // relay, OUT_1, OUT_2

  /* LEDs state update */
  PORTB &amp;=  ~(1 &lt;&lt; 1); // red off.
  PORTB |= (1 &lt;&lt; 0); // green on.

  PORTC &amp;= ~(1 &lt;&lt; 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 &lt;&lt; 0); // setting green on

    delay(500);
    PORTC ^= (1 &lt;&lt; 5);
    //    PORTB ^= (1 &lt;&lt; 0) | (1 &lt;&lt; 1);
    PORTB ^= (1 &lt;&lt; 1); // setting red off
    while (true) {
      TCCR2B = 0;
      count = 0;
      PORTB ^= (1 &lt;&lt; 0);
      delay(500);
    }
  }
}
</code></pre>
<p>when running the program The result I am expecting the accuracy of microseconds
but</p>
<p>for
input -&gt; Measured value
1 sec -&gt; 1.000387792
2 sec -&gt; 2.000784208
50 sec -&gt; 50.020926833
250 sec -&gt; 250.104557792</p>
<p>How to make the clock more precise, In the datasheet it is said that the clock is accurate to +- 2ppm.</p>
<p><a href="https://www.analog.com/media/en/technical-documentation/data-sheets/DS3231.pdf" rel="nofollow noreferrer">datasheet-ds3231</a></p>
 7508: <p>This may not be a proper answer to your question. Instead of telling you
how to improve the accuracy, I will show you how to measure it. The
issue is that the code you posted is doing too much stuff, and it is not
clear how it could be measuring the clock accuracy. So, instead I
suggest you try the code below:</p>
<ul>
<li>connect a push button between pin 2 and GND</li>
<li>connect the 32768 Hz signal to pin 5</li>
<li>watch the built-in LED blink</li>
</ul>
<pre class="lang-cpp prettyprint-override"><code>const uint8_t input_pin = 5;  // 32768 Hz on digital 5 = T1
const uint8_t clear_pin = 2;  // button to clear timer

void 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 &amp; (1 &lt;&lt; 14)) {
        digitalWrite(LED_BUILTIN, HIGH);
    } else {
        digitalWrite(LED_BUILTIN, LOW);
    }

    // Clear the counter on button press.
    if (digitalRead(clear_pin) == LOW) {
        TCNT1 = 0;
    }
}
</code></pre>
<p>What this sketch does is use Timer/counter 1 as a counter in order to
count the falling edges of the 32768 Hz signal. Bit 14 of the counter
should then toggle at 1 Hz. This bit is output on the built-in LED to
let you check its frequency. You can use the push button to reset the
phase of the blinks.</p>
<p>If you have a very accurate clock at hand, you can use the push button
to synchronize the blinks with the ticks of that clock, and then see how
long it takes to get visibly out of phase. You can also synchronise the
blinks of two Arduinos and see for how long they stay in sync. If you
have a scope, you could measure a tiny offset between the edges of the
two Arduino's LEDs, then see how this offset evolves with time.</p>
