Добрый день. Почему нижеследующий код приводит к коротким щелчкам с периодичностью в секунду вместо того, чтобы играть сигнал в течение секунды, потом секунда тишины и снова? Помогите советом, плз. #define BUZZER_PIN 3 void setup() { pinMode(BUZZER_PIN, OUTPUT); } void loop() { tone(BUZZER_PIN, 200, 1000); noTone(BUZZER_PIN); delay (1000); }
Спасибо, я так потом и сделал. Однако вопрос остался. Почему функция tone не приняла третий аргумент - длительность сигнала 1000 мс?
Попробуйте: Код (C++): void loop() { tone(BUZZER_PIN, 200, 5000); delay(1000); } По идее, звук должен быть 5 сек, затем пауза в 1 секунду. noTone вроде нужно вызывать, когда задержка в tone не указана, может поэтому он и отключает Ваш звуковой сигнал некорректно... Кстати, частота 200 Герц не слишком маленькая для динамика?
Все, разобрался. Помогли на ардуино.ру. Короче так, Ардуино, получив команду "tone(BUZZER_PIN, 200, 1000);" не ждет, как я полагал, 1000 мс, чтобы потом передать управление на команду noTone(BUZZER_PIN);, а делает это сразу! Потому и слышен лишь щелчок. Если сделать так, как предлагаете Вы (и я уже попробовал), то будет так. Ардуино дает команду на динамик звучать 5000 мс и сразу переходит к delay(1000); Замирает в таком состоянии только на 1000 мс, а не на 5000 мс и снова возвращается к началу цикла. Результат - постоянное звучание без каких либо внятных пауз. Странная логика, надо просто запомнить.
Проверил, паузы нет. Но если сделать наоборот: void loop() { tone(BUZZER_PIN, 200, 1000); delay(5000); } то это будет работать так. 1000 мс из 5000 мс задержки динамик звучит, потом остаток 4000 мс - молчит и снова в начало цикла.
Интересная логика Жаль на форуме специалистов по Arduino сейчас нет, подсказали бы, почему так происходит...
Частота 200 Гц норм для пьезожужжалки, выше - противнее звучит. А по поводу логики, то теперь понимаю, что она обычная. Если простыми словами, то Ардуино не ждет пока закончится выполнение функции, а начинает выполнять следующую за ней параллельно. Как раз иначе было бы странно. Например отдали бы мы команду динамику звучать 1000 мс. И что, пока он бы не закончил звучать не могли бы выполнить никакую другую команду? Как раз это было бы неудобно. А что до спецов, то они, очевидно, вечером набегут
У меня логика была в том, что там delay используется, то есть, пока пауза не закончится, ничего выполняться не будет, а так получается там другой процесс для паузы - многопоточный видимо, поэтому он и идёт вместе с delay в один момент. Но всё же, уточнить принцип хотелось бы, как там tone на Arduino реализовали...
tone, емнип, юзает таймер, поэтому работает вне зависимости от delay. Логика там простая - последним параметром передаём, через какой промежуток tone заткнётся, вот и всё. noTone надо вызывать только тогда, когда нужный промежуток времени уже прошёл. Поскольку функция tone неблокирующая, то вызов noTone сразу за вызовом tone приведёт к тому, что ничего пищать не будет.
Когда сомневаетесь - не лишним будет поглядывать в исходники ардуино, это вообще полезно на предмет "потихоньку разбираться в кишочках и низком уровне". Найдите файл Tone.cpp, он лежит в папке установки Arduino, в подпапке hardware/arduino/avr/cores/arduino - и там сразу будет видно, что юзается таймер, причём - не один, в зависимости от директив условной компиляции они могут юзаться разные