Operácie

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

Zo stránky SensorWiki

StudentMIPS (diskusia | príspevky)
StudentMIPS (diskusia | príspevky)
Bez shrnutí editace
Riadok 10: Riadok 10:
</code>
</code>


Zároveň bolo potrebné zmerať jeden bod frekvenčnej charakteristiky systému:
Zároveň bolo potrebné zmerať jeden bod frekvenčnej charakteristiky systemu:


<code>
<code>
Riadok 21: Riadok 21:
<code>T = 0.5 s</code>.
<code>T = 0.5 s</code>.


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


<code>
<code>
Riadok 35: Riadok 35:
== Analýza  a opis riešenia ==
== 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.
Cieľom riešenia je vytvoriť sínusový signal bez použitia matematických funkcií sin() alebo cos(). Tento problem sa rieši pomocou diskrétneho oscilátora, ktorý vychádza z diferenciálnej rovnice harmonického kmitania.


Základom je rovnica:
Základom je rovnica:
Riadok 49: Riadok 49:
==== Laplaceova transformacia ====
==== Laplaceova transformacia ====


Vychadzajme z prenosovej funkcie systému:
Vychadzajme z prenosovej funkcie systemu:


<code>
<code>
Riadok 58: Riadok 58:


<code>
<code>
Y(s) · (T · s + 1) = X(s)
Y(s) · (T · s + 1)
T · s · Y(s) + Y(s) = X(s)
T · s · Y(s) + Y(s) = X(s)
</code>
</code>
Riadok 68: Riadok 68:
</code>
</code>


Týmto získame diferenciálnu rovnicu systému v časovej oblasti.
Týmto získame diferenciálnu rovnicu systemu v časovej oblasti.


==== Diskretizácia ====
==== Diskretizácia ====
Riadok 124: Riadok 124:
</code>
</code>


Tento vzťah generuje stabilný sínusový signál bez zmeny amplitúdy.
Tento vzťah generuje stabilný sínusový signal bez zmeny amplitúdy.


==== Výpočet parametrov ====
==== Výpočet parametrov ====
Riadok 135: Riadok 135:


kde:
kde:
<code>T = 0.5 s</code>,
<code>T = 0.5 s</code>
<code>ω = 1 / T = 2 rad/s</code>,
<code>ω = 1 / T = 2 rad/s</code>
<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>


Riadok 177: Riadok 177:


kde:
kde:
<code>A0 = 128</code>,
 
<code>A0 = 128</code>
<code>A1 = 100</code>
<code>A1 = 100</code>


==== Diskretizacia systému <code>1 / (sT + 1)</code> ====
==== Diskretizacia systemu <code>1 / (sT + 1)</code> ====


Zo spojitej rovnice:
Zo spojitej rovnice:
Riadok 215: Riadok 216:
=== Algoritmus a program ===
=== Algoritmus a program ===


Algoritmus programu využíva diskrétny oscilátor a numerickú aproximáciu systému <code>1 / (sT + 1)</code>. Základné výpočty prebiehajú v prerušení Timer1 s frekvenciou 1 kHz:
Algoritmus programu využíva diskrétny oscilátor a numerickú aproximáciu systemu <code>1 / (sT + 1)</code>. Zakladne výpočty prebiehajú v prerušení Timer1 s frekvenciou 1 kHz:


* výpočet oscilátora
* výpočet oscilátora
* generovanie vstupu x
* generovanie vstupu x
* výpočet výstupu systému
* výpočet výstupu systemu
* výstup cez PWM
* výstup cez PWM
* odosielanie dát cez UART
* odosielanie dát cez UART
Riadok 388: Riadok 389:
</tabs>
</tabs>


Zdrojový kód: [[Médiá:MykytaOleksandr_sources.zip|MykytaOleksandr_sources.zip]]
Zdrojovy kod: [[Média:MykytaOleksandr_sources.zip|MykytaOleksandr_sources.zip]]


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


Funkcia systému bola overená pomocou výpisu dát cez UART. Do sériového portu sa posielajú dvojice hodnôt:
Funkcia systemu bola overená pomocou výpisu dát cez UART. Do sériového portu sa posielajú dvojice hodnot:


<code>x, y_sys</code>
<code>x, y_sys</code>


Tieto hodnoty je možné zobraziť napríklad pomocou '''SerialPlot''', kde je viditeľný vstupný sínusový signál a výstup systému.
Tieto hodnoty je možné zobraziť napríklad pomocou '''SerialPlot''', kde je viditeľný vstupný sínusový signal a výstup systemu.




Riadok 410: Riadok 411:
Pri overovaní bolo sledované, či:
Pri overovaní bolo sledované, či:


amplitúda výstupu zodpovedá očakávaniu
amplituda výstupu zodpovedá očakávaniu
systém vykazuje fázový posun
system vykazuje fázový posun
priebeh signálu je stabilný bez driftu
priebeh signalu je stabilný bez driftu
výstup reaguje správne na vstupný sínus
výstup reaguje správne na vstupný sínus


Zo signálov je možné pozorovať zmenu amplitúdy a fázový posun, čo predstavuje bod frekvenčnej charakteristiky systému.
Zo signálov je možné pozorovať zmenu amplitudy a fázový posun, čo predstavuje bod frekvenčnej charakteristiky systemu.




Riadok 422: Riadok 423:
<center><youtube>MkgRE0QNgtk</youtube></center>
<center><youtube>MkgRE0QNgtk</youtube></center>


Video demonštruje reálne správanie systému. Je na ňom viditeľné generovanie sínusového signálu, jeho spracovanie systémom a výstupné dáta zobrazené v '''SerialPlot'''. Video slúži na overenie, že implementácia funguje podľa očakávania.
Video demonštruje reálne správanie systemu. Je na ňom viditeľné generovanie sínusového signalu, jeho spracovanie systemom a výstupné dáta zobrazené v '''SerialPlot'''. Video slúži na overenie, že implementacia funguje podľa očakávania.


== Č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.
Pri riešení by bolo možné použiť presnejšiu metódu diskretizacie systemu 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.
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.
Ďalším zlepšením by mohlo byť automatické vyhodnotenie amplitudy a fázového posunu priamo v mikrokontroleri namiesto spracovania na PC.


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

Verzia z 16:07, 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 systemu:

H(s) = 1 / (s · T + 1)

pre frekvenciu: ω = 1 / T, kde T = 0.5 s.

Výstupný signal ma mat tvar:

A₀ + A₁ · sin(ωt + φ)

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

Analýza a opis riešenia

Cieľom riešenia je vytvoriť sínusový signal bez použitia matematických funkcií sin() alebo cos(). Tento problem 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 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 systemu:

H(s) = Y(s) / X(s) = 1 / (T · s + 1)

Po úprave:

Y(s) · (T · s + 1) 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 systemu 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ý signal 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

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

Generovanie signálu

Oscilátor generuje hodnoty v rozsahu:

[-1, 1]

Požadovaný výstup:

x = A0 + A1 · y

kde:

A0 = 128 A1 = 100

Diskretizacia systemu 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] = 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 systemu 1 / (sT + 1). Zakladne 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 systemu
  • 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)
{
}

}
#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))

#ifndef UART_H_
#define UART_H_

#include <stdio.h>

#define BAUD_PRESCALE  (((F_CPU / (BAUDRATE * 16UL))) - 1)

void uart_init( void );
int uart_putc( char c, FILE *stream );
void uart_puts( const char *s );
char uart_getc( void );
void delay(int delay); 

#endif /* UART_H_ */
#include <avr/io.h>
#include <util/delay.h>
#include "uart.h"

void uart_init( void ) 
{	
   #include <util/setbaud.h>
   
   UBRR0H = UBRRH_VALUE;
   UBRR0L = UBRRL_VALUE;
   #if USE_2X
    UCSR0A |= (1 << U2X0);
   #else
    UCSR0A &= ~(1 << U2X0);
   #endif


    UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
    UCSR0B = _BV(RXEN0) | _BV(TXEN0);
}

int uart_putc(char c, FILE *stream)
{
    if (c == '\n')
    {
        loop_until_bit_is_set(UCSR0A, UDRE0);
        UDR0 = '\r';
    }

    loop_until_bit_is_set(UCSR0A, UDRE0);
    UDR0 = c;

    return 0;
}


void uart_puts(const char *s)
{
}

char uart_getc(void) 
{
    loop_until_bit_is_set(UCSR0A, RXC0);
    return UDR0;
}

void delay(int delay)
{
  for (int i=1; i<=delay; i++)
  _delay_ms(1);
}

Zdrojovy kod: MykytaOleksandr_sources.zip

Overenie

Funkcia systemu bola overená pomocou výpisu dát cez UART. Do sériového portu sa posielajú dvojice hodnot:

x, y_sys

Tieto hodnoty je možné zobraziť napríklad pomocou SerialPlot, kde je viditeľný vstupný sínusový signal a výstup systemu.


Namerené priebehy vstupu a výstupu zo Serial Plot

Pri overovaní bolo sledované, či:

amplituda výstupu zodpovedá očakávaniu system vykazuje fázový posun priebeh signalu je stabilný bez driftu výstup reaguje správne na vstupný sínus

Zo signálov je možné pozorovať zmenu amplitudy a fázový posun, čo predstavuje bod frekvenčnej charakteristiky systemu.


Video:

Video demonštruje reálne správanie systemu. Je na ňom viditeľné generovanie sínusového signalu, jeho spracovanie systemom a výstupné dáta zobrazené v SerialPlot. Video slúži na overenie, že implementacia funguje podľa očakávania.

Čo by som urobil inak

Pri riešení by bolo možné použiť presnejšiu metódu diskretizacie systemu 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 amplitudy a fázového posunu priamo v mikrokontroleri namiesto spracovania na PC.