SOS maják: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
Bez shrnutí editace |
||
| (10 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. | 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. | ||
[[Obrázok:ard.jpg|400px|thumb|center|Vývojová doska ACROB.]] | [[Obrázok:ard.jpg|400px|thumb|center|Vývojová doska ACROB.]] | ||
| Riadok 16: | Riadok 16: | ||
== Analýza a opis riešenia == | == Analýza a opis riešenia == | ||
=== Teoretický rozbor (Pravidlá morzeovky) === | === Teoretický rozbor (Pravidlá morzeovky) === | ||
| Riadok 43: | Riadok 34: | ||
=== Technický prístup === | === Technický prístup === | ||
• Pre komunikáciu s PC som implementovali 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. | • 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. | ||
| Riadok 49: | Riadok 41: | ||
• Č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. | • Č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 === | |||
Mikrokontrolér: ATmega328P (16 MHz) | |||
• Výstup: Vstavaná LED dióda na porte PB5 (digitálny pin 13). | |||
• Komunikačné rozhranie: UART (Universal Asynchronous Receiver-Transmitter). | |||
• Prepojenie: USB kábel. | |||
=== Algoritmus a program === | === Algoritmus a program === | ||
| Riadok 54: | Riadok 55: | ||
Algoritmus programu | 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. | ||
<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 | // Definícia LED na porte B, pin 5 | ||
| Riadok 70: | Riadok 71: | ||
int main(void) | int main(void) | ||
{ | { | ||
// Inicializácia UART rozhrania | |||
uart_init(); | |||
// Nastavenie pinu PB5 ako výstup | // Nastavenie pinu PB5 ako výstup | ||
DDRB |= (1 << LED_PIN); | DDRB |= (1 << LED_PIN); | ||
// Odoslanie úvodnej správy po štarte zariadenia | |||
uart_puts("SOS Majak startuje...\n"); | |||
while (1) | while (1) | ||
| Riadok 77: | Riadok 84: | ||
// Písmeno S (3 krát krátky impulz) | // Písmeno S (3 krát krátky impulz) | ||
for (int i = 0; i < 3; i++) { | for (int i = 0; i < 3; i++) { | ||
uart_putc('.'); // Výpis bodky do terminálu | |||
PORTB |= (1 << LED_PIN); // LED zapne | PORTB |= (1 << LED_PIN); // LED zapne | ||
_delay_ms(200); // oneskorenie | _delay_ms(200); // oneskorenie | ||
| Riadok 83: | Riadok 91: | ||
} | } | ||
uart_putc(' '); // // Medzera v termináli | |||
_delay_ms(400); // Pauza medzi písmenami (píšem 400 ms, pretože 200 ms už máme z predchádzajúceho cyklu) | _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) | // 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 | |||
PORTB |= (1 << LED_PIN); // LED zapne | PORTB |= (1 << LED_PIN); // LED zapne | ||
_delay_ms(600); // 3 * T | _delay_ms(600); // 3 * T | ||
| Riadok 93: | Riadok 103: | ||
} | } | ||
uart_putc(' '); // Medzera v termináli | |||
_delay_ms(400); // Pauza medzi písmenami | _delay_ms(400); // Pauza medzi písmenami | ||
// Písmeno S (3 krát krátky impulz) | // Písmeno S (3 krát krátky impulz) | ||
for (int i = 0; i < 3; i++) { | for (int i = 0; i < 3; i++) { | ||
uart_putc('.'); // Výpis bodky do terminálu | |||
PORTB |= (1 << LED_PIN); // LED zapne | PORTB |= (1 << LED_PIN); // LED zapne | ||
_delay_ms(200); // oneskorenie | _delay_ms(200); // oneskorenie | ||
| Riadok 103: | Riadok 115: | ||
} | } | ||
_delay_ms(1200); | |||
uart_puts(" [OK]\n"); // Ukončenie SOS sekvencie v termináli a odriadkovanie | |||
_delay_ms(1200); // Pauza medzi SOS sekvenciami (píšem 1200 ms, pretože 200 ms už máme z predchádzajúceho cyklu) | |||
} | } | ||
| Riadok 111: | Riadok 125: | ||
</syntaxhighlight ></tab> | </syntaxhighlight ></tab> | ||
<tab name=" | <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 <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); | 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'': | ||
| Riadok 126: | Riadok 187: | ||
=== Overenie === | === Overenie === | ||
Funkčnosť systému som overil kombináciou vizuálnej kontroly a digitálnej diagnostiky cez sériovú linku. | |||
Metodika overovania: | |||
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.]] | [[Súbor:GeminiAI-image1.jpg|400px|thumb|center|Aplikácia.]] | ||
Aktuálna revízia z 13:12, 29. apríl 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. 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.

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 = 200 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).
• Medzera medzi slovami (koniec sekvencie SOS): trvá 7T (1400 ms).
Technický prístup
• Pre komunikáciu s PC som implementovali 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.
• 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é.
• Č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
Mikrokontrolér: ATmega328P (16 MHz)
• Výstup: Vstavaná LED dióda na porte PB5 (digitálny pin 13).
• Komunikačné rozhranie: UART (Universal Asynchronous Receiver-Transmitter).
• Prepojenie: USB kábel.
Algoritmus a program
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.
#define F_CPU 16000000UL
#define BAUD 9600
#include <avr/io.h>
#include <util/delay.h>
#include "uart.h"
// Definícia LED na porte B, pin 5
#define LED_PIN PB5
int main(void)
{
// Inicializácia UART rozhrania
uart_init();
// Nastavenie pinu PB5 ako výstup
DDRB |= (1 << LED_PIN);
// Odoslanie úvodnej správy po štarte zariadenia
uart_puts("SOS Majak startuje...\n");
while (1)
{
// Písmeno S (3 krát krátky impulz)
for (int i = 0; i < 3; i++) {
uart_putc('.'); // Výpis bodky do terminálu
PORTB |= (1 << LED_PIN); // LED zapne
_delay_ms(200); // oneskorenie
PORTB &= ~(1 << LED_PIN); // LED vypne
_delay_ms(200);
}
uart_putc(' '); // // Medzera v termináli
_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++) {
uart_putc('_'); // Výpis čiarky do terminálu
PORTB |= (1 << LED_PIN); // LED zapne
_delay_ms(600); // 3 * T
PORTB &= ~(1 << LED_PIN); // LED vypne
_delay_ms(200);
}
uart_putc(' '); // Medzera v termináli
_delay_ms(400); // Pauza medzi písmenami
// Písmeno S (3 krát krátky impulz)
for (int i = 0; i < 3; i++) {
uart_putc('.'); // Výpis bodky do terminálu
PORTB |= (1 << LED_PIN); // LED zapne
_delay_ms(200); // oneskorenie
PORTB &= ~(1 << LED_PIN); // LED vypne
_delay_ms(200);
}
uart_puts(" [OK]\n"); // Ukončenie SOS sekvencie v termináli a odriadkovanie
_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;
}
#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
#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);
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ť systému som overil kombináciou vizuálnej kontroly a digitálnej diagnostiky cez sériovú linku.
Metodika overovania:
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.

Video:
Č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.
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.