Вопрос по функции tone

Orrca
Offline
Зарегистрирован: 03.08.2016

Добрый день.

Почему нижеследующий код приводит к коротким щелчкам с периодичностью в секунду вместо того, чтобы играть сигнал в течение секунды, потом секунда тишины и снова? Помогите советом, плз. 



#define BUZZER_PIN 3



void setup()

{

pinMode(BUZZER_PIN, OUTPUT);

}



void loop()

{

tone(BUZZER_PIN, 200, 1000);

noTone(BUZZER_PIN);

delay (1000);

}

negavoid
Offline
Зарегистрирован: 09.07.2016

Потому что вы его сразу же выключаете.

#define BUZZER_PIN 3

void setup()
{
pinMode(BUZZER_PIN, OUTPUT);
}

void loop()
{
tone(BUZZER_PIN, 200);
delay (1000);
noTone(BUZZER_PIN);
delay(1000);
}

 

Orrca
Offline
Зарегистрирован: 03.08.2016

Не так. Третий аргумент в функции tone - длительность и у меня она задана 1000 мс, то есть сигнал должен звучать 1 секунду. Только после этого следует функия noTone. Но этого не происходит. Вместо этого слышен щелчок. Ваш вариант программы я пробовал сам. Работает. Но почему не работает исходный вариант? В этом и вопрос.

negavoid
Offline
Зарегистрирован: 09.07.2016

Orrca пишет:

Не так. Третий аргумент в функции tone - длительность и у меня она задана 1000 мс, то есть сигнал должен звучать 1 секунду. Только после этого следует функия noTone. Но этого не происходит. Вместо этого слышен щелчок. Ваш вариант программы я пробовал сам. Работает. Но почему не работает исходный вариант? В этом и вопрос.

Ответ: "Потому что вы его сразу же выключаете". :) Функция tone() неблокирующая, она не ждёт 1000 мсек, а включает генерацию и сразу возвращает управление обратно, на следующую команду, выключения генерации - noTone() - это щелчок. Потом delay() ждёт секунду молчания после щелчка, и всё по-новой.

void loop()
{
tone(BUZZER_PIN, 200, 1000);
delay(2000);
}

 

Orrca
Offline
Зарегистрирован: 03.08.2016

Большое спасибо за ответ. Это многое поясняет. Тогда еще один маленький вопрос. Если эта функция не блокирующая, то каков смысл ее третьего аргумента - длительность? Ведь если я правильно вас понял, то какое бы значение мы не подставили в качестве третьего аргумента, управление все равно пойдет к следующей команде?

gena
Offline
Зарегистрирован: 04.11.2012

  Присоединяюсь к вопросу.

negavoid
Offline
Зарегистрирован: 09.07.2016

Orrca пишет:

Большое спасибо за ответ. Это многое поясняет. Тогда еще один маленький вопрос. Если эта функция не блокирующая, то каков смысл ее третьего аргумента - длительность? Ведь если я правильно вас понял, то какое бы значение мы не подставили в качестве третьего аргумента, управление все равно пойдет к следующей команде?

Совершенно верно, но после заданной длительности генерация прекратится и пассивный динамик замолкнет, как в последнем примере #3 - секунду пищим - секунду молчим. Если же этот параметр не задавать, сигнал будет генерироваться "вечно". Удобно использовать как раз для всяких писков - отдали команду и пошли выполняться дальше, а оно пискнуло и замолкло. Можно и не использовать :)

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Проведите эксперимент - возьмите Ваш первоначальный код, где функция tone() вызывается с тремя аргументами и уберите после неё вызов noTone(). Генерация должна длится столько, сколько указано в третьем аргументе вызова tone().

Orrca пишет:

Ведь если я правильно вас понял, то какое бы значение мы не подставили в качестве третьего аргумента, управление все равно пойдет к следующей команде?

Да, но смысл в том, что это за следующая команда. У вас следующая кломанда -  прекращения генерации. Если будет какая-то другая, то генерация не должна прекращаться.

 

Orrca
Offline
Зарегистрирован: 03.08.2016

Спасибо за помощь, разобрался. Хоть это и странно.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Еще раз поразмыслите над логикой работы этой функции, и Вы обнаружите, что было бы странно, если бы она работала как-то по-другому.