-void snap_to_zero()
-{
- if ((millisecond > 0) && (millisecond < 15000)) { // If the second is from :00.0 to :15.0
- millisecond = 800; // snap back to :00.8
- }
- else if (millisecond > 45000) { // If the second is :45.0 or above
- millisecond = MILLISECONDS_PER_MINUTE + 800; // snap forward to :00.8 (minute will advance automatically)
- }
+void snap_to_zero() {
+ if ((millisecond > 0) && (millisecond < 15000)) { // If the second is from :00.0 to :15.0
+ millisecond = 800; // snap back to :00.8
+ }
+ else if (millisecond > 45000) { // If the second is :45.0 or above
+ millisecond = millis_per_minute + 800; // snap forward to :00.8 (minute will advance automatically)
+ }
+}
+
+
+// By determining how many timer ticks elapsed between two minute markers, we can calibrate our software clock.
+// Nominally it is 60000 milliseconds, but the software clock tends to drift.
+// So we start with an array of all 60000 ms, and we keep ten calibrations and average them.
+void calibrate() {
+
+ static unsigned long mpm_array[10] = { 60000, 60000, 60000, 60000, 60000, 60000, 60000, 60000, 60000, 60000 };
+ static int mpm = 0; // next one to update
+
+ static unsigned long last_calib = -86398000;
+ unsigned long m = millis();
+ unsigned long mm = m - last_calib;
+ if ((mm > 50000) && (mm < 70000)) {
+ mpm_array[mpm++] = mm;
+ if (mpm >= 10) {
+ mpm = 0;
+ }
+ millis_per_minute = (mpm_array[0] + mpm_array[1] + mpm_array[2] + mpm_array[3]
+ + mpm_array[4] + mpm_array[5] + mpm_array[6] + mpm_array[7]
+ + mpm_array[8] + mpm_array[9]) / 10;
+ }
+ last_calib = m;