DS3231 sq wave 1 sec timing

Hi All,

I have managed to enable the square wave pin on my DS3231 and set it to 1 hz.
I have attached it to pin 10, and wired the ground and vcc to my arduino uno.
Every time it changes state I am collecting micros into a variable and deducting it from the last time it was collected. I am then dividing by 1000, and so expect to see 500 (millis) each time considering the accuracy of the RTC module. This is my code

long LastRTCMicro;  //variable to store the last RTC Micro time - to be used for looping
long RTCmicro;     //variable to store the RTC Micro time as soon as the Sqwave pin is driven low
const int  sqWavePin = 10;    // the pin that the Sqwave attaches to
int sqWaveCounter = 0;   // counter for the number of cycles. 
int sqWaveState = 0;         // current state of the squarewave Pin either HIGH or LOW
int lastsqWaveState = 0;    // previous state so can see if its changed in the loop

void setup() {   //setup section is so that you can see the squarewave is enabled on the RTC and that the frequency is set correctly. 
  
  pinMode(sqWavePin, INPUT_PULLUP); //has to be a pullup - without 10mOhm resister arduino will not register the state change
  Serial.begin(250000);  
}

void loop() {
 if (sqWaveCounter <20){
 chkPin();
 }
  
}

void chkPin(){

sqWaveState = digitalRead(sqWavePin);
  if (sqWaveState != lastsqWaveState) { //state has changed
    
      RTCmicro = micros();  //grabs the current micro 
                                  
      sqWaveCounter += 1; //just used to stop it after 20 ticks
            
    
    lastsqWaveState = sqWaveState;
    Serial.println((RTCmicro-LastRTCMicro) / 1000) ;
    LastRTCMicro = RTCmicro; 
  }

}

Can anyone explain to me why it shows 496 in the serial window (attached pic) and not 500? It is a constant 496 everytime. Ive checked the RTC module by inserting the time and date and thats still holding well after 1 week - so I assume the module is ok…

Capture.JPG

Because the Arduino processor clock source is crap. Its only a resonator, not a quartz crystal.

Also with micros() there is about 4us variance (cannot think of the right word :frowning: ).

.

Can anyone explain to me why it shows 496 in the serial window (attached pic) and not 500?

You could, if you listed EVERYTHING that happens between assigning a new value to RTCmicro and copying that value as LastRTCMicro.

By the way, names like LastRTCMicro and CurrRTCMicro look like they are related. LastRTCMicro and RTCmicro do not.

larryd:
Also with micros() there is about 4us variance (cannot think of the right word :frowning: ).

resolution

aarg:
resolution

YES! need coffee now!

2017-08-02_7-06-30.png

PaulS:
You could, if you listed EVERYTHING that happens between assigning a new value to RTCmicro and copying that value as LastRTCMicro.

I have... thats the entire code above - Im just testing at this point. So its doing nothing other than monitoring a change on pin 10 - noting the current micros as soon as it changes, 1 maths equation (no floats) and printing to serial - before monitoring the pin again...
There is roughly 12us "resolution" in the code. (if thats the correct term).
The point is - the RTC (accurate to 2ppm) is pulling down pin 10 every 1000 millis. im collecting micros every 500millis and deducting it from the last time it was collected. its always 495. In fact if I add 5 millis to the equation and run it for 10 mins it doesnt vary from a perfect 500!

As I said, it is because micros() does not count 1,000,000 in a second. All the timers are derived from the CPU clock which is derived from a cheapo ceramic resonator.

aarg:
As I said, it is because micros() does not count 1,000,000 in a second. All the timers are derived from the CPU clock which is derived from a cheapo ceramic resonator.

thanks for the reply aarg. I appreciate that. The RTC DS3231 IS a guaranteed 1000000 per second though (over 20 ticks or so). I just didnt expect it to be 5 millis difference per 500 ... that equates to a huge 10000ppm. there is a problem with my code - i am sure.
long story short - I want to use the RTC sqwave pin to calculate the accuracy of my arduino clock. It cant be 10000 ppm surely!

As someone hinted above, micros() returns values in increments of 4, not 1, so you can get no better than 4us resolution.

KeithRB:
As someone hinted above, micros() returns values in increments of 4, not 1, so you can get no better than 4us resolution.

I only need 1ms accuracy over 60 sec period....

liddlec7:
It cant be 10000 ppm surely!

I can be. Look up the specs if you don't believe me.

Try this. Use millis() to measure the millisecond count between 60 square waves.

liddlec7:
I only need 1ms accuracy over 60 sec period....

From what? The system clock? Get a 32U4 based board like the Pro Micro or Leonardo, that have a real quartz crystal. Or a Chinese clone that has one.

Ha! Got an Adafruit Pro Trinket 3V 12 mHz in front of me right now running 17 + seconds slow an hour, I can call a minute 59705 millis and it holds within 1 second for more than 72 hours.
So it’s off by 295 millis + a few micros per minute.

edgemoron:
Ha! Got an Adafruit Pro Trinket 3V 12 mHz in front of me right now running 17 + seconds slow an hour, I can call a minute 59705 millis and it holds within 1 second for more than 72 hours.
So it's off by 295 millis + a few micros per minute.

Using a compensation offset only works if the temperature doesn't change. Not only are resonators inaccurate, but they are also highly temperature sensitive. I guess you can tell by now that I don't like resonators very much. :slight_smile:

@aarg:
Yep, I feel the same, how much more could a crystal add to the cost? 2%? (not talking about the Chinese clones).

liddlec7:
Can anyone explain to me why it shows 496 in the serial window (attached pic) and not 500? It is a constant 496 everytime.

Your arduino is wrong, and your RTC is right. The clock in your arduino is .8% slow. This is to be expected - it's one of the reasons why we need RTC clocks: they keep accurate time.

liddlec7:
I just didnt expect it to be 5 millis difference per 500 ... that equates to a huge 10000ppm.

Well, it's a lot for a horologist. But it's not a lot for electronic components. Recall that most resistors have a 5% tolerance.

The fact that the arduino resonator drifts by several minutes in a day (if you use it to measure time) is a real reminder of what an incredible achievement accurate mechanical clocks were. The discovery that quartz crystals could be made to vibrate with uncanny accuracy was a major game-changer for all sorts of things.

Just tried the same code with an original Uno. a much better 499700 per 500000 micros. so its out 600 micros per second. 600 X 60 secs = 36000 micros per minute. thats 600ppm - a lot better than 10000ppm....

Just tried a cheap NODE MCU ESP 8266. it differed a mere 403 micros over 60 secs. 6ppm.! WINNER