Существуют ли библиотеки сглаживания сигналов для Arduino?

14

Я работаю над мобильным роботом, управляемым по беспроводной линии связи 2,4 ГГц. Приемник подключен к Arduino Uno, который служит на борту в качестве основного контроллера. Наиболее критичный (и основной) входной канал, поступающий от приемника, производит очень шумный сигнал, который приводит к множеству незначительных изменений в выходной мощности исполнительных механизмов, даже если они не нужны.

введите описание изображения здесь
                    Участок ввода Arduino с интервалом 30 секунд.

Я ищу библиотеки, которые могут выполнять эффективное сглаживание. Есть ли какие-либо библиотеки сглаживания сигнала, доступные для Arduino (Uno)?

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

Ответы:

8

Microsmooth - это облегченная библиотека сглаживания сигналов, которая в настоящее время разрабатывается мной.

Это все еще продолжается, и цель состоит в том, чтобы сделать его легким с точки зрения памяти и быстрым. Библиотека предоставляет несколько фильтров для сглаживания:

  • Простая скользящая средняя
  • Экспоненциальная скользящая средняя
  • Накопительное скользящее среднее
  • Савицкий Голэй Фильтр
  • Алгоритм Рамера Дугласа Пекера
  • Калмогоров Зурбенко Фильтр

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

#include "microsmooth.h"
asheeshr
источник
Привет, у меня проблемы с использованием вашей библиотеки. Вы бы не использовали «Импортировать библиотеку ...», чтобы импортировать свою библиотеку, верно? Я попытался просто скопировать исходный код в мою папку .ino, но получаю ошибки об отсутствии файла automicrosmooth.h, о том, что серийный номер не определен, и об отсутствии ';'. Эта библиотека все еще работает? Спасибо
waspinator
@waspinator К сожалению об этом. Исправлены ошибки. Спасибо за ответ!
asheeshr
7

Я думаю, что вижу много шумовых пиков в вашем шумовом сигнале.

Медианный фильтр лучше избавляется от пиков шума одиночной выборки, чем любой линейный фильтр. (Это лучше, чем любой фильтр нижних частот, скользящее среднее, взвешенное скользящее среднее и т. Д. С точки зрения его времени отклика и его способности игнорировать такие выбросы шума одиночного образца).

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

библиотеки сглаживания сигналов в arduino.cc:

библиотеки сглаживания сигналов в github:

Будет ли что-то подобное в вашем роботе? (Медиана 3 требует очень небольшой мощности процессора, а значит, и быстрой):

/*
median_filter.ino
2014-03-25: started by David Cary
*/

int median_of_3( int a, int b, int c ){
    int the_max = max( max( a, b ), c );
    int the_min = min( min( a, b ), c );
    // unnecessarily clever code
    int the_median = the_max ^ the_min ^ a ^ b ^ c;
    return( the_median );
}

int newest = 0;
int recent = 0;
int oldest = 0;

void setup()
{
    Serial.begin(9600);
    // read first value, initialize with it.
    oldest = random(200);
    recent = oldest;
    newest = recent;
    Serial.println("median filter example: ");
}

void loop()
{
    // drop oldest value and shift in latest value
    oldest = recent;
    recent = newest;
    newest = random(200);

    Serial.print("new value: ");
    Serial.print(newest, DEC);

    int median = median_of_3( oldest, recent, newest );

    Serial.print("smoothed value: ");
    Serial.print(median, DEC);
    Serial.println("");

    delay(5000);
}
Дэвид Кэри
источник
4

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

Обе эти библиотеки имеют список данных, считываемых с аналогового датчика по вашему выбору, который усредняется. Каждое новое значение датчика добавляется в список, а последнее выбрасывается следующим образом:

List: 3 4 3 3 4 3 5 3 2 3 4 3 
new reading added. old one thrown out
      /--                     /--
List: 5 3 4 3 3 4 3 5 3 2 3 4
list averaged
Доктор
источник
В значительной степени то, что делает простой FIR-фильтр со всеми значениями отводов, установленными на 1. Изменение значений отводов может еще больше улучшить сигнал, но требует более высокой математики.
Джиппи
Примечание. Второе звено вычисляет совокупное скользящее среднее, которое не является практическим выбором для управления приводом, особенно такое, которое может включать частые пуски и остановки. Сглаженный сигнал всегда будет отставать от пикового значения фактического сигнала с достаточным запасом.
asheeshr
2

Вы можете отфильтровать это в цифровом виде, используя фильтр нижних частот:

int valueFilt = (1-0.99)*value + 0.99*valueFilt;

Измените 0,99, чтобы изменить частоту среза (ближе к 1,0 - более низкая частота). Фактическое выражение для этого значения - exp (-2 * pi * f / fs), где f - требуемая частота среза, а fs - частота, с которой производится выборка данных.

Другой тип «цифрового фильтра» - это фильтр событий. Это хорошо работает на данных, которые имеют выбросы; например, 9,9,8,10,9,25,9. Фильтр событий возвращает наиболее частое значение. По статистике это режим.

Статистические средние, такие как среднее значение, режим и т. Д., Могут быть рассчитаны с использованием средней библиотеки Arduino .

Пример, взятый со страницы библиотеки Arduino, относится к:

#include <Average.h>
#define CNT 600
int d[CNT];

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int i;

  for(i=0; i<CNT; i++)
  {
    d[i] = random(500);
  }  

  Serial.print("Mean: ");
  Serial.print(mean(d,CNT),DEC);
  Serial.print(" Mode: ");
  Serial.print(mode(d,CNT),DEC);
  Serial.print(" Max: ");
  Serial.print(maximum(d,CNT),DEC);
  Serial.print(" Min: ");
  Serial.print(minimum(d,CNT),DEC);
  Serial.print(" Standard deviation: ");
  Serial.print(stddev(d,CNT),4);
  Serial.println("");
  Serial.println("");

  delay(5000);
}
akellyirl
источник
1
Обратите внимание, что это будет очень медленно, так как он выполняет много неявных приведений к float и back.
Коннор Вольф