Operácie

Generátor harmonického signálu: Rozdiel medzi revíziami

Zo stránky SensorWiki

StudentMIPS (diskusia | príspevky)
updated not clear enough explanations
StudentMIPS (diskusia | príspevky)
formatting update
Riadok 1: Riadok 1:
Záverečný projekt predmetu MIPS / LS2026 - '''Oleksandr Mykyta'''
Záverečný projekt predmetu MIPS / LS2026 - '''Oleksandr Mykyta'''


== Zadanie ==
== Zadanie ==


Ulohou je generovat harmonicky signal bez pouzitia funkcii sin() alebo cos(). Namiesto toho sa ma pouzit oscilator realizovany ako prenosova funkcia:
Ú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) = \frac{1}{(s \cdot T)^2 + 1}$$
H(s) = 1 / ((s · T)^2 + 1)


Zaroven je potrebne zmerat jeden bod frekvencnej charakteristiky systemu:
Zároveň bolo potrebné zmerať jeden bod frekvenčnej charakteristiky systému:


$$H(s) = \frac{1}{s \cdot T + 1}$$
H(s) = 1 / (s · T + 1)


na frekvencii ω = 1 / T, pricom T = 0,5 s.
pre frekvenciu ω = 1 / T, kde T = 0,5 s.


Vystupny signal ma mat tvar:
Výstupný signál má mať tvar:


$$A_0 + A_1 \cdot \sin(\omega t + \varphi)$$
A₀ + A₁ · sin(ωt + φ)


kde:
kde:
A₀ = 128
A₀ = 128
A₁ = 100
A₁ = 100
 


__TOC__
__TOC__


== Analýza a opis riešenia ==


Cielom riesenia je vytvorit sinusovy signal bez pouzitia matematickych funkcii sin() alebo cos(). Tento problem sa riesi pomocou diskretneho oscilatora, ktory vychadza z diferencialnej rovnice harmonickeho kmitania.
== 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 = 0
 
Táto rovnica popisuje harmonické kmity (napr. pružina alebo LC obvod) 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 bez použitia knižničných funkcií.
 
 
=== 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í:
 
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_s
 
kde:
T = 0,5 s 
ω = 1 / T = 2 rad/s 
SAMPLE_RATE = 1000 Hz → T_s = 0,001 s 


### Laplaceova transformacia a prenosova funkcia
θ = 0,002 
Vychadzajme z nasej prenosovej funkcie H(s), co je v podstate len pomer vystupu k vstupu v Laplaceovej oblasti:


$$H(s) = \frac{Y(s)}{X(s)} = \frac{1}{T \cdot s + 1}$$


Ak chceme vediet, ako sa to sprava v case, potrebujeme to transformovat naspat. Vynasobime rovnicu krizom:
==== Aproximacia cos() ====


$$Y(s) \cdot (T \cdot s + 1) = X(s)$$
Keďže nie je dovolené použiť funkciu cos(), použije sa Taylorov rozvoj:
$$T \cdot s \cdot Y(s) + Y(s) = X(s)$$


Teraz pouzijeme inverznu Laplaceovu transformaciu. Hlavne pravidlo tu je, ze premenna s sa v casovej domene sprava ako derivacia: $\mathcal{L}^{-1}\{s \cdot Y(s)\} = \frac{dy}{dt}$. Po aplikovani inverznej transformacie dostaneme diferencialnu rovnicu:
cos(θ) ≈ 1 − θ²/2


$$T \cdot \frac{dy(t)}{dt} + y(t) = x(t)$$
Pre malé θ je táto aproximacia dostatočne presná.


Tymto sme si potvrdili, ze nasa prenosova funkcia v Laplaceovi a diferencialna rovnica v case su vlastne len dva pohlady na to iste.
Z toho:


### Diskretizácia
2cos(θ) ≈ 2 · (1 − θ²/2)
Mikrokontroler pracuje v diskretnom case, preto je potrebne nahradit derivacie rozdielmi medzi vzorkami (metoda konecnych diferencii).


Pouzie sa aproximacia druhej derivacie pre oscilator:


$$y'' \approx \frac{y[n] - 2y[n-1] + y[n-2]}{T_s^2}$$
==== Inicializácia oscilátora ====


### Diskrétny oscilátor
Pre správnu činnosť oscilátora sú potrebné počiatočné hodnoty:
Na generovanie stabilneho sinusu sa pouzije presny diskretny model zalozeny na trigonometrickej identite:


$$\sin(n\theta) = 2\cos(\theta)\cdot\sin((n-1)\theta) - \sin((n-2)\theta)$$
y1 = 1 
y2 = 1 − θ²/2


Po oznaceni:
Tieto hodnoty zabezpečia vznik sínusového priebehu.


$$y[n] = \sin(n\theta)$$


dostaneme rekurentny vztah:
==== Generovanie signálu ====


$$y[n] = 2\cos(\theta)\cdot y[n-1] - y[n-2]$$
Oscilátor generuje hodnoty v rozsahu ⟨−1, 1⟩.


Tento vztah generuje stabilny sinusovy signal bez zmeny amplitudy. Pre vypocet parametrov plati $\theta = \omega \cdot T_s$.
Požadovaný výstup:


### Aproximácia cos()
x = A0 + A1 · y
Kezde nie je dovolene pouzit funkciu cos(), pouzie sa aproximacia (Taylorov rozvoj):


$$\cos(\theta) \approx 1 - \frac{\theta^2}{2}$$
kde:
A0 = 128 
A1 = 100 


Tento vyraz sa pouzie ako koeficient oscilatora v programe.
Tým sa signál posunie do kladného rozsahu vhodného pre PWM.


### Systém 1 / (sT + 1) a koeficient alpha
Aby mikrokontroler vedel vyuzit system 1 / (sT + 1), musime ho previest do diskretneho casu pomocou Eulerovej metody. Derivaciu nahradime diferenciami:


$$\frac{dy}{dt} \approx \frac{y[n] - y[n-1]}{T_s}$$
==== Diskretizacia systému 1 / (sT + 1) ====


Ked to dosadime do diferencialnej rovnice:
Zo spojitej rovnice:


$$T \cdot \frac{y[n] - y[n-1]}{T_s} + y[n] = x$$
T · dy/dt + y = x


Po uprave dostaneme:
Použitím Eulerovej metódy:


$$y[n] = \left(\frac{T_s}{T + T_s}\right) \cdot x + \left(\frac{T}{T + T_s}\right) \cdot y[n-1]$$
dy/dt ≈ (y[n] y[n−1]) / T_s


Ak si oznacime α = Ts / (T + Ts), tak to vyzera ovela krajsie:
Po úprave:


$$y[n] = \alpha \cdot x + (1 - \alpha) \cdot y[n-1]$$
y[n] = (T_s / (T + T_s)) · x + (T / (T + T_s)) · y[n−1]


Co je to iste ako:
Po zavedení:


$$y[n] = y[n-1] + \alpha \cdot (x - y[n-1])$$
α = T_s / (T + T_s)
 
dostaneme praktický tvar:
 
y[n] = y[n−1] + α · (x y[n−1])


Pre dane hodnoty α ≈ 0,001996.


=== Algoritmus a program ===
=== Algoritmus a program ===


Algoritmus programu vyuziva Timer1 prerusenie, v ktorom sa vypocitava oscilator a nasledne filter. Vystup sa posiela do PWM modulu a data cez UART.
Celý výpočet prebieha 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
 


<tabs>
<tabs>
Riadok 188: Riadok 278:
</syntaxhighlight></tab>
</syntaxhighlight></tab>
</tabs>
</tabs>
Zdrojový kód: [[Médiá:projektOleksandrMykyta.zip|zdrojaky.zip]]


=== Overenie ===
=== Overenie ===


Funkcia systemu bola overena pomocou vypisu dat cez UART. Do serioveho portu sa posielaju dvojice hodnot: x, y_sys. Tieto hodnoty je mozne zobrazit napriklad pomocou Serial Plotteru, kde je viditelny vstupny sinusovy signal a vystup systemu.
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.


Zo signalov je mozne pozorovat zmenu amplitudy a fazovy posun, co predstavuje bod frekvencnej charakteristiky systemu. System sa chova presne tak, ako hovori teoria.


== Čo by som urobil inak ==
== Čo by som urobil inak ==


Pri rieseni by bolo mozne pouzit presnejsiu metodu diskretizacie systemu 1/(sT + 1), napriklad bilinearnu transformaciu, ktora by zlepsila presnost modelu.
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.


Taktiez by bolo mozne implementovat presnejsi vypocet cos(θ) bez aproximacie, napriklad pomocou lookup tabulky.
Ďalším zlepšením by mohlo byť automatické vyhodnotenie amplitúdy a fázového posunu priamo v mikrokontroleri namiesto spracovania na PC.


Dalsim zlepsenim by mohlo byt automaticke vyhodnotenie amplitudy a fazoveho posunu priamo v mikrokontroleri namiesto spracovania na PC.


[[Category:AVR]] [[Category:MIPS]]
[[Category:AVR]] [[Category:MIPS]]

Verzia z 12:10, 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 = 0

Táto rovnica popisuje harmonické kmity (napr. pružina alebo LC obvod) 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 bez použitia knižničných funkcií.


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í:

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_s

kde: 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 − θ²/2

Pre malé θ je táto aproximacia dostatočne presná.

Z 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

Tieto hodnoty zabezpečia vznik sínusového priebehu.


Generovanie signálu

Oscilátor generuje hodnoty v rozsahu ⟨−1, 1⟩.

Požadovaný výstup:

x = A0 + A1 · y

kde: A0 = 128 A1 = 100

Tým sa signál posunie do kladného rozsahu vhodného pre PWM.


Diskretizacia systému 1 / (sT + 1)

Zo spojitej rovnice:

T · dy/dt + y = x

Použitím Eulerovej metódy:

dy/dt ≈ (y[n] − y[n−1]) / T_s

Po úprave:

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] = y[n−1] + α · (x − y[n−1])


Algoritmus a program

Celý výpočet prebieha 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


#define F_CPU 16000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "uart.h"

#define SAMPLE_RATE 1000.0
#define T 0.5

#define A0 128
#define A1 100

float OSC_COEFF;

volatile float y = 0;
volatile float y1 = 0;
volatile float y2 = 0;

volatile float y_sys = 0;

float alpha;

FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);

ISR(TIMER1_COMPA_vect)
{
    y = OSC_COEFF * y1 - y2;

    y2 = y1;
    y1 = y;

    float x = A0 + A1 * y;

    y_sys = y_sys + alpha * (x - y_sys);

    OCR0A = (uint8_t)(y_sys);

    printf("%d,%d\n", (int)x, (int)y_sys);
}

void timer1_init()
{
    TCCR1B |= (1 << WGM12);

    OCR1A = 15999;

    TCCR1B |= (1 << CS10);

    TIMSK1 |= (1 << OCIE1A);
}

void pwm_init()
{
    DDRD |= (1 << PD6);

    TCCR0A |= (1 << COM0A1) | (1 << WGM01) | (1 << WGM00);
    TCCR0B |= (1 << CS01);
}

int main(void)
{
    uart_init();
    stdout = &mystdout;

    pwm_init();
    timer1_init();

    float Ts = 1.0 / SAMPLE_RATE;

    alpha = Ts / (T + Ts);

    float theta = (1.0 / T) * (1.0 / SAMPLE_RATE);

    y1 = 1.0;
    y2 = 1.0 - (theta * theta) / 2.0;

    OSC_COEFF = 2.0 * (1.0 - (theta * theta) / 2.0);

    sei();

    while (1)
    {
    }
}

Zdrojový kód: zdrojaky.zip


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.