Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C] odczyt z pilota JVC - gotowy przykład

kaktus_c++ 05 Kwi 2009 22:38 2687 0
  • #1
    kaktus_c++
    Poziom 18  
    Witam. Mam takiego pilota do JVC (kupiony rok temu za około 10 zł).
    [C] odczyt z pilota JVC - gotowy przykład
    Po wielu dniach ciężkich zmagań, w końcu udało mi się napisać program pod AtMege8 który pozwala go odbierać przy pomocy odbiornika podczerwieni TSOP1736.

    Przy tworzeniu programu , wspomagałem się 2 źródłami na temat kodu jvc, które się nieznacznie różnią.
    1) http://www.ustr.net/infrared/jvc.shtml
    2) http://www.sbprojects.com/knowledge/ir/jvc.htm

    Obsługa jest oczywiście w przerwaniu, od zbocza opadającego. Pin out odbiornika podczerwieni jest podłączony do pina PD2 (int0) i poprzez rezystor 3K do +5V.
    Algorytm pomija bit startu, nie używa timerów, Atmega jest ustawiona na 1MHz, ale częstotliwość AtMegi w tym przypadku może być dowolna (jeszcze tego nie sprawdzałem) .
    Adres i komenda jest wyświetlana na LCD.
    oto kod:
    Code:
    /*******************************************************************************/
    
    // odczyt pilota JVC , AtMega8 1MHz + TSOP1736 + LCD HD44780 //kaktus_c++ 05.04.2009
    /*******************************************************************************/
    #include <avr/io.h>
    #include <stdlib.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include "HD44780.c"
    #define SETBIT(ADDRESS,BIT)   (ADDRESS |= (1<<BIT))
    #define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
    #define FLIPBIT(ADDRESS,BIT)  (ADDRESS ^= (1<<BIT))
    //diody
    #define LED1         4      //do VCC
    #define LED1_PRT      PORTB
    #define LED1_DDR      DDRB
    #define LED2         5      //do VCC
    #define LED2_PRT      PORTB
    #define LED2_DDR      DDRB
    //odbiornik podczerwieni - przerwanie int0
    #define IR         2      //pin z rezystorem 3K do GND
    #define IR_PIN       PIND
    #define IR_DDR      DDRD
    #define LED1_ON         SETBIT(LED1_DDR,LED1); CLEARBIT(LED1_PRT,LED1);
    #define LED1_FLIP      FLIPBIT(LED1_PRT,LED1);
    #define LED2_ON         SETBIT(LED2_DDR,LED2); CLEARBIT(LED2_PRT,LED2);
    #define LED2_FLIP      FLIPBIT(LED2_PRT,LED2);
    #define ENABLE_INT0_FALLING   CLEARBIT(MCUCR,ISC00);SETBIT(MCUCR,ISC01);GICR=(1<<INT0) //przerwanie int0 od zbocza opadajacego
    static volatile unsigned char adres   = 0;//odebrany z odbiornika podczerwieni adres urządzenia
    static volatile unsigned char komenda = 0;//odebrana z odbiornika podczerwieni komenda
    //--------------
    int main(void)
    {
       LCD_Initialize();
       LCD_Clear();
       CLEARBIT(IR_DDR,IR);//pin odbiornika podczerwieni TSOP1736, jako wejscie
       LED1_ON;//sygnalizacja ze uruchomiono przerwanie
       LED2_ON;//sygnalizacja ze uruchomiono przerwanie i odczytano adres i komende
       ENABLE_INT0_FALLING;//wlacz przerwanie od zbocza opadajacego
       _delay_ms(10);
       sei();//wlacz  przerwania
       char bufor[10]="  ";
       while(1)
       {
          LCD_GoTo(0,0);
          LCD_WriteText("adr=");
          LCD_WriteText(utoa(adres,bufor,16));
          LCD_WriteText(" kom=");
          LCD_WriteText(utoa(komenda,bufor,16));
          LCD_WriteText("     ");
          _delay_ms(100);
       }
    }
    //-----------------------------------------
    SIGNAL(SIG_INTERRUPT0)
    {
    unsigned int licznik = 0xFFFF;//licznik bitow, gdy licznik == 0 to wczytano 16 bitow
    unsigned int kod = 0;//odebrane 16 bitow z pilota
    unsigned char czas;
    LED1_FLIP;//sygnalizacja ze uruchomiono przerwanie
    while(1)
    {
       _delay_us(5);//przeczekaj jesli ewentualnie opada zbocze
       for(czas=0;bit_is_clear(IR_PIN,IR);czas++)//czekaj poki jest sygnal - "1",czyli poki jest 0V
       {
          _delay_us(56);
          if(czas>15){return;}//"1" powinna trwac 525-560us, przerywam jesli czas>15*56us
       }
       if(czas<5)  {return;}//przerywam jesli czas<5*56us
       _delay_us(5);//przeczekaj jesli ewentualnie narasta zbocze
       for(czas=0;bit_is_set(IR_PIN,IR);czas++)//czekaj poki jest brak sygnalu - "0", czyli poki jest +5V
       {
          _delay_us(56);
          if(czas>35){return;}//"0" moze trwac od 525 do 1680 us, przerywam jesli czas>35*56us
       }
       if(czas<5)     {return;}//przerywam jesli czas<5*56us
       if(czas<15)// +5V bylo przez krotki czas , wczytujemy bit 0
       {
          CLEARBIT(kod,15);
          licznik>>=1;
          if(!licznik){_delay_us(5);adres=kod&0x00FF;komenda=kod>>8;LED2_FLIP;return;}//if(licznik==0) koniec;
          kod>>=1;
       }
       else// +5V bylo przez dlugi czas , wczytujemy bit 1
       {
          SETBIT(kod,15);
          licznik>>=1;
          if(!licznik){_delay_us(5);adres=kod&0x00FF;komenda=kod>>8;LED2_FLIP;return;}//if(licznik==0) koniec;
          kod>>=1;
          while(bit_is_set(IR_PIN,IR)){};//czekaj poki brak sygnalu
       }
    }
    }

    Tutaj jeszcze podaję odczytane z mojego pilota kody :
    (adres = 0x03)
    tv 0x17
    mute 0x1c
    sleep 0x03
    vol+ 0x1e
    vol- 0x1f
    ch+ 0x19
    ch- 0x18

    pilot nada się do zabawy ze zdalnym sterowaniem robocika/zabawki.

    A w czym problem? - Teraz już w niczym.
    Kod działa niemalże 100% dobrze. Na pewno komuś się przyda. Czasem po dłuższej zabawie, coś się dzieje i pilot mimo że go nie przyciskam , to wysyła jakieś śmieci których program nie rozpoznaje, ale to chyba wina wadliwego pilota.

    Prawdę mówiąc nie szukałem zbyt intensywnie kodu w C dla odczytu jvc, ale jeśli ktoś ma kod do odczytu jvc, ale lepszy, to bym chętnie zobaczył. Przydał by się kod z wykorzystaniem timerów/przerwań od timerów, tak aby momentach podczas gdy program odlicza sobie czas występowania 0 lub 1, program opuszczał przerwanie i robił w między czasie inne rzeczy.
    Załączniki: