# Arduino nano timing precision

How precisely can an Arduino nano be timed? The project I am working on needs two Arduino nano to work synchronously. Arduino one have to activate a relay after 2700 sec and Arduino two have to activate a second relay after 2700.360 sec (360 milli seconds after )

With the code given below the required accuracy is not achieved.

``````volatile uint32_t ovfCount = 0UL;
volatile uint32_t currentTime = 0UL;
volatile unsigned long time_prev = 0UL;
volatile unsigned long dT = 0UL;

unsigned long delayTime = 2700UL;     //Seconds
unsigned long coilActivateTime = 5UL;  // seconds

volatile unsigned long _waitTime = delayTime * 1000UL + 360UL;
uint32_t _burnTime = coilActivateTime * 1000UL;

volatile bool coilOn_flag = false;

ISR(INT0_vect) {

EIMSK = 0b00000000;

TCCR1B = B00011100;
PORTB ^= (1<<0);
ovfCount = 0;
TIFR2 = 0;
TCNT2 = 0;

}

ISR(TIMER2_OVF_vect) {
ovfCount++;
}

ISR(TIMER1_OVF_vect) {
//pass
}

ISR(TIMER1_COMPA_vect) {
//pass
}

ISR(TIMER1_COMPB_vect) {
uint8_t tcnt2 = TCNT2;
uint32_t ovf_count = ovfCount;

if (bit_is_set(TIFR2, TOV2) && tcnt2 < 128) {
ovf_count++;
}

uint32_t totalCount = ovf_count << 8 | tcnt2;  // raw count
// uint32_t currentTime = totalCount * 0.004;     // milli second
currentTime = totalCount * 4UL/1000UL;  // milli second

if (currentTime >= _waitTime) {
PORTC ^= (1 << 5);   // relay Switch
TCCR1A = B00000010;
TIMSK1 = B00000101;
PORTB |= (1<<1);
if (coilOn_flag) {
TCCR1B = 0;
PORTB ^= (1 << 1) | (1<<0);
}
coilOn_flag = true;
_waitTime = _burnTime;
ovfCount = 0;
TCNT2 = 0;
}
}

void setup() {
Serial.begin(115200);
/*setting the pin directions*/
DDRB |= (1 << 1) | (1 << 0); // gL, rL
DDRC |= (1 << 5);  // relay
DDRD &= B11111011; // interrupt- interrupt

/* INITIAL STATE SETTING FOR THE PINS */
PORTB &= B11111100; // rL, gL
PORTC &= B11011111; // relay

/* 8Bit Timer*/
TCCR2A = 0;
TCCR2B = 0;
TCCR2A = B00000011;
TCCR2B = B00001100;
OCR2A = 250;
TCNT2 = 0;
TIFR2 = 0;
TIMSK2 = B00000001;

/* 16 bit timer */
TCCR1A = 0;
TCCR1B = 0;
TCCR1A = B10000010;
// TCCR1B = B00011100;
TCCR1B = 0;
ICR1 = 62461;
OCR1A = 6206;
OCR1B = 624;
TCNT1 = 0;
TIFR1 = 0;
TIMSK1 = B00000111;

/* External INTERRUPT */
EICRA = 0b00000010;
EIFR = 0;
EIMSK = 0b00000001;

PORTB ^= (1<<0);
}

void loop() {

}
``````

How to correct the code.?

• you said nothing about the required precision of the two values ... you also did not say if there is anything wrong with the code Jan 9 at 15:57
• The internal clock of an Arduino is not really good for timing long durations with high precision (due to manufacturing differences and clock drift with temperature). For that a RTC (Real Time Clock) would be needed. Though: If you only need precision in the time difference between the two relay activations, then you could trigger the second Arduino from the first to start the timing there. Millisecond range is normally easily reached with Arduinos Jan 9 at 16:24
• why can't one Arduino control both relays?
– Juraj
Jan 9 at 18:34
• both are going to be inside 2 different systems. I do start the clock on both at the same time using a common interrupt signal. Jan 10 at 6:09