Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 22:23 17 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : automatic clock trim for MX170

Author Message
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2294
Posted: 07:02pm 22 Jan 2017
Copy link to clipboard 
Print this post

for quite a while i've been thinking about automatic trimming (disciplining) of the cpu clock on an MX170 micromite using an external crystal reference. this might take the form of the 1Hz output from an RTC module, or be derived from the 50/60Hz mains, or (in my case) obtained from a 32kHz watch crystal attached to a CD4060 ripple counter that generates a 2Hz output.

the big advantage of this approach, over simply using periodic calls to RTC GETTIME, is that frequency measurement, PWM, and other cpu clock dependant functions are also trimmed.

with the 2Hz signal from my CD4060 hooked up to pin 26, i used the following piece of code, implementing a crude proportional–integral control loop:

SetPin 26, inth, trimISR

Do
Print count, Str$(E,3,2), Str$(I,3,2),, trim, Time$, Timer

Do: Loop Until flag
flag = 0 ' comment out this line to consume computrons
Loop


trimISR:
count = Timer Mod 500
E = 250 - count
I = ((I * 0.8) + (E * 0.2))

trim = Fix((E * 0.3) + (I * 0.7))
If trim < -31 Then trim = -31
If trim > 31 Then trim = 31

Option clocktrim trim
flag = 1
IReturn

thr results were surprisingly good, with extremely quick convergence to a stable state, although the loop stabalized at values around 256 (in my case) rather than the target of 250. this doesn't really matter, as long as it is stable:

> run
0 0.00 0.00 0 00:00:15 15186
361 -111.00 -22.20 -31 00:00:15 15369
355 -105.00 -38.76 -31 00:00:15 15863
349 -99.00 -50.81 -31 00:00:16 16357
344 -94.00 -59.45 -31 00:00:16 16851
338 -88.00 -65.16 -31 00:00:17 17345
332 -82.00 -68.53 -31 00:00:17 17839
326 -76.00 -70.02 -31 00:00:18 18334
320 -70.00 -70.02 -31 00:00:18 18828
314 -64.00 -68.81 -31 00:00:19 19322
309 -59.00 -66.85 -31 00:00:19 19816
303 -53.00 -64.08 -31 00:00:20 20310
297 -47.00 -60.66 -31 00:00:20 20804
291 -41.00 -56.73 -31 00:00:21 21298
285 -35.00 -52.39 -31 00:00:21 21793
279 -29.00 -47.71 -31 00:00:22 22287
273 -23.00 -42.77 -31 00:00:22 22781
268 -18.00 -37.81 -31 00:00:23 23275
262 -12.00 -32.65 -26 00:00:23 23769
257 -7.00 -27.52 -21 00:00:24 24264
253 -3.00 -22.62 -16 00:00:24 24761
251 -1.00 -18.29 -13 00:00:25 25258
249 1.00 -14.43 -9 00:00:25 25756
248 2.00 -11.15 -7 00:00:26 26256
248 2.00 -8.52 -5 00:00:26 26755
248 2.00 -6.41 -3 00:00:27 27255
249 1.00 -4.93 -3 00:00:27 27756
249 1.00 -3.75 -2 00:00:28 28256
250 0.00 -3.00 -2 00:00:28 28757
251 -1.00 -2.60 -2 00:00:29 29258
252 -2.00 -2.48 -2 00:00:29 29759
252 -2.00 -2.38 -2 00:00:30 30260
253 -3.00 -2.51 -2 00:00:30 30760
254 -4.00 -2.80 -3 00:00:31 31261
255 -5.00 -3.24 -3 00:00:31 31762
255 -5.00 -3.59 -4 00:00:32 32262
256 -6.00 -4.08 -4 00:00:32 32763
256 -6.00 -4.46 -4 00:00:33 33263
256 -6.00 -4.77 -5 00:00:33 33763
256 -6.00 -5.01 -5 00:00:34 34263
256 -6.00 -5.21 -5 00:00:34 34763
256 -6.00 -5.37 -5 00:00:35 35264
257 -7.00 -5.70 -6 00:00:35 35764
256 -6.00 -5.76 -5 00:00:36 36264
256 -6.00 -5.81 -5 00:00:36 36764
257 -7.00 -6.04 -6 00:00:37 37264
256 -6.00 -6.04 -6 00:00:37 37764
256 -6.00 -6.03 -6 00:00:38 38264
256 -6.00 -6.02 -6 00:00:38 38763
256 -6.00 -6.02 -6 00:00:39 39263
256 -6.00 -6.01 -6 00:00:39 39763
256 -6.00 -6.01 -6 00:00:40 40263
256 -6.00 -6.01 -6 00:00:40 40763
256 -6.00 -6.01 -6 00:00:41 41263
255 -5.00 -5.81 -5 00:00:41 41763
256 -6.00 -5.84 -5 00:00:42 42263
256 -6.00 -5.88 -5 00:00:42 42763
256 -6.00 -5.90 -5 00:00:43 43263
256 -6.00 -5.92 -5 00:00:43 43763
>

commenting out the line containing "flag = 0" creates a little jitter in the calling of the ISR, with the result of the trim values wandering just a bit (between -4 and -7 in my case), but still quite acceptable stability.

here is the setup used:



note the use of a 270k series resistor for the crystal, and 3M3 biasing resistor; i've read that one needs to be careful to not over-drive 32kHz watch crystals as it is quite easy to damage them.

geoff: this could be a really neat addition to the micromite firmware, with the syntax of GETTIME extended thus:
RTC GETTIME [, intpin]

intpin would then be attached to the 1Hz output from the RTC, and if specified the RTC chip would be configured to active the 1Hz output. the mmbasic firmware could then provide the ISR and do the trimming internally, which would eliminate the jitter i've been seeing.

just an idea - the above BASIC code adequately achieves the results required for my own application.


cheers,
rob :-)Edited by robert.rozee 2017-01-24
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 1994
Posted: 04:55am 23 Jan 2017
Copy link to clipboard 
Print this post

Hi Robert. Hope you are well.

this is really interesting. I used another approach for the same problem without trimming the clock. I was only basing this on accurate time passage so your solution is better in that it corrects PWM and frequency measurement.

Roman Black has an intesting article here (using Bresenham's work) which I used as the inspiration

http://www.romanblack.com/one_sec.htm

this maintains the accumulated error so while it may not give accurate intervals at any one point, over time it is very precise. I never finished playing with it (got overtaken with work) your post here has awakened the idea again.

How did you determine the constants in the I and Trim calculations?


cheersEdited by CaptainBoing 2017-01-24
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2294
Posted: 01:36am 24 Jan 2017
Copy link to clipboard 
Print this post

i remember doing something similar based on bresenham's line algorithm 25 years ago when i was at uni:

on the IBM PC hardware, timer interrupt ticks were derived from a 14.31818MHz NTSC colour burst crystal - normally divided by 4 in TV applications to give 3.579545MHz - that in the case of the PC was divided by 12, then by 65536, to give a timer tick rate of approximately 18.2 ticks per second.

the 65536 divisor was programmable, and to increase the tick rate to 1mS required an approximately 1193.2 divisor. the (somewhat pedantic) solution i used was to dynamically change the divisor on each 'tick', selecting between 1193 and 1194 governed by brasenham's algorithm. as i recall the trick was to accumulate the under/over error at eack tick, then selected the divisor for the next interval (1193 or 1194) based upon the sign of the accumulated error.

it was a pedantic solution in that it would have been just as accurate to use 1193 for 4 ticks, then 1194 for the 5th. the error introduced by this would have been less than the inaccuracies in the colour burst crystal. the only advantage of the more complex solution was that my code would keep exact time with the BIOS clock - i actually looked at the BIOS source code to find the exact crystal value assumed, and have a vague feeling that it may have been a fraction different from the 'correct' value derived from the official colour burst frequency.


the choices of constants for calculating I and trim? best guesses!

the I calculation is an approximation of the integral of the error (E) over time. the approximation is in discarding 'old' errors, and giving greater prominance to current (and more recent) errors. with constants of 0.8 and 0.2 the current error gets a 20% weighting, then previous one gets 16%, then 13%, etc. if you used constants of 0.99 and 0.01 (for instance) error terms going further back in time would be taken into account.

the trim constants are even less scientific, 0.3 weighting for E was pulled out of thin air, and changing it didn't seem to make much difference. the sum of the two constants seemed to best be 1, as my feeling was that this should keep the offset error introduced close to the final trim value.


cheers,
rob :-)Edited by robert.rozee 2017-01-25
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 1994
Posted: 03:49am 26 Jan 2017
Copy link to clipboard 
Print this post

*sigh* getting all misty eyed... Those were the days...

I was never happier than when I was knee-deep in Z80 assembler and weather radar
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024