Tone generator

Ive been trying to output 14hz using tone as well as the Tone library however I am unable to get it to work. Ive tried to do it my self using delay and delayMicroseconds however the timing is not precise and I am unable to get a stable output.

Does anyone have any suggestion on how I can get this to work,

TIA

You haven't posted your code, which is sad, because we don't know exactly what you are doing.

However testing my own code:

void setup ()
{
  tone(5, 15);
}

void loop () {}

This gives a measured frequency of 974 Hz.

However:

void setup ()
{
  tone(5, 14);
}

void loop () {}

Gives me 170 Hz.

And:

void setup ()
{
  tone(5, 13);
}

void loop () {}

Gives me 89 Hz.

So there seems to be no correlation between the requested, and actual, frequency at low frequencies. A requested frequency of 440 gave reasonably accurate results (439.36 Hz).

Ok so thats why it seems that the LED stays lit. I have looked into the TimerOne library using

#include <TimerOne.h>

void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
  Timer1.initialize(35714);
  Timer1.pwm(9, 512, 35714);
}
void callback() {
  digitalWrite(13, digitalRead(13) ^ 1);
}
void loop() {
  Timer1.attachInterrupt(callback);
}

However I think it does not go to ground when it goes to LOW because my transistor stays on.
Ill keep looking for a solution however it seems this will be harder than I thought it would be

Running your exact code on my Uno, LED 13 flickered and I measured a frequency of 13.975 Hz.

I figured it out. I had to change the change state to instead use a if statement.

#include <TimerOne.h>
int a =0;
void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
  Timer1.initialize(35714);
  digitalWrite(13, LOW);
  Timer1.pwm(9, 512, 35714);
}
void callback() {
  if (a == 0) {
  digitalWrite(13, HIGH);
  a = 1;
}
else {
  digitalWrite(13, LOW);
  a = 0;
}
}
void loop() {
  Timer1.attachInterrupt(callback);
}

The other code worked on my led but when it came to the transistor I guess it did not drop down to 0V as the transistor stayed active. However this new code works great. I will just tweak the timing until 14hz is achieved. (+1-2 should get around there)

Thanks for your input. Im glad this is working.

brianmay27:
...

...

void loop() {
  Timer1.attachInterrupt(callback);
}
...

Do that in setup, not loop. Your ISR worked for me, but this should also work:

if (digitalRead(13) == LOW)
  digitalWrite(13, HIGH);
else
  digitalWrite(13, LOW);

or digitalWrite(13, !digitalRead(13)); // watch the !

I was going to write that but got talked out of it here:

http://arduino.cc/forum/index.php/topic,74861.0.html

Lastly on a pure note, it "violates" type, we are relying on that LOW is !HIGH by the quirks of C's boolean representation.

However if coding for myself I would do what you suggested. :slight_smile:

NIck, there is so much to be learned form other peoples optimizations. But I like the documented ones.
At school we learned to at least keep the original code as comment, together with how the optimization works.
So people could understand where you came from...

// milliRadians = 1000 * degrees * 2 * PI / 360; // expensive float in math
==>
unsigned long milliRadians = degrees * 17750L/1017L;

I think I like magic numbers :slight_smile: