Tone() генерирует высокий звук при отпускании кнопки

У меня есть простая схема, которая использует функцию tone() для воспроизведения некоторых звуков. У меня также есть кнопка, связанная с функцией прерывания, при каждом нажатии которой изменяется переменная.

Иногда при нажатии кнопки раздается высокий звук. Странно, что это происходит не каждый раз.

Вы можете взглянуть на эту симуляцию: https://wokwi.com/projects/291958456169005577

Если вы будете нажимать кнопки непрерывно, вы услышите звук.

Почему срабатывает этот звук? Есть ли способ смягчить это? Возможно, внести изменения в функцию tone()? Или, возможно, установить фильтр нижних частот, так как это похоже на высокочастотный звук?

, 👍2

Обсуждение

Ничего необычного в симуляции не слышу... с железом тоже самое?, @jsotola

какой актуатор вы используете, и сам ли актуатор производит нежелательный звук (а не катушка или что-то в этом роде)? Функция tone() генерирует прямоугольную волну, а согласно теории Фурье прямоугольная волна, естественно, содержит много высших гармоник. Если у вас неподходящий актуатор, который резонирует на этих гармониках, это может объяснить такое поведение..., @Sim Son

@jsotola Если вы нажмете на кнопки (скажем, сделаете это 20 раз), вы наверняка услышите какие-то глючные звуки при нажатии в какой-то момент. Да, то же самое происходит и с железом (а значит, эмулятор просто великолепен)., @user1584421

@SimSon Я просто использую кнопку ..., @user1584421

хорошо, теперь я слышу это ... не слышно с ноутбука ... слышно с телефона Android, @jsotola

пожалуйста, добавьте код в свой пост ... вопрос должен стоять сам по себе, без необходимости обращаться к внешнему источнику, чтобы увидеть код, @jsotola

поставьте delay(1); после сигнала... проверяем, почему это работает, @jsotola

@jsotola Я исправил заголовок!, @user1584421


2 ответа


1

Мое объяснение этой проблемы заключается в том, что последний импульс, сгенерированный функцией tone(), прерывается, когда на выходе находится высокий уровень. Это приводит к тому, что последний импульс оказывается короче, чем он должен быть, чтобы соответствовать желаемой звуковой частоте.

Хотя длина импульса не имеет значения для непрерывного выхода (где частота импульса определяет частоту звука), одиночный короткий импульс можно интерпретировать как импульс более высокой частоты. Согласно теории Фурье, по крайней мере, его основная частота будет выше, чем у более длинных импульсов.

Наблюдения, которые могут подтвердить мою теорию:

  • проблема возникает случайным образом примерно в 50 % случаев (для сигнала с коэффициентом заполнения 50 %).
  • частота ошибочного тона варьируется и всегда выше желаемой частоты, в зависимости от того, насколько коротким является замыкающий импульс.

Похоже, это относится к симуляции.

Возможные исправления:

a) предоставьте функции tone() необязательный аргумент duration и надейтесь, что библиотека сама решит эту проблему (чего на самом деле может и не быть, поскольку проблема даже в симуляция)

b) обязательно используйте период, кратный периоду прямоугольной волны для duration, чтобы волна всегда останавливалась на низком уровне

Согласно моей теории, фильтр нижних частот не будет работать как исправление, потому что частота ошибки может быть близка к желаемой частоте и является «первичным сигналом», а не просто какой-то низкоамплитудной гармоникой, которую было бы легче обнаружить. фильтровать по (гораздо более сильному) фундаментальному фактору.

,

Большое спасибо за то, что нашли время, чтобы изучить и создать рисунки! Я решил эту проблему, используя предложение jsotola и размещение delay(1); после вызова tone()., @user1584421


4

Вот результат моего расследования.

Проблема вызвана двумя факторами.

Во-первых, это дребезг контактов переключателя.

Во-вторых, недостаточная сила подтягивания на переключателе, но это может быть проблема симулятора.

Прилагаемое изображение показывает данные, полученные модулем логического анализатора Wokwi.

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

Остальные трассировки помечены.

,

Большое спасибо за это расследование! Мне удалось решить эту проблему, используя решение, которое вы предоставили в комментарии. В частности, я использовал delay(1); после tone()., @user1584421

правильное устранение дребезга переключателя - реальное решение ... игнорировать переходы переключателя в течение 5 мс после начального перехода, @jsotola