Пятница, 26.04.2024, 00:10
Приветствую Вас Гость | RSS
Главная | Каталог статей | Регистрация | Вход
Меню сайта
Реклама Google
Форма входа
Категории раздела
Это нужно знать! [17]
Изучаем AVR [30]
Программаторы [12]
Необходимое ПО [8]
Готовые устройства [73]
Справочная [38]
Инструмент [0]
Технология [8]
Литература [0]
Arduino скетчи [18]
Поиск
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Микроконтроллеры - это просто!
Главная » Статьи » Arduino скетчи

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

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

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

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


Саму схему я путём экспериментов полностью изменил, поскольку микросхема усилителя 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
  for (unsigned char n = 0; n < 16; ++n) {          // Изображение шкалы
    Serial.print((n == input) ? '+' : '-');
  }
  Serial.print('|');
}

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

В схеме присутствуют два потенциометра, подключенные к входам 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()                                    // Основной цикл программы
{
  out = (analogRead(MICINPUT) << 6);           // Чтение состояния микрофонного входа
                                               // со сдвигом значения в диапазон [0..65536]

  filter();                                    // Обработка сигнала фильтром
  mixReverb();                                 // Наложение эффекта ревербератора 
  while(waitForInterrupt);                     // Ожидание прерывания
  OCR2A = (out >> 8) & 0xFF;                   // Вывод сигнала на выход ШИМ
  waitForInterrupt = true;                     // Установка флага ожидания прерывания
  ++nbuf;                                      // Увеличение индекса буфера на 1
  if (nbuf >= BUFSIZE) {                       // Если индекс вышел за пределы размеров буфера
    nbuf = 0;                                        // Обнуление индекса
    filterInput = (analogRead(FILTERINPUT) >> 4);    // Чтение состояния регулятора частоты среза фильтра
    echoInput = (analogRead(ECHOINPUT) >> 3);        // Чтение состояния регулятора уровня реверберации
  }
}

void setupPWMOutput()                          // Настройка ШИМ
{
  TCCR2A = 0;
  TCCR2A |= _BV(WGM21) | _BV(WGM20);           // Режим быстрого ШИМ (TOP = 0xFF)
  TCCR2A |= _BV(COM2A1);                       // Сброс OC2A при совпадении, установка OC2A в нижней точке,
                                               // (не-инверсный режим).

  TCCR2B = 0;
  TCCR2B |= _BV(CS20);                         // Тактовый сигнал таймера 2 - от предделителя /1
  TIMSK2 |= _BV(OCIE2A);                       // Разрешить прерывание TIMER2_COMPA_vect
}

ISR(TIMER2_COMPA_vect)                         // Обработка прерывания TIMER2_COMPA_vect
{
  waitForInterrupt = false;                    // Сброс флага ожидания прерывания
}

void clearBuffer()                             // Инициализация буфера
{
  for (int n = 0; n < BUFSIZE; ++n) {          // Заполнение буфера нулями
    buffer[n] = 0;
  }
}

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);
    prevx[3] = prevx[2];
    prevx[2] = prevx[1];
    prevx[1] = prevx[0];
    prevx[0] = out;
    out = fout;
}

void mixReverb()                                // Наложение реверберации на сигнал
{
  unsigned int rev = buffer[nbuf] * echoInput ;
  out = (out >> 1) + rev;
  buffer[nbuf] = ((out >> 9) & 0x7F) + ((rev >> 9) & 0x7F);
}

Категория: Arduino скетчи | Добавил: Alex (01.06.2014)
Просмотров: 5980 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright MyCorp © 2024