ATmega8 - Sony infravörös távirányító vétele

2013-07-27

 

A Sony infravörös távirányítója által használt protokolt SIRC nek nevezik.

Annyiból macerás, hogy háromféle is van belőle, szerencsére az első 7 parancsbit mindegyiknél azonos, és ez tartalmazza melyik gombot nyomtuk le. Én tulajdonképpen a 15 bites verziót programoztam le (ez lekezeli a 12 bitest is) , bár az eszköz azonosítóra lehet hogy nem is lesz szükségem, a kiterjesztett biteknek meg végképp nem jártam utána. Ha valikenek szüksége van rá, kicsit módosítania kell a programon.

Így néz ki a feldolgozandó jelünk. Az interneten azt írták, hogy a bitek a lefutó élnél kezdődnek, de én úgy találtam, egyszerűbb dolgom lesz, ha a felfutó éltől felfutó élig mérek. A "0"-ás bit 2T időtartam, az "1"-es 3T hosszú. A távirányító ciklikusan újraküldi a lenyomott gomb kódját, de két kód között egy hosszabb szünetet tart. 1T a leírások szerint 600 usec hosszú.

Somogyi - 10000 - 08

0 - 1001000 - 19-/ 22\54/ 25\26/ 2B\26/ 2B\53/ 26\26/ 2B\26/ 2A\26/ 2B\52/28\26/2A\26/2B\26/2B\26/FF\A4/26\53/26\26/2B\26/2A
1 - 0000000 - 19-/ 22\26/ 2A\26/ 2B\26/ 2B\26/ 2A\27/ 2A\26/ 2B\26/ 2B\53/26\26/2A\27/2A\26/2B\26/FF\A5/25\26/2B\25/2B\26/2B
2 - 1000000 - 19-/ 22\54/ 26\25/ 2B\26/ 2B\26/ 2A\27/ 2A\26/ 2B\26/ 2B\53/26\26/2B\26/2A\26/2B\26/FF\A4/25\54/26\26/2A\26/2B
3 - 0100000 - 19-/ 22\26/ 2B\53/ 26\26/ 2A\27/ 2A\26/ 2B\26/ 2B\26/ 2B\53/26\26/2B\26/2A\26/2B\26/FF\A4/25\27/2A\54/26\26/2A
4 - 1100000 - 19-/ 22\54/ 26\53/ 26\26/ 2B\25/ 2B\26/ 2B\26/ 2B\26/ 2A\54/26\26/2B\26/2A\26/2B\26/FF\A5/25\53/26\54/25\26/2B
5 - 0010000 - 19-/ 22\26/ 2A\27/ 2A\54/ 25\27/ 2A\27/ 2A\26/ 2B\26/ 2B\54/25\26/2B\26/2A\26/2B\26/FF\A5/25\26/2B\26/2A\54/26
6 - 1010000 - 19-/ 22\54/ 26\25/ 2B\54/ 25\26/ 2B\26/ 2B\26/ 2B\26/ 2A\54/26\26/2B\25/2B\26/2B\26/FF\A5/25\54/25\26/2B\54/25
7 - 0110000 - 19-/ 22\26/ 2B\53/ 26\54/ 25\26/ 2B\26/ 2B\26/ 2A\26/ 2B\54/26\26/2A\27/2A\26/2B\26/FF\A4/25\26/2B\53/26\54/26
8 - 1110000 - 19-/ 22\52/ 28\53/ 26\54/ 25\26/ 2B\26/ 2B\26/ 2A\26/ 2B\54/26\26/2A\27/2A\26/2B\26/FF\A4/25\54/26\52/27\54/26
9 - 0001000 - 19-/ 22\26/ 2A\27/ 2A\26/ 2B\54/ 25\26/ 2B\26/ 2B\26/ 2B\53/26\26/2B\26/2A\26/2B\26/FF\A4/25\26/2B\26/2B\26/2A
Sony - 00100110 - 64

0 - 0011000 - 19-/ 20\2B/ 24\2B/ 25\53/ 24\53/ 25\2B/ 24\2B/ 25\2B/ 24\2B/25\2B/24\53/24\2C/24\2B/25\53/24\53/24\2B/FF\A3/24
1 - 0000000 - 19-/ 1F\2D/ 23\2D/ 23\2C/ 23\2D/ 22\2D/ 23\2D/ 23\2C/ 23\2D/23\2C/23\55/22\2D/23\2D/23\54/23\54/23\2B/FF\A3/24
2 - 1000000 - 19-/ 20\56/ 21\2D/ 23\2B/ 24\2D/ 23\2C/ 23\2B/ 25\2C/ 23\2D/23\2C/23\57/20\2D/23\2B/25\54/23\55/22\2B/FF\A4/23
3 - 0100000 - 19-/ 20\2C/ 23\55/ 23\2B/ 24\2D/ 23\2C/ 23\2D/ 23\2C/ 23\2D/22\2D/23\53/24\2D/23\2D/23\52/25\54/23\2D/FF\A4/23
4 - 1100000 - 19-/ 20\54/ 23\55/ 23\2C/ 23\2B/ 25\2C/ 23\2D/ 22\2D/ 23\2D/23\2C/23\53/25\2C/23\2D/22\53/25\54/23\2D/FF\A4/23
5 - 0010000 - 19-/ 20\2C/ 23\2D/ 23\54/ 23\2D/ 23\2D/ 22\2D/ 23\2C/ 23\2D/23\2D/22\55/23\2D/22\2F/21\54/23\55/22\2D/FF\A4/23
6 - 1010000 - 19-/ 20\56/ 21\2D/ 23\54/ 23\2D/ 23\2A/ 25\2B/ 24\2D/ 23\2D/23\2C/23\55/22\2D/23\2B/24\55/23\54/23\2D/FF\A4/23
7 - 0110000 - 18-/ 26\2A/ 26\53/ 24\51/ 27\2B/ 24\2B/ 25\2A/ 25\29/ 27\2B/24\2B/25\51/26\29/27\2A/25\51/27\52/25\2B/FF\A2/25
8 - 1110000 - 19-/ 20\50/ 27\53/ 25\50/ 27\29/ 26\2B/ 25\29/ 26\29/ 27\2B/24\29/27\51/26\29/27\29/26\51/27\50/27\29/FF\A2/25
9 - 0001000 - 19-/ 20\2C/ 23\2D/ 23\2B/ 24\55/ 23\2B/ 24\2D/ 23\2C/ 23\2B/25\2C/23\55/23\2C/23\2D/23\54/23\55/22\2D/FF\A4/23

Itt láható a két távirányítóról rögzített jelem (lásd: ATmega8 - Infravörös jelrögzítő), kicsit beleszerkesztettem, hogy én is jobban értsem mi történik. A távirányító neve után van írva, hogy milyen eszköazonosítót küld. Az egyes sorok elején az a gomb van, amelyiket lenyomtam. Utána binárisan leírtam, milyen biteket küld, azután a rögzített adatok találhatók. Ha megnézzük, elég nagy szórásuk van a küldött jeleknek. 1T periódus 1F-2F-ig terjed, 2T pedig 50-55-ig. Ez ugye hexadecimálisan értendő, és a kapcsolás 14 usec-enként számol. A számítgatásaimat most mellőzve, úgy találtam, a "0"-ás bitek (2T) rövidebbek voltak minden esetben mint 81 periódus, vagyis 1134 usec, az "1"-es bitek (3T) pedig hosszabbak voltak mint 116 periódos, vagyis 1624 usec. Az időt T0 számlálóval méri az áramkör. 4MHz órajelnél, 64-es előosztást alkamazva, 16 usec-ként lép a számláló, 90-es érték, éppen 1440 usec-re adódik. Tehát a program a 90-nél rövidebb biteket "0"-nak, a hoszabbakat "1" nek értelmezi.

A kapcsolás teljesen megegyezik a fentebb már emlegetett ATmega8 - Infravörös jelrögzítőnél alkalmazottal, ezért újabb fotót sem csináltam.

Az infavörös vevő jelét az INT0 lábon figyeli az áramkör, ez felfutó élnél generál megszakítást. A T0 számláló túlcsordulás megszakítása is be van kapcsolva, mert le kell kezelni, hogy a számláló ne prögjön körbe két kód között, és bizonytalan állapotból induljon, továbbá ekkor zárul le az adatok vétele. Az áramkör soros vonalon küldi el, milyen parancs és eszköz azonosítót vett.



/*******************************************************************************
*   Author       -  Kiraly Tibor
*                   http://www.tkiraaly.hu
*   Date         -  2013.07.27.
*   Chip         -  Atmel ATmega8
*   Compiler     -  avr-gcc (WinAVR)
*
*   KT SIRC vevo
*   
********************************************************************************
*
*   AVR  4 - INT0 - TSOP 2236 2
*   AVR  1 - NRES - switch, 4k7-tel felhuzva
*   AVR 15 - PB1  - LED, 470R-el felhuzva
*
*******************************************************************************/

#define F_CPU                4 MHZ
#define T0_DIVIDER           64        // 16 usec




#include "tkiraaly_atmega8.h"
#include <util/delay.h>
#include <avr/pgmspace.h>




volatile U8 ir_flag;                   // adat kesz
volatile U8 ir_bitcount;               // bitek szamlalasa
volatile U8 ir_command;                // 7 bit - parancs kod
volatile U8 ir_command_;
volatile U8 ir_device;                 // 5/8 bit - eszkoz kod
volatile U8 ir_device_;
//          ir_extend                  // 0/8 bit - nincs hasznalva  




void usart_putc( U8);                  // USART 1 karakter kiirasa
void usart_puthexc( U8);               // USART 1 hexadecimalis szamjegy kiirasa
void usart_puthexb( U8);               // USART 1 byte hexadecimalis kiirasa




ISR( INT0_vect)                        // INT0 - felfuto el figyelese
{
   T0_STOP;
   if( TCNT0 < 200)                    // bit/ nem adas koz
   {
      if ( ir_bitcount < 16)           // csak az elso 15 bit feldolgozasa
      {
         if ( ir_bitcount < 8)         // command bitek (7)
         { 
            ir_command_ >>= 1;
            if( TCNT0 > 90) ir_command_ |= 0B01000000;  // 1
         }
         else
         {                             // device bitek (8)
            ir_device_ >>= 1;
            if( TCNT0 > 90) ir_device_ |= 0B10000000;   // 1
         }
         ir_bitcount++;
      }
   }
   TCNT0= 0;                            // meres inditasa
   T0_NORMAL;
}




ISR( TIMER0_OVF_vect)                  // 255 periodusnal hosszabb ido, adas vege
{
   T0_STOP;
   TCNT0= 255;                         // atporges visszaallitas
   ir_command= ir_command_;            // adatok kimasolasa
   ir_device= ir_device_;
   ir_flag= 1;                         // flag beallitas
   ir_bitcount= 1;                     // valtozok alapba allitasa
   ir_command_= 0;
   ir_device_= 0;
}




int main( void)
{
   U8 t_command;
   U8 t_device;

   PB1_OUT;                            // LED

   T0_STOP;
   TCNT0= 255;
   T0_IT_OVF_ENABLE;

   ir_flag= 0;
   ir_bitcount= 1;
   ir_command_= 0;
   ir_device_= 0;

   INT0_RISING;
   IT_INT0_ENABLE;

   USART_SET_9600_8N1;

   IT_ENABLE;

   usart_putc('S');
   usart_putc('I');
   usart_putc('R');
   usart_putc('C');
   usart_putc( 13);
   
   for(;;)
   {
      if( ir_flag)
      {
         t_command= ir_command;
         t_device=  ir_device;
         ir_flag= 0;
         usart_puthexb( t_command);
         usart_putc( '-');
         usart_puthexb( t_device);
         usart_putc( 13);
      } 
   }
   return 0;
}

     


void usart_putc( U8 c)                 // USART 1 karakter kiiras
{
    while( BTC( UCSRA, UDRE));         // 1, ha kesz az adat fogadasara
    UDR= c;
}



 
void usart_puthexc( U8 c)              // USART 1 hexadecimalis szamjegy kiirasa
{
   c&= 0x0F;
   if( c < 10) c+= '0';
   else        c+= 'A'- 10;
   usart_putc( c);
}




void usart_puthexb( U8 c)              // USART 1 byte hexadecimalis kiirasa
{
   usart_puthexc( c >> 4);
   usart_puthexc( c);
}

Itt a vége, fuss el véle, legytek az én vendégeim, innen letölthetitek a hozzávalókat összecsomagolva.