Улучшение точности, программное

Onkel
Offline
Зарегистрирован: 22.02.2016

если проблема в шуме, то усреднение дает сглаживание шума в среднеарифметическом корень из числа измерений. Если шум 1%, то для получения сигнал/шум 0.1% вам нужно усреднить по 100 измерениям. Если значение меняется и вам нужно отслеживать тренд, то это немного другая задача. Я такого рода задачи считаю по экспоненциально взвешенной скользящей средней, чем больше N тем больше усредняется шум, но тем медленнее реакция. Вам лучше по эксп. взвешенной скользящей средней, с характерным усреднением по 100 измерениям. Это если вы ничего не знаете о шумах, если характеристики шума известны то применяется специальным образом рассчитанный цифровой ( в т.ч. конечный) фильтр. Но начните со скользящей средней. Формула для э.в.с.с. простая , см. вики или любой учебник

Экспоненциально взвешенное скользящее среднее, экспоненциальное скользящее среднее (англ. exponentially weighted moving average — англ. EWMA, англ. exponential moving average — англ. EMA) — разновидность взвешенной скользящей средней, веса которой убывают экспоненциально и никогда не равны нулю[3]. Определяется следующей формулой[1][2][4][5][6]:

EMAt=α⋅pt+(1−α)⋅EMAt−1,{\displaystyle {\textit {EMA}}_{t}=\alpha \cdot p_{t}+(1-\alpha )\cdot {\textit {EMA}}_{t-1},}{\textit  {EMA}}_{t}=\alpha \cdot p_{t}+(1-\alpha )\cdot {\textit  {EMA}}_{{t-1}},

где EMAt{\displaystyle {\textit {EMA}}_{t}}{\textit  {EMA}}_{t} — значение экспоненциального скользящего среднего в точке t{\displaystyle t}t (последнее значение, в случае временного ряда), EMAt−1{\displaystyle {\textit {EMA}}_{t-1}}{\textit  {EMA}}_{{t-1}} — значение экспоненциального скользящего среднего в точке t−1{\displaystyle t-1}t-1 (предыдущее значение в случае временного ряда), pt{\displaystyle p_{t}}p_{t} — значение исходной функции в момент времени t{\displaystyle t}t (последнее значение, в случае временного ряда),  α{\displaystyle \ \alpha }\ \alpha (сглаживающая константа от англ. smoothing constant) — коэффициент характеризующий скорость уменьшения весов, принимает значение от 0 и до 1, чем меньше его значение тем больше влияние предыдущих значений на текущую величину среднего.

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

EMA0=p0.{\displaystyle {\textit {EMA}}_{0}=p_{0}.}{\textit  {EMA}}_{0}=p_{0}.

Коэффициент  α{\displaystyle \ \alpha }\ \alpha, может быть выбран произвольным образом, в пределах от 0 до 1, например, выражен через величину окна усреднения:

 α=2n+1.{\displaystyle \ \alpha ={\frac {2}{n+1}}.}\ \alpha ={\frac  {2}{n+1}}.
dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

ua6em пишет:

Надеяться, что INA219 оригинал не приходится?

Их не подделывают, на сайте техаса голые чипы по 80 центов в партии тыща штук. А готовый модуль на али по полтора бакса.

Волшебник
Offline
Зарегистрирован: 22.12.2016

andriano пишет:

Если у Вас вагон времени - делайте процессинг хоть до 32 разрядов, достоверными все равно будут не более 10, и то при условии, что Вы не разгоняли АЦП.

Почитайте на досуге атмеловскую аппликейшн ноут AVR121.  А потом напишите в тех супорт атмела что они идиоты, и 14-бит им не видать как собственных ушей.

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Опять баянистую тему задели. Волшебник, вы уверены, что andriano не про абсолютную точность вёл речь?

Волшебник
Offline
Зарегистрирован: 22.12.2016

dimax пишет:

Опять баянистую тему задели. Волшебник, вы уверены, что andriano не про абсолютную точность вёл речь?

Уверен что он как раз о ней и говорит. Я и говорю путаница в названии топика, точность тут вообще ни при делах. Нет смысла ни о какой точности говорить если сама измеряемая величина не то что платино-иридиевого стандарта не имеет, так вообще физико-математически не определена в СИ.

Хотя справедливости ради стоить заметить что andriano во многом прав. Если теоретизировать о дизайне идеальных АЦП.

 Не прав он (как и многие на этом форуме) тогда, когда безапеляционно утверждает что АЦП сразу становится 6-8 бит если его раскрутить на 1 МГц, и что шумы не Гаусовские , хотя никаких доказательств не приводит.

Я тут перемерял последние 4 часа, используя свой код для измерения ЕНОБ-а на МЕГЕ, где-то в другом топике выкладывал, поищите. Так вот на 1 МГц ( разгонка х8) АЦП теряет пол-бита всего. А результаты БПФ абсолютно точно гарантируют Гаусовское распределение шума. 100%-но  математически достоверно.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

вот только недавно проводил свои исследования АЦП, выложил в своей теме в проектах .. не читали что ли? Там при повышении скорости присутствует как раз систематическая ошибка из-за медленной скорости работы мультиплекора встроенного АЦП. Даже если его не трогать и проводить измерения строго с одной ноги, то все равно, согласно даташиту в первые 1.5 такта АЦП происходит "переустановка согласно ADMUX", что и дает именно систематическую ошибку. Хорошо видно на выложенных сканах с плоттера ИДЕ. Эффективно как-бы "загрубляется" шаг оцифровки до 5-6 бит. на скорости 400-600ksps.

Смотреть тут: самодельная мега2560, мега128а с памятью 512 килобайт, пост №15 и далее

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Onkel пишет:

если проблема в шуме, то усреднение дает сглаживание шума в среднеарифметическом корень из числа измерений. Если шум 1%, то для получения сигнал/шум 0.1% вам нужно усреднить по 100 измерениям. Если значение меняется и вам нужно отслеживать тренд, то это немного другая задача.

да кто его знает в чём проблема ))) так как контур работает в БАТ смею предположить, что в некоторый момент времени меняется нагрузка за счёт увеличения "отсоса" энергии, закон изменения известен одному создателю, отсюда и флуктуации, шум теоретически не выше 5-й гармоники, практически не мерял, нечем

Реализовано в коде 256 измерений и рассчёт средней

PS WDRAKULA - делай прибор, расслабляет не хуже перцовки )))

Onkel
Offline
Зарегистрирован: 22.02.2016

ua6em пишет:

 

 шум теоретически не выше 5-й гармоники, практически не мерял, нечем

Реализовано в коде 256 измерений и рассчёт средней
 

Среднеарифметическая? А скользящая не лучше?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Onkel пишет:

ua6em пишет:

 

 шум теоретически не выше 5-й гармоники, практически не мерял, нечем

Реализовано в коде 256 измерений и рассчёт средней
 

Среднеарифметическая? А скользящая не лучше?

Режим INA219 - 16S и я в цикле 16 раз вызываю, что там получается не владею, колебания значений 2-3 единицы

Onkel
Offline
Зарегистрирован: 22.02.2016

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

 

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Onkel пишет:

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

в коде не подскажите?

Onkel
Offline
Зарегистрирован: 22.02.2016

ua6em пишет:

 

в коде не подскажите?

 

Х(0)=Inp(0)

X(n)=X(n-1)+2* (Inp(n) - X(n-1))/(1+N)

тут

Х(0) - нулевое среднее значение

 Inp(0) - нулевой значение входной величины

X(n) - энное среднее значение (текущее)

X(n-1)   -(n-1 ) "ое среднее значение (предыдущее)

 Inp(n) - текущее входное значение

N - окно усреднения, берите 16 (если хотиет вместе с усреднением в чипе получить общее 256 и усреднение сигнал/шум 16). При N=0 формула дает просто текущее значение.

Ну или выше я приводил формулы, можно через альфу.

 

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

нашел такое решение:
 

файл stm32fxx_it.c
uint16_t tmp_arr[256] = {0}; // массив где храним мгновенные значения
uint16_t tmp_rez = 0; // для хранения текущего результата
uint32_t sum = 0; // здесь хранится сумма всех элементов массива
uint32_t number = 0; // а сюда запишем результат вычисления среднего скользящего

void TIM1_UP_IRQHandler(void) // обработчик прерывания таймера (интервал через который будем делать замер запуская АЦП)
{
HAL_ADC_Start_IT(&hadc1);
HAL_TIM_IRQHandler(&htim1);
}

void ADC1_2_IRQHandler(void) // обработчик прерывания по окончанию преобразования
{
static uint8_t cnt = 0; // статическая переменная которая будет переполняться, специально делаю так чтобы не использовать условия if и т.д. , но размер окна получается в 256 значений
sum -= tmp_arr[cnt]; // отнимаем от общ. сум. знач. ячейки массива которую в дальнейшем перезапишем новым знач (т.е. самое старое значение)
tmp_res = HAL_ADC_GetValue(&hadc1); // по оконч. преобраз, присваиваем результ.временной перем.
sum += tmp_res; // прибавляем результат в общую сумму
tmp_arr[cnt] = tmp_res; // перезаписываем значение ячейки с которой работали
++cnt; // увеличиваем счетчик
number = sum >> 8; // делим на 256, т.е. количество элементов массива
HAL_ADC_IRQHandler(&hadc1);
}

 

Onkel
Offline
Зарегистрирован: 22.02.2016

если у вас не взвешенная , а простая конечная сумма то в конечности фильтра нет необходимости - скользящая экспоненциальная средняя требует лишь 2 float переменные - текущее и предыдущее значение среднего. У вас получится фильтр- аналог простой RC цепочки, а вам ведь больше и не нужно.

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Попробую одолеть вашу китайскую грамоту - тунже цу воды )))

Onkel
Offline
Зарегистрирован: 22.02.2016

ua6em пишет:

Попробую одолеть вашу китайскую грамоту - тунже цу воды )))

жё ши ичи.

Экспоненциально взвешенная скользящая средняя - очень простая штука, её даже брокеры на бирже знают

http://berg.com.ua/indicators-overlays/types-of-moving-averages/