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


14

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

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

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


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

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

Ответы:


8

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

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

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

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

#include "microsmooth.h"

Привет, у меня проблемы с использованием вашей библиотеки. Вы бы не использовали «Импортировать библиотеку ...», чтобы импортировать свою библиотеку, верно? Я попытался просто скопировать исходный код в мою папку .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);
}

1
Обратите внимание, что это будет очень медленно, так как он выполняет много неявных приведений к float и back.
— Коннор Вольф
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.