Skocz do zawartości

[C] Obsługa IR - nadajnik i odbiornik


Pomocna odpowiedź

Napisano

Witam

Chciałbym się dowiedzieć w jaki sposób skonstruować nadajnik oraz odbiornik IR.

Myślałem o częstotliwości 36kHz, ale inna również może być.

Nadajnik chciałem zrobić na attiny13, a odbiornik najlepiej na atmega8.

Największym problemem jest możliwość wysłania 4 różnych bitów (w zależności od 4 wejść attiny13).

Jeśli ktoś posiada jakieś schematy lub/i kod źródłowy, to bardzo proszę o ich udostępnienie.

Pozdrawiam

Neter:Z jednej strony masz diodę nadawczą. Zasilasz ją bezpośrednio z pina procesora z wyjściem PWM + rezystor ok. 200R (200om) (dla 5V, dla 3,3V daj 100R). Pasmo 38kHz jest ok.

Samo nadawanie możesz zrealizować w ten sposób, że najpierw nadajesz "początek paczki", a następnie poszczególne bity.

Początek paczki niech ma 200ms, a potem na zmianę 50ms braku sygnału i 50ms nadawania (lub nie) w zależności czy bit jest "1" czy "0". Czyli pseudokod wygląda tak:


...
while(1)
{
  //przerwa miedzy paczkami
  wylaczPWM();
  delayms(500); //500ms przerwy
  pobierzstanybitow();
  //200ms sygnal startu paczki
  wlaczPWM();
  delayms(200);
  //stan niski wysylanie pierwszego bitu
  wylaczPWM();
  delayms(50);
  if (bit1jestustawiony()) wlaczPWM(); //jak bit ustawiony to 1
  delayms(50);
  //powtarzamy ostatnie 4 linijki dla bitow2,3,4
  wylaczPWM();
  delayms(50);
  if (bit2jestustawiony()) wlaczPWM(); //jak bit ustawiony to 2
  delayms(50);
  wylaczPWM();
  delayms(50);
  if (bit3jestustawiony()) wlaczPWM(); //jak bit ustawiony to 3
  delayms(50);
  wylaczPWM();
  delayms(50);
  if (bit4jestustawiony()) wlaczPWM(); //jak bit ustawiony to 4
  delayms(50);
  wylaczPWM();
  //cos tu mozna innego robic
}

Czyli w przypadku wszystkich bitów na 0 masz paczkę

_----________(jeden znak to 50ms,koniec paczki)

dla wszystkich bitów na 1 masz:

_----_-_-_-_-(jeden znak to 50ms,koniec paczki)

Odbiornik najlepiej byłoby zrobić na przerwaniu, ale bez przerwania najprościej to:

void sprawdzIR()
{
  if(!wejsciezodbiornikaIR()) return; //brak "1" z odbiornika - nie ma początku paczki
  //poczatek paczki? sprawdz czy 200ms ciagly sygnal
  delayms(50);
  if(!wejsciezodbiornikaIR()) return; //brak "1" z odbiornika - nie ma początku paczki
  delayms(50);
  if(!wejsciezodbiornikaIR()) return; //brak "1" z odbiornika - nie ma początku paczki
  delayms(25);//tutaj tylko 25ms zeby wejsc w "srodek" sygnału
  if(!wejsciezodbiornikaIR()) return; //brak "1" z odbiornika - nie ma początku paczki
  //200ms sygnal ciagly, sprawdz teraz czy jest 50ms sygnalu 0
  delayms(50);
  if(wejsciezodbiornikaIR()) return; //brak "0" z odbiornika - cos nie tak
  delayms(50);
  //czytaj bit 1
  bit1=wejsciezodbiornikaIR();
  //sprawdz teraz czy jest 50ms sygnalu 0
  delayms(50);
  if(wejsciezodbiornikaIR()) return; //brak "0" z odbiornika - cos nie tak
  delayms(50);
  //czytaj bit 2
  bit2=wejsciezodbiornikaIR();
  //sprawdz teraz czy jest 50ms sygnalu 0
  delayms(50);
  if(wejsciezodbiornikaIR()) return; //brak "0" z odbiornika - cos nie tak
  delayms(50);
  //czytaj bit 3
  bit3=wejsciezodbiornikaIR();
  //sprawdz teraz czy jest 50ms sygnalu 0
  delayms(50);
  if(wejsciezodbiornikaIR()) return; //brak "0" z odbiornika - cos nie tak
  delayms(50);
  //czytaj bit 4
  bit4=wejsciezodbiornikaIR();
  //sprawdz teraz czy jest 50ms sygnalu 0
  delayms(50);
  if(wejsciezodbiornikaIR()) return; //brak "0" z odbiornika - cos nie tak
  //jak tutaj dotarles to paczka jest poprawna i te bit1..bit4 mozna wykorzystac
}

przerwy 200ms/50ms są bardzo duże i wg. potrzeb powinieneś móc ten czas bardzo skrócić. Jednak jest to na tyle długi czas, że jak podłączysz obok zwykłą diodę to będziesz widział co nadajesz i odbierasz, więc łatwiej będzie sprawdzić czy sam nadajnik/odbiornik działa poprawnie.

Powodzenia

  • Pomogłeś! 1

Dziękuję bardzo za pomoc. Postaram się dzisiaj kupić odbiornik 38kHz, i sprawdzić, czy wszystko będzie działało tak jak trzeba.

Jeśli będę miał jakiś problem, to napiszę.

Pozdrawiam

Ja robiłem nadajnik IR na ATTiny25 (pracujący w trybie Tiny13), co prawda na 36KHz, ale jak dobrze pamiętam program był na tyle uniwersalny że konfiguracja całego urządzenia była zapisywana w EEPROM, więc jest to tylko kwestia konfigu CPU.

O nawet ocalał po formacie ❓🤣

'Plik konfiguracji systemu pilota.
' UWAGA!! ten plik po kompilacji da plik *.eep, który nalerzy wgrać do
' pamięci EEPROM mikrokontrolera. Pozwala on zmieniać konfiguracje bez
' potrzeby przeprogramowywania pamięci FLASH.

' Deklaracja i znaczenie poszczególnych bitów w zmiennej Config_sys
Dim Config_sys As Eram Byte At &H28
'bit 7 6  5 4 3 2 1 0
'    | |  | | | | | |
'    | |  | | | | | FIR.0 bit 0 wyboru częstotliwości nośnej set = 36KHz
'    | |  | | | | FIR.1 bit 1 wyboru częstotliwości nośnej set = 38KHz
'    | |  | | | FIR.2 bit 2 wyboru częstotliwości nośnej set = 40KHz
'    | |  | | IN.0 = Bit 0 wyboru zestawu komend. 00 = piórnik ver Ficu,
'    | |  | | 01 = ver Kriss
'    | |  | IN.1 = Bit 1 wyboru zestawu komend 10 - ver 2.0 zestaw 1,
'    | |  | 11 - ver 2 zestaw 2.
'   A2 A1 A0 = bity wyboru adresu bazowego


' Definicje dla EEPROM
' Zmieniając te definicjie mozna zmiecić zakres adresów, oraz kody komend dla
' poszczegulnych konfogóracji.
$eeprom
Adr_bazowy:
Data 0                                                      'pierwsza komóraka na 0
Data 0 , 4 , 12 , 14                                        'dane właściwe
Data 16 , 17 , 18 , 19
Data &HAA , 0 , 0                                           'Znacznik końca tablicy adresów i puste pola
Data 0 , 0 , 0 , 0
'Zestawy komend
Ficu:
Data 10 , 11 , 12 , 13

Kiss:
Data 10 , 20 , 30 , 40

P2_1:
Data 16 , 17 , 26 , 27                                      ' komendy podstawowe
Data 14 , 48 , 0 , 0                                        ' komendy rozszerzone

P2_2:
Data 22 , 23 , 24 , 25
Data 53 , 54 , 0 , 0

'TU WPISZ KONFIGURACJIE PILOTA
Con_sys:
Data &B00000001

Kod właściwi. Jednak to było kompatybilne z Tiny15 ❓

'Program: pilot Tiny 25/45
'CPU : Tiny 15 kompatybili mode.

$regfile = "attiny25.dat"
'$tiny
'$crystal = 1600000                 'F CPU 1,6 MHz
$include "Config_pilot.bas"
Const 36khz = 22
Const 38khz = 21
Const 40khz = 20
Const T1_on = &B10010101
Const T1_off = &B10100101
Const Port_mask = &B00011101


Dim Adres As Byte
Dim Key As Byte
Dim Key_buf As Byte
Dim Ep_adr As Byte
Dim Wsk_ep As Byte
Dim Key_en As Bit
Dim Sys_key As Bit
Dim I As Byte

Declare Sub Sys_ini
Declare Sub Logic_0
Declare Sub Logic_1

Config Portb = Input
Config Portb.1 = Output
Portb = &B00011101                                          'Ustaw wartości startowe PB.
Gtccr.2 = 1
Call Sys_ini
Key_en = 1
Do
 If Key_en = 1 Then
  Key = Not Portb
  Key = Key And Port_mask
  If Key <> 0 Then
     Waitms 25
     Key_buf = Not Portb
     Key_buf = Key_buf And Port_mask
     If Key = Key_buf Then
        Key_en = 0
        Select Case Key_buf
        Case 1 : Readeeprom Key , Ep_adr
        Case 4 : Wsk_ep = Ep_adr + 1
                 Readeeprom Key , Wsk_ep
        Case 8 : Wsk_ep = Ep_adr + 2
                 Readeeprom Key , Wsk_ep
        Case 16 : Wsk_ep = Ep_adr + 3
                 Readeeprom Key , Wsk_ep
        End Select
        'Dla zestawu rozszerzonego:
        If Sys_key = 1 Then
           If Key = 9 Then
              Wsk_ep = Ep_adr + 4
              Readeeprom Key , Wsk_ep
           End If
           If Key = 6 Then
              Wsk_ep = Ep_adr + 5
              Readeeprom Key , Wsk_ep
           End If
        End If
        'Nadawanie kodu RC5
        Logic_1
        Logic_1
        Logic_0
        For I = 4 To 0 Step -1                             '5 bit address, msb first
           If Adres.i = 0 Then
              Logic_0
           Else
              Logic_1
           End If
        Next
        For I = 5 To 0 Step -1                             '6 bit command, msb first
           If Key.i = 0 Then
              Logic_0
           Else
              Logic_1
           End If
        Next
        Tccr1 = T1_off
        Waitms 90
        Set Key_en
     End If
  End If
 End If
Loop

Sub Sys_ini
  Local Buf As Byte
  Buf = Config_sys And &B00000111
  Select Case Buf
  Case 1 : Ocr1a = 36khz
  Case 2 : Ocr1a = 38khz
  Case 4 : Ocr1a = 40khz
  End Select
  Buf = Config_sys And &B11100000
  Shift Buf , Right , 5
  Incr Buf
  Readeeprom Adres , Buf
  Buf = Config_sys And &B00011000
  Shift Buf , Right , 3
  Select Case Buf
  Case 0 : Ep_adr = 17
            Sys_key = 0
  Case 1 : Ep_adr = 21
            Sys_key = 0
  Case 2 : Ep_adr = 25
            Sys_key = 1
  Case 3 : Ep_adr = 33
            Sys_key = 1
  End Select
  'konfiguracja timera 1
  Tccr1 = T1_off
End Sub

Sub Logic_0
 Tccr1 = T1_on
 Waitus 883
 Tccr1 = T1_off
 Waitus 884
End Sub

Sub Logic_1
 Tccr1 = T1_off
 Waitus 883
 Tccr1 = T1_on
 Waitus 884
End Sub

Schemat, ale nie jest on do końca szczęśliwy.

Kupiłem odbiornik IR 36kHz (TSOP1736), podłączyłem to INT0. Zbocze ustawione jest na narastające, dawałem kondensator 10n lub/i rezystor 1k między VCC i OUT TSOP'a. Niestety, ale układ jest za bardzo czuły. Wystarczy zbliżyć dłoń, od razu włącza się przerwanie.

Wykonanie przerwania

SIGNAL(SIG_INTERRUPT0) 
{  
cli(); 
LCD_CLEAR;
LCD_LOCATE(0, 0);
lcd_puts("siema xD");
_delay_ms(100);
sei(); 
}

Włączenie przerwania:

MCUCR = (1<<ISC01);
GICR = (1<<INT0);
sei();

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...