Why is my blinky not stable? - Page 1
Forum section: electronics / beginners

author: mortos360
author_rank: Regular Contributor
timestamp: March 23, 2014, 10:23:30 pm
content: I know that arduino is not very welcome here, but thats what I started with and teached myself so far.But my question is not arduino related... I just use it for this test.I made a simple blinky program that runs a pin 20ms ON then 20ms OFF... basically 25Hz... but its not stable, and I don't understand why?!By not stable, I mean that the frequency that I am measuring is jumping between 25.08 Hz and 25.07 Hz or so... why is that?I know that crystals can have very big difference in stability//accuracy, but we are talking about Hz here... a 16MHz crystal should have that a bit more stable then what I am measuring... or am I missing here something? ...or measuring it wrong? for the measurement I am using a DG4102 function gen. from rigol.. its has a build in counter. I don't have a real counter yet...Is it normal that a MC with cheap crystal has such an inaccuracy or am I doing something wrong here... and if its normal, how do I get a stable frequency?

author: madires
author_rank: Super Contributor
timestamp: March 23, 2014, 10:45:21 pm
content: I think we need a few details about your blinky project to be able to answer your question. Are you using an ATmega with an external 16MHz crystal? Please post the code!

author: mortos360
author_rank: Regular Contributor
timestamp: March 23, 2014, 10:50:57 pm
content: Quote from: madires on March 23, 2014, 10:45:21 pmYes, its a simple ATmega2560 with a 16MHz crystal.The code is just a loop:digitalWrite(output, HIGH)delay(20)digitalWrite(output, LOW)delay(20)

author: hamster_nz
author_rank: Super Contributor
timestamp: March 23, 2014, 11:20:57 pm
content: How are you "delaying" for 20ms? is it acheived through a h/w timer, or running instructions that take 20ms of CPU cycles?Arduino uses a timer to count milliseconds, so if you are delaying through executing clock cycles then every 1ms or so a few cycles will be stolen for timer interrupt processing, and this could be causing your jitter.If this is the case on a O'scope with infinite persistance you should see two distinct edges (as long as you have resolution to distinguish them!)Try something like this, which does reference back to the internal H/W timer - I haven't tested it, but you should get the idea that rather than waiting for 20ms, it is watching for 20ms to pass by checking the timer. It also has a bug when mills() rolls over, but that will take a while!int led = 13;void setup() {pinMode(led, OUTPUT);}void loop() {static unsigned int now = 0;static char led_state = 0;int newNow = millis() /20;if(now != newNow) {now = newNow;led_state = !led_state;digitalWrite(led, led_state ? HIGH : LOW);}}

author: matkar
author_rank: Regular Contributor
timestamp: March 23, 2014, 11:53:09 pm
content: Your frequency measurement is jumping on the last digit? You can't judge crystal accuracy with your measurement. For what we know your clock might jump from 25.0799999999 to 25.08000000000.Use timer interrupts to get exact periods.

author: hamster_nz
author_rank: Super Contributor
timestamp: March 24, 2014, 12:00:38 am
content: Quote from: matkar on March 23, 2014, 11:53:09 pmBut it looks like it should be 25.00Hz - so it is out by about 0.3%...

author: mariush
author_rank: Super Contributor
timestamp: March 24, 2014, 01:35:12 am
content: The delay function in the Arduino is not accurate. Those 20ms are not really 20ms and there can be a slight difference between delays.If you want to do it right, use assembly to get around the crud Arduino adds.. see this thread:https://www.eevblog.com/forum/microcontrollers/a-more-efficient-blink-for-avr-processors/?topicseenThere's even a video link in that thread, which shows an arduino program written in arduino doing exactly that, blinking a led.

author: kizzap
author_rank: Unknown
timestamp: March 24, 2014, 01:50:36 am
content: are we all also going to ignore the fact that instructions are not immediate, and take time? assuming a 16MHz crystal, a single instruction cycle will take 62.5nswhen you also consider that the digitalWrite function is more then just a simple write to port function (at least a read, XOR, write function on the whole port I would suspect), and the fact that the delay as others have said is not the most accurate thing, I am surprised that the output frequency is closealso what are you measuring the frequency with?Might be best to ditch the arduino code, and delve down into the assembly realm-kizzap

author: Rick Law
author_rank: Super Contributor
timestamp: March 24, 2014, 02:09:48 am
content: Using a delay function involves more inaccuracy than just the delay. If you doloop() {flipOnOff();delay(20);}Even if that delay is exactly 20ms, you went back to caller (Operating System) and now waited for it to call you back. Once you go back to the caller, the caller (Operating System) would have other house keeping stuff to do and wont call you back until all the house keeping work is finished. How long the house-keeping stuff take depends on how much house-keeping awaits and that changes. If you have a serial print in action, or serial data coming in, the OS will have more (or less) work to do from call to call.A better way is:#define waitTimeLed 20 // 20ms waiting timelong lastTimeLedFlipped=0;loop() {long currentMS=millis();if ((currentMS-lastTimeLedFlipped)>=waitTimeLed) { // waited longer than 20mslastTimeLedFlipped= currentMS;flipLedOnOff(); // however you turn it on or off}} // now go back to the OSWith this "is it time to do it yet" approach, you eliminated most of the other issues. Another benefit is now you can have multiple time dependent items. You can see one can insert another timer to say turn off the music:#define waitTimeLed 20 // 20ms waiting timelong lastTimeLedFlipped=0;#define waitTimeBuzzer 100long buzzerOnTime=0;loop() {long currentMS=millis();if ((currentMS-lastTimeLedFlipped)>=waitTimeLed) { // waited longer than 20mslastTimeLedFlipped= currentMS;flipLedOnOff(); // however you turn it on or off}if ((currentMS-buzzerOnTime)>=waitTimeBuzzer) { // time to turn on the buzzerbuzzerOnTime=currentMS;goTurnBuzzerOnOrOff();}}Switch to this approach, you should see the timer being more stable.

author: hamster_nz
author_rank: Super Contributor
timestamp: March 24, 2014, 08:23:45 am
content: I just had to look a little bit more...Here is a grab of the of the jitter in calling "delay(20);" on an Arduino Uno.Looks to be about 10us of jitter, and takes about 0.06mS longer than you would believe from looking at the source (which might be the duration of the digialWrite() call).

author: mortos360
author_rank: Regular Contributor
timestamp: March 24, 2014, 10:17:24 am
content: Just to make that clear... I don't care if I get 25Hz or 25.5Hz, i know that different commands will have different execution timings and that it ads up... what disturbs me is the jitter.I still don't understand why the frequency is jumping so much. (I am measuring 25.07X.XXX so the last 4 digits are all over the place)It looks like the loop has a different number on cycles each run... which is impossible, or?Each instruction needs x amount of cycles and when you loop it, it should always be the same... or am I wrong here?

author: TMM
author_rank: Frequent Contributor
timestamp: March 24, 2014, 11:14:04 am
content: It's because there are interrupts being executed in the background that provide the functionality for arduino functions like delay() in the first place.Using a chinese made Arduino Nano with the default blink sketch adjusted to delay(20); i get a frequency stable to +/-100uHz with a 10second gate time on a DG4062. About 5uS jitter.If you need more exact timing, run your code from a timer interrupt:http://www.instructables.com/id/Arduino-Timer-Interrupts/i.e. you set it up so ISR(TIMER[0/1]_COMPA_vect) gets called every 20us, and you have that code turn on the LED every second time, and turn it off every other time.edit:Code:int led = 13; //led pinlong Fs = 50; //sampling rate (twice the desired frequency)boolean led_status = false; //state logic for toggling ledvoid setup() {//TIMER INTERRUPT SETUPcli();TCCR1A = 0; //normal modeTCCR1B = 0; //clear TCCR1BTCCR1B |= (1 << WGM12); //CTC modeTCCR1B |= (1 << CS11) | (1 << CS10); //prescaler = 64OCR1A = (16000000/(Fs*64))-1; //set required interrupt delay for timer1aTIMSK1 |= (1 << OCIE1A); //enable timer1a interruptsei();//reenable interruptspinMode(led, OUTPUT);}void loop() {while(1); //do nothing!}ISR(TIMER1_COMPA_vect) //timer 1 interrupt{if(led_status){digitalWrite(led, LOW);led_status=false;}else{digitalWrite(led, HIGH);led_status=true;}}Jitter is less than 100ns. Frequency stability better than 10uHz.

author: mortos360
author_rank: Regular Contributor
timestamp: March 24, 2014, 11:36:15 am
content: Quote from: TMM on March 24, 2014, 11:14:04 amThanks!!I will give it a try in the evening.

author: amyk
author_rank: Super Contributor
timestamp: March 24, 2014, 01:32:42 pm
content: ...and if you wantreallyexact timing, forget about all the Arduino cruft and write it all in Asm.

author: zapta
author_rank: Super Contributor
timestamp: March 24, 2014, 03:43:13 pm
content: If you want really accurate time, use one of the spare timers of your Arduino. It will give you a rock stable frequency, and will free your cpu to do other things.

author: matts-uk
author_rank: Contributor
timestamp: March 24, 2014, 03:51:39 pm
content: Quote from: hamster_nz on March 24, 2014, 08:23:45 amJust for kicks, I wondered whether delayMicros() could do any better;Using digitalWriteCode:#define LED_PIN 13//...void loop(){delayMicroseconds(10000);delayMicroseconds(9870);digitalWrite(LED_PIN, !digitalRead(LED_PIN));}Direct to the PortCode:#define bitCheck(var,pos) ((var) & (1<<(pos)))const uint8_t ledPin = 5;//...void loop(){delayMicroseconds(10000);delayMicroseconds(9870);bitClear(DDRB, ledPin);if(bitCheck(PINB, ledPin) ) {bitSet(DDRB, ledPin);bitClear(PORTB, ledPin);}else {bitSet(DDRB, ledPin);bitSet(PORTB, ledPin);}}

author: hamster_nz
author_rank: Super Contributor
timestamp: March 24, 2014, 08:34:12 pm
content: Quote from: amyk on March 24, 2014, 01:32:42 pm... and if you wantreally reallyexact timing, forget about all the Asm cruft and do it with descrete logic... and if you wantreally really reallyexact timing, forget about all the descrete logic cruft and do it all in a FPGA... and if you wantreally really really reallyexact timing, forget about all the FPGA cruft and do it all in custom siliconIt IS turtles all the way down.... the problem is where to stop. Here is my rules of thumb for platform to different response times to changing inputs* 10ms - PCs / General purpose computers with general-purpose OS (without H/W assist)* 1ms or so - Micro controllers (without H/W assist, interrupts enabled, multiple things to manage), PC with RTOS* 100us or so - Micro controllers (without H/W assist, interrupts enabled, single tasks), maybe PC with RTOS* 10us or so - Micro controllers (without H/W assist, interrupts disabled, single tasks)* 1us or so - PC or slow Micro, with H/W assistance or hand-optimised code (e.g. timer/counter),* 100us or so - fast Micro, with H/W assistance or hand-optimised code* 10ns or so - low end FGPA* 1ns or so - implemented in silicon* less than 1ns - you must be kidding.

author: miguelvp
author_rank: Super Contributor
timestamp: March 24, 2014, 10:27:58 pm
content: Quote from: hamster_nz on March 24, 2014, 08:34:12 pmNot saying to use a PC to blink a light but the Query Performance counter (using the Time Stamp Counter with RDTSC) on a processor is very accurate. My old PC with a 6600 dual core running at 2.40GHz means each count is 0.416666(6) nanoseconds. But I agree with you, having a good timer is one thing, using the signal to do something is anotherI wonder if the Galileo has a performance counter, it should since it's a pentium right?But at 400MHz the CPU tick is 2.5ns, so that should be good for 10ns or so.http://en.wikipedia.org/wiki/Time_Stamp_CounterNote that the Intel Atom does support it, and even the AVR32 has a Performance Clock Counter based on CPU cycles.You might need to code the CPUID to decide on the behavior of the counter.CPUID opcode (0x0fa2)RDTSC opcode (0x0f31)I might need to pick myself a Galileo after all, looks like a beast of a processor, and I don't have an Arduino and this is Uno R3 compatible for shields.A quick search reveals the Intel Quark X1000 might not have RDTSC but newer chips (X1010 and X1020D) have them.http://www.cpu-world.com/news_2014/2014031301_Intel_expands_Quark_family_with_new_products.htmlBut the doc here says it doeshttps://communities.intel.com/docs/DOC-21826QuoteBut I will trust Intel more than pc-world for info on their own products.

author: Rick Law
author_rank: Super Contributor
timestamp: March 25, 2014, 03:35:52 am
content: Quote from: miguelvp on March 24, 2014, 10:27:58 pmBut have you taken into account the crystal that created the 2.4GHz signal. The crystal would likely limit you to 0.5% accuracy even if temperature is relatively constant.

author: miguelvp
author_rank: Super Contributor
timestamp: March 25, 2014, 01:41:40 pm
content: Quote from: Rick Law on March 25, 2014, 03:35:52 amThat's true, I forgot to mention that you'll need to use an accurate external oscillator to count how many ticks per second your MCU ticks at. But once you measure it, you can use that oscillator for other things.

author: Rick Law
author_rank: Super Contributor
timestamp: March 29, 2014, 05:55:28 am
content: Quote from: miguelvp on March 25, 2014, 01:41:40 pmMy favorite desktop clock used to try to impress me on how hard it works - it ticks at least once more than it needs to every day. But, after it joined the union, it quit running after 5pm until 8am the next day.What is really really annoying is, typical clock chips like DS1307 doesn't allow for compensation (like specifying exactly how many crystal ticks per 1000 second). I can see the 16MHz MCU (or 2.4GHz CPU) being uncompensated since 1% faster/slower CPU/MCU is a non-issue, but a crystal at 20ppm (0.002%) you are off 1.73 seconds a day, or about a minute a month just for the crystal alone.So, typical battery clock means everyone is in their own time zone. However undesirable, that is reality. Reality however doesn't make it less annoying when one has to adjust clocks all the time.

author: miguelvp
author_rank: Super Contributor
timestamp: March 29, 2014, 08:13:49 pm
content: Quote from: Rick Law on March 29, 2014, 05:55:28 amIf you really want accurate then go for a RTC/TCXO (Real Time Clock/Temperature Compensated Crystal Oscillator) that allows for additional compensation. For example the PCF2127AT/2Y will add ~$3 to your BOM but if you set it to run at 16384 Hz or even down to 1Hz to get your performance counter timing. It has even aging compensation.That's the cheapest I found, you can always spend more to get something a bit better that is accurate at 32768 Hz (this one in particular can be set to that, but it falls into a 60:40 duty cycle, so not good for that frequency. More expensive ones allow for more adjusting parameters.But like you said, for a CPU that is fast and provides a Time Stamp Counter or Performance Counter, I would't even worry about compensating it.

author: Rick Law
author_rank: Super Contributor
timestamp: March 30, 2014, 04:39:41 am
content: Quote from: miguelvp on March 29, 2014, 08:13:49 pmYeah, I know there are a few high accuracy clock chips with internal compensation at a few bucks more. I am just annoyed that I got a couple of projects already build with the uncompensated DS1307 and wanted to rant a bit.I actually logged some data after the rant I made. After about 20 hours of run, using my PC clock as reference (not to say that my PC clock is accurate), my MCU is fast by 53ms/hour, and my DS1307 is fast by 2.7 times that. Which is ironic because I got the DS1307 to get a more accurate time for data logging - inexperience always hurts and I just learned from that.When I have some time, I think I may actually experiment around and see if I can use the MCU to do compensation just for the hell of it. Every 3600.053 seconds on the MCU millis() is actually 1hour on a more accurate clock, so in theory it should work.It is impractical of course, since I will have to verify every MCU board as each would need a different compensation factor, and I may have an MCU on a board that has far less reliable millis() because of noise and board layout. But trying to make it work should be educational and fun.

author: miguelvp
author_rank: Super Contributor
timestamp: March 30, 2014, 05:08:50 am
content: PC's RTCs are not that accurate, good thing most PCs sync time every week.Typical drift on a PC's RTC is around 5 seconds per day, that's 208ms per hour.Some PC's can be off by up to 20 seconds per day. The problem is not with the RTC chip but how the interrupt might be handled.So part of the problem with using that as a reference is that the reference is broken. Use a real stop watch if you really want to measure time. Not sure about cell phones, so try to find a real time keeping piece, i.e. wristwatch with a chronographEdit: Or use your Oscilloscope to measure the timer signal, that's probably as good as it can get.

author: miguelvp
author_rank: Super Contributor
timestamp: March 30, 2014, 06:39:58 am
content: Here is how unstable a PC RTC is compared to the QueryPerformanceCounterThe first number is number of microseconds that is off in the current tickthe second number is the average.So in a thousand seconds it's 55 milliseconds off.in a hundred thousand seconds it's 5.5 seconds off.so in 27.777777777777777777777777777778 hours is 5.5 seconds off.That' 1 day 3 hours 46 minutes and 40 seconds to drift 5.5 seconds.Per day would be, 27.7(7) is to 5.5 like 24 is to X so, X = 24*5.5/27.7(7) = 4.752 seconds per day drift.And look at how the seconds fluctuate (first value) it's horrible!my PC seems to actually run slow on the RTCCode:second drift = -0.000055, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000054, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000054, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000054, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000031, total drift = -0.000053second drift = -0.000079, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000054, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000048, total drift = -0.000055second drift = -0.000062, total drift = -0.000055second drift = -0.000051, total drift = -0.000055second drift = -0.000059, total drift = -0.000055second drift = -0.000052, total drift = -0.000055second drift = -0.000060, total drift = -0.000055second drift = -0.000046, total drift = -0.000055second drift = -0.000063, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000054, total drift = -0.000055second drift = -0.000057, total drift = -0.000055second drift = -0.000043, total drift = -0.000055second drift = -0.000067, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000030, total drift = -0.000055second drift = -0.000080, total drift = -0.000055second drift = -0.000054, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000054, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000057, total drift = -0.000055second drift = 0.000122, total drift = -0.000051second drift = -0.000232, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000054, total drift = -0.000055second drift = -0.000056, total drift = -0.000055second drift = -0.000050, total drift = -0.000055second drift = -0.000060, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000043, total drift = -0.000055second drift = -0.000067, total drift = -0.000055second drift = -0.000055, total drift = -0.000055second drift = -0.000054, total drift = -0.000055second drift = -0.000056, total drift = -0.000055Edit: granted, that jumping per second is probably due to aliasing due to the interrupt system that maintains the clock, but in any event the average clock is still off by 55 microseconds per second average.Edit2: And thinking about it it might be that both are off, meaning the QPC and the RTC, the thing is the QPC keeps real time (even if a wrong time) the RTC oscillates a lot.I could adjust the QPC to match the average RTC easily if that was giving a good clock in the long run. But I tend to trust the QueryPerformanceFrequency to actually give me the CPU clock, so I guess I would have to spend a full day with a chrono to check if the RTC is right or the QPC is right, or both are wrong!No matter what, the average of the RTC is consistent with the QPC so there is hope!I had the program running for almost 3 hours and the average is still 55 micro seconds per secondEdit3: So QueryPerformanceFrequency claims my CPU is 2,400,050,000 Hz (weird number because it's way too round).If I adjust for the -0.000055 seconds per second and trust the average of the RTC then my CPU frequency is really: 2,399,917,997.25 Hz for a 2.4GHz rated system.That looks more plausible, But no matter what the QPC doesn't jump up and down like the RTC. I will have to investigate further to see where in between the true time lies upon.In the past I always used the average of the RTC to determine the actual frequency of the CPU when using the RDTSC, but since the introduction of the QueryPerformanceCounter and QueryPerformanceFrequency I did rely on that frequency instead. Maybe I should not.

author: miguelvp
author_rank: Super Contributor
timestamp: March 30, 2014, 09:02:26 am
content: So changing to trust the RTC, here is the output, but I still have to determine how off the RTC is2nd number is the average drift kept by the QPC, the first one is still the deviation per second of the RTC and is still horrible.So after computing the real frequency of the CPU I can have a clock with no drift by using the QPC.But I will have to investigate where the frequency of the CPU really is at between 2,400,050,000 Hz and 2,399,917,997 Hz.Code:Frequency MHz = 2399.917997second drift = -0.000001, average drift/s = -0.000001second drift = 0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000001second drift = -0.000000, average drift/s = -0.000000second drift = 0.000001, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = 0.000001, average drift/s = -0.000000second drift = -0.000002, average drift/s = -0.000000second drift = 0.000001, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000001, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000001, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000001, average drift/s = -0.000000second drift = -0.000002, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000001, average drift/s = -0.000000second drift = -0.000002, average drift/s = -0.000000second drift = 0.000001, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = -0.000002, average drift/s = -0.000000second drift = 0.000001, average drift/s = -0.000000second drift = -0.000007, average drift/s = -0.000001second drift = 0.000006, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = 0.000040, average drift/s = 0.000000second drift = -0.000042, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000001, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000000, average drift/s = -0.000000second drift = -0.000002, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = 0.000000, average drift/s = -0.000000second drift = -0.000001, average drift/s = -0.000000

author: miguelvp
author_rank: Super Contributor
timestamp: March 30, 2014, 07:00:29 pm
content: So I ran a program overnight to compute my true CPU frequency based on the RTC clock.I used the brute force approach, because I didn't want to deal with signal processing of both clocks so I averaged 8 hours worth of it.Otherwise I will have to sample the RTC with respect the QPC and viceversa and with some math get the number, but it was late so brute force it is.So the speed of the CPU's performance counter according to the RTC is 2399913708.04589784 Hz.Note the decimal part is because we are dealing with two signals of different periods, so that is the frequency taking away the time discreet offset of the RTC.Having that calibration data I can preload the average of 8 hours worth of data and run my program.With that frequency value I have a 1ns precise clock (based on the average second of the RTC over 8 hours)The first value is the second variaton of the RTC with respect of the performance counter per second.The second value is the average mean time according to the performance counter. (pretty much absorbing the waveform from the RTC being sampled at random discreet points.Code:Frequency MHz = 2399.913708second drift = -0.000006850, average drift/s = -0.000000000second drift = 0.000006455, average drift/s = -0.000000000second drift = -0.000000276, average drift/s = -0.000000000second drift = 0.000000286, average drift/s = -0.000000000second drift = 0.000000043, average drift/s = -0.000000000second drift = 0.000000991, average drift/s = 0.000000000second drift = -0.000000261, average drift/s = 0.000000000second drift = -0.000006809, average drift/s = -0.000000000second drift = 0.000006549, average drift/s = 0.000000000second drift = 0.000000834, average drift/s = 0.000000000second drift = -0.000001701, average drift/s = -0.000000000second drift = -0.000000164, average drift/s = -0.000000000second drift = 0.000001659, average drift/s = 0.000000000second drift = 0.000000200, average drift/s = 0.000000000second drift = -0.000000385, average drift/s = 0.000000000second drift = -0.000000490, average drift/s = 0.000000000second drift = -0.000000299, average drift/s = -0.000000000second drift = 0.000000568, average drift/s = 0.000000000second drift = 0.000000264, average drift/s = 0.000000000second drift = -0.000000239, average drift/s = 0.000000000second drift = 0.000001205, average drift/s = 0.000000000second drift = -0.000000359, average drift/s = 0.000000000second drift = -0.000000048, average drift/s = 0.000000000second drift = -0.000000963, average drift/s = 0.000000000second drift = 0.000002439, average drift/s = 0.000000000second drift = -0.000000310, average drift/s = 0.000000000second drift = -0.000000569, average drift/s = 0.000000000second drift = -0.000000340, average drift/s = 0.000000000second drift = -0.000006100, average drift/s = -0.000000000second drift = 0.000006703, average drift/s = 0.000000000second drift = 0.000000200, average drift/s = 0.000000000second drift = 0.000000946, average drift/s = 0.000000000second drift = -0.000001308, average drift/s = 0.000000000second drift = 0.000000774, average drift/s = 0.000000000second drift = -0.000000839, average drift/s = 0.000000000second drift = 0.000000358, average drift/s = 0.000000000second drift = -0.000005879, average drift/s = -0.000000000second drift = 0.000006286, average drift/s = 0.000000000second drift = 0.000002079, average drift/s = 0.000000000second drift = -0.000000846, average drift/s = 0.000000000second drift = -0.000000895, average drift/s = 0.000000000second drift = 0.000023038, average drift/s = 0.000000000second drift = -0.000022031, average drift/s = 0.000000000second drift = -0.000000205, average drift/s = 0.000000000second drift = -0.000000003, average drift/s = 0.000000000second drift = 0.000000440, average drift/s = 0.000000000second drift = -0.000001143, average drift/s = 0.000000000second drift = 0.000001111, average drift/s = 0.000000000second drift = 0.000000564, average drift/s = 0.000000000second drift = -0.000001690, average drift/s = 0.000000000second drift = 0.000000616, average drift/s = 0.000000000second drift = 0.000000440, average drift/s = 0.000000000second drift = -0.000000145, average drift/s = 0.000000000second drift = 0.000000530, average drift/s = 0.000000000second drift = -0.000000636, average drift/s = 0.000000000second drift = 0.000001153, average drift/s = 0.000000000second drift = -0.000001064, average drift/s = 0.000000000second drift = 0.000000575, average drift/s = 0.000000000second drift = 0.000000628, average drift/s = 0.000000000second drift = -0.000000483, average drift/s = 0.000000000second drift = 0.000000268, average drift/s = 0.000000000second drift = -0.000000115, average drift/s = 0.000000000second drift = -0.000000370, average drift/s = 0.000000000second drift = 0.000000440, average drift/s = 0.000000000second drift = 0.000024925, average drift/s = 0.000000000second drift = -0.000024716, average drift/s = 0.000000000second drift = -0.000000269, average drift/s = 0.000000000second drift = 0.000001423, average drift/s = 0.000000000second drift = -0.000000318, average drift/s = 0.000000000second drift = 0.000002330, average drift/s = 0.000000000second drift = -0.000002838, average drift/s = 0.000000000second drift = 0.000001966, average drift/s = 0.000000000second drift = -0.000001476, average drift/s = 0.000000000second drift = 0.000000020, average drift/s = 0.000000000second drift = 0.000000598, average drift/s = 0.000000000second drift = 0.000000155, average drift/s = 0.000000000second drift = 0.000000219, average drift/s = 0.000000000second drift = -0.000001004, average drift/s = 0.000000000second drift = 0.000000425, average drift/s = 0.000000000second drift = 0.000000249, average drift/s = 0.000000000second drift = 0.000000024, average drift/s = 0.000000000second drift = -0.000000025, average drift/s = 0.000000000second drift = -0.000000625, average drift/s = 0.000000000second drift = -0.000000104, average drift/s = 0.000000000second drift = 0.000002435, average drift/s = 0.000000000second drift = -0.000001634, average drift/s = 0.000000000second drift = -0.000001053, average drift/s = 0.000000000second drift = 0.000000635, average drift/s = 0.000000000second drift = 0.000000159, average drift/s = 0.000000000second drift = -0.000000063, average drift/s = 0.000000000second drift = 0.000000380, average drift/s = 0.000000000second drift = -0.000000179, average drift/s = 0.000000000second drift = 0.000000538, average drift/s = 0.000000000second drift = 0.000000129, average drift/s = 0.000000000second drift = -0.000000693, average drift/s = 0.000000000second drift = 0.000000264, average drift/s = 0.000000000second drift = -0.000000914, average drift/s = 0.000000000second drift = 0.000001531, average drift/s = 0.000000000second drift = -0.000001079, average drift/s = 0.000000000second drift = 0.000000174, average drift/s = 0.000000000second drift = 0.000000609, average drift/s = 0.000000000second drift = 0.000000980, average drift/s = 0.000000000second drift = -0.000000078, average drift/s = 0.000000000second drift = -0.000000884, average drift/s = 0.000000000second drift = 0.000000489, average drift/s = 0.000000000second drift = -0.000000745, average drift/s = 0.000000000I'm going to start it again and let it run for a long time.