[Ovmsdev] Tick math
tom at idleloop.com
Thu Oct 23 09:32:32 HKT 2014
This is a pretty cool trick!
I was a bit confused when I first read the thread. The marksec time unit
is 50ms, it's 1/50,000 of a second, or 20 microseconds. Fine, that's just
a notation thing.
The trick of improving the rounding error on the increment once per second
is a little more complicated. If you do it once per second, sometimes
that's 10 interrupts and sometimes it's once every 9 interrupts (about 2
out of 41 times). You can fix that by making the counter correction once
every 10 interrupts, which is effectively just adding one decimal place to
your increment counter. But, we don't have to do that at all.
I wrote a program to try every possible time unit between 1/1000 and
1/60000 of a second and found the time unit with the smallest error.
Using a marksec of 1/45681 means there would be 4790.000026 marksecs per
interrupt. Rounding that to 4790 for the counter increment value
introduces an error of -0.00000000056 seconds per interrupt, which works
out to losing -0.00046 seconds per day.
So, each interrupt, increment the counter by 4790. When the total is equal
to or greater than 45681, increment car_time and subtract 45681 from the
There is a better value of 61903 with an increment value of 6491 which
cuts that error by a factor of three, but it doesn't work with a 16-bit
unsigned integer because of overflow problems (61902 + 6491 > 65535).
From: Mark Webb-Johnson <mark at webb-johnson.net>
Reply-To: OVMS Developers <ovmsdev at lists.teslaclub.hk>
Date: Tuesday, October 21, 2014 at 11:22 PM
To: OVMS Developers <ovmsdev at lists.teslaclub.hk>
Subject: Re: [Ovmsdev] Tick math
>+1, I like. Especially because MarkSecs sounds a bit rude...
>Of course, the final correction is that if we know every time we add 105
>to the count, we are off by 0.1424ms, then after 10 times we are off by
>1.424ms, so we could just adjust the amount we deduct appropriately. 999
>vs 1,000 and instantly 3 times better. That works even better with
>MarkSecs (which might as well be 60ms vs 50ms, as we are good for up to
>65535 for an unsigned int16). At that point, we're more accurate than the
>clock on the PIC18.
>Every 104.8576ms interrupt, we add 6291 to the counter, knowing that we
>are off by 0.0076ms (0.4560 marksecs).
>Now, when counter exceeds 60,000 (10 interrupts), we have added 62,910 to
>the counter (6,291 ten times) and each of those times we were too low by
>0.4560 marksecs, so we are 4.560 marksecs too low, so we increment
>car_time by 1 second and decrement the counter by 59,995. We should then
>be out by 0.007333ms over that 1 second. I think that's about 1/2 second
>Or, using 1 marksecs as 50ms: for every 104.8576ms interrupt, we add 5243
>to the counter, knowing we are off by 0.02ms (0.12 marksecs). Now, when
>counter exceeds 50,000 (10 interrupts), we have added 52,430 to the
>counter (5,243 ten times) and each of those times we were too high by
>0.12 marksecs, so we are 1.2 marksecs too high, so we increment car_time
>by 1 second and decrement the counter by 50,001. We should then by out by
>0.002ms over that 1 second. I think that is about 0.17 seconds a day.
>Or, using 1 marksecs as 42ms (I just love the number 42, and in this case
>it gives us a very small loss of precision): for every 104.8576ms
>interrupt, we add 4404 to the counter, knowing we are off by 0.000456ms
>(0.0192 marksecs). Now, when counter exceeds 42,000 (10 interrupts), we
>have added 44,040 to the counter (4,404 ten times) and each of those
>times we were too low by 0.0192 marksecs, we we are 0.192 marksecs too
>low, so we don't need to adjust. We should then be out by 0.00456ms over
>that 1 second. I think that is about 0.39 seconds a day, but we have
>solved the answer to life the universe and everything.
>Or, my maths may be even more wrong.
>On 22 Oct, 2014, at 1:38 pm, Gianluca Magalotti <gianluca at magalotti.net>
>> Ok, so you every 104.8576ms will add 5243MarkSecs (just invented a new
>>time unit) right?
>> And when the counter reaches or pass 50000 you add one second and
>>subtract 50000 to the count.
>> This way you are over 0.0024ms per timer interrupt, roughly 0.022ms per
>>second, that is less than 2s per day (that is, every 43690s we count one
>> Please check my math.... But you won!
>> Gianluca Magalotti dal mio iPad mini
>>> Il giorno 22/ott/2014, alle ore 06:00,
>>>ovmsdev-request at lists.teslaclub.hk ha scritto:
>>> Sorry, in my P.S., I think I miscalculated the improvement.
>>> 1] Current methodology:
>>> Signed 16 bit integer
>>> Every 104.8576ms timer interrupt, add 105ms to the counter.
>>> If counter >1,000 treat it as 1 second and deduct 1,000 from counter.
>>> Accuracy: loses 0.1424ms per timer interrupt.
>>> 2] 50ms methodology:
>>> Signed 16 bit integer
>>> Every 104.7576ms timer interrupt, add 5243 to the counter.
>>> That is equivalent to 5242.88 50ms chunks.
>>> Difference is 0.88 / 50 ms
>>> Accuracy: loses 0.01760ms per timer interrupt
>>> Or, is my new maths wrong? Is the inaccuracy 0.01760ms or 0.12ms per
>>> Confused, I am.
>> OvmsDev mailing list
>> OvmsDev at lists.teslaclub.hk
>OvmsDev mailing list
>OvmsDev at lists.teslaclub.hk
More information about the OvmsDev