View Categories

Генерация звука

Меандр #

Самый простой способ генерации звука микроконтроллером - квадратный сигнал (меандр), по сути классический пример с миганием светодиода раз в секунду является меандром с частотой в 1 Гц.

При уменьшении значения задержек частота сигнала будет увеличиваться - чтобы сигнал оставался квадратным, значения задержек должны быть одинаковыми.

// мигает светодиод на плате. Можно задать частоту
#define FREQ 2  // частота в Гц

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

void loop() {
    digitalWrite(LED_BUILTIN, HIGH);
    delayMicroseconds(1000000 / FREQ / 2);
    digitalWrite(LED_BUILTIN, LOW);
    delayMicroseconds(1000000 / FREQ / 2);
}

Зуммер #

Для того, чтобы "послушать" сигнал, нужен динамик или пьезоэлектрическая "пищалка" - зуммер, он же баззер (buzzer). Его можно снять со старого корпуса компьютера, материнской платы или найти в Ардуино-наборе:

Зуммеры бывают двух видов - активные и пассивные, отличить их можно подключив питание 5V (или меньше) от платы Arduino:

  • Активные издают громкий писк просто при подаче питания - у них фиксированная звуковая частота: внутри находится плата, которая генерирует звук. Таким зуммером не получится воспроизводить свой сигнал
  • Пассивные при подаче питания просто щёлкают - такой зуммер сможет издавать звук заданной частоты с МК

Для уменьшения нагрузки на пин подключим зуммер через резистор на пару сотен Ом или через потенциометр для регулировки громкости:

Загрузим код, который будет выдавать сигнал с частотой 500 Гц:

#define FREQ 500    // частота в Гц
#define BUZ_PIN 2   // пин зуммера

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

void loop() {
    digitalWrite(BUZ_PIN, HIGH);
    delayMicroseconds(1000000 / FREQ / 2);
    digitalWrite(BUZ_PIN, LOW);
    delayMicroseconds(1000000 / FREQ / 2);
}

Зуммер пищит! В схеме с потенциометром можно изменять громкость рукояткой. Поэкспериментируйте с частотой звука.

Изменение частоты #

Давайте подключим второй потенциометр на аналоговый пин A0 - пусть он изменяет частоту звука от 500 Гц до "бесконечности". Вот схема и код:

#define BUZ_PIN 2
#define POT_PIN A0

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

void loop() {
    int val = analogRead(POT_PIN);
    // макс. период - 1023*2 мкс, частота - 489 Гц

    digitalWrite(BUZ_PIN, HIGH);
    delayMicroseconds(val);
    digitalWrite(BUZ_PIN, LOW);
    delayMicroseconds(val);
}

Проблема такого способа генерации звука в том, что МК занят только одной задачей - генерировать звук. Если нужно выполнять ещё какой-то код, то он будет "спотыкаться" о задержки, а если он будет долго выполняться и вносить свои задержки - частота начнёт "плавать" и звук будет искажаться. В примере выше у нас есть analogRead - он выполняется около 120 мкс на Nano, это означает что частота будет ограничена примерно 8 кГц, т.к. во время опроса потенциометра звук не "воспроизводится". А также нарушится форма волны - перестанет быть квадратной. Это не так важно, но это факт.

Функция tone #

В Arduino есть функция tone, которая позволяет генерировать звук асинхронно, независимо от задержек и прочих блокирующих конструкций. В AVR Arduino генерацией звука занимается аппаратный таймер. Достаточно вызвать tone(пин, частота) для запуска генерации и noTone(пин) для отключения:

#define BUZ_PIN 2

void setup() {
    // писк 500 Гц на 3 секунды
    tone(BUZ_PIN, 500);
    delay(3000);
    noTone(BUZ_PIN);
}

void loop() {
}

Функция tone может принимать и третий аргумент - время сигнала в мс, т.е. звук отключится сам по асинхронному таймеру:

#define BUZ_PIN 2

void setup() {
    // писк 500 Гц на 3 секунды
    tone(BUZ_PIN, 500, 3000);
}

void loop() {
}

Пример с настройкой частоты:

#define BUZ_PIN 2
#define POT_PIN A0

void setup() {
}

void loop() {
    int hz = analogRead(POT_PIN) * 20; // до 20 кГц
    tone(BUZ_PIN, hz);
    delay(10);
}
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх