Ну, давайте сделаем, что-нибудь этакое!

А сделаем мы следующее: соберем вот такую не сложную конструкцию. Здесь как вы сами можете видеть плата Arduino UNO подключена к компьютеру через USB порт, к которой подключена отладочная плата MSGEQ7, вообще это даже не отладочная плата, а самодостаточный модуль, к которому в качестве аудио сигнала можно подключить, через разъем аудио-джек, любой аудиоплеер или что-то подобное  либо через штырьковый разъем подключить микрофонный усилитель. …Сейчас мы подключаем плеер.

Аудиосигнал с выхода плеера поступает на вход микросхемы MSGEQ7

Аудиосигнал с выхода плеера поступает на вход микросхемы MSGEQ7 а дальше на Arduino UNO

Объявляем переменные для NSGEQ7.

int strobePin = 7; // STROBE Pin на MSGEQ7
int resetPin = 8; // RESET Pin на MSGEQ7
int outPin = A5; // OUT Pin на MSGEQ7
int level [7]; // массив для хранения значений 7 частотных диапазонов

Это ненамного сложнее чем то, чем мы уже занимались на прошлых уроках…

Все, что мы здесь делаем, это указываем, куда подключаем выход STROBE, а подключаем мы его к цифровому порту 7, платы ARDUINO, RESET подключаем к цифровому порту 8 и OUT к аналоговому порту ARDUINO A0. В последней строке мы создаем массив из семи значений, который мы будем использовать для хранения показаний с аналогового вывода. Теперь давайте перейдем к настройкам..

void setup() {
 
  Serial.begin (9600);
 
  // инициализация выводов
  pinMode      (strobePin, OUTPUT);
  pinMode      (resetPin,  OUTPUT);
  pinMode      (outPin,    INPUT);
 
  // задаем исходное состояние для выводов
  digitalWrite (resetPin,  LOW);
  digitalWrite (strobePin, LOW);
  delay        (1);
 
  // Сброс MSGEQ7 в соответствии с временной диаграммой из Datasheet
  digitalWrite (resetPin,  HIGH);   // переключаем RESET в HIGH
  delay        (1);                 // небольшая задержка в 1мс
  digitalWrite (resetPin,  LOW);    // переключаем RESET в LOW
  digitalWrite (strobePin, HIGH);   // переключаем STROBE в HIGH и ожидаем
  // переключения STROBE в LOW, чтобы можно было начать получать данные на выходе OUT
  delay        (1);                 // снова задержка
 
}

Опять же, здесь нет ничего ужасного. Сначала мы указываем ARDUINO установить связь с внешним миром Serial.begin (9600), т.е. отправлять и принимать данные на внешние устройства, со скоростью 9600 бит/сек.

Затем мы устанавливаем режимы работы для выводов: RESET и STROBE как OUTPUT (исходящие), а для аналогового вывода A0 INPUT (входящий).

Затем мы устанавливаем начальное состояние для выводов, точно так же, как показано на диаграмме см. здесь… все в LOW (низко).

Наконец, мы производим действия сброса, чтобы перевести мультиплексор в состояние для выдачи первого значения частоты. Единственное реальное отличие между тем что происходит здесь и временной диаграммой, заключается в том, что я не перевожу strobePin в HIGH сразу, когда на resetPin еще высокий потенциал — это не даст никакого результата, так как высокий потенциал на RESET предотвращает использование STROBE. Дальше идет задержка «delay» в 1 мс при высоком RESET, что значительно перекрывает минимально необходимые «tr» в 100 нс, указанные на временной диаграмме. Затем мы переводим RESET в LOW, и сразу даем HIGH на STROBE и снова делаем задержку на 1 мс, это гарантирует, что мы превысим минимально необходимые «trs» в 72 мкс.

Не большое отступление — Соответствие величин:

1 Наносекунда = 0.001 Микросекунда

10 Наносекунд = 0.01 Микросекунда

100 Наносекунд = 0.1 Микросекунда

1000 Наносекунд = 1 Микросекунда

1 Микросекунда = 0.001 Миллисекунда

10 Микросекунд = 0.01 Миллисекунда

100 Микросекунд = 0.1 Миллисекунда

1000 Микросекунд = 1 Миллисекунда

1 Миллисекунда = 0.001 Секунда

10 Миллисекунд = 0.01 Секунда

100 Миллисекунд = 0.1 Секунда

1000 Миллисекунд = 1 Секунда

 

Обозначение:

наносекунда   нс  ns

микросекунда  мкс µs

миллисекунда  мс  ms

 

Чтобы не существовало путаницы:
delay() — задержка в миллисекундах (рус. — мс, eng. — ms)
delayMicrodseconds — задержка на указанный в аргументе период в микросекундах (мкс и µs)

С настройками все, поэтому пришло время собрать некоторые данные.

void loop() {
 
  // здесь идет цикл, где мы с помощью импульса STROBE помещаем
  // каждую полосу частотного фильтра в массив
  for (int i = 0; i < 7; i++) {
    digitalWrite       (strobePin, LOW);
    delayMicroseconds  (100);                  // необходимая задержка
    level[i] =         analogRead (outPin);    // используем функцию analogRead
    digitalWrite       (strobePin, HIGH);
    delayMicroseconds  (100);                    // необходимая задержка
  }
  // здесь тоже цикл, но уже для наглядности вывода данных
  for (int i = 0; i < 7; i++) {
    Serial.print       (level[i]);
    Serial.print       (»   «);
  }
  // сам вывод данных в монитор порта
  Serial.println (); 

}

Нам нужно получить семь кусков данных с выхода MSGEQ7, поэтому мы собираемся запустить цикл FOR. В первом цикле мы активируем STROBE, — даем на него сигнал LOW, и делаем пауза 100 мкс, чтобы учесть время установления выхода. Когда выходной сигнал установлен, мы считываем напряжение с аналогового порта (outPin — Arduino A0) с помощью функции analog Read (Напоминание! — analogRead используется в Arduino для того, чтобы считывать значения с устройств, подключенных к аналоговому порту) и записываем его в массив level[i] Здесь можно освежить в памяти информацию о  массивах, если кто подзабыл.

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

Данные работы MSGEQ7 в осциллографе

Данные работы MSGEQ7 в осциллографе

Деление сетки по оси X равна 5 мкс. В верхней части экрана вы можете видеть желтую линию, которая представляет собой строб-сигнал (контакт STROBE). Синей линии отдан весь экран — это выходное значение на вывод OUT, напряжение на нем почти отсутствует. Сигнал STROBE переходит на LOW, сообщая тем самым MSGEQ7 выводить напряжение, представляющее частотную характеристику на выходе OUT, на экране видно очень четкое изменение напряжения, от совсем низкого до пикового. Я смотрел на этот тест по крайней мере дюжину раз, и ни разу не видел, чтобы время нарастания было больше, чем 20мкс, так что, как мне кажется, значение «to» в 36мкс это с Большим запасом… Каждый раз наблюдая за «живым сигналом», который иногда плавный, а иногда бешеный, время нарастания все равно не превышало 20мкс, поэтому технические требования даже очень консервативны. У меня с этим нет проблем.

Как только мы захватили наше аналоговое значение, мы даем на STROBE — HIGH и снова задерживаем в таком состоянии на 100мкс, на этот раз, чтобы подготовиться к следующему считыванию. В принципе, период сигнала должен быть не менее чем 72мкс. Я думаю, что эта задержка, — это время, необходимое мультиплексору для перехода к следующему полосовому фильтру, т.е. детектор успеет выполнить свою работу, а затем мультиплексор получит напряжение готовое для отправки на выход.

Последний акт — это быстро «выплюнуть» наши данные в последовательный монитор. Я хочу предупредить вас, что, когда вы закончите эксперименты с серийным монитором и перейдете к созданию собственных проектов со светодиодами или другими компонентами, вам нужно будет закомментировать все лишнее в отладочном коде.
 
Далее в качестве примера, идет небольшой скетч, который выводит на дисплей семь значений частоты через последовательный монитор, добавляет 40 мс задержки, что позволяет замедлить слишком быстро меняющиеся значения. Тем не менее, для нашего исследования этого вполне достаточно.

int strobePin = 7;
int resetPin = 8;
int outPin = A0;
int level[7];

void setup() {

Serial.begin (9600);

pinMode (strobePin, OUTPUT);
pinMode (resetPin, OUTPUT);
pinMode (outPin, INPUT);

digitalWrite (resetPin, LOW);
digitalWrite (strobePin, LOW);
delay (1);

digitalWrite (resetPin, HIGH);
delay (1);
digitalWrite (resetPin, LOW);
digitalWrite (strobePin, HIGH);
delay (1);

}

void loop() {

for (int i = 0; i < 7; i++) {
digitalWrite (strobePin, LOW);
delayMicroseconds (100);
level[i] = analogRead (outPin);
digitalWrite (strobePin, HIGH);
delayMicroseconds (100);
}

for (int i = 0; i < 7; i++) {
Serial.print (level[i]);
Serial.print (» «);
}

Serial.println ();

}

Что в результате мы увидим?

Мы увидим, как значения, полученные с выхода OUT микросхемы MSGEQ7, отобразятся на странице последовательного монитора.

Монитор порта, скетч и генератор аудио сигналов

Монитор порта, скетч и генератор аудио сигналов

На рисунке – Монитор Порта Arduino отображающий семь колонок — семь частотных диапазонов, код программы в Arduino IDE и Программный генератор звуковых частот, с одновременной генерацией семи звуковых частот.

Как и обещал в предыдущей статье — проверенные микросхемы MSGEQ7 и платы можно приобрести здесь

Datasheets на MSGEQ7 —  http://www.mix-sig.com/images/datasheets/MSGEQ7.pdf

Всем удачи!