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

 
 
 
Reply to this topicStart new topic
> Цифровой ФНЧ iir + датчик постоянного тока, Можно ли отфильтровать сеть?
yanvasiij
сообщение Mar 21 2013, 12:51
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Доброго времени суток!

Суть проблемы такова: есть фото-датчик (обычный фотодиод + резистор подтянутый на 3.3), используется как индикатор свечения флоурисцентной лампы. Поскольку лампа не просто светит а "мерцает" с частотой сети, то сигнал, снимаемый с датчика, образует сумму постоянной составляющей и переменной отдаленной похожей половину периода синуса, вдобавок разночастотные помехи, которые весело резвятся "поверх" сигнала. Первоначально я просто делал скользящее осреднение по периоду мерцания лампы, но нет-нет по неясной причине АЦП выдавал неприлично высокий уровень (как будто нет свечения вообще) и выскакивала ошибка свечения лампы. Тогда я решал эту проблему всякими неприличными алгоритмическими ветвлениями, но теперь решил попробовать цифровой фильтр. Вкратце ознакомился с общей теорией отсюда, воспользовался вот этой программой и сгенерил код со следеющими параметрами: iir-ФНЧ Батервотра 4-го порядка, частота выборок 103 герца, частота среза 13 Гц (по-правде говоря пробовал разные значения, просто здесь привожу последнее, 103 герца из соображений, что фильтр не борется с частотами кратными частоте найквиста, а 13 Гц потому что меньше 50 и время переходного процесса не слишком большое). Далее настроил высокоприритетную задачу которая опрашивала АЦП с частотой 103 Гц и данные отправляла в фильтр, возвращаемое значение выводилось мне. Вообщем никакой фильтрации я не увидел, не знаю как там с помехами, но 50 Гц точно не подавляет, показания "пляшут". Ниже привожу код фильтра и задачи которая вызывает фильтр. Может кто-нибудь подскажет, что я делаю не так, буду очень признателен.

Фильтр:
Код
#define NCoef 4
#define DCgain 16

int16_t iir(int16_t NewSample) {
    int16_t ACoef[NCoef+1] = {
         2763,
        11052,
        16578,
        11052,
         2763
    };

    int16_t BCoef[NCoef+1] = {
        16384,
        -31933,
        28030,
        -11648,
         1929
    };

    static int32_t y[NCoef+1]; //output samples
    //Warning!!!!!! This variable should be signed (input sample width + Coefs width + 4 )-bit width to avoid saturation.

    static int16_t x[NCoef+1]; //input samples
    int n;

    //shift the old samples
    for(n=NCoef; n>0; n--) {
       x[n] = x[n-1];
       y[n] = y[n-1];
    }

    //Calculate the new output
    x[0] = NewSample;
    y[0] = ACoef[0] * x[0];
    for(n=1; n<=NCoef; n++)
        y[0] += ACoef[n] * x[n] - BCoef[n] * y[n];

    y[0] /= BCoef[0];
    
    return y[0] / DCgain;
}


Задача вызывающая фильтр:
Код
uint16_t adc0MVal;
__task void getUfoSensorsDataTask (void)
{
    for(;;)
    {
        os_dly_wait(39); //Это RTXовская задержка по времени равно 9.7 мс - частота 103 Гц
        uint16_t tmpAdc = (~ADCRead( 0 ))&0x1FF;
        adc0MVal = iir((int16_t)tmpAdc);//tmp0;
    }
}


Спасибо!

Сообщение отредактировал yanvasiij - Mar 21 2013, 13:02
Go to the top of the page
 
+Quote Post
Fat Robot
сообщение Mar 21 2013, 13:17
Сообщение #2


ʕʘ̅͜ʘ̅ʔ
*****

Группа: Свой
Сообщений: 1 008
Регистрация: 3-05-05
Пользователь №: 4 691



1. чтобы посмотреть, что не так, подайте на вход Вашего фильтра отсчеты синусоиды с разными амплитудами и частотами. Посмотрите, как фильр себя ведет. Сымитируйте АЦП, когда на его входе отсчеты синусоиды.

2. Если у Вас присутствуют импульсные помехи, то вместо линейного фильтра (в Вашем случае ск. среднего или БИХ) было бы эффективней использовать медианный фильтр, как устройство для оценки "среднего" значения.

3. Ну и конечно логически инвертировать отсчет АЦП, а потом накладывать маску - это какая-то военная хитрость
Go to the top of the page
 
+Quote Post
Дмитрий_Б
сообщение Mar 21 2013, 14:14
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 211
Регистрация: 25-10-09
Пользователь №: 53 195



Частота дискретизации 400 Гц поможет. Лампа вспыхивает 100 Гц.
Go to the top of the page
 
+Quote Post
Guest_TSerg_*
сообщение Mar 21 2013, 18:11
Сообщение #4





Guests






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

Варианты с частотой среза ~10 Гц:
1. RC-цепочка
2. Предварительный ФНЧ нужного порядка на ОУ.

Чтобы было понятно - частота среза 10 Гц гарантирует с использованием компаратора на постоянном пороге переключения время реакции примерно в 0.2 сек.
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Mar 22 2013, 09:06
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Цитата(Fat Robot @ Mar 21 2013, 19:17) *
1. чтобы посмотреть, что не так, подайте на вход Вашего фильтра отсчеты синусоиды с разными амплитудами и частотами. Посмотрите, как фильр себя ведет. Сымитируйте АЦП, когда на его входе отсчеты синусоиды.

2. Если у Вас присутствуют импульсные помехи, то вместо линейного фильтра (в Вашем случае ск. среднего или БИХ) было бы эффективней использовать медианный фильтр, как устройство для оценки "среднего" значения.

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



Цитата(Дмитрий_Б @ Mar 21 2013, 20:14) *
Частота дискретизации 400 Гц поможет. Лампа вспыхивает 100 Гц.


Дмитрий_Б, Fat Robot спасибо! Дмитрий_Б оказался прав. Все просто прекрасно заработало при изменении частоты дискретизации. Правда очень многое осталось неясным.

Во-первых, при настройке фильтра на 400 Гц он не работал, входил в какой-то непонятный колебательный процесс и даже в отсутствии сигнала выдавал какой то бешенный рандом в диапазоне от нуля до максимума. Когда при очередном изменении я случайно настроил фильтр на 200 Гц, а частота задачи вызывающей фильтр так и осталась 400 Гц он заработал, при чем настолько хорошо заработал, что я даже опешил - можно посторить АЧХ и оно совпадет с картинкой на проге. Это мне не понятно, выходит прога неверно генерит код?

Во-вторых, если я ставлю порядок выше 3-го фильтр начинает "колебаться", как я это уже упомянул. При частоте среза ниже 4 Гц включительно, фильтр начинает работать нормально, но как только "видит" мои колебания в 100 Гц снова срывается и начинает рандомно колебаться и уже не восстанавливается даже в отсутствии сигнала. Сейчас у меня 2-ой порядок частота среза 5 Гц, частота дискретизации выставленная в программе 200 Гц, а реально вызывается 400 Гц. Кажется, что все работает отлично, но может ли такое случится, что при помехе некоторой частоты он также сорвется? Может это из-за целочисленных вычислений (мне не хотелось связываться с float и я выбрал целочисленный способ)?

Имитировать частоты софтовым способом, как сказал Fat Robot, я не стал. Поскольку синус, который я буду таким образом подавать будет полностью синхронизирован с частотой работы задачи, вызывающей фильтр. Я думаю просто воспользоваться генератором сигналов, хотябы с той же звуковой карты. А вот про медианный фильтр наверно хорошая идея, вот только тут у меня знаний еще меньше чем в области БИХ и КИХ фильтров. Что же касается инверсии, то это делает специально, мне же нужно свечение, а оно тем больше чем меньше напряжение на АЦП.

TSerg схемотехнические способы не рассматриваю в принципе. Зачем что-то городить на плате, если можно софтовым способом убрать?

Вообщем, всем большое спасибо!

Сообщение отредактировал yanvasiij - Mar 22 2013, 09:18
Go to the top of the page
 
+Quote Post

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

 


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


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