Pages: [1] 2   Go Down
Author Topic: millis() off by 20%?  (Read 1545 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 19
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi folks,

i've been having timing issues with one of my sketches, and eventually figured out that millis() is fast by about 20% on my board (Uno).  In my sketch, i log a line once every 1000ms (as received by millis()).  I've also got a GPS attached, so i can check the internal time against the GPS time. 

It's pretty consistent, but for every 10s that passes on the GPS, about 7800ms (give or take a hundred or so ms to account for lag) passes on the internal clock. 

Does anyone know why this might be happening?  I googled around for others having this problem, but i only found folks talking about millis being off around 5s per day.

Thanks.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24370
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Have you changed the crystal?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16518
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I don't find it all that remarkable that the ceramic resonator is off by 20%.

Really?

I would find that very remarkable and if so, put it off as a mismarked resonator or defective.

SparkFun rates their 16mhz resonator at +/-0.5% or better from -20C-+80C.

http://www.sparkfun.com/products/9420

PS: A resonator with a 20% error would not even be able to upload sketches from the IDE as the bootloader sets up the baudrate assuming a 16mhz clock frequency.

Lefty

« Last Edit: September 27, 2011, 11:49:22 am by retrolefty » Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16518
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Which is exactly why the Arduino folks used a real crystal in the "USB" processor and not a ceramic resonator. Your honor, I rest my case.

Your honor the witness doesn't know what he is talking about. Even if the 8u2 clock was 100% accurate the serial communications between the 328p and the arduino IDE couldn't possibly work if the 328p clock was 20% off as it is what determines what speed the serial data is clocked into or out of the hardware usart in the 328p. The hardware serial library calculates the baudrate divider hardware in the 328p assuming a 16mhz clock, as does the bootloader code to allow uploading of a sketch. An arduino with a processor clock error of 20% just wouldn't function with the IDE.

Are you sure you wish to rest your case before the jury?

Lefty
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

i've been having timing issues with one of my sketches, and eventually figured out that millis() is fast by about 20% on my board (Uno).  In my sketch, i log a line once every 1000ms (as received by millis()).  I've also got a GPS attached, so i can check the internal time against the GPS time. 

It's pretty consistent, but for every 10s that passes on the GPS, about 7800ms (give or take a hundred or so ms to account for lag) passes on the internal clock. 

Does anyone know why this might be happening?  I googled around for others having this problem, but i only found folks talking about millis being off around 5s per day.

It seems very strange that millis() seems to be 20% out but the serial port is working normally. Can you post your sketch? Are you using arduino-0022?
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16518
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

And yet __Tango's Uno appears to be accepting (and presumably sending) serial data between the Arduino processor and the USB processor. Even with a 20% error.

 I haven't even looked into Tango's problem. I'm just responding to your statement that ceramic resonators can have up to 20% error. Again I will state, the Arduino board could not even function with the IDE if the clock was 20% off value from 16mhz. I showed you accuracy specification of one rather inexpensive resonator showing it's accuracy specification. Have you any links to datasheets showing a 16Mhz ceramic clock resonator for sale with a 20% accuracy tolerance specification?

What is your theory for why they used a real crystal on the USB processor, but a cheap ceramic resonator for the Arduino processor?  Upon casual observation, that would seem backwards.

I have no idea what drove the Arduino people to use both a crystal and a resonator on the board. I know on first release the Uno board's picture showed using two crystals.

Lefty

Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16518
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tang;

 Yes, please show your sketch. The only thing I can think of that could cause such a large error in you millis() function over time is if you are somehow directly or indirectly causing interrupts to be disabled for long periods of time. As millis() utilizes a timer interrupt, it's important not to disable interrupts any longer then necessary.

Lefty
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 19
Arduino on the rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For my own sketch using millis() and Serial.print*() I found that sending data with Serial.println() messes up the counted millis. And the lower the serial console baud rate, the bigger the effect. My conclusion was that the two interfere.

At least setting the baud rate as high as possible solved the problem for the most part.
Logged

Global Moderator
Netherlands
Online Online
Shannon Member
*****
Karma: 170
Posts: 12457
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dear __TANGO,

could you post your sketch that has the 20% error?   maybe there is some logic stopping the millis()  clock in it ... That happens sometimes with interrupts etc.

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16518
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

1) __Tango would be reporting a DIFFERENT problem (that he couldn't upload sketches) if there were a problem communicating between the USB processor and the Arduino processor.  The fact that he is able to upload code and download test results would appear to be prima facia evidence that the serial and USB communication are operational.

Agreed, and that means the clock frequency of the 328p is accurate enough to support the 115200 baudrate of the bootloader, not something possible if the resonator was off by 20%.


2) The places that fabricate and assemble PC boards for cheap are deep in the interior of a place where datasheets (even if they did exist) are written in a language foreign to both of us.  And those assembly vendors concentrate on delivering the minimum requirement for the lowest price. That is how they survive in their industry.  OTOH, if "official" Arduino boards are really manufactured in Italy then we must come up with some other explanation.  Or __Tango could have a counterfeit or clone for all we know.

"Official" Arduino boards are made in Italy, however they have lincensed some firms (SparkFun? other?) to manufacture some of their board types. Of course the vast number of Asian 'arduino' boards are not official but are made and sold without regards to and violating the Arduino trademark.

3) I suspect that the board manufacturer (Arduino?, their vendor?, a counterfeiter?) saves money by requiring only some sort of functionality test at the end of the assembly line and does not reject boards for clock frequency excursions.  I continue to reject the notion that a u-proc clock can be used for timekeeping in any meaningful way.  We have RTC and TCO for that sort of thing.

Time keeping over longer periods is best done using a RTC or other methods, no disagreement there. Even if one used a high accuracy crystal or TCXO or OCXO clock oscillator, the fact that interrupt useage can effect millis() accumulation over time is a good reason not to use software RTC functions.

4) They left the hole patterns for a proper crystal for those who find the cheap ceramic resonator intolerable.

Or to give them flexiblity on sourcing parts for batch manufacturing runs. There wanting and receiving FCC type acceptenace for the Uno board could be another reason for their resonator choice. Only someone from the Arduino firm could answer those questions.

5) I agree that there could be other reasons for __Tango's reported results. But apparently my world-view is not as tidy and accurate as yours. An Arduino board is low-end mass-market consumer goods. Not intended to be any kind of accurate laboratory- (or even industrial-) grade product.  Note that there is no published spec for the Uno clock accuracy.

It is a mass-market product for sure, but must have a time base accuracy good enough to support the 115200 baudrate used by the bootloader.
Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 64
Posts: 6055
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

For my own sketch using millis() and Serial.print*() I found that sending data with Serial.println() messes up the counted millis. And the lower the serial console baud rate, the bigger the effect. My conclusion was that the two interfere.

Which one would expect.  Serial.print() blocks until the string it has been given has been transferred.  So in your case you were actually measuring how long it took to transfer data and not the accuracy of millis().

This is why it is important for the OP to post their code.  It is more likely their method for measuring millis() is at fault and not the board itself.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Austin, TX
Offline Offline
Faraday Member
**
Karma: 64
Posts: 6055
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Gentlemen,

Any chance you guys could take your "discussion" offline?  It isn't relevant (anymore) to the original poster's question.

Thanks.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16518
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gentlemen,

Any chance you guys could take your "discussion" offline?  It isn't relevant (anymore) to the original poster's question.

Thanks.

Actually I think we scared him away?

Lefty

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

My Arduino Ethernet is receiving lots of data via NewSoftSerial (actually, the latest version named 'SoftwareSerial' internally) and saving it to an SD card.

I've been using RTClib's millis()-based clock, and it's slow by four hours or more after a 24-hour period. I know NewSoftSerial uses pin change interrupts a lot - could these be getting in the way of the millis() timers?

(The solution is, of course, to use a hardware RTC. And I've discovered one lives in the VC0706 camera. I'm going burrowing...)
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 220
Posts: 6587
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I think the problem is that SoftwareSerial disables interrupts for a whole character period when sending or receiving a character. If you are sending or receiving at 9600 baud or slower, this is more than a millsecond and you will lose some of the timer interrupts that are needed for millis() to return the correct value. You could try using a higher baud rate, but a better solution is to use a hardware UART.

If you already are using a higher baud rate, then try setting whatever is sending the data to use 2 stop bits instead of 1.
« Last Edit: September 28, 2011, 05:16:39 am by dc42 » Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Pages: [1] 2   Go Up
Jump to: