Цифровий фільтр 3-ї гармоніки

Програми для ARDUINO DUE
Відповісти
Аватар користувача
radioman
Site Admin
Повідомлень: 96
З нами з: 28 вересня 2020, 12:01
Дякував (ла): 6 разів
Подякували: 2 рази

Цифровий фільтр 3-ї гармоніки

Повідомлення radioman »

На github давно викладено спрощену схему і скетч цифрового металодетектора з прямим опрацюванням на ARDUINO UNO. В його коді є цікавий момент, а саме - цифровий фільтр 3-ї гармоніки:

Код: Виділити все

    const double halfRoot2 = sqrt(0.5);
// sin α= 0.70710678
// cos α= 0.70710678
    
// Massage the results to eliminate sensitivity to the 3rd harmonic, and divide by 200
    double bin0 = (averages[0] + halfRoot2 * (averages[1] - averages[3]))/f;
    double bin1 = (averages[1] + halfRoot2 * (averages[0] + averages[2]))/f;
    double bin2 = (averages[2] + halfRoot2 * (averages[1] + averages[3]))/f;
    double bin3 = (averages[3] + halfRoot2 * (averages[2] - averages[0]))/f;
    sampleReady = false;          // we've finished reading the averages, so the ISR is free to overwrite them again
Але я не розібрався як він працює. Зрозуміло, що вимірювання проводяться 8 разів за період:
This gives us 16 ADC clock cycles for each ADC conversion (it actually takes 13.5 cycles), and we take 8 samples per cycle of the coil drive voltage.
The ADC implements four phase-sensitive detectors at 45 degree intervals. Using 4 instead of just 2 allows us to cancel the third harmonic of the coil frequency.
... ми беремо 8 вимірювань за цикл. Реалізовано чотири фазочутливі детектори з інтервалом 45 градусів. Використання 4 вимірювань замість 2 дає змогу відфільтрувати третю гармоніку робочої частоти. (переклад довільний)
Під час розрахунку результат ділиться на константу const double f = 200.0;, але я не знайшов :( у коді накопичення сигналу - не уважний :?

PS. Цей код дає змогу фідвільтрувати 3-тю гармоніку при використанні широкосмугового вхідного підсилювача.
pawa
Повідомлень: 75
З нами з: 28 вересня 2020, 20:26
Дякував (ла): 1 раз
Подякували: 5 разів

Re: Цифровий фільтр 3-ї гармоніки

Повідомлення pawa »

Мабуть якщо намалювати сигнал і 4 "детектори" зрозуміти буде простіше.
Аватар користувача
radioman
Site Admin
Повідомлень: 96
З нами з: 28 вересня 2020, 12:01
Дякував (ла): 6 разів
Подякували: 2 рази

Re: Цифровий фільтр 3-ї гармоніки

Повідомлення radioman »

У темі IB металошукач на ARDUINO DUE я приводив осциллограму синхронізації Tx та RX. Для реалізації квадратурного детектора необхідно провести 2 вимірювання з інтервалом у 90 градусів (я проводжу 4 з тим же інтервалом для отримання більшої кількості вимірювань).
У скетчі MetalDetector.ino пропонується проводити вимірювання не кожні 90, а кожні 45 градусів:
Вимірювання кожні 45 градусів
Вимірювання кожні 45 градусів
Не знаю де знаходиться початок вимірювань: він може бути як під номером 0, так і під номером 2. Згідно нашої схеми:

0 косинус
1 косинус +45
2 синус
3 синус +45

тоді, наведені в першому пості, формули означають:
косинус
bin0 = косинус + 0.70710678*(косинус45 - синус45)
bin1 = косинус45 + 0.70710678*(косинус + синус)
синус
bin2 = синус + 0.70710678*(косинус45 + синус45)
bin3 = синус45 + 0.70710678*(синус – косинус)

Далі з отриманих значень розраховується дві амплітуди (довжина вектора) та середнє значення:

Код: Виділити все

double amp1 = sqrt((bin0 * bin0) + (bin2 * bin2));
double amp2 = sqrt((bin1 * bin1) + (bin3 * bin3));
double ampAverage = (amp1 + amp2)/2.0;
і дві фази та їх середнє:

Код: Виділити все

const double radiansToDegrees = 180.0/3.1415927;

// The ADC sample/hold takes place 2 clocks after the timer overflow
    double phase1 = atan2(bin0, bin2) * radiansToDegrees + 45.0;
    double phase2 = atan2(bin1, bin3) * radiansToDegrees;
  
    if (phase1 > phase2)
    {
      double temp = phase1;
      phase1 = phase2;
      phase2 = temp;
    }
    double phaseAverage = ((phase1 + phase2)/2.0) - phaseAdjust;
Відповісти