IR diody pro Lasertag

Viktor Sekanina, Marek Labudík
xsekan02studfeec.vutbr.cz, xlabud01studfeec.vutbr.cz

Obsah:

  1. Úvod
  2. Realizace
  3. Závěr
  4. Literatura

Úvod

Lasertag je hra, která se hrává v temné místnosti naplněné několika hráči vybavenými vestami a zbraněmi. Projektil vystřelený ze zbraně je realizován pomocí úzkého infračerveného paprsku, kterým se osvítí čidlo na protivníkově vestě a tím jej zasáhneme. Pistole má instalovaný laser, který ale slouží spíše k zaměření a na detekci zásahu se nepodílí.

Realizace

Žádná běžná infračervená LED (IR LED) nemá dostatečně malý vyzařovací úhel (1° je stále mnoho), takže na vzdálenost několika metrů se paprsek roztáhne do šíře několika desítek centimetrů. Přitom je potřeba, aby na vzdálenost několika desítek metrů o vysílací IR LED byl průměr ozářeného kruhu kolem 20cm. Vyzařovací úhel může být snížen přidáním trubice na pouzdro LED. Tímto sice omezíme vyzařovací úhel, snížime tak ale i vyzářený výkon, protože je trubice utlumí. Proto nesmí být trubice příliš dlouhá, ani příliš krátká. Testovány jsou různé délky trubic a různé IR LED.
Cuprum trubky
Ledky jsou zasunuty v měděných trubkách o vnitřním průměru 4mm a protože ledky mají 5mm pouzdro, je jeden okraj trubice zvětšen na 5mm. Trubky jsou délky 11, 20 a 25cm. Pro testování IR LED vznikl jednoduchý přijímač a vysílač. Na následujícím obrázku je schéma vysílače.
IRvysílač
Za ochranou diodou proti přepólování je lineární 5ti voltový stabilizátor, následuje supresorová dioda (transil) jako ochrana proti přepětí (člověk nikdy neví...) a nezbytné kondenzátory. Jádrem věci je ATMEGA16. Příslušenství činí nějaké ledky a tlačítka, umístěné tak, že při stisknutí tlačítka se rozsvítí jemu příslušná LEDka. Samozřejmě, že tyto ledky a množství tlačítek nejsou vůbec třeba, stejně jako třeba to, že ledky jsou jsou spínány přes tranzistory :-). IR dioda je přes darlingtonovo zapojení tranzistorů připojena k výstupu OC0 (čítače/časovače0). Na tomto výstupu je generován modulovaný signál na kmitočtu 38kHz. Modulace je nutná, protože tak lze dosáhnout požadovaného špičkového výkonu ledky, čím kratší je doba svitu LED, tím větší proud jí může procházet, tj. ledka dále dosvítí. Zároveň s tím lze přenášet informaci - posloupnost bitů. Protokol je podobný protokolu JVC, který používají běžné dálkové ovladače, je však zjednodušený, žádné opakování, kontrola chyb... má sloužit pouze k odvysílání zadané sekvence. Protokol je popsaný v laboratorních návodech k předmětu BZTV [1] nebo třeba zde. Na přiložených obrázcích z osciloskopu jsou časové relace: První dva obrázky jsou měřeny na IR LED a ostatní jsou obrázky naprogramovaného protokolu zachyceného infračerveným čidlem.
Celý průběh na LEDce
Nosný kmitočet
logicka 1
Šířka impulzu
Šířka impuzu
Za detektorem
Proud IR ledkou je pro každou ledku jiný, ale pohybuje se mezi 20mA a 100mA při Ud~1,5V mimo pulzní režim. V pulzním režimu se proud ledkou pohybuje kolem 1A v závislosti na době svitu ku době, kdy ledka nesvítí.

Dostupné IR LED:

  • SFH4550-dostupná ve Farnellu, vyz. úhel 3°, 850mW/Sr.
  • 510E850C-dostupná např. v GME jako IR850, vyz. úhel 13°, 160mW/Sr.
  • TSHF5210-dostupná v TME, vyz. úhel 10°, 180mW/Sr.
  • Pozn. jednotka mW/Sr znamená přibližně vyzářený výkon v daném úhlu.

    Složený vysílač
    TOP
    BOTTOM
    Deska plošného spoje byla vyrobena narychlo rukou, aby se mohlo testovat, schéma vznikalo zároveň s výrobou této desky a do eaglu bylo překresleno až při psaní této stránky.

    Program odesílá předem naprogramované sekvence o délce 32bitů. Právě odeslaná sekvence se zobrazí na displeji. Nejdůležitější část programu je popsána tu:

      ISR( TIMER0_COMP_vect ) 	/*generuje nosný kmitočet 38kHz na pin OC0*/
      {
      if (inter==0) 
      	{
      	inter=1;  /*stav IR LEDky*/
      	IRON;     /*zapnout IR LED*/
      	}
      else 
      	{
      	inter=0;  /*stav IR LEDky*/
      	IROFF;    /*vypnout IR LED*/
      	}
      }
    
      ISR( TIMER1_COMPA_vect )
      {
      TCCR1B = 0b00001000;   /*zastavit čítače*/
      TCCR0 = 0b00001000;
      IROFF;                 /*vypnout IR LED*/
      inter=0;
      TCNT0 = 0;	           /*vynulovat čítače*/
      TCNT1 = 0;
      prerus=0;              /*vyvolat reakci v hlavním programu*/
      } 
    	

    A v programu "vyslat":

    void vyslat(uint32_t vyslane)
    {
    uint8_t pocetbitu;
    uint32_t kopie = vyslane;     /*kopie vysílané sekvence*/
    uint32_t maska = 0x80000000;
    uint32_t zprac;
    
    /*start vysilani*/
    OCR0 = 131;                  /*kmitočet nosné 38kHz*/
    OCR1A = 1313;                /*impulz dlouhý 8,4ms -> start*/
    TCCR1B = 0b00001011;          /*zapnout čítače*/
    TCCR0 = 0b00001001;
    prerus=1;                   /*nastavit příznak*/
    while(prerus==1);           /*cekej nastavenou dobu impulzu*/
    IROFF;                     /*zapnutá IR LEDka ve spínacím režimu = konec LEDky*/
    
    OCR1A = 656;//4,2ms        /*mezera dlouhá 4,2ms*/ 
    TCCR1B = 0b00001011;       /*zapnout čítač pro odpočítání doby, nikoli generátor nosné*/
    prerus=1;
    while(prerus==1);          /*cekej nastavenou dobu mezery*/
    IROFF;
    /*bit navíc - byl již naprogramován v přijímači - přijímač vznikl dříve než vysílač*/
    /*vyšli logickou 1 */
    	OCR1A = 82;       /*impulz cca.0,52ms*/
    	TCCR1B = 0b00001011;
    	TCCR0 = 0b00001001; 
    	prerus=1;
    	while(prerus==1);
    	IROFF;
    
    	OCR1A = 257;     /*mezera 1,65ms*/
    	TCCR1B = 0b00001011; 
    	prerus=1;
    	while(prerus==1);
    	IROFF;
    //-----------------
    zprac = kopie & maska;   /*do zprac je uložen nejvyšší bit z vysílané sekvence*/
    
    for (pocetbitu=0;pocetbitu<=33;pocetbitu++)   /*zpracování vysílané sekvence bit po bitu pomocí rotace masky*/
    {
    	if (zprac == 0)
    	{                    /*sekvence pro log.0*/
    	OCR1A = 82;
    	TCCR1B = 0b00001011;
    	TCCR0 = 0b00001001; 
    	prerus=1;
    	while(prerus==1);
    	IROFF;
    
    	OCR1A = 82;
    	TCCR1B = 0b00001011; 
    	prerus=1;
    	while(prerus==1);
    	IROFF;
    	}
    	else
    	{                    /*sekvence pro log.1*/
    	OCR1A = 82;
    	TCCR1B = 0b00001011;
    	TCCR0 = 0b00001001; 
    	prerus=1;
    	while(prerus==1);
    	IROFF;
    
    	OCR1A = 257;
    	TCCR1B = 0b00001011; 
    	prerus=1;
    	while(prerus==1);
    	IROFF;
    	}
    kopie=kopie<<1;
    zprac = kopie & maska;   /*rotace masky a její aplikace na vysílanou sekvenci*/
    }
    }
    	

    Přijímač vznikl na pokusné destičce takového vzhledu, že se její fotku autor stydí zveřejnit. Schéma přijímače:

    IRpřijímač
    Opět použití megy32 není nutné, byla prostě po ruce. Program je však napsán pro ni. Detektor může být vcelku cokoli podobného na nosný kmitočet 38kHz, např. TSOP1738, SFH5110-38. Na výstupu z čidla jsou už přímo demodulované obdélníky, takže stačí hlídat hranu a spouštět čítač nebo použít input capture, který, správně nastavený, splní stejnou funkci. Stav čítače se převede na čas, který pak udává jednotlivé přijaté bity. 32 přijatých bitů se ve formě 0x00000000 zobrazí na displeji.

    ISR( INT1_vect )  /*přišla sestupná hrana*/
    {
    if (detect == 0)
    {	
    TCCR1B = 0b00000010;		/*spousti se citac pro mereni delky impulzu (presc.=8)*/
    detect = 1;             /*bude se prijimat sekvence*/
    }
    else
    {
    	prijate = prijate<<1;       /*rotace bitů do prijate*/
    	if (pocitadlo != 33)
    	{
    			hodnota = TCNT1;        /*zjistovani delky impulzu+mezery*/
    			TCNT1 = 0;               /*zastaveni citace*/
    			
    				if (hodnota>26900 && hodnota<27050)		/*odpovida zhruba 8,4ms+4,2ms -> start*/
    				pocitadlo++;
    				if (hodnota>4000 && hodnota<4700)		/*odpovida zhruba 2,1ms -> log.1*/
    				{
    				pocitadlo++;
    				prijate |= 0x0001;
    
    				}
    				if (hodnota>1800 && hodnota<2400)		/*odpovida zhruba 1,05ms -> log.0*/
    				{
    				pocitadlo++;
    				}
    			
    			
    	}
    }
    }
    
    int main( void )
    {
    
    	MCUCR = 0b00001000;		//sestupna hrana
    	GICR = 0b10000000;	//int 1 Interrupt enable   /*nastavení přerušení*/
    
    	TCNT1 = 0;
    
    	DDRA = 0xFF;
    	DDRC = 0b00100000;			//ledka
    	PORTD = 0b00001100;		//pullup int 0, 1
    	PORTC = 0;
    	_delay_ms(500);
    	PORTC = 0b00100000;
    	_delay_ms(500);
    	PORTC = 0b00000000;
    	_delay_ms(500);         /*zůstalo z testování - bliknutí připájenou ledkou - není ve schematu!!!!*/
    
    	lcd_init();
    	lcd_gotoxy(0,0);
    	lcd_puts("DISPLEJ 16x2");
    	sei();                  /*inicializace displeje a povolení přerušení*/
    
    while(1){
    
    	if (pocitadlo == 33)
    	{
    	cli();
    	TCCR1B = 0;
    	pocitadlo = 0;
    	detect = 0;          /*byla přijmuta sekvence*/
    	prijateL = prijate & 0x0000FFFF;
    	prijates = prijate & 0xFFFF0000;
    	prijateH = prijates>>16;               /*rozdeleni 32bit. slova, aby to slo zobrazit na dislpeji*/
    	lcd_gotoxy(0,1);
    	sprintf(lcd_buffer,"%x",prijateH);
    	lcd_puts(lcd_buffer);
    	sprintf(lcd_buffer,"%x",prijateL);
    	lcd_puts(lcd_buffer);                  /*zobrazení slova ve tvaru 0x00000000 na displeji*/
    	PORTC = 0b00100000;                    /*stejný pozůstatek z testování-není ve schematu!!!!*/
    	lcd_gotoxy(0,0);
    	lcd_puts("Prijato     ");
    	sei();
    	}
    neco++;                                  /*todle zůstalo po simulaci, ničemu to nevadí*/
    }
    
    
    }
    
    	

    Závěr

    Samotné testování úhlu a dosahu mezi vysílačem a přijímačem naráží na problém bílých zdí; Detektor přijme signál i odrazem nečerné stěny a proto je nutné vzdálenosti proměřit v místosti určené pro hru lasertag. Nejlepší z IR LEDek byla jednoznačně SFH4550, délka trubky na dosah cca. 40m neměla velký vliv. Délka trubky bude mít vliv hlavně na průměr osvíceného kruhu v místě měření. Zdrojové kódy jsou napsány ne moc přehledným způsobem, avšak navrhnutá konstrukce by se dala použít například pro příjem kódu z dálkového ovladače a pomocí něj něco ovládat, případně pro nějaký jednoduchý přenos dat mezi jednočipy.

    Zdrojové kódy: IR_RX. IR_TX.

    Schéma: schema.

    Literatura

    [1] HANUS, S. Dálkové ovládání televizního přijímače. Elektronické skriptum. Brno: FEKT VUT v Brně, 2010.