Цитата(des00 @ Jan 4 2015, 17:18)

банальный корректор постоянки : измерение узким фильтром уровня постоянки и вычитание его из сигнала. Ну а затем пиковый детектор на скользящем окне наблюдения?
Это слишком "жирно" у меня STM32F103 на 72МГц.
Простое решение это нужно усреднять значение сигнала за какой-то период и смотреть на отклонение сигнала от усредненного.
Вопрос в том как есть ли методы нахождения периода усреднения и порога для принятия решения.
Для начала я написал функцию «скользящего среднего»
Код
// адаптивная подсторойка "нулевого" уровня
void adaptive_calc_average(int new_sample, statistic *stat, MD_PARAMETER *md_parameter)
{
int difference = stat->average - new_sample;
if (abs(difference) < md_parameter->amp_difference )
{
stat->average *=31;
stat->average +=new_sample;
stat->average /=32;
}
}
Предполагалось, что период усреднения можно будет адаптировать в зависимости от сигнала. Пока реализован только механизм отброса заведомо больших отклонений.
if (abs(difference) < md_parameter->amp_difference ) , такие отклонения в расчет не попадают.
Затем была написана функция определения объекта по отклонению сигнала от текущего среднего.
Код
//---------------------------------------------------
// определить наличие объекта по статистике сигнала в покое
int pulse_width_detecting(int new_sample, statistic *stat, MD_PARAMETER *md_parameter)
{
int difference, abs_difference;
adaptive_calc_average(new_sample, stat, md_parameter);
difference = stat->average - new_sample;
if (abs(difference) < md_parameter->amp_difference) // сигнал не превысил порог
{
pulse_width =0;
pulse_sign =0;
return 0;
}
if (pulse_sign ==0) // первое превышение порога
{
if (difference > 0) pulse_sign = 1;
if (difference < 0) pulse_sign = -1;
return 0;
}
if ((difference <0) && (pulse_sign < 0)) // отрицательный импульс
{
pulse_width++;
if (pulse_width > md_parameter->amp_len) return -1;
else return 0;
}
if ((difference > 0) && (pulse_sign >0)) // положительный импульс
{
pulse_width++;
if (pulse_width > md_parameter->amp_len) return 1;
else return 0;
}
pulse_width=0;
pulse_sign =0;
return 0;
}
Определяется длина непрерывного отклонения сигнала от текущего среднего, превышающее порог.
Решил привязать значение порога к статистике сигнала – среднее/среднеквадратичное отклонения. Для простоты взял 128 (int len) значений сигнала
//---------------------------------------------------
// подсчитать статитику фонового сигнала
void calc_stat(int *data, int len, statistic *stat)
{
int i, max, min;
float sum, sum2;
max = min = data[0];
sum =0;
for (i=0; i<len; i++)
{
if (max < data[i]) max = data[i];
if (min > data[i]) min = data[i];
sum += data[i];
}
stat->average = sum/len; // среднее значение
max = abs(max - stat->average);
min = abs(stat->average - min);
if (max > min) stat->max_diff = max; // максимальный выброс был в плюс
else stat->max_diff = min; // максимальный выброс был в минус
sum = sum2 =0;
for (i=0; i<len; i++)
{
sum += abs(stat->average - data[i]);
sum2 += abs(stat->average - data[i]) * abs(stat->average - data[i]);
}
stat->mean_diff = sum/len;
stat->sco = sqrt(sum2)/len;
}
Прогнал 4 образца Cu, Al, Fe, Ni и подобрал значение порога ширины импульса.
Нажмите для просмотра прикрепленного файлакрасный – сигнал;
синий – текущее среднее;
зеленый – функция детектирования сигнала.
Вроде бы все хорошо. Решил сменить условия эксперимента.
Поменять уровень помех я не могу, поэтому принудительно сдвинул фазу захвата данных АЦП.
Параметры обнаружения оставил те же.
Нажмите для просмотра прикрепленного файла Взаимосвязь среднего отклонения прослеживается, при изменении среднего отклонения с 0,2188 до 0,2422 появились ложные цели при тех же параметрах.
Решил проверить зависимость по "старым" измерениям. Собрал статистику о том во сколько раз порог должен превышать значение среднего отклонения. Получилось число от 5 до 64 – то есть корреляции нет. :-(
В аналогичном приборе автор отказался от адаптивной подстройки, и порог выбирается вручную. Оно как бы и логично при пороге 2 и 3 все работает.
У меня в теории, у автора в практике :-)
Есть фильтры Калмана о них пол интернета исписано, но толкового описания нет, да и STM32F103 его не потянет.
Есть фильтры которыми выявляют отклик от эхолотов и радиолокаторов. Но они тоже тяжеловесные.
Вот и думаю, есть проще типовое решение адаптивной подстройки порога или нет?