Need help generating tone of exact frequency

Hello,
I need to generate a tone somewhere in the frequency range 8269.8Hz to 8273.3Hz
I already tried using tone() but it doesn't even come close and I don't understand that timer stuff
I'm using an Arduino Uno but I got a Mega 2560 if that would help

Thank you

Get a cheap DDS board, like AD9850.
Typically accurate to something like 1/30Hz.

Your expectation of achieving +/-0.02% accuracy based on the timing reference of a hobbyist-quality processor board is extremely unrealistic.

somewhere in the frequency range 8269.8Hz to 8273.3Hz

Please explain what this means.

Does it matter what the frequency is, as long as it is in that range? If so, how accurately must the frequency be known?

Does it matter what the frequency is, as long as it is in that range? If so, how accurately must the frequency be known?

no, it doesn't matter where the frequency is as long as it is in that range

The Mega and the Uno both use a ceramic resonator for timing. It's not accurate enough for your application and the frequency also drifts horribly with temperature.

aarg:
The Mega and the Uno both use a ceramic resonator for timing. It's not accurate enough for your application and the frequency also drifts horribly with temperature.

My UNO Board and other 50 Boards in Lab/with pupils have this crystalOsc.jpg type of "frequency determining element". Is it crystal or ceramic (ceramicOsc.jpg)?

crystalOsc.jpg

ceramicOsc.jpg

@GolamMostafa, the resonator on board the UNO and MEGA does not look like that, it is not in a epoxy dipped package like you have shown above. It is in a very small can, like a crystal.

aarg:
The Mega and the Uno both use a ceramic resonator for timing. It's not accurate enough for your application and the frequency also drifts horribly with temperature.

A drift of 1Hz would be okay

randomhuman3232:
A drift of 1Hz would be okay

Why don't you take a proper engineering approach and start by comparing the specs of your proposed target board against your requirements? As I opined in Reply #2, your expectations may be unrealistic.

For example, the Murata CSTCE_V, which is similar if not identical to the one on the UNO and MEGA, has an initial spec of +/-0.5% and a temp drift of 0.3%. So your 8270Hz frequency could be +/- 66 Hz.

Use micros() and blink without delay, see what you can achieve.

8269.8Hz to 8273.3Hz = period of 120.9 microseconds to 120.8 uS.
120 is divisible by 4, the Arduino does micros() in multiples of 4.
So is 1/2 of that, so that works out well.

Try this code out

unsigned long halfPeriod = 60;
unsigned long previousTime;
unsigned long currentMicros;
unsigned long nextHalfPeriod;
byte outputPin = 2;


void setup(){
pinMode (outputPin, OUTPUT);
previousTime = micros();
}
void loop(){
  while (1){ // avoid loop jitter, might still get some from micros()/millis() interrupts
    currentMicros = micros();
    if ((currentMicros - nextHalfPeriod) >= halfPeriod){
    PIND = 0b00000100; // toggle D2 by writing 1 to the input register
    nextHalfPeriod = nextHalfPeriod + halfPeriod;
    }
  }
}

I see in the Reddit thread on this topic, that you plan on using the tone for a transmitter. Are you sure that a square wave will be appropriate for that? If it's for a local oscillator or some such thing, you need a sine wave.

CrossRoads:
Use micros() and blink without delay, see what you can achieve.

8269.8Hz to 8273.3Hz = period of 120.9 microseconds to 120.8 uS.
120 is divisible by 4, the Arduino does micros() in multiples of 4.
So is 1/2 of that, so that works out well.

Try this code out

unsigned long halfPeriod = 60;

unsigned long previousTime;
unsigned long currentMicros;
unsigned long nextHalfPeriod;
byte outputPin = 2;

void setup(){
pinMode (outputPin, OUTPUT);
previousTime = micros();
}
void loop(){
  while (1){ // avoid loop jitter, might still get some from micros()/millis() interrupts
    currentMicros = micros();
    if ((currentMicros - nextHalfPeriod) >= halfPeriod){
    PIND = 0b00000100; // toggle D2 by writing 1 to the input register
    nextHalfPeriod = nextHalfPeriod + halfPeriod;
    }
  }
}

on my Arduino, that code results in an output frequency of ~8333Hz and if I adjust the halfPeriod variable to 61 the frequency jumps to ~8197Hz so nowhere near accurate enough

aarg:
I see in the Reddit thread on this topic, that you plan on using the tone for a transmitter. Are you sure that a square wave will be appropriate for that? If it's for a local oscillator or some such thing, you need a sine wave.

The Arduino output gets (through a filter) fed into the input of my amplifier and then (through another filter) into the antenna

Won't you need better accuracy? Wiki says,
"Operations tend to congregate around the frequencies 8.27 kHz, 6.47 kHz, 5.17 kHz and 2.97 kHz.[17] Bandwidths of a few tens of µHz[citation needed] are typical and both receiver and transmitter must have their frequency locked to a stable reference such as a GPS disciplined oscillator or a rubidium standard."

aarg:
Won't you need better accuracy? Wiki says,
"Operations tend to congregate around the frequencies 8.27 kHz, 6.47 kHz, 5.17 kHz and 2.97 kHz.[17] Bandwidths of a few tens of µHz[citation needed] are typical and both receiver and transmitter must have their frequency locked to a stable reference such as a GPS disciplined oscillator or a rubidium standard."

The receiver bandwidth is 4Hz wide so if I drift 2Hz that would be okay I'm going to have a better setup later but I want this one to work before I spend a bunch of money

randomhuman3232:
The receiver bandwidth is 4Hz wide so if I drift 2Hz that would be okay I'm going to have a better setup later but I want this one to work before I spend a bunch of money

Then go with reply #1. Or you can program the 16U2 co-processor on the UNO, it has a real quartz crystal.

aarg:
Then go with reply #1. Or you can program the 16U2 co-processor on the UNO, it has a real quartz crystal.

Does the Coprocessor have access to the Arduino pins?

randomhuman3232:
Does the Coprocessor have access to the Arduino pins?

No but it has pins you can access because it has its own ICSP connector. I have used it to generate a PPS pulse. It's the chip that does the USB-serial conversion. Another way is to use a clone board, often they use a quartz crystal for the main processor instead of a resonator.