Arduino - 音调毫不拖延
Arduino - Tone without delay
我试图在改变 LCD 显示器上的内容时播放音调。我四处搜索并尝试了 protothreads,但似乎延迟仍然阻止了程序。我也试过完全消除延迟,但它跳过了除最后一个音符之外的所有内容。有没有办法在不使用延迟的情况下播放音调? (也许是毫秒?)
示例音序列:
//Beats per Minute
#define BPM 250
//Constants, try not to touch, touch anyways.
#define Q 60000/BPM //Quarter note
#define W 4*Q //Whole note
#define H 2*Q //Half note
#define E Q/2 //Eigth note
#define S Q/4 //Sixteenth note
void toneFunction()
{
tone(tonePin,C5,Q);
delay(1+W);
tone(tonePin,C5,Q);
delay(1+W);
tone(tonePin,C5,Q);
delay(1+W);
tone(tonePin,C6,W);
}
您可以设置一个计时器并将音符更改逻辑放入中断服务程序 (ISR)。
每隔 X 毫秒,计时器将重置并中断您的主循环。 ISR 将 运行 并选择下一个音符并调用音调函数。退出 ISR 后,程序从中断点继续。
我附上了我在我的一个项目中使用的代码。定时器将每 50 毫秒(20 赫兹)中断一次主循环,因此您必须将自己的数字放入 OCR1A 和预分频器中。请阅读有关 arduino 中定时器中断的更多信息,以便您了解如何执行此操作(例如此处:http://www.instructables.com/id/Arduino-Timer-Interrupts/step2/Structuring-Timer-Interrupts/). You can also see the example at the end of this page (http://playground.arduino.cc/Code/Timer1)以获得更用户友好的方式。
setup() {
....
/* Set timer1 interrupt to 20Hz */
cli();//stop interrupts
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
OCR1A = 781; // approximately 20Hz
TCCR1B |= (1 << WGM12);// turn on CTC mode
TCCR1B |= (1 << CS12) | (1 << CS10); // 1024 presxaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
sei();//allow interrupts
}
...
ISR(TIMER1_COMPA_vect){
// pick next note
}
我试图在改变 LCD 显示器上的内容时播放音调。我四处搜索并尝试了 protothreads,但似乎延迟仍然阻止了程序。我也试过完全消除延迟,但它跳过了除最后一个音符之外的所有内容。有没有办法在不使用延迟的情况下播放音调? (也许是毫秒?)
示例音序列:
//Beats per Minute
#define BPM 250
//Constants, try not to touch, touch anyways.
#define Q 60000/BPM //Quarter note
#define W 4*Q //Whole note
#define H 2*Q //Half note
#define E Q/2 //Eigth note
#define S Q/4 //Sixteenth note
void toneFunction()
{
tone(tonePin,C5,Q);
delay(1+W);
tone(tonePin,C5,Q);
delay(1+W);
tone(tonePin,C5,Q);
delay(1+W);
tone(tonePin,C6,W);
}
您可以设置一个计时器并将音符更改逻辑放入中断服务程序 (ISR)。
每隔 X 毫秒,计时器将重置并中断您的主循环。 ISR 将 运行 并选择下一个音符并调用音调函数。退出 ISR 后,程序从中断点继续。
我附上了我在我的一个项目中使用的代码。定时器将每 50 毫秒(20 赫兹)中断一次主循环,因此您必须将自己的数字放入 OCR1A 和预分频器中。请阅读有关 arduino 中定时器中断的更多信息,以便您了解如何执行此操作(例如此处:http://www.instructables.com/id/Arduino-Timer-Interrupts/step2/Structuring-Timer-Interrupts/). You can also see the example at the end of this page (http://playground.arduino.cc/Code/Timer1)以获得更用户友好的方式。
setup() {
....
/* Set timer1 interrupt to 20Hz */
cli();//stop interrupts
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
OCR1A = 781; // approximately 20Hz
TCCR1B |= (1 << WGM12);// turn on CTC mode
TCCR1B |= (1 << CS12) | (1 << CS10); // 1024 presxaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
sei();//allow interrupts
}
...
ISR(TIMER1_COMPA_vect){
// pick next note
}