реклама на сайте
подробности

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> STM32F4: цифровой фильтр АЦП
k000858
сообщение Dec 26 2014, 11:28
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 31-01-12
Пользователь №: 69 978



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

В МК есть FPU и инструкции DSP. Быть может есть готовые библиотеки в CMSIS для подобных расчетов?
Go to the top of the page
 
+Quote Post
kovigor
сообщение Dec 26 2014, 12:30
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(k000858 @ Dec 26 2014, 15:28) *
Так делается или есть способ похитрее программно сгладить шумы?

Делается. Если со схемотехникой и разводкой все в порядке, то этот метод вполне применим.
Рискну спросить. А антиалиасный фильтр перед АЦП имеется ? Хотя бы простейшая RC - цепочка ? И насколько сложно будет исправить некорректно разведенную плату ?
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 26 2014, 13:02
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Вот простейший фильтр:
CODE
#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;
}
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Dec 26 2014, 13:13
Сообщение #4


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(k000858 @ Dec 26 2014, 13:28) *
Так делается или есть способ похитрее программно сгладить шумы?


После АЦП до любых других фильтров всегда применяйте медианный.
Здесь где-то на форуме недалеко есть тема со сравнением быстродействия различных реализаций медианного фильтра.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Dec 26 2014, 15:53
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



экспонента для плавных процессов тоже хорошо броски борет
Go to the top of the page
 
+Quote Post
Aner
сообщение Dec 26 2014, 19:56
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 4 869
Регистрация: 28-02-08
Из: СПБ
Пользователь №: 35 463



Если шум на ацп: иногда вместо 0 показывает 0.1-0.3В (вход мерит до 72В благодаря резистивному делителю). Это нужно исправлять. Вы хоть прикиньте ошибку и динам диапазон. Может у вас 6 разрядов шумят из 12. А может меряете програмно не верно, без учета входых реактивностей.
Ну исправите вы что-то софтом усредните, отмедианите, откалманите, а аппаратная ошибка дающая шум останется.
Go to the top of the page
 
+Quote Post
k000858
сообщение Dec 29 2014, 04:12
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 31-01-12
Пользователь №: 69 978



Цитата(kovigor @ Dec 26 2014, 16:30) *
Делается. Если со схемотехникой и разводкой все в порядке, то этот метод вполне применим.
Рискну спросить. А антиалиасный фильтр перед АЦП имеется ? Хотя бы простейшая RC - цепочка ? И насколько сложно будет исправить некорректно разведенную плату ?

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

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

Цитата(scifi @ Dec 26 2014, 17:02) *
Вот простейший фильтр:
CODE
#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х словах?
Go to the top of the page
 
+Quote Post
k000858
сообщение Dec 29 2014, 06:45
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 31-01-12
Пользователь №: 69 978



Цитата(AlexandrY @ Dec 26 2014, 16:13) *
После АЦП до любых других фильтров всегда применяйте медианный.
Здесь где-то на форуме недалеко есть тема со сравнением быстродействия различных реализаций медианного фильтра.

в DSP библиотеках CMSIS что то есть для медианного фильтра?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Dec 29 2014, 06:58
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
спасибо за пример. еще бы допереть как его использовать.
можно в 2х словах?


идея в том что вы вызываете void filter_init(int a)
с первым полученным от АЦП значением или 0

а далее каждое новое значение пихаете в void filter_advance(int a), и когда вам надо
отфильтрованный результат, берете его в int filter_result(void)


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



Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 29 2014, 07:18
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Golikov A. @ Dec 29 2014, 09:58) *
идея в том что вы вызываете void filter_init(int a) ...

Спасибо за пояснения. А я хотел просто послать на RTFM: в комментариях к коду, вообще-то, всё написано :-)
Go to the top of the page
 
+Quote Post
adnega
сообщение Dec 29 2014, 08:26
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(k000858 @ Dec 29 2014, 08:12) *
На входе АЦП простой резистивный делитель + кондер на GND

Общеизвестно, что на сопротивление такого делителя накладываются ограничения.
У вас R не больше предельного значения? В противном случае АПЦ превращается в показометр.
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 29 2014, 08:37
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(k000858 @ Dec 29 2014, 07:12) *
На входе АЦП простой резистивный делитель + кондер на GND
На входе Vref рекомендуемая схема от ST

Цитата(adnega @ Dec 29 2014, 11:26) *
Общеизвестно, что на сопротивление такого делителя накладываются ограничения.
У вас R не больше предельного значения? В противном случае АПЦ превращается в показометр.

Кроме того, конденсатор должен быть рядом с ножкой МК. Это же относится и к Vref. Проверено хождением по граблям :-)
Go to the top of the page
 
+Quote Post
k000858
сообщение Dec 29 2014, 09:21
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 31-01-12
Пользователь №: 69 978



Цитата(adnega @ Dec 29 2014, 11:26) *
Общеизвестно, что на сопротивление такого делителя накладываются ограничения.
У вас R не больше предельного значения? В противном случае АПЦ превращается в показометр.


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

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

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

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

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

Цитата(Golikov A. @ Dec 29 2014, 09:58) *
идея в том что вы вызываете void filter_init(int a)
с первым полученным от АЦП значением или 0

а далее каждое новое значение пихаете в void filter_advance(int a), и когда вам надо
отфильтрованный результат, берете его в int filter_result(void)


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

спасибо.
а чем такой способ отличается от медианного фильтра (в 2х словах, если не сложно) ?
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 29 2014, 09:30
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(k000858 @ Dec 29 2014, 12:21) *
Применил вышеописанный фильтр. Без подключенного измеряемого напряжения (на входе АЦП 0В):
до применения показания были 0 - 0.3В
после применения (результат берется из 100 измерений) 0.07-0.12В т.е. 0В никогда не бывает.

Можно предположить, что помеха настолько велика, что среднеквадратичное отклонение имеет порядок 0.1В, что и даёт такое среднее значение около 0 (потому что отрицательные значения на входе АЦП заменяются нулём, а положительные остаются). Это предположение нужно подтвердить. Оцифруйте 100...1000 отсчётов при ненулевом входе и посчитайте статистические показатели: среднее, мин., макс., среднеквадратичное отклонение.
Если предположение подтвердится, то можно приподнять сигнал на входе АЦП ещё одним резистором (к Vref, например), чтобы сигнал на входе АЦП никогда не опускался ниже 0 даже в присутствии шумов. Ну а потом эту поправку от резистора учесть в расчётах, естественно.
Go to the top of the page
 
+Quote Post
adnega
сообщение Dec 29 2014, 09:33
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(k000858 @ Dec 29 2014, 13:21) *
В общем делаю вывод, что частота помехи слишком высокая и в измерения слишком часто попадают броски. Будь частота помехи пониже, от фильтра было бы больше пользы.
Быть может у кого то еще появятся мысли о том, как мне победить помеху программным способом...

Если Rain будет больше рекомендованного значения, то в каждой выборке вы будете иметь бросок, и программно такое не обработать.
Осциллограф наглядно покажет эти броски на ножке АЦП.
Ради эксперимента увеличьте емкость между входом АЦП и GND до мкФ, время выборки АЦП увеличьте до максимума - должно полегчать.
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 20:13
Рейтинг@Mail.ru


Страница сгенерированна за 0.01517 секунд с 7
ELECTRONIX ©2004-2016