Cleaning up frequency variance of tone()

I have tone(8, 1500) generating my 1500 Hz square wave, which is exactly what I need, but when I scope it I get about 1505.5 Hz. Believe it or not, this is unacceptable. Is there some way I can get it down to 1500 ± .1 Hz? Either via software or hardware, it's all the same for my application.

Perhaps there is a math error in the tone library. Even if the system clock was being divided by 10666 instead of 10666.6666... it should still come out as 1500.094 Hz.

Maybe it's using an 8-bit timer. That would mean they'd have to use a clock pre-scaler (divider) of 64. The resulting clock is then 250,000 which is 166.666 times what you want. If that gets truncated to 166 the frequency would come out 1506.024 Hz. Perhaps you should program Timer 1 (the 16-bit timer) to generate the frequency you want.

johnwasser:
Perhaps there is a math error in the tone library. Even if the system clock was being divided by 10666 instead of 10666.6666... it should still come out as 1500.094 Hz.

Maybe it's using an 8-bit timer. That would mean they'd have to use a clock pre-scaler (divider) of 64. The resulting clock is then 250,000 which is 166.666 times what you want. If that gets truncated to 166 the frequency would come out 1506.024 Hz. Perhaps you should program Timer 1 (the 16-bit timer) to generate the frequency you want.

With tone() set to 1495, I scope a value of 1496. With tone() set to 1505, I see 1505.1. That's more reasonable. However, picking a random value off the top of my head, with tone(9, 2106), I scope 2117.3. Is this still related to the clock pre-scaler?

Is this still related to the clock pre-scaler?

Yes. And the fact that an 8 bit timer is used. And the fact that certain frequencies are impossible to generate from a fixed frequency processor.

Well, ok. I'm willing to accept that. Can anyone steer me in a good direction to start learning about programming my 16-bit timer to see if I can bend it to my will?

http://www.arduino.cc/playground/Code/Timer1

Can anyone steer me in a good direction to start learning about programming my 16-bit timer to see if I can bend it to my will?

It's going to be a bit difficult to help you do that given the fact that the timer is inanimate. Unless you're a cyborg. Are you a cyborg? Hmm. Probably not or you would not need help getting a bit of silicon to perform your bidding.

If you'd like serious help, I suggest providing a brief description of your project and what you'd like to accomplish.

I wear glasses, so by the crudest definition, yes, I am a cyborg.

Funny comments aside, someone above mentioned I could program the timer to do what I want. I'd like to know a good place to start reading on the techniques and feasibility.

My entire project is beyond the scope of this thread, the little blue board is just a small part of it. For now, I need to generate a 1500±.1 Hz 50% duty cycle square wave.

For now, I need to generate a 1500±.1 Hz 50% duty cycle square wave ... someone above mentioned I could program the timer to do what I want.

Let's find out...

Frequency of Timer 1 in CTC Mode = F_CPU / (2 * N * (1 + OCR)) ; N = 1, 8, 64, 256, or 1024
Frequency of Timer 1 in CTC Mode = 16000000 / (2 * 1 * (1 + 5332))
Frequency of Timer 1 in CTC Mode = 1500.093756

Yup. And there are the N and OCR values you will need.

I'd like to know a good place to start reading on the techniques and feasibility.

The link provided by @johnwasser is a good start. The datasheet is also handy...