Go Down

Topic: Internal oscillator 328P how 'inaccurate' is it? (Read 4343 times) previous topic - next topic

CopperDog

So I have my 328P running the calibrated internal oscillator (no external crystal or resonator). The datasheet indicates the internal is not designed for high accuracy. So how inaccurate are we talking about here?

My chip is running a game timer. Can I expect to see timing errors in the range of seconds, minutes or just a few millis in a 30 minute game?
Personal bytes are finite, save room for play.

Coding Badly


DrAzzy

Page 304 quotes +/-10% for the '328p, which is terribad - but that's over the full temp range specified, while you're likely to be running it at room temperature.

Some of the other AVR chips spec 2%, or 2% w/in narrow temp range, 10% w/in full temp range.
ATTinyCore for x4/x5/x61/x7/x8/x41/1634/828/x313 megaTinyCore for the megaavr ATtinies - Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts, mosfets, awesome prototyping board in my store http://tindie.com/stores/DrAzzy

jboyton

It also says that user calibration via the OSCCAL register can narrow the error to ±1% over the whole temperature range. Even allowing for a narrower range it still sounds like the error would be on the order of seconds per 30 minutes. But I have not tried it, not yet anyway.

CopperDog

This application could be exposed to anything from -15 to 30+ Celsius so the I expect there to be some effects. The calibration is set to 0x9A which in the data sheet is listed as a reserved address. Any idea what that setting is giving me for a clock frequency?
Personal bytes are finite, save room for play.

CopperDog

#5
May 13, 2015, 01:43 am Last Edit: May 13, 2015, 01:58 am by CopperDog
Have you tuned the oscillator?
The 0x9A clock calibration setting refers to the tuned value correct? To get the best internal accuracy the clock calibration should be set to match the system voltage, if I'm reading this right.  If I'm interpolating correctly then my internal oscillator should be set to 7.99 MHz for the 5V rail. Is this correct?
Personal bytes are finite, save room for play.

jboyton

The calibration is set to 0x9A which in the data sheet is listed as a reserved address. Any idea what that setting is giving me for a clock frequency?
Huh? What do you mean the value is a reserved address?

It's in the data sheet. At system reset a default value is loaded into the OSSCAL register which gives you 8MHz ± 10%. You can reprogram the register to tweak the frequency and get better accuracy. There are charts in the data sheet that show the relationship between the OSSCAL value and the frequency, as well as the temperature dependence. But if it were me I'd want to measure the clock frequency, either with an oscilloscope or by comparing the output of a counter against a stopwatch over some period of time.

I suppose it would be possible to continually tweak the value based on temperature and voltage measurements. I don't know how well that would work. At some point it's easier to buy a crystal.

CopperDog

Huh? What do you mean the value is a reserved address?
Sorry, this is my first foray into the chip settings. When I search the data sheet the only reference I find for 0x9A is a page that shows it as a reserved address.

I had a crystal on the chip but the audio (tone) output of this chip is getting sent to a siren through a 5W amplifier. I was getting an artifact from the crystal that could be heard in the amplifier output. Running on the 8MHz internal I get none of that.

I'll look for the charts.
Personal bytes are finite, save room for play.

CopperDog

Ahh. I see the chart you mean. (ATmega328P: Calibrated 8 MHz RC Oscillator Frequency vs. OSCCAL Value).

So, the 0x9A (154 DEC) at 8MHZ plots outside the charts best range. The 8MHZ line intersects the curve at 184 or 0xB8. Am I interpreting that correctly? 
Personal bytes are finite, save room for play.

CopperDog

Is it as simple as putting OSCCAL = 154; in Setup()?
Personal bytes are finite, save room for play.

uxomm

Quote
Is it as simple as putting OSCCAL = 154; in Setup()?
Yes!

But with the value you may have to experiment to get good results.

You could also take a look what the OSCCAL of your individual 328P is at the moment like

Code: [Select]

void setup()
{
     Serial.begin(9600);
     Serial.println(OSCCAL);
}
Always decouple electronic circuitry.

CopperDog

Personal bytes are finite, save room for play.

westfw

The OSCCAL loaded at reset is one that is programmed at the factory to yield the specification in the datasheet (~10% at some particular operating voltage, IIRC.)
You can fine-tune the value for your particular operating conditions, and/or a slightly different frequency, by loading a different value into OSCCAL, but you probably have to determine the value experimentally - it's not something you can just read off the graph in the datasheet - if the datasheet were exact, they'd just program OSCCAL to have the exactly correct value.

There are some tools that you can use to find more accurate values, assuming that you have an accurate thing to measure them.  Google "osccal calibration clock arduino" and there are lots of results...


CopperDog

Yes I see your point. Just referencing the graph is not going to do it. I'll do some testing. The accuracy may be enough as is.
Personal bytes are finite, save room for play.

Nicknml

#14
May 13, 2015, 09:23 pm Last Edit: May 13, 2015, 09:24 pm by Nicknml
I've had an experience with inaccuracy of an internal oscillator, not with a 328p but with a 1284p.  When I was using the serial peripheral, I was getting garbage output.  I thought the serial peripheral was fried from a wiring mistake.  I then decided to switch over to an external crystal and the serial worked fine, which pointed to the internal oscillator being problematic.  I then used PWM on one of the pins to get a frequency low enough that could be measured my my multimeter's frequency measurement function. Turned out, it was off a bit.

I then hooked up the external crystal (and of course made the necessary changes to the fuses) and read the factory programmed OSCCAL value to give me a starting point.  I then switched back to the internal oscillator and experimented until I found an OSCCAL value that got me as close as I could get to 8 MHz.  After that, the serial peripheral worked off of the internal oscillator just fine.

Go Up