Generátor harmonického signálu: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
Bez shrnutí editace |
||
| Riadok 1: | Riadok 1: | ||
Záverečný projekt predmetu MIPS / LS2026 - | Záverečný projekt predmetu MIPS / LS2026 - Oleksandr Mykyta | ||
== Zadanie == | == Zadanie == | ||
Úlohou bolo generovať | Úlohou bolo generovať harmonický signál bez použitia funkcií sin() alebo cos(). | ||
Na tento účel bol použitý oscilátor realizovaný ako prenosová funkcia: | Na tento účel bol použitý oscilátor realizovaný ako prenosová funkcia: | ||
| Riadok 10: | Riadok 10: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Zároveň bolo potrebné zmerať jeden bod | Zároveň bolo potrebné zmerať jeden bod frekvenčnej charakteristiky systému: | ||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 33: | Riadok 33: | ||
__TOC__ | __TOC__ | ||
== Analýza a opis riešenia == | == Analýza a opis riešenia == | ||
Cieľom riešenia je vytvoriť | Cieľom riešenia je vytvoriť sínusový signál bez použitia matematických funkcií sin() alebo cos(). Tento problém sa rieši pomocou diskrétneho oscilátora, ktorý vychádza z diferenciálnej rovnice harmonického kmitania. | ||
Tento problém sa rieši pomocou | |||
Základom je rovnica: | Základom je rovnica: | ||
| Riadok 44: | Riadok 43: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Táto rovnica popisuje | Táto rovnica popisuje harmonické kmity a jej riešením sú funkcie <code>sin()</code> a <code>cos()</code>. To znamená, že ak vieme túto rovnicu numericky riešiť, vieme generovať sínus. | ||
=== Teoretický základ a odvodenia === | === Teoretický základ a odvodenia === | ||
| Riadok 50: | Riadok 49: | ||
==== Laplaceova transformacia ==== | ==== Laplaceova transformacia ==== | ||
Vychadzajme z prenosovej funkcie systému: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 63: | Riadok 62: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Použitím | Použitím inverznej Laplaceovej transformacie (kde s predstavuje deriváciu) dostaneme: | ||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
T · dy(t)/dt + y(t) = x(t) | T · dy(t)/dt + y(t) = x(t) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Týmto získame diferenciálnu rovnicu systému v časovej oblasti. | |||
==== Diskretizácia ==== | ==== Diskretizácia ==== | ||
Mikrokontrolér pracuje v | Mikrokontrolér pracuje v diskrétnom čase, preto je potrebné nahradiť derivácie rozdielmi medzi vzorkami. | ||
Pre druhú deriváciu: | Pre druhú deriváciu použijeme aproximáciu: | ||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 79: | Riadok 80: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Po dosadení do <code>y'' + ω²y = 0</code>: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
y | y[n] = (2 / (1 + ω²T_s²)) · y[n−1] − (1 / (1 + ω²T_s²)) · y[n−2] | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Táto rovnica predstavuje numerickú aproximáciu oscilátora, ale nie je ideálna z hľadiska stability amplitúdy. | |||
==== Diskrétny oscilátor (presný model) ==== | ==== Diskrétny oscilátor (presný model) ==== | ||
Presnejší prístup vychádza z trigonometrických identít: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 106: | Riadok 103: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Dosadením: | |||
<code>A = (n−1)θ</code> | <code>A = (n−1)θ</code> | ||
<code>B = θ</code> | <code>B = θ</code> | ||
dostaneme: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 117: | Riadok 114: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Označením: | |||
<code>y[n] = sin(nθ)</code> | <code>y[n] = sin(nθ)</code> | ||
vznikne rekurentný vzťah: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
y[n] = 2 · cos(θ) · y[n−1] − y[n−2] | y[n] = 2 · cos(θ) · y[n−1] − y[n−2] | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Tento vzťah generuje stabilný sínusový signál bez zmeny amplitúdy. | |||
==== Výpočet parametrov ==== | ==== Výpočet parametrov ==== | ||
Platí: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 135: | Riadok 134: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
kde: | |||
<code>T = 0.5 s</code> | <code>T = 0.5 s</code> | ||
| Riadok 141: | Riadok 140: | ||
<code>SAMPLE_RATE = 1000 Hz</code> | <code>SAMPLE_RATE = 1000 Hz</code> | ||
<code>T_s = 0.001 s</code> | <code>T_s = 0.001 s</code> | ||
<code>θ = 0.002</code> | <code>θ = 0.002</code> | ||
==== | ==== Aproximacia cos() ==== | ||
Taylorov rozvoj: | Keďže nie je dovolené použiť funkciu cos(), použije sa Taylorov rozvoj: | ||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 154: | Riadok 151: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Z toho: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 162: | Riadok 159: | ||
==== Inicializácia oscilátora ==== | ==== Inicializácia oscilátora ==== | ||
Pre správnu činnosť oscilátora sú potrebné počiatočné hodnoty: | |||
<code>y1 = 1</code> | <code>y1 = 1</code> | ||
| Riadok 169: | Riadok 166: | ||
==== Generovanie signálu ==== | ==== Generovanie signálu ==== | ||
Oscilátor generuje hodnoty v rozsahu: | |||
<code> | <code>[-1, 1]</code> | ||
Požadovaný výstup: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 179: | Riadok 176: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
kde: | |||
<code>A0 = 128</code> | <code>A0 = 128</code> | ||
<code>A1 = 100</code> | <code>A1 = 100</code> | ||
==== | ==== Diskretizacia systému 1 / (sT + 1) ==== | ||
Zo spojitej rovnice: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 192: | Riadok 189: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Použitím Eulerovej metódy: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 198: | Riadok 195: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Po úprave: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 206: | Riadok 203: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Po zavedení: | |||
<code>α = T_s / (T + T_s)</code> | <code>α = T_s / (T + T_s)</code> | ||
dostaneme praktický tvar: | |||
<syntaxhighlight lang=""> | <syntaxhighlight lang=""> | ||
| Riadok 219: | Riadok 216: | ||
=== Algoritmus a program === | === Algoritmus a program === | ||
Algoritmus programu využíva diskrétny oscilátor a numerickú aproximáciu systému 1 / (sT + 1). Základné výpočty prebiehajú v prerušení Timer1 s frekvenciou: | |||
<code>1 kHz</code> | <code>1 kHz</code> | ||
* výpočet oscilátora | |||
* generovanie vstupu x | |||
* výpočet výstupu systému | |||
* výstup cez PWM | |||
* odosielanie dát cez UART | |||
=== Overenie === | === Overenie === | ||
Funkcia systému bola overená pomocou výpisu dát cez UART. Do sériového portu sa posielajú dvojice hodnôt: | |||
<code>x, y_sys</code> | <code>x, y_sys</code> | ||
Tieto hodnoty je možné zobraziť napríklad pomocou Serial Plotteru, kde je viditeľný vstupný sínusový signál a výstup systému. | |||
Zo signálov je možné pozorovať zmenu amplitúdy a fázový posun, čo predstavuje bod frekvenčnej charakteristiky systému. | |||
== Čo by som urobil inak == | == Čo by som urobil inak == | ||
Pri riešení by bolo možné použiť presnejšiu metódu diskretizacie systému 1 / (sT + 1), napríklad bilineárnu transformaciu, ktorá by zlepšila presnosť modelu. | |||
Taktiež by bolo možné implementovať presnejší výpočet cos(θ) bez aproximacie, napríklad pomocou lookup tabuľky. | |||
Ďalším zlepšením by mohlo byť automatické vyhodnotenie amplitúdy a fázového posunu priamo v mikrokontroleri namiesto spracovania na PC. | |||
[[Category:AVR]] [[Category:MIPS]] | [[Category:AVR]] [[Category:MIPS]] | ||
Verzia z 13:32, 18. apríl 2026
Záverečný projekt predmetu MIPS / LS2026 - Oleksandr Mykyta
Zadanie
Úlohou bolo generovať harmonický signál bez použitia funkcií sin() alebo cos(). Na tento účel bol použitý oscilátor realizovaný ako prenosová funkcia:
H(s) = 1 / ((s · T)^2 + 1)Zároveň bolo potrebné zmerať jeden bod frekvenčnej charakteristiky systému:
H(s) = 1 / (s · T + 1)pre frekvenciu:
ω = 1 / T,
kde
T = 0.5 s.
Výstupný signál má mať tvar:
A₀ + A₁ · sin(ωt + φ)kde:
A₀ = 128,
A₁ = 100.
Analýza a opis riešenia
Cieľom riešenia je vytvoriť sínusový signál bez použitia matematických funkcií sin() alebo cos(). Tento problém sa rieši pomocou diskrétneho oscilátora, ktorý vychádza z diferenciálnej rovnice harmonického kmitania.
Základom je rovnica:
y'' + ω²y = 0Táto rovnica popisuje harmonické kmity a jej riešením sú funkcie sin() a cos(). To znamená, že ak vieme túto rovnicu numericky riešiť, vieme generovať sínus.
Teoretický základ a odvodenia
Laplaceova transformacia
Vychadzajme z prenosovej funkcie systému:
H(s) = Y(s) / X(s) = 1 / (T · s + 1)Po úprave:
Y(s) · (T · s + 1) = X(s)
T · s · Y(s) + Y(s) = X(s)Použitím inverznej Laplaceovej transformacie (kde s predstavuje deriváciu) dostaneme:
T · dy(t)/dt + y(t) = x(t)Týmto získame diferenciálnu rovnicu systému v časovej oblasti.
Diskretizácia
Mikrokontrolér pracuje v diskrétnom čase, preto je potrebné nahradiť derivácie rozdielmi medzi vzorkami.
Pre druhú deriváciu použijeme aproximáciu:
y'' ≈ (y[n] − 2y[n−1] + y[n−2]) / T_s²Po dosadení do y + ω²y = 0:
y[n] = (2 / (1 + ω²T_s²)) · y[n−1] − (1 / (1 + ω²T_s²)) · y[n−2]Táto rovnica predstavuje numerickú aproximáciu oscilátora, ale nie je ideálna z hľadiska stability amplitúdy.
Diskrétny oscilátor (presný model)
Presnejší prístup vychádza z trigonometrických identít:
sin(A + B) = sin(A)cos(B) + cos(A)sin(B)
sin(A − B) = sin(A)cos(B) − cos(A)sin(B)Po sčítaní:
sin(A + B) + sin(A − B) = 2 · sin(A) · cos(B)Dosadením:
A = (n−1)θ
B = θ
dostaneme:
sin(nθ) + sin((n−2)θ) = 2 · cos(θ) · sin((n−1)θ)Označením:
y[n] = sin(nθ)
vznikne rekurentný vzťah:
y[n] = 2 · cos(θ) · y[n−1] − y[n−2]Tento vzťah generuje stabilný sínusový signál bez zmeny amplitúdy.
Výpočet parametrov
Platí:
θ = ω · T_skde:
T = 0.5 s
ω = 1 / T = 2 rad/s
SAMPLE_RATE = 1000 Hz
T_s = 0.001 s
θ = 0.002
Aproximacia cos()
Keďže nie je dovolené použiť funkciu cos(), použije sa Taylorov rozvoj:
cos(θ) ≈ 1 − θ²/2Z toho:
2cos(θ) ≈ 2 · (1 − θ²/2)Inicializácia oscilátora
Pre správnu činnosť oscilátora sú potrebné počiatočné hodnoty:
y1 = 1
y2 = 1 − θ²/2
Generovanie signálu
Oscilátor generuje hodnoty v rozsahu:
[-1, 1]
Požadovaný výstup:
x = A0 + A1 · ykde:
A0 = 128
A1 = 100
Diskretizacia systému 1 / (sT + 1)
Zo spojitej rovnice:
T · dy/dt + y = xPoužitím Eulerovej metódy:
dy/dt ≈ (y[n] − y[n−1]) / T_sPo úprave:
y[n] = x − (T / T_s) · y[n] − (T / T_s) · y[n−1]
y[n] · (1 + (T / T_s)) = x − (T / T_s) · y[n−1]
y[n] = (T_s / (T + T_s)) · x + (T / (T + T_s)) · y[n−1]Po zavedení:
α = T_s / (T + T_s)
dostaneme praktický tvar:
y[n] = α · x + (1 − α) · y[n−1]
y[n] = y[n−1] + α · (x − y[n−1])Algoritmus a program
Algoritmus programu využíva diskrétny oscilátor a numerickú aproximáciu systému 1 / (sT + 1). Základné výpočty prebiehajú v prerušení Timer1 s frekvenciou:
1 kHz
- výpočet oscilátora
- generovanie vstupu x
- výpočet výstupu systému
- výstup cez PWM
- odosielanie dát cez UART
Overenie
Funkcia systému bola overená pomocou výpisu dát cez UART. Do sériového portu sa posielajú dvojice hodnôt:
x, y_sys
Tieto hodnoty je možné zobraziť napríklad pomocou Serial Plotteru, kde je viditeľný vstupný sínusový signál a výstup systému.
Zo signálov je možné pozorovať zmenu amplitúdy a fázový posun, čo predstavuje bod frekvenčnej charakteristiky systému.
Čo by som urobil inak
Pri riešení by bolo možné použiť presnejšiu metódu diskretizacie systému 1 / (sT + 1), napríklad bilineárnu transformaciu, ktorá by zlepšila presnosť modelu.
Taktiež by bolo možné implementovať presnejší výpočet cos(θ) bez aproximacie, napríklad pomocou lookup tabuľky.
Ďalším zlepšením by mohlo byť automatické vyhodnotenie amplitúdy a fázového posunu priamo v mikrokontroleri namiesto spracovania na PC.