<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div><br></div>Looks good.<div><br></div><div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>(45681/4790)*104.8576 = 1000.0000053411</div></blockquote></div><div><br></div><div>I've committed that, and will carry on testing tonight.</div><div><br></div><div>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:</div><div><br></div><div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div><div>  // Timer 1 enabled, Fosc/4, 16 bit mode, prescaler 1:8</div><div>  T1CON = 0b10110101; // @ 5Mhz => 51.2uS / 256</div><div>  IPR1bits.TMR1IP = 0; // Low priority interrupt</div><div>  PIE1bits.TMR1IE = 1; // Enable interrupt</div><div>  TMR1L = 0;</div><div>  TMR1H = 0;</div></div></blockquote></div><div><br></div><div>but the @5Mhz comment is incorrect because that is not what our oscillator runs at.</div><div><br></div><div>Regards, Mark.</div><div><br><div><div>On 23 Oct, 2014, at 9:32 am, Tom Saxton <<a href="mailto:tom@idleloop.com">tom@idleloop.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">This is a pretty cool trick!<br><br>I was a bit confused when I first read the thread. The marksec time unit<br>is 50ms, it's 1/50,000 of a second, or 20 microseconds. Fine, that's just<br>a notation thing.<br><br>The trick of improving the rounding error on the increment once per second<br>is a little more complicated. If you do it once per second, sometimes<br>that's 10 interrupts and sometimes it's once every 9 interrupts (about 2<br>out of 41 times). You can fix that by making the counter correction once<br>every 10 interrupts, which is effectively just adding one decimal place to<br>your increment counter. But, we don't have to do that at all.<br><br>I wrote a program to try every possible time unit between 1/1000 and<br>1/60000 of a second and found the time unit with the smallest error.<br><br>Using a marksec of 1/45681 means there would be 4790.000026 marksecs per<br>interrupt. Rounding that to 4790 for the counter increment value<br>introduces an error of -0.00000000056 seconds per interrupt, which works<br>out to losing -0.00046 seconds per day.<br><br>So, each interrupt, increment the counter by 4790. When the total is equal<br>to or greater than 45681, increment car_time and subtract 45681 from the<br>counter.<br><br>There is a better value of 61903 with an increment value of 6491 which<br>cuts that error by a factor of three, but it doesn't work with a 16-bit<br>unsigned integer because of overflow problems (61902 + 6491 > 65535).<br><br>   Tom<br><br>-----Original Message-----<br>From: Mark Webb-Johnson <<a href="mailto:mark@webb-johnson.net">mark@webb-johnson.net</a>><br>Reply-To: OVMS Developers <<a href="mailto:ovmsdev@lists.teslaclub.hk">ovmsdev@lists.teslaclub.hk</a>><br>Date: Tuesday, October 21, 2014 at 11:22 PM<br>To: OVMS Developers <<a href="mailto:ovmsdev@lists.teslaclub.hk">ovmsdev@lists.teslaclub.hk</a>><br>Subject: Re: [Ovmsdev] Tick math<br><br><blockquote type="cite"><br>+1, I like. Especially because MarkSecs sounds a bit rude...<br><br>Of course, the final correction is that if we know every time we add 105<br>to the count, we are off by 0.1424ms, then after 10 times we are off by<br>1.424ms, so we could just adjust the amount we deduct appropriately. 999<br>vs 1,000 and instantly 3 times better. That works even better with<br>MarkSecs (which might as well be 60ms vs 50ms, as we are good for up to<br>65535 for an unsigned int16). At that point, we're more accurate than the<br>clock on the PIC18.<br><br>Every 104.8576ms interrupt, we add 6291 to the counter, knowing that we<br>are off by 0.0076ms (0.4560 marksecs).<br><br>Now, when counter exceeds 60,000 (10 interrupts), we have added 62,910 to<br>the counter (6,291 ten times) and each of those times we were too low by<br>0.4560 marksecs, so we are 4.560 marksecs too low, so we increment<br>car_time by 1 second and decrement the counter by 59,995. We should then<br>be out by 0.007333ms over that 1 second. I think that's about 1/2 second<br>a day.<br><br>Or, using 1 marksecs as 50ms: for every 104.8576ms interrupt, we add 5243<br>to the counter, knowing we are off by 0.02ms (0.12 marksecs). Now, when<br>counter exceeds 50,000 (10 interrupts), we have added 52,430 to the<br>counter (5,243 ten times) and each of those times we were too high by<br>0.12 marksecs, so we are 1.2 marksecs too high, so we increment car_time<br>by 1 second and decrement the counter by 50,001. We should then by out by<br>0.002ms over that 1 second. I think that is about 0.17 seconds a day.<br><br>Or, using 1 marksecs as 42ms (I just love the number 42, and in this case<br>it gives us a very small loss of precision): for every 104.8576ms<br>interrupt, we add 4404 to the counter, knowing we are off by 0.000456ms<br>(0.0192 marksecs). Now, when counter exceeds 42,000 (10 interrupts), we<br>have added 44,040 to the counter (4,404 ten times) and each of those<br>times we were too low by 0.0192 marksecs, we we are 0.192 marksecs too<br>low, so we don't need to adjust. We should then be out by 0.00456ms over<br>that 1 second. I think that is about 0.39 seconds a day, but we have<br>solved the answer to life the universe and everything.<br><br>Or, my maths may be even more wrong.<br><br>Mark.<br><br>On 22 Oct, 2014, at 1:38 pm, Gianluca Magalotti <<a href="mailto:gianluca@magalotti.net">gianluca@magalotti.net</a>><br>wrote:<br><br><blockquote type="cite">Ok, so you every 104.8576ms will add 5243MarkSecs (just invented a new<br>time unit) right?<br>And when the counter reaches or pass 50000 you add one second and<br>subtract 50000 to the count.<br>This way you are over 0.0024ms per timer interrupt, roughly 0.022ms per<br>second, that is less than 2s per day (that is, every 43690s we count one<br>second more.)<br><br>Please check my math.... But you won!<br><br>Gianluca Magalotti dal mio iPad mini<br><br><blockquote type="cite">Il giorno 22/ott/2014, alle ore 06:00,<br><a href="mailto:ovmsdev-request@lists.teslaclub.hk">ovmsdev-request@lists.teslaclub.hk</a> ha scritto:<br><br>Sorry, in my P.S., I think I miscalculated the improvement.<br><br>1] Current methodology:<br><br>Signed 16 bit integer<br>Every 104.8576ms timer interrupt, add 105ms to the counter.<br>If counter >1,000 treat it as 1 second and deduct 1,000 from counter.<br><br>Accuracy: loses 0.1424ms per timer interrupt.<br><br>2] 50ms methodology:<br><br>Signed 16 bit integer<br>Every 104.7576ms timer interrupt, add 5243 to the counter.<br>That is equivalent to 5242.88 50ms chunks.<br>Difference is 0.88 / 50 ms<br>Accuracy: loses 0.01760ms per timer interrupt<br><br>Or, is my new maths wrong? Is the inaccuracy 0.01760ms or 0.12ms per<br>timer tick?<br><br>Confused, I am.<br><br>Mark.<br></blockquote>_______________________________________________<br>OvmsDev mailing list<br><a href="mailto:OvmsDev@lists.teslaclub.hk">OvmsDev@lists.teslaclub.hk</a><br>http://lists.teslaclub.hk/mailman/listinfo/ovmsdev<br></blockquote><br>_______________________________________________<br>OvmsDev mailing list<br><a href="mailto:OvmsDev@lists.teslaclub.hk">OvmsDev@lists.teslaclub.hk</a><br>http://lists.teslaclub.hk/mailman/listinfo/ovmsdev<br><br></blockquote><br><br>_______________________________________________<br>OvmsDev mailing list<br><a href="mailto:OvmsDev@lists.teslaclub.hk">OvmsDev@lists.teslaclub.hk</a><br>http://lists.teslaclub.hk/mailman/listinfo/ovmsdev<br></blockquote></div><br></div></body></html>