[Ovmsdev] Tick math

Mark Webb-Johnson mark at webb-johnson.net
Thu Oct 23 11:30:52 HKT 2014


Looks good.

(45681/4790)*104.8576 = 1000.0000053411

I've committed that, and will carry on testing tonight.

Now, of course this depends on the calculation of 104.8576ms per timer1 interrupt. I have no idea where that figure originally came from, or if it is correct. It does looks like the LED count counts 10 of these to get 1 flash a second, so it seems correct. The initialisation for timer1 is:

  // Timer 1 enabled, Fosc/4, 16 bit mode, prescaler 1:8
  T1CON = 0b10110101; // @ 5Mhz => 51.2uS / 256
  IPR1bits.TMR1IP = 0; // Low priority interrupt
  PIE1bits.TMR1IE = 1; // Enable interrupt
  TMR1L = 0;
  TMR1H = 0;

but the @5Mhz comment is incorrect because that is not what our oscillator runs at.

Regards, Mark.

On 23 Oct, 2014, at 9:32 am, Tom Saxton <tom at idleloop.com> wrote:

> 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
> counter.
> 
> 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).
> 
>   Tom
> 
> -----Original Message-----
> 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
>> a day.
>> 
>> 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.
>> 
>> Mark.
>> 
>> On 22 Oct, 2014, at 1:38 pm, Gianluca Magalotti <gianluca at magalotti.net>
>> wrote:
>> 
>>> 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
>>> second more.)
>>> 
>>> 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
>>>> timer tick?
>>>> 
>>>> Confused, I am.
>>>> 
>>>> Mark.
>>> _______________________________________________
>>> OvmsDev mailing list
>>> OvmsDev at lists.teslaclub.hk
>>> http://lists.teslaclub.hk/mailman/listinfo/ovmsdev
>> 
>> _______________________________________________
>> OvmsDev mailing list
>> OvmsDev at lists.teslaclub.hk
>> http://lists.teslaclub.hk/mailman/listinfo/ovmsdev
>> 
> 
> 
> _______________________________________________
> OvmsDev mailing list
> OvmsDev at lists.teslaclub.hk
> http://lists.teslaclub.hk/mailman/listinfo/ovmsdev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.teslaclub.hk/pipermail/ovmsdev/attachments/20141023/a97d3f27/attachment-0001.html>


More information about the OvmsDev mailing list