Математическая фильтрация данных с аналогового пина
- Войдите на сайт для отправки комментариев
Ср, 06/02/2019 - 23:31
Есть программка, простенький вольтметр выводящий считываемое напряжение на многоразрядный семисегментный индикатор. Но у меня проблема с некорректным выводом. Понимаю что надо делать мат. фильтр но не сталкивался еще с ними. Нужна помощь знатоков. Снизу программа(на всякий).
bool one [10][8] =
{
{1, 1, 1, 1, 1, 1, 1, 0},
{1, 0, 1, 1, 0, 0, 0, 0},
{1, 1, 1, 0, 1, 1, 0, 1},
{1, 1, 1, 1, 1, 0, 0, 1},
{1, 0, 1, 1, 0, 0, 1, 1},
{1, 1, 0, 1, 1, 0, 1, 1},
{1, 1, 0, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 0, 1, 1}
};
bool two [10][8] =
{
{0, 1, 1, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 0, 0, 0, 0},
{0, 1, 1, 0, 1, 1, 0, 1},
{0, 1, 1, 1, 1, 0, 0, 1},
{0, 0, 1, 1, 0, 0, 1, 1},
{0, 1, 0, 1, 1, 0, 1, 1},
{0, 1, 0, 1, 1, 1, 1, 1},
{0, 1, 1, 1, 0, 0, 0, 0},
{0, 1, 1, 1, 1, 1, 1, 1},
{0, 1, 1, 1, 1, 0, 1, 1}
};
float VoltA;
int VoltB;
int Volt;
int VoltC;
void setup()
{
for(int pin =2; pin <= 17; pin++)
{
pinMode(pin, OUTPUT);
digitalWrite(pin,LOW);
}
pinMode(A5, INPUT);
Serial.begin(9600);
}
void DigitDraw(int digit)
{
for(int i = 0; i <= 8; i++)
{
if(one[digit][i] == 1) digitalWrite(i + 2, HIGH); else digitalWrite(i + 2, LOW);
}
}
void DigitDraw2(int digit2)
{
for(int q = 0; q <= 8; q++)
{
if(two[digit2][q] == 1) digitalWrite(q + 2, HIGH); else digitalWrite(q + 2, LOW);
}
}
void SelectDigit(byte select)
{
for(int c = 10; c<=12; c++)
{
digitalWrite(c, HIGH);
}
digitalWrite(select, LOW);
}
void loop()
{
Volt = analogRead(A5);
VoltA = analogRead(A5);
VoltA = VoltA/204.6;
Volt = Volt/204.6;
VoltA=(VoltA-Volt)*10;
VoltB=VoltA;
VoltC = Volt/10;
Serial.println(Volt);
SelectDigit(10);
DigitDraw2(VoltA);
delay(5);
SelectDigit(12);
DigitDraw2(VoltC);
delay(5);
SelectDigit(11);
DigitDraw2(Volt);
delay(5);
}
я угадаю проблему с 7 попыток ;)
Нет такого чудо-фильтра, который некорректные значения в корректные превращает. Формулируйте проблему точнее. И прочитайте в первой теме раздела Песочница правила оформления сообщений и конкретно вставки кода.
http://geekmatic.in.ua/filtracia_shumov_analogovogo_signala - вот тот самый чудо-фильтр) Мне надо что-то подобное для моего кода
Среднее арифметическое. Замеряем N раз в цикле, суммируем. После цикла делим сумму на N.
PS: Неформатированный код читать лень.
vavandrik, https://github.com/asheeshr/Microsmooth
Для нормальной фильтрации нужно, для начала правильно читать. Там обычно важна частота оцифровки.
А так, есть программа, которая генерирует готовый фильтр (исходник) по заданным характеристикам. Правда, как видно из дискуссии вот здесь, при одних условиях она хороша, а при других коллегу не устроила.
Вообще-то обработка результатов экспиримента - это целая наука. Вкратце можно посоветовать следующий алгоритм:
1) Считали некоторое количество данных
2) Вычислили среднее арифметическое
3) Вычислили среднюю погрешность
4) Выбросили результаты, не попадающие в погрешность
5) Вычислили среднее арифметическое из оставшихся данных
Для данной задачи вполне подойдет.
Может просто медиану брать - один qsort, а эффект примерно тот же.
Может просто медиану брать - один qsort, а эффект примерно тот же.
Не совсем так - надо сеять резко выбивающиеся данные - они сильно портят результат и, соответственно, смещают медиану.
Вообще-то обработка результатов экспиримента - это целая наука. Вкратце можно посоветовать следующий алгоритм:
1) Считали некоторое количество данных
2) Вычислили среднее арифметическое
3) Вычислили среднюю погрешность
4) Выбросили результаты, не попадающие в погрешность
5) Вычислили среднее арифметическое из оставшихся данных
Для данной задачи вполне подойдет.
- "Считали некоторое количество данных" - это не первый пункт, а где-то десятый: сначала эксперимент нужно спланировать, в частности, понять, что хотим мерять, с какой точностью, каким способом и т.д.
- При наличии значительных выбросов этот алгоритм будет работать плохо. Среднее арифметическое может уйти куда угодно. Для первоначальной оценки лучше использовать медиану. И иногда этого оказывается достаточно.
Может просто медиану брать - один qsort, а эффект примерно тот же.
Не совсем так - надо сеять резко выбивающиеся данные - они сильно портят результат и, соответственно, смещают медиану.
Не совсем так - надо сеять резко выбивающиеся данные - они сильно портят результат и, соответственно, смещают медиану.
А ежели сама природа сигнала хаотична - как тут определишь норму?
Для нормальной фильтрации нужно, для начала правильно читать. Там обычно важна частота оцифровки.
А ежели сама природа сигнала хаотична - как тут определишь норму?
А ежели сама природа сигнала хаотична - то достаточно точно Вы сможете померить только верний и нижний уровень сигнала. Но если это реально "белый шум".
Нужно всего лишь добавить:
float Volt = 0.0;
float VoltNew;
float alpha = 0.2;
// alpha - параметр сглаживания (примерно равен 1/n, где n - параметр усреднения)
// диапазон значений: 1 <= alpha < 0
// подобрать экспериментально в зависимости от характера входящего потока данных