Перейти к содержанию
    

STM32F4: цифровой фильтр АЦП

Есть девайс, мерит напряжение. К сожалению, плата разведена не очень хорошо, есть шум на ацп: иногда вместо 0 показывает 0.1-0.3В (вход мерит до 72В благодаря резистивному делителю).

Планирую добавить усреднение: замерять с помощью АЦП 100 (например 100) раз канал, затем вычислять среднее арифметическое из полученных значений. Так делается или есть способ похитрее программно сгладить шумы?

 

В МК есть FPU и инструкции DSP. Быть может есть готовые библиотеки в CMSIS для подобных расчетов?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так делается или есть способ похитрее программно сгладить шумы?

Делается. Если со схемотехникой и разводкой все в порядке, то этот метод вполне применим.

Рискну спросить. А антиалиасный фильтр перед АЦП имеется ? Хотя бы простейшая RC - цепочка ? И насколько сложно будет исправить некорректно разведенную плату ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот простейший фильтр:

#define SHIFT 4 // filter time constant is T*2^SHIFT

static int acc;

// seed filter with initial value
void filter_init(int a)
{
   acc = a << SHIFT;
}

// call this periodically and supply filter with input data
void filter_advance(int a)
{
   acc += a - (acc >> SHIFT);
}

// filter output
int filter_result(void)
{
   return acc >> SHIFT;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так делается или есть способ похитрее программно сгладить шумы?

 

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

Здесь где-то на форуме недалеко есть тема со сравнением быстродействия различных реализаций медианного фильтра.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если шум на ацп: иногда вместо 0 показывает 0.1-0.3В (вход мерит до 72В благодаря резистивному делителю). Это нужно исправлять. Вы хоть прикиньте ошибку и динам диапазон. Может у вас 6 разрядов шумят из 12. А может меряете програмно не верно, без учета входых реактивностей.

Ну исправите вы что-то софтом усредните, отмедианите, откалманите, а аппаратная ошибка дающая шум останется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Делается. Если со схемотехникой и разводкой все в порядке, то этот метод вполне применим.

Рискну спросить. А антиалиасный фильтр перед АЦП имеется ? Хотя бы простейшая RC - цепочка ? И насколько сложно будет исправить некорректно разведенную плату ?

На входе АЦП простой резистивный делитель + кондер на GND

На входе Vref рекомендуемая схема от ST

 

Схема будет переделана в следующих ревизиях устройства, как только будут найдены источники помех и способы их устранения.

Сейчас задача - улучших характеристики АЦП уже эксплуатируемых устройств (т.е. программно)

 

Вот простейший фильтр:

#define SHIFT 4 // filter time constant is T*2^SHIFT

static int acc;

// seed filter with initial value
void filter_init(int a)
{
   acc = a << SHIFT;
}

// call this periodically and supply filter with input data
void filter_advance(int a)
{
   acc += a - (acc >> SHIFT);
}

// filter output
int filter_result(void)
{
   return acc >> SHIFT;
}

спасибо за пример. еще бы допереть как его использовать.

можно в 2х словах?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Здесь где-то на форуме недалеко есть тема со сравнением быстродействия различных реализаций медианного фильтра.

в DSP библиотеках CMSIS что то есть для медианного фильтра?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо за пример. еще бы допереть как его использовать.

можно в 2х словах?

 

идея в том что вы вызываете void filter_init(int a)

с первым полученным от АЦП значением или 0

 

а далее каждое новое значение пихаете в void filter_advance(int a), и когда вам надо

отфильтрованный результат, берете его в int filter_result(void)

 

 

это обычная экспонента

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

идея в том что вы вызываете void filter_init(int a) ...

Спасибо за пояснения. А я хотел просто послать на RTFM: в комментариях к коду, вообще-то, всё написано :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На входе АЦП простой резистивный делитель + кондер на GND

Общеизвестно, что на сопротивление такого делителя накладываются ограничения.

У вас R не больше предельного значения? В противном случае АПЦ превращается в показометр.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На входе АЦП простой резистивный делитель + кондер на GND

На входе Vref рекомендуемая схема от ST

Общеизвестно, что на сопротивление такого делителя накладываются ограничения.

У вас R не больше предельного значения? В противном случае АПЦ превращается в показометр.

Кроме того, конденсатор должен быть рядом с ножкой МК. Это же относится и к Vref. Проверено хождением по граблям :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Общеизвестно, что на сопротивление такого делителя накладываются ограничения.

У вас R не больше предельного значения? В противном случае АПЦ превращается в показометр.

 

плата разведена довольно неплохо, а вот схема питания устройства ( ... -> 5В -> 3.3В) так себе, соответственно Vref получается довольно шумным не смотря на фильтр.

 

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

 

Применил вышеописанный фильтр. Без подключенного измеряемого напряжения (на входе АЦП 0В):

до применения показания были 0 - 0.3В

после применения (результат берется из 100 измерений) 0.07-0.12В т.е. 0В никогда не бывает.

 

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

 

Быть может у кого то еще появятся мысли о том, как мне победить помеху программным способом...

 

идея в том что вы вызываете void filter_init(int a)

с первым полученным от АЦП значением или 0

 

а далее каждое новое значение пихаете в void filter_advance(int a), и когда вам надо

отфильтрованный результат, берете его в int filter_result(void)

 

 

это обычная экспонента

спасибо.

а чем такой способ отличается от медианного фильтра (в 2х словах, если не сложно) ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Применил вышеописанный фильтр. Без подключенного измеряемого напряжения (на входе АЦП 0В):

до применения показания были 0 - 0.3В

после применения (результат берется из 100 измерений) 0.07-0.12В т.е. 0В никогда не бывает.

Можно предположить, что помеха настолько велика, что среднеквадратичное отклонение имеет порядок 0.1В, что и даёт такое среднее значение около 0 (потому что отрицательные значения на входе АЦП заменяются нулём, а положительные остаются). Это предположение нужно подтвердить. Оцифруйте 100...1000 отсчётов при ненулевом входе и посчитайте статистические показатели: среднее, мин., макс., среднеквадратичное отклонение.

Если предположение подтвердится, то можно приподнять сигнал на входе АЦП ещё одним резистором (к Vref, например), чтобы сигнал на входе АЦП никогда не опускался ниже 0 даже в присутствии шумов. Ну а потом эту поправку от резистора учесть в расчётах, естественно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Быть может у кого то еще появятся мысли о том, как мне победить помеху программным способом...

Если Rain будет больше рекомендованного значения, то в каждой выборке вы будете иметь бросок, и программно такое не обработать.

Осциллограф наглядно покажет эти броски на ножке АЦП.

Ради эксперимента увеличьте емкость между входом АЦП и GND до мкФ, время выборки АЦП увеличьте до максимума - должно полегчать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...