Operácie

SOS maják: Rozdiel medzi revíziami

Zo stránky SensorWiki

StudentMIPS (diskusia | príspevky)
StudentMIPS (diskusia | príspevky)
Bez shrnutí editace
 
(9 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 4: Riadok 4:
== Zadanie ==
== Zadanie ==


Cieľom úlohy bolo vytvoriť program v jazyku C pre mikroprocesor ATmega328P, ktorý simuluje optický maják vysielajúci medzinárodný núdzový signál SOS (... --- ...). Program musí bežať v nekonečnej slučke a dodržiavať štandardizované časové intervaly pre Morseovu abecedu. Projekt je rozšírený o sériovú komunikáciu (UART), ktorá slúži na monitorovanie stavu zariadenia v reálnom čase na pripojenom počítači.
Cieľom úlohy bolo vytvoriť program v jazyku C pre mikroprocesor ATmega328P, ktorý simuluje optický maják vysielajúci medzinárodný núdzový signál SOS (... --- ...). Program musí bežať v nekonečnej slučke a dodržiavať štandardizované časové intervaly pre Morseovu abecedu.
 


[[Obrázok:ard.jpg|400px|thumb|center|Vývojová doska ACROB.]]


'''Literatúra:'''  
'''Literatúra:'''  
Riadok 21: Riadok 21:
Základom riešenia je dodržanie medzinárodného štandardu pre Morseovu abecedu. Aby bol signál SOS čitateľný pre kohokoľvek, musí program striktne dodržiavať pomery medzi svetelným impulzom a tichom.
Základom riešenia je dodržanie medzinárodného štandardu pre Morseovu abecedu. Aby bol signál SOS čitateľný pre kohokoľvek, musí program striktne dodržiavať pomery medzi svetelným impulzom a tichom.


Definoval som základnú časovú jednotku T = 200 ms. Všetky ostatné intervaly sú násobkom tejto jednotky:
Definoval som základnú časovú jednotku T = 100 ms. Všetky ostatné intervaly sú násobkom tejto jednotky:
 
• Bodka (dot): trvá presne 1T (200 ms).
 
• Čiarka (dash): trvá presne 3T (600 ms).
 
• Medzera medzi prvkami (v rámci jedného písmena): trvá 1T (200 ms).


Medzera medzi písmenami (S a O): trvá 3T (600 ms).
Bodka (dot): trvá presne 1T (100 ms).


Medzera medzi slovami (koniec sekvencie SOS): trvá 7T (1400 ms).
Čiarka (dash): trvá presne 3T (300 ms).


=== Technický prístup ===
Medzera medzi prvkami (v rámci jedného písmena): trvá 1T (100 ms).
Pre komunikáciu s PC som implementoval UART rozhranie s rýchlosťou 9600 baud.


Riadenie portov: Využívam register smeru dát DDRB a výstupný register PORTB. Nastavenie pinu PB5 na logickú jednotku aktivuje vstavanú LED diódu.
Medzera medzi písmenami (S a O): trvá 3T (300 ms).


Bitová manipulácia: Namiesto prepisovania celého registra používam bitové masky (|= a &= ~). To zaručuje, že ovplyvňujem iba pin LED diódy a ostatné piny procesora zostávajú nezmenené.
Medzera medzi slovami (koniec sekvencie SOS): trvá 7T (700 ms).
 
• Časovanie: Na generovanie presných páuz využívam funkciu _delay_ms() z knižnice <util/delay.h>. Frekvencia procesora je definovaná na 16 MHz (F_CPU), čo zabezpečuje, že reálny čas zodpovedá vypočítaným intervalom.


=== Hardvérová konfigurácia ===
=== Hardvérová konfigurácia ===
Mikrokontrolér: ATmega328P (16 MHz)
Mikrokontrolér: ATmega328P (16 MHz)


Výstup: Vstavaná LED dióda na porte PB5 (digitálny pin 13).
Svetelný výstup: Modrá LED dióda.


Komunikačné rozhranie: UART (Universal Asynchronous Receiver-Transmitter).
Prepojenie: Nepájivé kontaktné pole (breadboard), prepojovacie vodiče a USB kábel pre napájanie a sériový prenos.


Prepojenie: USB kábel.
Ochranný prvok: Rezistor s odporom 220 omov.


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


Riadiaci program je implementovaný v jazyku C pre architektúru AVR. Logika programu je postavená na nekonečnej slučke while, ktorá cyklicky vykonáva sekvenciu medzinárodného núdzového signálu SOS.
Technické detaily implementácie:


• Konfigurácia portov: Vo funkcii inicializacia() som nastavil pin PB5 ako výstupný pomocou registra smeru dát DDRB. Ostatné piny portu ostali nezmenené.


Algoritmus programu pracuje v nekonečnej slučke (while(1)), ktorá postupne volá sekvencie pre jednotlivé písmená "S" a "O". Hlavná logika spočíva v ovládaní LED diódy a odosielaní dát cez UART.
• Práca s bitmi: Pre manipuláciu s jednotlivými bitmi som použil makrá set_bit a clear_bit. Tento spôsob zabezpečuje bezpečnú zmenu stavu pinu bez ovplyvnenia zvyšku registra PORTB.
 
• Štruktúra cyklov: Jednotlivé znaky SOS sekvencie som rozdelil do cyklov for. Každý cyklus zodpovedá jednému písmenu, čo zjednodušuje úpravu počtu impulzov.
 
• Časovanie: Použil som knižnicu <util/delay.h> s konštantou T = 100ms. Výsledné pauzy medzi písmenami 3T a slovami 7T som vyskladal kombináciou základného oneskorenia v cykloch a doplnkových pauz za nimi.


<tabs>
<tabs>
<tab name="AVR C-code"><syntaxhighlight  lang="c++" style="background: LightYellow;">
<tab name="AVR C-code"><syntaxhighlight  lang="c++" style="background: LightYellow;">
#define F_CPU 16000000UL
#define F_CPU 16000000UL
#define BAUD 9600
#include <avr/io.h>
#include <avr/io.h>
#include <util/delay.h>
#include <util/delay.h>
#include "uart.h"


// Definícia LED na porte B, pin 5
#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT)) // Nastaví konkrétny bit na 1 (Log 1)
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) // Vynuluje konkrétny bit na 0 (Log 0)
 
// Zabudovana dioda pre Arduino Uno)
#define LED_PIN PB5
#define LED_PIN PB5


int main(void)
// Zvolil som základnu časovu jednotku Morseovej abecedy (1T = 100ms)
{
#define T 100
    // Inicializácia UART rozhrania
    uart_init();


     // Nastavenie pinu PB5 ako výstup
void inicializacia() {
     DDRB |= (1 << LED_PIN);
     // Nastavenie pinu LED_PIN ako výstupného
   
     set_bit(DDRB, LED_PIN);
    // Odoslanie úvodnej správy po štarte zariadenia
}
    uart_puts("SOS Majak startuje...\n");


     while (1)  
int main(void) {
    {
    inicializacia();
         // Písmeno S (3 krát krátky impulz)
 
     while (1) {
         // Písmeno S (. . .)  
         for (int i = 0; i < 3; i++) {
         for (int i = 0; i < 3; i++) {
             uart_putc('.');            // Výpis bodky do terminálu
             set_bit(PORTB, LED_PIN);  // LED zapne
            PORTB |= (1 << LED_PIN);  // LED zapne
             _delay_ms(T);             // Trvanie bodky (1T)
             _delay_ms(200);           // oneskorenie
             clear_bit(PORTB, LED_PIN); // LED vypne
             PORTB &= ~(1 << LED_PIN); // LED vypne
             _delay_ms(T);             // Medzera medzi prvkami (1T)
             _delay_ms(200);
         }
         }
       
        // Medzera medzi písmenami (3T celkovo, 1T už máme z cyklu, pridáme 2T)
        _delay_ms(2 * T);


        uart_putc(' '); // // Medzera v termináli
         // Písmeno O (_ _ _)
        _delay_ms(400); // Pauza medzi písmenami (píšem 400 ms, pretože 200 ms už máme z predchádzajúceho cyklu)
 
         // Písmeno O (3 krát dlhý impulz)  
         for (int i = 0; i < 3; i++) {
         for (int i = 0; i < 3; i++) {
             uart_putc('_');            // Výpis čiarky do terminálu
             set_bit(PORTB, LED_PIN);  // LED zapne
            PORTB |= (1 << LED_PIN);  // LED zapne
             _delay_ms(3 * T);         // Trvanie čiarky (3T)
             _delay_ms(600);           // 3 * T
             clear_bit(PORTB, LED_PIN); // LED vypne
             PORTB &= ~(1 << LED_PIN); // LED vypne
             _delay_ms(T);             // Medzera medzi prvkami (1T)
             _delay_ms(200);
         }
         }


         uart_putc(' '); // Medzera v termináli
         // Medzera medzi písmenami (3T celkovo, 1T už máme z cyklu, pridáme 2T)
         _delay_ms(400); // Pauza medzi písmenami
         _delay_ms(2 * T);


         // Písmeno S (3 krát krátky impulz)  
         // Písmeno S (. . .)  
         for (int i = 0; i < 3; i++) {
         for (int i = 0; i < 3; i++) {
             uart_putc('.');            // Výpis bodky do terminálu
             set_bit(PORTB, LED_PIN);  // LED zapne
            PORTB |= (1 << LED_PIN);  // LED zapne
             _delay_ms(T);             // Trvanie bodky (1T)
             _delay_ms(200);           // oneskorenie
             clear_bit(PORTB, LED_PIN); // LED vypne
             PORTB &= ~(1 << LED_PIN); // LED vypne
             _delay_ms(T);             // Medzera medzi prvkami (1T)
             _delay_ms(200);
         }
         }


          
         // Medzera medzi SOS sekvenciami (7T celkovo, 1T už máme, pridáme 6T)
        uart_puts(" [OK]\n"); // Ukončenie SOS sekvencie v termináli a odriadkovanie
        _delay_ms(6 * T);
        _delay_ms(1200);      // Pauza medzi SOS sekvenciami (píšem 1200 ms, pretože 200 ms už máme z predchádzajúceho cyklu)
 
     }
     }


     return 0;
     return 0;
}
}
</syntaxhighlight ></tab>
<tab name="uart.h"><syntaxhighlight  lang="c++" style="background: LightYellow;">
#ifndef UART_H_
#define UART_H_
void uart_init( void );   
void uart_putc( char c );
void uart_puts( const char *s );
char uart_getc( void );
#endif
</syntaxhighlight ></tab>
<tab name="uart.c"><syntaxhighlight  lang="c++" style="background: LightYellow;">
#include <avr/io.h>
#include <util/setbaud.h>
#include "uart.h"
void uart_init( void ) {
    UBRR0H = UBRRH_VALUE;
    UBRR0L = UBRRL_VALUE;
#if USE_2X
    UCSR0A |= _BV(U2X0);
#else
    UCSR0A &= ~(_BV(U2X0));
#endif
    UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
    UCSR0B = _BV(RXEN0) | _BV(TXEN0); 
}
void uart_putc(char c) {
  if (c == '\n')
    {
      uart_putc('\r');
    }
  loop_until_bit_is_set(UCSR0A, UDRE0);
  UDR0 = c;
}
void uart_puts(const char *s) {
    while (*s) {
        uart_putc(*s++);
    }
}
char uart_getc(void) {
    loop_until_bit_is_set(UCSR0A, RXC0);
    return UDR0;
}
unsigned int adc_read(char a_pin);
</syntaxhighlight ></tab>
</syntaxhighlight ></tab>
</tabs>
</tabs>


Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x ''zdrojaky.zip'':  
Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x ''zdrojaky.zip'':  


Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
Zdrojový kód: [[Médiá:MIPS_Projekt_Rostyslav_Fursov.zip | zdrojaky.zip]]


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


Funkčnosť systému som overil kombináciou vizuálnej kontroly a digitálnej diagnostiky cez sériovú linku.
Funkčnosť som overil vizuálnou kontrolou:
 
Vizuálny test: Po nahratí kódu LED dióda na breadboarde správne cykluje sekvenciu SOS (3x krátky, 3x dlhý, 3x krátky blik).
Metodika overovania:
Časovanie: Overil som, že pauzy medzi písmenami a dĺžka impulzov zodpovedajú nastaveným časom T a 3T.
Hardvér: Zapojenie s 220om rezistorom je stabilné a LED pracuje bez chýb.


Fyzická kontrola: Po nahratí programu do mikrokontroléra som sledoval vstavanú LED diódu na pine PB5. Potvrdil som, že sekvencia troch krátkych bliknutí, troch dlhých bliknutí a následnej pauzy presne zodpovedá medzinárodnému štandardu SOS.
Sériová diagnostika: Zariadenie som ponechal pripojené k PC cez USB kábel. Pomocou terminálového programu PuTTY nastaveného na rýchlosť 9600 baud som sledoval textový výstup.
Výsledok testu:
Pri každom zapnutí LED na krátky čas sa v termináli objavila bodka, pri dlhom bliknutí čiarka.
[[Súbor:GeminiAI-image1.jpg|400px|thumb|center|Aplikácia.]]


'''Video:'''
'''Video:'''
<center><youtube>D0UnqGm_miA</youtube></center>
<center><youtube>QpGNhgCLjSs</youtube></center>
 


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


Zamyslite sa spätne nad problémom, ktorý ste riešili a napíšte, čo sa vám nepodarilo a nabudúce by ste spravili inak.  
Použitie časovačov: Namiesto funkcie _delay_ms, ktorá blokuje procesor, by som využil hardvérové časovače a prerušenia. To by umožnilo mikrokontroléru vykonávať iné úlohy počas čakania na ďalší blik. Nastaviteľná rýchlosť: Pridal by som potenciometer na analógový vstup, ktorým by bolo možné plynule meniť dĺžku základnej časovej jednotky T (rýchlosť vysielania).





Aktuálna revízia z 16:21, 2. máj 2026

Záverečný projekt predmetu MIPS / LS2026 - Rostyslav Fursov


Zadanie

Cieľom úlohy bolo vytvoriť program v jazyku C pre mikroprocesor ATmega328P, ktorý simuluje optický maják vysielajúci medzinárodný núdzový signál SOS (... --- ...). Program musí bežať v nekonečnej slučke a dodržiavať štandardizované časové intervaly pre Morseovu abecedu.


Literatúra:


Analýza a opis riešenia

Teoretický rozbor (Pravidlá morzeovky)

Základom riešenia je dodržanie medzinárodného štandardu pre Morseovu abecedu. Aby bol signál SOS čitateľný pre kohokoľvek, musí program striktne dodržiavať pomery medzi svetelným impulzom a tichom.

Definoval som základnú časovú jednotku T = 100 ms. Všetky ostatné intervaly sú násobkom tejto jednotky:

• Bodka (dot): trvá presne 1T (100 ms).

• Čiarka (dash): trvá presne 3T (300 ms).

• Medzera medzi prvkami (v rámci jedného písmena): trvá 1T (100 ms).

• Medzera medzi písmenami (S a O): trvá 3T (300 ms).

• Medzera medzi slovami (koniec sekvencie SOS): trvá 7T (700 ms).

Hardvérová konfigurácia

Mikrokontrolér: ATmega328P (16 MHz)

• Svetelný výstup: Modrá LED dióda.

• Prepojenie: Nepájivé kontaktné pole (breadboard), prepojovacie vodiče a USB kábel pre napájanie a sériový prenos.

• Ochranný prvok: Rezistor s odporom 220 omov.

Algoritmus a program

Riadiaci program je implementovaný v jazyku C pre architektúru AVR. Logika programu je postavená na nekonečnej slučke while, ktorá cyklicky vykonáva sekvenciu medzinárodného núdzového signálu SOS. Technické detaily implementácie:

• Konfigurácia portov: Vo funkcii inicializacia() som nastavil pin PB5 ako výstupný pomocou registra smeru dát DDRB. Ostatné piny portu ostali nezmenené.

• Práca s bitmi: Pre manipuláciu s jednotlivými bitmi som použil makrá set_bit a clear_bit. Tento spôsob zabezpečuje bezpečnú zmenu stavu pinu bez ovplyvnenia zvyšku registra PORTB.

• Štruktúra cyklov: Jednotlivé znaky SOS sekvencie som rozdelil do cyklov for. Každý cyklus zodpovedá jednému písmenu, čo zjednodušuje úpravu počtu impulzov.

• Časovanie: Použil som knižnicu <util/delay.h> s konštantou T = 100ms. Výsledné pauzy medzi písmenami 3T a slovami 7T som vyskladal kombináciou základného oneskorenia v cykloch a doplnkových pauz za nimi.

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT)) // Nastaví konkrétny bit na 1 (Log 1)
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) // Vynuluje konkrétny bit na 0 (Log 0)

// Zabudovana dioda pre Arduino Uno)
#define LED_PIN PB5

// Zvolil som základnu časovu jednotku Morseovej abecedy (1T = 100ms)
#define T 100

void inicializacia() {
    // Nastavenie pinu LED_PIN ako výstupného
    set_bit(DDRB, LED_PIN);
}

int main(void) {
    inicializacia();

    while (1) {
        // Písmeno S (. . .) 
        for (int i = 0; i < 3; i++) {
            set_bit(PORTB, LED_PIN);   // LED zapne
            _delay_ms(T);              // Trvanie bodky (1T)
            clear_bit(PORTB, LED_PIN); // LED vypne
            _delay_ms(T);              // Medzera medzi prvkami (1T)
        }
        
        // Medzera medzi písmenami (3T celkovo, 1T už máme z cyklu, pridáme 2T)
        _delay_ms(2 * T); 

        // Písmeno O (_ _ _)
        for (int i = 0; i < 3; i++) {
            set_bit(PORTB, LED_PIN);   // LED zapne
            _delay_ms(3 * T);          // Trvanie čiarky (3T)
            clear_bit(PORTB, LED_PIN); // LED vypne
            _delay_ms(T);              // Medzera medzi prvkami (1T)
        }

        // Medzera medzi písmenami (3T celkovo, 1T už máme z cyklu, pridáme 2T)
        _delay_ms(2 * T);

        // Písmeno S (. . .) 
        for (int i = 0; i < 3; i++) {
            set_bit(PORTB, LED_PIN);   // LED zapne
            _delay_ms(T);              // Trvanie bodky (1T)
            clear_bit(PORTB, LED_PIN); // LED vypne
            _delay_ms(T);              // Medzera medzi prvkami (1T)
        }

        // Medzera medzi SOS sekvenciami (7T celkovo, 1T už máme, pridáme 6T)
        _delay_ms(6 * T); 
    }

    return 0;
}

Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x zdrojaky.zip:

Zdrojový kód: zdrojaky.zip

Overenie

Funkčnosť som overil vizuálnou kontrolou: Vizuálny test: Po nahratí kódu LED dióda na breadboarde správne cykluje sekvenciu SOS (3x krátky, 3x dlhý, 3x krátky blik). Časovanie: Overil som, že pauzy medzi písmenami a dĺžka impulzov zodpovedajú nastaveným časom T a 3T. Hardvér: Zapojenie s 220om rezistorom je stabilné a LED pracuje bez chýb.


Video:

Čo by som urobil inak

Použitie časovačov: Namiesto funkcie _delay_ms, ktorá blokuje procesor, by som využil hardvérové časovače a prerušenia. To by umožnilo mikrokontroléru vykonávať iné úlohy počas čakania na ďalší blik. Nastaviteľná rýchlosť: Pridal by som potenciometer na analógový vstup, ktorým by bolo možné plynule meniť dĺžku základnej časovej jednotky T (rýchlosť vysielania).


Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.