как не составит труда заполнить буфер замерами перед тем, как начать запрашивать усредненные замеры.

Обратите внимание на то, что переменная sum для хранения суммы в функции average объявлена с типом long. Это особенно важно, если используется емкий буфер и есть вероятность, что сумма превысит максимальное положительное значение int, которое немногим больше 32 000. Отметьте также, что она безопасно может возвращать результат усреднения в виде значения int, потому что среднее значение будет находиться в диапазоне значений отдельных замеров.

Введение в фильтрацию

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

Наиболее распространенный способ фильтрации в Arduino — низкочастотная фильтрация. Представьте, что у вас имеется датчик освещенности и вы пытаетесь определить общий уровень освещенности и поминутную динамику ее изменения, например, чтобы определить момент, когда станет достаточно темно, чтобы включить освещение. Но вам нужно устранить высокочастотные изменения освещенности, вызванные такими событиями, как быстрое перемещение вблизи датчика объектов, заслоняющих свет, или засветка датчика искусственными источниками света, которые в действительности мерцают с частотой напряжения питания (50 Гц, если вы живете в России). Если вас интересует только медленно изменяющаяся часть сигнала, то вам нужен низкочастотный фильтр. И наоборот, если требуется откликаться на скоротечные события и игнорировать более протяженные тенденции, используйте высокочастотный фильтр.

Вернемся к проблеме искажений, вызываемых частотой переменного тока в электросети. Если, к примеру, вам нужно исключить только паразитную гармонику с частотой 50 Гц и оставить гармоники с частотами выше и ниже этого значения, тогда простое отсечение низкочастотных гармоник не даст желаемого результата. Для решения этой задачи следует использовать полосовой фильтр, который удалит только гармонику с частотой 50 Гц или, что более вероятно, все гармоники с частотами от 49 до 51 Гц.

Простой низкочастотный фильтр

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

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

Сглаженное значениеn = (Коэффициент х Сглаженное значениеn–1) + ((1 – Коэффициент) х Замерn).

Коэффициент — это константа между 0 и 1. Чем выше значение коэффициента, тем сильнее эффект сглаживания.

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

// sketch_13_02_simple_smoothing

const int samplePin = A1;

const float alpha = 0.9;

void setup()

{

  Serial.begin(9600);

}

void loop()

{

  static float smoothedValue = 0.0;

  float newReading = (float)analogRead(samplePin);

  smoothedValue = (alpha * smoothedValue) +

    ((1 — alpha) * newReading);

  Serial.print(newReading); Serial.print(",");

  Serial.println(smoothedValue);

  delay(1000);

}

Скопировав результаты сглаживания из окна монитора последовательного порта и вставив их в электронную таблицу, можно построить график, чтобы увидеть, насколько хорошо выполняется сглаживание. На рис. 13.3 показан результат работы предыдущего скетча в плате, к аналоговому входу A1 которой подключен некоторый источник переменного сигнала.

Рис. 13.3. График изменения сглаженных значений

Как видите, для выхода на нормальный уровень сглаживания требуется некоторое время. Если увеличить значение коэффициента, например, до 0,95, сглаживание получится еще более сильным. Построение графиков на основе данных, скопированных из окна монитора последовательного порта, — отличный способ проверить, насколько результат сглаживания соответствует вашим потребностям.

Цифровая обработка сигналов в Arduino Uno

На рис. 13.4 изображена схема подключения источника сигнала звуковой частоты к контакту A0 на плате Arduino и приемника выходного ШИМ-сигнала (10 кГц), генерируемого платой. В качестве генератора сигнала я использовал приложение на смартфоне и подключил выход для наушников на телефоне к плате Arduino.

Рис. 13.4. Использование Arduino Uno для цифровой обработки сигнала

ВНИМАНИЕ

Предупреждаю, что подобное использование телефона может повлечь за собой аннулирование гарантийных обязательств производителя и выход телефона из строя.

Входной сигнал с генератора смещается с помощью C1, R1 и R2 так, чтобы он колебался относительно средней точки 2,5 В и АЦП мог читать любые уровни сигнала. Если убрать эти элементы, сигнал будет колебаться относительно 0 В.

На выходе я добавил простой RC-фильтр на элементах R3 и C2, чтобы устранить несущую частоту ШИМ. Несущая частота ШИМ, равная 10 кГц, к сожалению, слишком близка к частоте основного сигнала, чтобы ее можно было подавить полностью.

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

Следующий скетч использует библиотеку TimerOne, чтобы сгенерировать ШИМ-сигнал и выполнять замеры с частотой 10 кГц:

// sketch_13_03_null_filter_uno

#include <TimerOne.h>

const int analogInPin = A0;

const int analogOutPin = 9;

void setup()

{

  Timer1.attachInterrupt(sample);

  Timer1.pwm(analogOutPin, 0, 100);

}

void loop()

{

}

void sample()

{

  int raw = analogRead(analogInPin);

  Timer1.setPwmDuty(analogOutPin, raw);

}

На рис. 13.5 изображен сигнал, подаваемый на вход Arduino (верхний график), и выходной сигнал, генерируемый платой Arduino (нижний график). Оба сигнала имеют частоту 1 кГц. Выходной сигнал имеет в целом неплохую форму до частоты 2–3 кГц, но на более высоких частотах начинает приобретать треугольную форму, что объясняется малым числом замеров, приходящихся на один цикл. На осциллограмме можно наблюдать остатки несущей гармоники, искажающие выходной сигнал, но в целом он имеет совсем неплохую форму. Этого вполне достаточно для обработки сигналов с речевой частотой.

Рис. 13.5. Воспроизведение сигнала с частотой 1 кГц платой Arduino Uno

Цифровая обработка сигналов в Arduino Due

Теперь проведем тот же эксперимент с платой Arduino Due, способной производить замеры с более высокой частотой. Код для модели Uno из предыдущего раздела нельзя использовать с платой Due, так

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату