Hi,
when implement tone() Schedule?
Thanks
Hi,
when implement tone() Schedule?
Thanks
kenji - you could try to use the timer setPeriod function described at
http://leaflabs.com/docs/lang/api/hardwaretimer.html#lang-hardwaretimer
with setCount.
there are multiple timers, so you could have independent tones (one frequency per timer) on different pins.
Here's a snippet of code for tone() that I used to test some of the arduino sketches on the RET6. A more general version would check that pin provided is PWM and then lookup the corresponding timer/channel
// for maple pwm pins associated with specific timer/channel
// pin 24 timer 4 channel 4
#define TonePin 24
#define DUTY 2 //2 50% 4 25% hi
HardwareTimer timer(4);
// freq in Hz duration in ms
void tone(int pin, int freq, int duration) {
timer.pause();
pinMode(pin,PWM);
timer.setPrescaleFactor(72); // microseconds
timer.setOverflow(1000000/freq);
timer.setMode(TIMER_CH4,TIMER_PWM);
timer.setCompare(TIMER_CH4,1000000/freq/DUTY);
timer.setCount(0); // probaby doesn't matter
timer.refresh(); // start it up
timer.resume();
delay(duration);
timer.pause();
}
manitou, nice!
hardware tone() is the way to go.
Thats a lot nicer than arduino/wirings tone which arbitrarily steals timer resources in the background. I think examples like this which are small enough though still requiring a little work to understand are vastly better than everything hidden.
++good.
feurig - strongly agree with you.
A few 'Goldilocks' examples (not too big, not too small, not too hard, not too easy :-) that do interesting things motivate learning.
good += HUGE_GOODNESS
The only speaker I have is one of those 0-30V piezos from radio shack. I get the same tone, same duration no matter what I do with the variables. Hints?
The sketch
[quote]
// for maple pwm pins associated with specific timer/channel
// pin 24 timer 4 channel 4
#define TonePin 9
#define DUTY 2 //2 50% 4 25% hi
HardwareTimer timer(4);
void setup() {
}
// freq in Hz duration in ms
void tone(int pin, int freq, int duration) {
timer.pause();
pinMode(pin,PWM);
timer.setPrescaleFactor(72); // microseconds
timer.setOverflow(1000000/freq);
timer.setMode(TIMER_CH4,TIMER_PWM);
timer.setCompare(TIMER_CH4,1000000/freq/DUTY);
timer.setCount(0); // probaby doesn't matter
timer.refresh(); // start it up
timer.resume();
delay(duration);
timer.pause();
}
void loop(){
tone(9, 2000, 200);
delay(500);
}
[/quote]
Do you have a link to the RadioShack part? Most piezo's have the tone generator built in, they run off DC, and have a constant frequency. So you won't hear any change in tone with those. Also, piezos have usually a limited frequency range. You need a real speaker like this: http://www.radioshack.com/product/index.jsp?productId=2062406
But don't hook it up the to the Maple directly, 8 Ohm resistance is too much current to handle for the maple, you need a transistor in between to amplify the Maple output current.
I suspected that may be the case and it appears so. http://www.radioshack.com/product/index.jsp?productId=2062397
Thanks for your help
Well I tried a speaker, same thing. One tone no matter what I change. Changing pins changes the tone a little, but nothing huge. I have changed everything I can think of to make it sound different, and nothing. Duration variable seems useless as well. The pin variable is the only one that makes any change.
Thanks for your help, though.
Have you tested the pin+speaker to prove it works?
For example:
void loop() {
pinMode(TonePin,OUTPUT);
for (int i=100; i<1000; i+= 50) {
for (int j=0; j<500; j++) {
digitalWrite(TonePin, HIGH);
delayMicroseconds(i);
digitalWrite(TonePin, LOW);
delayMicroseconds(i);
}
}
}
Does that make a falling tone?
(WARNING: That code is not tested, or even compiled)
You chose to define TonePin as 9. That won't work. it has to be pin 24 so that the timer channel matches up with the pin. You can choose another pin, but you'll need to look up the associated timer and channel and modify Tone() accordingly.
Thanks for the code snippet, gbulmer. It would not build, though. I have been pretty busy/preoccupied lately as my wife and I's home burnt. We live in a motorhome, so it doesn't take much of a fire to set you back lol. Once we get our new living quarters, I'll be back on it, though. Thanks again!
manitou, great info, thanks! I'll try this as well. I'm not sure why I have become so side tracked by a homegrown tone() function, but I have. I bet one thing for sure, when it's all done and tone() works, I'll know more about this board than when I started and I'll know things I doubt I would have learned doing any other project.
Anyway, thanks guys! I didn't just leave, just been busy with thangs.
Note that the pin/timer/channel mappings differ based on the version of Maple you are using. My example was for an RET6. Check the pin mappings for your Maple model. (As noted, a more robust version of tone() could use the pin number to look up the timer/channel ....)
Here is v2 of a snippet of code for tone that follows the Arduino implementation more closely. It uses a timer/interrupt and any digital pin. It also uses the funky duration logic of Arduino.
volatile static int toggle_count=0;
static int tone_pin;
HardwareTimer timer(2);
// freq in Hz duration in ms
void tone(int pin, int frequency, int duration) {
timer.pause();
pinMode(pin,OUTPUT);
tone_pin = pin;
if (duration > 0 ) toggle_count = 2 * frequency * duration / 1000;
else toggle_count = -1;
// timer.setPeriod(2*1000000/freq); // in microseconds
timer.setPrescaleFactor(CYCLES_PER_MICROSECOND); // microseconds
timer.setOverflow(1000000/frequency/2);
timer.setChannel1Mode(TIMER_OUTPUT_COMPARE);
timer.setCompare(TIMER_CH1, 1); // Interrupt 1 count after each update
timer.attachCompare1Interrupt(handler_tone);
timer.refresh(); // start it up
timer.resume();
}
void noTone(int pin) {
timer.pause();
digitalWrite(pin,LOW);
}
// ISR
void handler_tone(void) {
if (toggle_count != 0){
togglePin(tone_pin);
if (toggle_count > 0) toggle_count--;
} else noTone(tone_pin);
}
You must log in to post.