Измерьте изменения напряжения при неизвестной базовой линии

Я хотел бы отслеживать аудиопоток и определять, когда он «активен» и воспроизводится музыка, или когда он «неактивен» и молчит. Как лучше всего измерить, когда аудиопоток меняет состояние и продолжает оставаться «активным»?

Каждый аудиопоток усиливается с помощью этой схемы.

Каждый аудиопоток имеет разное базовое напряжение, когда он не воспроизводится и «тихий», но это напряжение имеет тенденцию слегка дрейфовать и меняться. Возможно это дефект моего усилителя. У меня нет OScope, а мой мультиметр плохо показывает низкое напряжение, поэтому я не могу точно определить, откуда берется дрейф.

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

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

#include <elapsedMillis.h>    //измеряем прошедшее время

const int analogInPin = A0;   //Вывод аналогового входа — чтение со схемы усилителя
const int statusLight = 10;   //Цифровой выход для индикаторной лампы
int sensorValueA = 0;         //Теперь показания датчика
int sensorValueB = 0;         //Предыдущие показания датчика
int sensorDeltaA = 0;          //Изменение показаний датчика
int sensorDeltaB = 0;          //Запись последней дельты — полезно для предотвращения случайного срабатывания при запуске
int sensorThreshold = 50;      //Порог в дельте для запуска действия
elapsedMillis turnOverTime;   //Таймер для измерения оборота между изменениями показаний датчика


void loop() {
  //измеряем аналоговый вход
  sensorValueA = analogRead(analogInPin);
  sensorDeltaA = abs(sensorValueA - sensorValueB);

 //проверяем, превышают ли данные порог, и включаем
  if ((sensorDeltaA >= sensorThreshold) and (sensorDeltaB != 0)) {
    turnOverTime = 0;
    powerStateA = true;
  } 

  sensorValueB = sensorValueA;

  //проверяем, не были ли возвращены данные датчика, выходящие за пороговое значение, в пределах окна задержки, выключаем
  if (turnOverTime >= delayTime) {
    turnOverTime = 0;
    powerStateA = false;    
  }

  //если состояние электропитания изменится, действуйте соответственно
  if (powerStateA != powerStateB) {
    digitalWrite(statusLight, powerStateA);  
  }
}

, 👍1

Обсуждение

Похоже, вам нужно соединить сигнал по переменному току и добавить резистор на несколько мегаОм для заземления., @Gerben

Где в цепи я хотел бы заземлить? До или после усилителя? А что такое пара переменного тока? Я новичок в сфере обработки звука и понимаю, как мало я знаю., @Aaron Ciuffo


1 ответ


Лучший ответ:

1

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

  • Сигнал переменного тока.
  • Смещение постоянного тока

Вас интересует сигнал переменного тока, а не смещение постоянного тока. Именно это смещение постоянного тока и дрейфует в вашей текущей модели.

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

Самый простой способ — с конденсатором.

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

Самый простой способ — добавить смещение постоянного тока.

Но разве мы только что не избавились от ненужного смещения постоянного тока? Ага. Но это было неизвестное смещение постоянного тока. Если мы затем добавим смещение постоянного тока, которое нам известно и является стабильным, то мы сможем с ним работать.

Вот очень простая схема:

schematic

Конденсатор C1 устраняет существующее смещение постоянного тока. Затем R1 и R2 образуют делитель напряжения, дающий напряжение 2,5 В (половина 5 В), которое затем добавляется к чистому сигналу переменного тока.

Это означает, что сигнал теперь колеблется в районе 2,5 В. Тишина — это 2,5 В, а шум — другие значения выше и ниже этого значения.

Поскольку 2,5 В составляет половину от 5 В, на которых работает Arduino, тишина должна составлять где-то около половины значения АЦП. Это примерно 512. Звук будет как выше, так и ниже этого значения.

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

Для простоты, поскольку вам все равно, положительное оно или отрицательное, вы можете удалить знак из числа, чтобы получить просто величину.

int audio = analogRead(A0); // Получить образец
audio = audio - 512; // Удалить смещение постоянного тока
audio = abs(audio); // Удалить знак

Теперь вы можете сравнить это с пороговым значением:

if (audio > 100) {
    // сделать что-нибудь
}
,

Не предполагаете ли вы, что звуковой сигнал не превышает +/- 2,5 В? (Это вполне может быть верным предположением)., @Nick Gammon

Этот ответ исключительно хорошо описан. Спасибо! Источником звука является выход RCA проигрывателя Squeezebox и разъем для наушников Chromecast Audio. Я измерил (плохо, с помощью ненужного мультиметра RadioShack), что напряжение значительно ниже 1 В. Нужно ли мне сначала пропускать аудиопоток через усилитель, прежде чем использовать эту схему?, @Aaron Ciuffo

Стандартный выходной уровень линии не будет превышать около 1,5 В., @Majenko

Если у меня есть два источника звука и я хочу измерить их независимо, будет ли это работать? Разве я в конечном итоге не подключил бы два делителя напряжения параллельно, чтобы каждая ветвь делителя 5К вместо 10К?, @Aaron Ciuffo

Нет, разделители — это отдельные объекты. Каждый делитель по-прежнему представляет собой пару резисторов номиналом 10 КОм (всего 20 КОм). Общее сопротивление *по источнику питания* уменьшится вдвое (10К вместо 20К), но каждый делитель вообще ничего об этом не знает., @Majenko