internal quartz time stability

Hi all,

I was reading that the arduino quartz is very sensitive to temperature changes, and that this can influence the internal time keeping... since I will need to use the arduino to control a system that will require milliseconds long impulses repeated in cycles for a few hours, someone suggested me to use an external quartz.

Is that true? Do you have any suggestion for this?

Thanks :slight_smile:

nekran82:
Hi all,

I was reading that the arduino quartz is very sensitive to temperature changes, and that this can influence the internal time keeping... since I will need to use the arduino to control a system that will require milliseconds long impulses repeated in cycles for a few hours, someone suggested me to use an external quartz.

Is that true? Do you have any suggestion for this?

Thanks :slight_smile:

Depending on the board you are using it might not even be a quartz resonator, but rather a ceramic resonator, or in less common boards using the internal R/C time base. The standard Uno board uses an external 16 MHz ceramic resonator. All that aside your questions is one that can't really be answered unless you give a accuracy specification requirement. Any and all methods may meet your requirements or not depending on what your specific project accuracy requirements are.

nekran82:
will require milliseconds long impulses repeated in cycles for a few hours

That part seems easy enough. What might make it harder is if you have requirements for the accuracy of the frequency/duration of the pulses. Do you any requirements of that sort? If so, what are they?

Ok, thank you.

To try to answer, I have connected the Arduino (UNO SMD) to a TIP122 to drive a 24V operated special valve. These valves (4 of them) are normally close, and will have to open for a time that could go from 1 millisecond to a few seconds. The accuracy and the precision are both important... the precision is important because if I need 1 millisecond it can't be once 2, then 5 or then 0.3, the results will vary too much. And the accuracy is needed for the same reasons, I can't have a system that acts precisely off target.

For what concerns the length of the process, I need it to be able to run for hours without any change in the timekeeping... you can imagine that if the Arduino loses 0.5 millisecs per hour, after 2 hours the entire process could be precise but not accurate anymore...

Thanks!

Try this simple count up timer with your Ardiuno.
Fire up the serial monitor at 115200.

Watch the time against something like

down at the lower right and see how well it tracks.

unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedTime;

byte hundredths;
byte tenths;
byte secondsOnes;
byte oldsecondsOnes;
byte secondsTens;
byte minutesOnes;
byte minutesTens;


void setup(){

Serial.begin(115200); // make serial monitor match
Serial.println (Setup Done");
}

void loop(){

currentMicros = micros();

// how long's it been?
elapsedTime = currentMicros - previousMicros;
if ( elapsedTime >=10000UL){  // 0.01 second passed? Update the timers
previousMicros  = previousMicros + 10000UL;
hundredths = hundredths+1;
if (hundredths == 10){
    hundredths = 0;
    tenths = tenths +1;
    if (tenths == 10){
        tenths = 0;
        secondsOnes = secondsOnes + 1;
        if (secondsOnes == 10){
            secondsOnes = 0;
            secondsTens = secondsTens +1;
            if (secondsTens == 6){ 
                secondsTens = 0;
                minutesOnes =  minutesOnes + 1;
                if (minutesOnes == 10){
                    minutesOnes = 0;
                    minutesTens = minutesTens +1;
                    if (minutesTens == 6){
                        minutesTens = 0;
                        } // minutesTens rollover check
                     } // minutesOnes rollover check
                 } // secondsTens rollover check
              } // secondsOnes rollover check
          } // tenths rollover check
       } // hundredths rollover check
} // hundredths passing check



if (oldSecondsOnes != secondsOnes){  // show the elapsed time
oldSecondsOnes = secondsOnes;

Serial.print(minutesTens);
Serial.print(":");

Serial.print(minutesOnes);
Serial.print(":");

Serial.print(secondsTens);
Serial.print(":");

Serial.println(secondsOnes);


} // end one second check

} // end loop

May need a little tweaking, I don't have to check that it compiles correctly here.

You're using the terms precision and accuracy in a way that I don't recognise.

You can easily control the duration of the pulses in the range of a few milliseconds and you should be able to get an accuracy of the order of tens of microseconds.

Controlling the frequency of the signals over the long term will be harder. The Arduino's processor clock is only accurate to a few hundred parts per million (and the accuracy will vary with various factors such as temperature) so if you want to have something happen at a particular real-world time, you really need a real time clock source. If your project has internet access then you can get a reasonably accurate clock source from an online time server. However, real time clock modules are inexpensive and easy to use so would seem a more sensible solution. Also note that it's possible to manage this sort of timing outside the Arduino. For example you could plug the power supply for your Arduino into an ordinary domestic timer that simply powers it up when it's time to do something, or if it will be plugged into a PC then you could have a scheduled job on the PC that sends a message to the Arduino when it is time to do something. But for a fully self-contained solution, the RTC module seems like your best bet.

Hi. I would recomnend a ds3231 based rtc. They are temperature compensated, very accurate and very cheap on ebay if you can wait for delivery from china. This should take care of thr long periods between pulses.

For accurate pulses, you could buy an atmega328 preloaded with bootloader and a high accurracy crystal.

For accurate pulses, you could buy an atmega328 preloaded with bootloader and a high accurracy crystal.

That only helps if you have good code tho.
High accuracy crytal helps. These are both pretty good.

But I generally have these on hand and have not seen any issues with 22pF caps.
http://www.dipmicro.com/store/XC7-16000
http://www.dipmicro.com/store/C1K22-50

Frequency : 3.579-80MHZ (data sheet covers several devices, 16 MHz included)
1.4 Frequency tolerance at 25? : +/-20 PPM
1.5 Frequency Stability at (-10??+60 ?) : +/-30 PPM
1.6 Load Capacitance ( CL ) : 18 PF

These valves (4 of them) are normally close, and will have to open for a time that could go from 1 millisecond to ...

What sort of valves are these? If they control fluid flow, most will take much longer than a few milliseconds to open or close.

Wow, thanks guys!

The valves are used for a chemical process called Atomic Layer Deposition, and they are specifically made for opening - closing on the millisecond (or more) for a lot of cycles.

I'll look into your suggestions, I hope I'll be able to understand some of it :slight_smile: :slight_smile: :slight_smile:

I have been running this sketch for 12 hours now, is still within a second of NIST.gov time, the closest I could get to starting it.
Adding some mS on/off times for IO should be pretty easily doable.
If you want to add code to precisely sync it to external source once a day that should be possible. I've not tried anything like that, preferring to make standalone embedded projects.

unsigned long currentMicros;
unsigned long previousMicros;
unsigned long elapsedTime;

byte hundredths;
byte tenths;
byte secondsOnes;
byte oldSecondsOnes;
byte secondsTens;
byte minutesOnes = 9;
byte minutesTens;

void setup(){

  Serial.begin(115200); // make serial monitor match
  Serial.println ("Setup Done");
}

void loop(){

  currentMicros = micros();

  // how long's it been?
  elapsedTime = currentMicros - previousMicros;
  if ( elapsedTime >=10000UL){  // 0.01 second passed? Update the timers
    previousMicros  = previousMicros + 10000UL;
    hundredths = hundredths+1;
    if (hundredths == 10){
      hundredths = 0;
      tenths = tenths +1;
      if (tenths == 10){
        tenths = 0;
        secondsOnes = secondsOnes + 1;
        if (secondsOnes == 10){
          secondsOnes = 0;
          secondsTens = secondsTens +1;
          if (secondsTens == 6){ 
            secondsTens = 0;
            minutesOnes =  minutesOnes + 1;
            if (minutesOnes == 10){
              minutesOnes = 0;
              minutesTens = minutesTens +1;
              if (minutesTens == 6){
                minutesTens = 0;
              } // minutesTens rollover check
            } // minutesOnes rollover check
          } // secondsTens rollover check
        } // secondsOnes rollover check
      } // tenths rollover check
    } // hundredths rollover check
  } // hundredths passing check



  if (oldSecondsOnes != secondsOnes){  // show the elapsed time
    oldSecondsOnes = secondsOnes;

    Serial.print(minutesTens);
    //Serial.print(":");

    Serial.print(minutesOnes);
    Serial.print(":");

    Serial.print(secondsTens);
    //Serial.print(":");

    Serial.println(secondsOnes);
    //Serial.print(":");

  } // end one second check

} // end loop

Again... thanks! :slight_smile:

I was having a thought about it over lunch, in the end I'm not sure I need to synchronize it with a given time, I am more interested in the circuit clock being regular, so the valves opening - closing times will be the same (let's say 10 milliseconds) even after a few hours of running.

Anyway, thanks!!!

I believe the Arduino can keep that regularity for you.
How ofter do you want that pulse to occur?
Every 5 minutes? 30 times a second? 1 then 2 then 3 then 4 then back to 1?
Provide some specifics.

Sketch running 23 hours now, still in sync...

28-29 hours now, my crystal equipped Duemilanove has gained about 1.5 seconds on the Gov't internet time.
It's also been a pretty warm day here, 80's in the house during the day, cooling down nice for the night.

www.nist.gov has also apparently crashed! So here's the Duemilanove against another US site.

I'll check again in the morning and see how it's doing.
The gov't I mean; the duemilanove will be fine.

Sorry, I forgot about the frequency...

The impulses will be cycled in 1-2-3-4-5-1-2-3-4-5-1-2-3-... Ideally one of the pulses (let's say 1) will be 0.1 to 0.5 milliseconds, then the rest of the pulses will be in the seconds range (1 to 5 more or less). Therefore I can expect one pulse in the milliseconds range every 15-20 seconds or so. The cycles will be repeated for hundreds of times, or more, that depends on how the process is going...

Thanks :slight_smile: