Перейти к содержимому

Как подключить микрофон к ардуино

  • автор:

Датчик звука

Sound Sensor

Датчик позволяет через микрофон определить звук (шум), который превысит заданный уровень. Например, определить момент включения мотора, плача ребёнка и другие источники звука. Уровень шума определяется подстройкой потенциометра на модуле. Кроме того, на модуле есть светодиод, который начинает светиться при обнаружении звука. Также есть второй светодиод, показывающий питание. Иногда встречается название — датчик хлопков, такое определение точнее отражает характер работы.

Sound Sensor

Подстройка производится экспериментальным путём. Крутите отвёрткой в нужную сторону, пока не добьётесь желаемого результата.

Подключение очень простое — у модуля три вывода: питание 5В, земля и цифровой вывод.

Скетч для модуля.

 int soundPin = 10; int soundVal = HIGH; boolean alarm = false; unsigned long lastSoundDetectTime; int soundAlarmTime = 500; // промежуток времени в миллисекундах void setup () < Serial.begin(9600); pinMode(soundPin, INPUT); >void loop () < soundVal = digitalRead(soundPin) ; // считываем показания с вывода 10 if (soundVal == LOW) // если появился звук < lastSoundDetectTime = millis(); // запоминаем время появления звука if (!alarm) < Serial.println("Alarm! Alarm!"); alarm = true; >> else < if ((millis() - lastSoundDetectTime) >soundAlarmTime && alarm) < Serial.println("Quiet"); alarm = false; >> > 

Запустите скетч, откройте Serial Monitor и начинайте говорить. При обнаружении звука на экране появится надпись «Alarm! Alarm!». Данный скетч можно применять для определения ночного тыгыдыка кота в квартире. В реальной жизни чувствительность датчика желает лучшего, на хлопок реагирует, а на голос практически нет.

Модули с цифровым и аналоговым выводами

Также можно встретить модули, у которых четыре вывода: питание, земля, цифровой и аналоговый выводы. К ним относятся модели KY-030 (устар.), KY-037 (микрофон с высокой чувствительностью), KY-038 (конденсаторный микрофон).

KY-037

Подключение у модулей одинаковое.

 KY-037 | Arduino ---------------- AO | A GND | GND + | 5V DO | D 

На модуле датчика должен загореться индикатор питания L1. Необходимо сначала подкрутить подстроечный резистор, настроив чувствительность датчика. В настройке чувствительности поможет индикатор L2. Если индикатор L2 при включении модуля тоже загорается, крутим подстроечный резистор против часовой стрелки до тех пор, пока не дойдём до момента затухания индикатора. Если же индикатор L2 находится в выключенном состоянии при включении модуля, значит крутим подстроечный резистор по часовой стрелке, пока не дойдём до момента, когда индикатор начнёт загораться. В итоге, нужно поймать момент, где чуть повернув подстроечный резистор в одну или другую сторону, индикатор стремиться потухнуть или загореться, и затем нужно повернуть совсем немного против часовой стрелки, чтобы индикатор L2 потух, но при хлопках в ладоши пытался загораться.

Скетч для цифрового вывода смотри выше. Для аналогового вывода напишите самостоятельно.

Включить по хлопку и выключить через несколько секунд

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

 const int sensorD0 = 4; // пин для выхода D0 датчика const int led = 13; // пин светодиода void setup () < pinMode(led, OUTPUT); // устанавливаем цифровой пин 2 в режим выхода >void loop () < int sensorValue = digitalRead(sensorD0); // получаем сигнал с датчика if (sensorValue == 1) //если получен сигнал от датчика в виде единицы < digitalWrite(led, HIGH); // включаем светодиод delay(5000); // делаем паузу, чтобы светодиод горел 5 секунд >if (sensorValue == 0) // если приходит сигнал от датчика в виде нуля digitalWrite(led, LOW); // выключаем светодиод > 

Включить и выключать поочерёдно по хлопку

Напишем новый скетч с другой логикой — по первому хлопку включить светодиод, по повторному хлопку светодиод выключим.

 const int sensorD0 = 4; // пин для выхода D0 датчика const int led = 13; // пин светодиода int ledState = LOW; // статус светодиода "выключен" void setup () < pinMode(led, OUTPUT); >void loop () < int sensorValue = digitalRead(sensorD0); // получаем сигнал с датчика if (sensorValue == 1 && ledState == LOW) //если порог громкости достигнут и светодиод был выключен < digitalWrite(led, HIGH); // включаем светодиод ledState = HIGH; // устанавливаем статус светодиода "включен" delay(100); // небольшая задержка для фильтрации помех >else < if (sensorValue == 1 && ledState == HIGH) // если порог громкости достигнут и светодиод был включен < digitalWrite(led, LOW); // выключаем светодиод ledState = LOW; // устанавливаем статус светодиода "выключен" delay(100); // небольшая задержка для фильтрации помех >> > 

Включаем светодиод по двойному хлопку

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

 const int sensorD0 = 4; // пин для выхода D0 датчика const int led = 13; // пин светодиода int ledState = LOW; // статус светодиода "выключен" long soundTime = 0; // время первого хлопка void setup () < pinMode(led, OUTPUT); >void loop () < int sensorValue = digitalRead(sensorD0); // получаем сигнал с датчика if (sensorValue == 1 && ledState == LOW) //если порог громкости достигнут и светодиод был выключен < long curTime = millis(); // запоминаем текущее время // если текущее время хлопка больше времени последнего хлопка на 100 миллисекунд // и хлопок произошел не позже чем через 1000 миллисекунд после предыдущего // считаем такой хлопок повторным и реагируем на него if ((millis() >soundTime) && ((curTime - soundTime) > 100) && ((curTime - soundTime) < 1000)) < digitalWrite(led, HIGH); // включаем светодиод ledState = HIGH; // устанавливаем статус светодиода "включен" delay(100); // небольшая задержка для фильтрации помех >soundTime = millis(); //записываем время последнего хлопка > else // иначе < if (sensorValue == 1 && ledState == HIGH) // если порог громкости достигнут и светодиод был включен < digitalWrite(led, LOW); // выключаем светодиод ledState = LOW; // устанавливаем статус светодиода "выключен" delay(100); // небольшая задержка для фильтрации помех >> > 

Подключение микрофонного модуля KY-038 к Arduino

Модули KY-038 и KY-037 представляют собой датчики звука. Отличие версии 037 от 038 лишь в размере микрофона. Эти модули находят свое применение в различных системах управления. Например, такие модули часто устанавливают в подъездах для включения освещения при звуке шагов, что позволяет значительно сэкономить электроэнергию. Также с помощью этих модулей можно управлять роботом посредством хлопков или других звуков.

Модуль состоит из микрофона и потенциометра, позволяющего регулировать чувствительность датчика. Также в модуле имеется компаратор – устройство, посылающее цифровой сигнал при достижении аналоговым сигналом на входе определенных значений.

Характеристики:

  • Питание: 3,3-5 В постоянного тока
  • Потребляемый ток: 10 мА
  • Выходной сигнал: цифровой и аналоговый

Модуль имеет 4 вывода:

  1. ”+” – питание
  2. “G” – “земля”
  3. “A0” – аналоговый выход, передающий выходное напряжения на микрофоне
  4. “D0” – цифровой выход, посылающий логическую единицу при достижении порогового уровня громкости

Подключение к Arduino:

Для подключения датчика нам необходимы:

  • Любая Arduino-совместимая плата
  • Компьютер с установленной средой Arduino IDE.
  • USB кабель для подключения Arduino к персональному компьютеру

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

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

Принципиальная схема подключения компонентов:

Пример кода

const int digital = 2; // Цифровой вход пин 2 const int analog = A0; // Аналоговый вход пин A0 void setup() < pinMode(digital, INPUT); Serial.begin(9600); >void loop() < Serial.print("Digital: "); Serial.print(digitalRead(digital)); // Цифровой сигнал с датчика Serial.print(", Analog: "); Serial.println(analogRead(analog)); // Аналоговый сигнал с датчика delay(50); >

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

Давайте теперь добавим в нашу схему светодиод и попробуем управлять им с помощью хлопков. Для подключения светодиода необходим резистор номиналом около 220 Ом.

Принципиальная схема подключения компонентов:

Пример кода

const int digital = 2; // Цифровой вход пин 2 const int analog = A0; // Аналоговый вход пин A0 const int led = 9; // Светодиод void setup() < pinMode(led, OUTPUT); Serial.begin(9600); >void loop() < Serial.print("Digital: "); Serial.print(digitalRead(digital)); // Цифровой сигнал с датчика Serial.print(", Analog: "); Serial.println(analogRead(analog)); // Аналоговый сигнал с датчика delay(50); if (analogRead(analog) < 625 || analogRead(analog) >637) < //Диапозон значений устанавливайте самостоятельно из рассчёта +-4 от показаний в тишине digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); >>

Рекомендуемые товары

Датчик звука с конденсаторным микрофоном KY-038

Датчик звука с конденсаторным микрофоном KY-038

Модуль состоит из микрофона и потенциометра, позволяющего регулировать чувствительность датчика. Так..

Arduino + микрофон

В данной статье рассматривается частный случай подключения микрофона к Arduino. Всё написанное также верно и для клонов Arduino, например Freeduino.

В статье встречаются технические термины, для понимания которых могут быть не бесполезны статьи Использование прерываний Arduino , Таймеры-счётчики Arduino и Как подключить к Arduino.

Подключение микрофона к Arduino.

Надо заметить, что подключить к Arduino конденсаторный (электретный) микрофон — это задача, которая требует навыка работы с операционными усилителями, поскольку сам по себе выходной сигнал от микрофона довольно слабый, и поэтому прежде, чем подать сигнал с микрофона на АЦП (аналого-цифровой преобразователь), его желательно предварительно усилить, и заодно немножко почистить от шума в цепях питания.

Дело в том, что в схеме Arduino питание цифровой и аналоговой цепей микроконтроллера производится по упрощённой схеме, без LC-фильтра между ними. И соответственно, всё, что происходит в цифровой части схемы, попадает в аналоговый сигнал, оцифровываемый с помощью АЦП.

Поэтому, подключая микрофон, я включил в цепь питания микрофона и операционного усилителя дроссель L1, что позволило заметно снизить количество шумов в сигнале.

В качестве схемы для подключения микрофона я взял за основу схему подключения микрофона из Application Note AVR335: Digital Sound Recorder with AVR and DataFlash . Микрофон подключал так называемый компьютерный, то есть со стерео-джеком 3.5-мм.

Саму схему я путём экспериментов полностью изменил, поскольку микросхема усилителя TL071, приводимая в Application Note, у меня от +5 Вольт работать не захотела, а в даташите я так и не смог найти минимальное напряжение, которое ей требуется. Поэтому использовал в качестве усилителя тот низковольтовый операционник, который имелся в запасе, а им оказался KA2209, который меня в своё время привлёк своей ценой и тем, что он требует однополярного напряжения. Но вообще-то это усилитель мощности и даже не аудио. Хотя с питанием от дросселя он меня даже удивил тем, что не шумит (без дросселя шумел довольно заметно). Так что я счёл его использование в данной схеме вполне приемлемым.

Для того, чтобы откалибровать схему, я подал на вход вместо сигнала от микрофона напряжение +5 Вольт, используя для отображения простой скетч, отображающий состояние АЦП на текстовом терминале, совместимом с VT100:

void setup ()

Serial .begin(230400);

Serial .print(«\x1B[?25l»); // Выключение курсора

void loop ()

unsigned char input = (analogRead(A0) >> 6); // Чтение состояния входа Analog In 0 со сдвигом значения в диапазон [0..15]

Serial .print(«\x1B[0;0H|»); // Курсор в позицию 0, 0

Serial .print((n == input) ? ‘+’ : ‘-‘);

Serial .print(‘|’);

В linux после успешной компиляции и загрузки скетча в память микроконтроллера, можно вызвать эмулятор VT100-терминала командой

screen /dev/ttyUSB0 230400

где /dev/ttyUSB0 — это путь к USB-устройству Arduino. Выход из screen производится нажатием Ctrl+A , затем Ctrl+\ и ответом y на запрос подтверждения выхода. Либо отключением Arduino от USB.

Калибровку удобно производить, снимая сигнал с ползунка потенциометра. После этого можно подать на вход схемы сигнал от микрофона и посмотреть, насколько результат совпадает с ожидаемым.

В схеме присутствуют два потенциометра, подключенные к входам Analog In 1 и 2 . В скетче они используются для регулировки фильтра и уровня реверберации соответственно.

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

Скетч захватывает сигнал с входа АЦП, затем сигнал обрабатывается обрезным фильтром ВЧ четвёртого порядка, на него накладывается эффект реверберации, затем сигнал выводится на вывод широтно-импульсного модулятора (ШИМ) Digital 11 , к которому подключен 8-Омный динамик с усилителем класса D. Текст скетча с комментариями приводится ниже:

#define MICINPUT A0 // Микрофон подключен к выводу Analog In 0

#define FILTERINPUT A1 // Регулятор частоты среза фильтра — вывод Analog In 1

#define ECHOINPUT A2 // Регулятор уровня реверберации — вывод Analog In 2

#define PWMOUTPIN 11 // Вывод ШИМ — Digital 11

volatile bool waitForInterrupt = true; // Флаг ожидания прерывания

unsigned int out = 0; // Виртуальный звуковой выход

unsigned char filterInput = 0; // Состояние регулятора частоты среза фильтра

unsigned char echoInput = 0; // Состояние регулятора уровня реверберации

#define BUFSIZE 1096 // Размер буфера ревербератора

unsigned char buffer[BUFSIZE]; // Буфер ревербератора

int nbuf = 0; // Текущий индекс буфера ревербератора

void setup() // Инициализация микроконтроллера

noInterrupts(); // Выключить прерывания

clearBuffer(); // Инициализация буфера ревербератора

pinMode(PWMOUTPIN, OUTPUT); // Контакт вывода ШИМ в режим вывода

setupPWMOutput(); // Настройка ШИМ

interrupts(); // Включение прерываний

void loop() // Основной цикл программы

// со сдвигом значения в диапазон [0..65536]

filter(); // Обработка сигнала фильтром

mixReverb(); // Наложение эффекта ревербератора

while(waitForInterrupt); // Ожидание прерывания

OCR2A = (out >> 8) & 0xFF; // Вывод сигнала на выход ШИМ

waitForInterrupt = true; // Установка флага ожидания прерывания

++nbuf; // Увеличение индекса буфера на 1

nbuf = 0; // Обнуление индекса

filterInput = (analogRead(FILTERINPUT) >> 4); // Чтение состояния регулятора частоты среза фильтра

echoInput = (analogRead(ECHOINPUT) >> 3); // Чтение состояния регулятора уровня реверберации

void setupPWMOutput() // Настройка ШИМ

TCCR2A |= _BV(WGM21) | _BV(WGM20); // Режим быстрого ШИМ (TOP = 0xFF)

TCCR2A |= _BV(COM2A1); // Сброс OC2A при совпадении, установка OC2A в нижней точке,

TCCR2B |= _BV(CS20); // Тактовый сигнал таймера 2 — от предделителя /1

TIMSK2 |= _BV(OCIE2A); // Разрешить прерывание TIMER2_COMPA_vect

ISR(TIMER2_COMPA_vect) // Обработка прерывания TIMER2_COMPA_vect

waitForInterrupt = false; // Сброс флага ожидания прерывания

void clearBuffer() // Инициализация буфера

void filter() // Фильтр ВЧ четвёртого порядка

static unsigned int prevx[4] = < 0, 0, 0, 0 >;

unsigned int fout = out — (prevx[0] >> 7) * (filterInput >> 1)

— (prevx[1] >> 7) * (filterInput >> 2)

— (prevx[2] >> 7) * (filterInput >> 3);

— (prevx[3] >> 7) * (filterInput >> 4);

void mixReverb() // Наложение реверберации на сигнал

unsigned int rev = buffer[nbuf] * echoInput ;

out = (out >> 1) + rev;

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

Arduino и микрофон

Arduino весьма неплохо измеряет напряжение, почему бы не подключить к ней микрофон? Просто голый микрофонный капсюль подключать нет смысла, для работы с ним понадобятся ещё некоторые электронные компоненты. У китайцев есть несколько вариантов микрофонных модулей, но самый хороший из них – на базе микросхемы MAX9814 (вынесен на картинке справа), такой и идёт в наборе GyverKIT:

Данный модуль обеспечивает:

  • Усиление сигнала с микрофона до амплитуды 1.25V (выходной диапазон 0.. 2.5V)
  • Встроенный АРУ – автоматическая регулировка усиления, выравнивает громкость тихих и громких звуков
  • Подавление шума – сигнал с микрофона довольно чистый даже при не очень хорошем питании. Его очень приятно обрабатывать, да и рацию можно сделать

Пины и настройки модуля:

  • GND и Vdd (V+): питание, 3.. 5V
  • Out: выход сигнала для подключения к МК
  • Gain (G): настройка усиления
    • Никуда не подключен: 60dB
    • На GND: 50dB
    • На VCC: 40dB
    • Никуда не подключен: 1:4000 мс
    • На VCC: 1:2000 мс
    • На GND: 1:500 мс

    Подключение

    К питанию и на аналоговый пин:
    Примечание:

    • На схеме с Arduino (слева) можно переключить опорное напряжение (пин REF) на встроенный источник 3.3V, желательно через резистор на 10к. Соответственно в программе вызвать analogReference(EXTERNAL) . Это нужно для того, чтобы расширить диапазон чтения сигнала микрофона и обрабатывать его более точно (он выдаёт 0.. 2.5V)
    • На схеме с Wemos (справа) мы подключаем микрофон на питание 3.3V. Сигнал он всё равно выдаёт 0.. 2.5V, что очень хорошо: у Wemos как раз 3.3V – верхняя граница напряжения на аналоговый пин A0

    Библиотеки

    Модуль выдаёт аналоговый сигнал, то есть его достаточно опрашивать стандартными средствами Arduino для получения сырого сигнала. Но полезные библиотеки всё таки есть:

    • Если микрофон используется для измерения громкости звука, то можно воспользоваться библиотекой амплитудного анализа VolAnalyzer, которая обработает звук и преобразует громкость в нужный диапазон, а также будет автоматически подстраивать чувствительность при изменении среднего уровня громкости
    • Clap – библиотека для распознавания хлопков в ладоши, удобно использовать совместно с VolAnalyzer
    • Для частотного анализа звука можно использовать библиотеку FHT (только для AVR)

    Примеры

    Выведем сырой сигнал в порт
    void setup() < Serial.begin(9600); // переключаем на внешнее опорное // его подключаем к 3.3V analogReference(EXTERNAL); >void loop()

    Откроем монитор порта и скажем что-нибудь в микрофон

    Отлично! Но это сырой сигнал, с ним работать неудобно – он не отражает усреднённую громкость, а всего лишь показывает форму звукового сигнала

    Пример с VolAnalyzer

    Заведём похожий пример, но с библиотекой VolAnalyzer: выведем приведённую “громкость” звука и построим график:

    #include "VolAnalyzer.h" VolAnalyzer analyzer(A0); // микрофон на А0 void setup() < Serial.begin(9600); // переключаем на внешнее опорное // его подключаем к 3.3V analogReference(EXTERNAL); >void loop() < // если анализ завершён if (analyzer.tick()) < Serial.println(analyzer.getVol()); >>

    И получим гораздо более применимые для проектов значения:

    Такой сигнал достаточно подать на светодиод – и уже получится светомузыка!

    Домашнее задание

    • Изучить библиотеку VolAnalyzer

    Связанные уроки

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *