2015-10-10 2 views
1

Я пытаюсь воспроизвести тон, изменяя что-то на ЖК-дисплее. Я искал вокруг и пробовал protothreads, но кажется, что задержка все еще блокирует программу. Я также попытался удалить задержку вообще, но она пропустила все, кроме последней заметки. Есть ли способ играть тон без задержки? (Миллис возможно?)Arduino - Тон без задержки

Пример последовательности тона:

//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); 
} 
+0

Вам нужно 4 звуковых сигнала (beeeep beeeep beeeep beep) справа? Что означает 1 + W в функции задержки? Аргумент функции задержки - миллисекунда. –

+0

@AdisakAnusornsrirung 1 + W = целая нота плюс 1 миллисекунда. – pandalion98

+0

Задержка означает остановку воспроизведения тона? –

ответ

2

Вы можете установить таймер и поставить к сведению изменения логики в подпрограмме обработки прерываний (ISR).

Каждые X миллисекунд таймер сбрасывает и прерывает ваш основной цикл. ISR запустится и выберет следующую заметку и вызовет функцию тона. После выхода из ISR программа продолжается с момента ее прерывания.

Я приложил код, который использовался в одном из моих проектов. Таймер прерывает основной цикл каждые 50 мс (20 Гц), поэтому вам нужно будет поместить свои собственные номера в OCR1A и предварительный сканер. Пожалуйста, прочитайте больше о прерывании таймера в arduino, чтобы вы поняли, как это сделать (например, здесь: http://www.instructables.com/id/Arduino-Timer-Interrupts/step2/Structuring-Timer-Interrupts/). Вы также можете увидеть пример в конце этой страницы (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 
} 
+0

Whoa. На самом деле не было уверен, как использовать таймер 1 раньше. – pandalion98