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
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 type of "frequency determining element". Is it crystal or ceramic ()?
@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.
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.
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.