Operácie

Diaľkové ovládanie spotrebiča pomocou infračerveného signálu: Rozdiel medzi revíziami

Zo stránky SensorWiki

StudentMIPS (diskusia | príspevky)
StudentMIPS (diskusia | príspevky)
 
(9 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 19: Riadok 19:
== Analýza  a opis riešenia ==
== Analýza  a opis riešenia ==


Pre komunikáciu pomocou infračerveného signálu som použil prijímač AX-1838HS a IR ovládač Car MP3, ktoré sú bežne dodávané v sete s Arduino UNO.  
Pre komunikáciu pomocou infračerveného signálu som použil prijímač AX-1838HS a IR ovládač Car MP3, ktoré sú bežne dodávané v sete s Arduino UNO. Ďalšími použitým súčiastkami je LED dióda na reprezentáciu funkčnosti a 220 ohm rezistor.
[[Obrázok:1838.jpg|400px|thumb|center|IR prijímač AX-1838HS]]
[[Obrázok:1838.jpg|400px|thumb|center|IR prijímač AX-1838HS]]
[[Obrázok:mp3.jpg|400px|thumb|center|IR ovládač Car MP3]]
[[Obrázok:mp3.jpg|400px|thumb|center|IR ovládač Car MP3]]
Riadok 29: Riadok 29:
*PIN pre LED diódu je nastavený ako výstup
*PIN pre LED diódu je nastavený ako výstup


[[Súbor:GeminiAI-image3.jpg|400px|thumb|center|Celkový pohľad na zariadenie.]]
[[Obrázok:1.png|400px|thumb|center|Schéma zapojenia.]]


=== Teoretický úvod do IR signálu ===
=== Teoretický úvod do IR signálu ===
Riadok 43: Riadok 43:
*výsledkom je 32-bitové číslo, ktoré reprezentuje príkaz z diaľkového ovládača.
*výsledkom je 32-bitové číslo, ktoré reprezentuje príkaz z diaľkového ovládača.


[[Súbor:GeminiAI-image2.jpg|400px|thumb|center|Schéma zapojenia.]]
 




Riadok 53: Riadok 53:
<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
#include <avr/io.h>
#include <avr/io.h>
#include <util/delay.h>
#define IR_PIN PIND
#define IR_BIT PD3
#define LED_PORT PORTB
#define LED_DDR DDRB
#define LED_BIT PB0
//časové limity v mikrosekundách pre NEC signál
#define LEAD_PULSE_MIN 8500
#define LEAD_PULSE_MAX 9500
#define LEAD_SPACE_MIN 4000
#define LEAD_SPACE_MAX 5000
#define BIT_PULSE_MIN 400
#define BIT_PULSE_MAX 700
#define BIT_0_SPACE_MIN 400
#define BIT_0_SPACE_MAX 700
#define BIT_1_SPACE_MIN 1500
#define BIT_1_SPACE_MAX 2000
#define BUTTON_1_CODE 0xFFA25D  // tlačidlo 1
#define BUTTON_2_CODE 0xFF629D  // tlačidlo 2
uint32_t ir_receive(void) {
    uint32_t data = 0;
   
    // čakanie začiatku signálu: LOW cca 9ms (LEAD PULSE)
    while (IR_PIN & (1 << IR_BIT));
   
    uint16_t count = 0;
    while (!(IR_PIN & (1 << IR_BIT))) {
        _delay_us(10);
        count += 10;
        if (count > 12000) return 0;
    }
    if (count < LEAD_PULSE_MIN || count > LEAD_PULSE_MAX) return 0;


int main(void)
    count = 0;
{
    while (IR_PIN & (1 << IR_BIT)) {
  unsigned int measuredValue;
        _delay_us(10);
        count += 10;
        if (count > 7000) return 0;
    }
    if (count < LEAD_SPACE_MIN || count > LEAD_SPACE_MAX) return 0;


  while (1)
    for (uint8_t i = 0; i < 32; i++) {
  {
        count = 0;
    /*  relax  */ 
        while (!(IR_PIN & (1 << IR_BIT))) {
  }
            _delay_us(10);
            count += 10;
            if (count > 1000) return 0;
        }
        if (count < BIT_PULSE_MIN || count > BIT_PULSE_MAX) return 0;


  return(0);
        count = 0;
        while (IR_PIN & (1 << IR_BIT)) {
            _delay_us(10);
            count += 10;
            if (count > 3000) return 0;
        }
 
        if (count > BIT_1_SPACE_MIN && count < BIT_1_SPACE_MAX) {
            data = (data << 1) | 1;
        } else if (count > BIT_0_SPACE_MIN && count < BIT_0_SPACE_MAX) {
            data = (data << 1) | 0;
        } else {
            return 0;
        }
    }
 
    return data;
}
}
void io_init(void) {
    LED_DDR |= (1 << LED_BIT);
    DDRD &= ~(1 << IR_BIT);
    PORTD |= (1 << IR_BIT);
}
int main(void) {
    io_init();
    uint8_t led_on = 0;
    while (1) {
        uint32_t code = ir_receive();
        if (code == BUTTON_1_CODE) {
            led_on = 1;
        } else if (code == BUTTON_2_CODE) {
            led_on = 0;
        }
        if (led_on) {
            LED_PORT |= (1 << LED_BIT);
        } else {
            LED_PORT &= ~(1 << LED_BIT);
        }
        _delay_ms(100);
    }
}


</syntaxhighlight ></tab>
</syntaxhighlight ></tab>
Riadok 77: Riadok 170:
</tabs>
</tabs>


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á:ProjektMarekŠoltés2025.zip|zdrojaky.zip]]


=== Overenie ===
=== Overenie ===
Riadok 85: Riadok 177:
Na ovládanie LED diódy stačia dve tlačítka, pri prijatí kódu tlačidla  „1“ sa nastaví stav LED diódy na zapnutý, pri prijatí kódu tlačidla „2“ sa stav LED diódy nastaví na vypnutý. Iné kódy sú ignorované.
Na ovládanie LED diódy stačia dve tlačítka, pri prijatí kódu tlačidla  „1“ sa nastaví stav LED diódy na zapnutý, pri prijatí kódu tlačidla „2“ sa stav LED diódy nastaví na vypnutý. Iné kódy sú ignorované.


Na konci uvádzame fotku hotového zariadenia.


[[Súbor:GeminiAI-image1.jpg|400px|thumb|center|Aplikácia.]]
 
[[Obrázok:zariadeniems.jpg|400px|thumb|center|Zhotovené zariadenie]]
'''Video:'''
'''Video:'''
<center><youtube>D0UnqGm_miA</youtube></center>
<center><youtube>D0UnqGm_miA</youtube></center>

Aktuálna revízia z 09:30, 17. máj 2025

Záverečný projekt predmetu MIPS / LS2025 - Meno Priezvisko


Zadanie

Cieľom môjho zadania bolo vytvoriť program, ktorý umožní ovládať pomocou infračerveného diaľkového ovládača spotrebič, svietidlo, v mojom príklade som na demonštráciu použil LED diódu. Podmienkou bolo, že nie je povolené použiť žiadne externé knižnice na spracovanie IR signálu, ako je napríklad IRremote, ktorá by úlohu výrazne zjednodušila.

Vývojová doska Arduino UNO.

Literatúra:



Analýza a opis riešenia

Pre komunikáciu pomocou infračerveného signálu som použil prijímač AX-1838HS a IR ovládač Car MP3, ktoré sú bežne dodávané v sete s Arduino UNO. Ďalšími použitým súčiastkami je LED dióda na reprezentáciu funkčnosti a 220 ohm rezistor.

IR prijímač AX-1838HS
IR ovládač Car MP3

Zapojenie a nastavenie

  • IR prijímač je pripojený na vstup Arduina (PIN PD3)
  • LED dióda je pripojená na výstup (PIN PB0)
  • PIN pre IR prijímač je nastavený ako vstup s interným pull-up rezistorom, čo zabezpečuje stabilný logický stav, keď IR prijímač neodovzdáva signál
  • PIN pre LED diódu je nastavený ako výstup
Schéma zapojenia.

Teoretický úvod do IR signálu

Infračervený prijímač neprodukuje priamo dekódované kódy, ale vysiela digitálny signál, ktorý predstavuje modulovaný IR svetelný impulz. V tomto prípade ide o NEC protokol, ktorý prenáša 32-bitové správy s pevnými časovými intervalmi pre logické 0 a 1.

NEC IR protokol

Manuálna implementácia dekódovania NEC protokolu

Keďže nebolo možné použiť hotovú knižnicu, bolo potrebné napísať funkciu, ktorá:

  • čaká na začiatok signálu (dlhý LOW pulz – tzv. lead pulse)
  • meria časové úseky LOW a HIGH úrovní na vstupe, aby rozpoznala jednotlivé bity (0 alebo 1)
  • spočíta postupne 32 bitov dát
  • výsledkom je 32-bitové číslo, ktoré reprezentuje príkaz z diaľkového ovládača.



Algoritmus a program

Po zapnutí sa vykoná inicializácia pinov – LED pin sa nastaví ako výstup a IR pin ako vstup s aktivovaným pull-up odporom. Hlavná slučka programu neustále čaká na infračervený signál pomocou funkcie ir_receive. Táto funkcia najprv zachytí úvodný signál (LEAD PULSE a SPACE) a potom načíta 32 bitov kódu vyslaného z diaľkového ovládača. Každý bit je určený dĺžkou trvania signálu – krátka doba znamená logickú nulu, dlhšia logickú jednotku. Po úspešnom prijatí kódu sa porovná s preddefinovanými hodnotami pre tlačidlá 1 a 2. Ak bol prijatý kód pre tlačidlo 1, LED dióda sa zapne, ak pre tlačidlo 2, LED sa vypne.


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

#define IR_PIN PIND
#define IR_BIT PD3
#define LED_PORT PORTB
#define LED_DDR DDRB
#define LED_BIT PB0

//časové limity v mikrosekundách pre NEC signál 
#define LEAD_PULSE_MIN 8500
#define LEAD_PULSE_MAX 9500
#define LEAD_SPACE_MIN 4000
#define LEAD_SPACE_MAX 5000
#define BIT_PULSE_MIN 400
#define BIT_PULSE_MAX 700
#define BIT_0_SPACE_MIN 400
#define BIT_0_SPACE_MAX 700
#define BIT_1_SPACE_MIN 1500
#define BIT_1_SPACE_MAX 2000

#define BUTTON_1_CODE 0xFFA25D  // tlačidlo 1
#define BUTTON_2_CODE 0xFF629D  // tlačidlo 2

uint32_t ir_receive(void) {
    uint32_t data = 0;
    
    // čakanie začiatku signálu: LOW cca 9ms (LEAD PULSE)
    while (IR_PIN & (1 << IR_BIT));
    
    uint16_t count = 0;
    while (!(IR_PIN & (1 << IR_BIT))) {
        _delay_us(10);
        count += 10;
        if (count > 12000) return 0;
    }
    if (count < LEAD_PULSE_MIN || count > LEAD_PULSE_MAX) return 0;

    count = 0;
    while (IR_PIN & (1 << IR_BIT)) {
        _delay_us(10);
        count += 10;
        if (count > 7000) return 0;
    }
    if (count < LEAD_SPACE_MIN || count > LEAD_SPACE_MAX) return 0;

    for (uint8_t i = 0; i < 32; i++) {
        count = 0;
        while (!(IR_PIN & (1 << IR_BIT))) {
            _delay_us(10);
            count += 10;
            if (count > 1000) return 0;
        }
        if (count < BIT_PULSE_MIN || count > BIT_PULSE_MAX) return 0;

        count = 0;
        while (IR_PIN & (1 << IR_BIT)) {
            _delay_us(10);
            count += 10;
            if (count > 3000) return 0;
        }

        if (count > BIT_1_SPACE_MIN && count < BIT_1_SPACE_MAX) {
            data = (data << 1) | 1;
        } else if (count > BIT_0_SPACE_MIN && count < BIT_0_SPACE_MAX) {
            data = (data << 1) | 0;
        } else {
            return 0;
        }
    }

    return data;
}

void io_init(void) {
    LED_DDR |= (1 << LED_BIT);
    DDRD &= ~(1 << IR_BIT);
    PORTD |= (1 << IR_BIT);
}

int main(void) {
    io_init();

    uint8_t led_on = 0;

    while (1) {
        uint32_t code = ir_receive();

        if (code == BUTTON_1_CODE) {
            led_on = 1;
        } else if (code == BUTTON_2_CODE) {
            led_on = 0;
        }

        if (led_on) {
            LED_PORT |= (1 << LED_BIT);
        } else {
            LED_PORT &= ~(1 << LED_BIT);
        }

        _delay_ms(100);
    }
}
#include <avr/io.h>

void adc_init(void);                                   // A/D converter initialization

unsigned int adc_read(char a_pin);


Zdrojový kód: zdrojaky.zip

Overenie

Na ovládanie LED diódy stačia dve tlačítka, pri prijatí kódu tlačidla „1“ sa nastaví stav LED diódy na zapnutý, pri prijatí kódu tlačidla „2“ sa stav LED diódy nastaví na vypnutý. Iné kódy sú ignorované.


Zhotovené zariadenie

Video:



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