IR Modtager
IR modtageren er et modul der oprindeligt er udviklet til fjernbetjeninger af TV, men som har vundet så meget indpas, at det anvendes i de fleste fjernbetjeninger i dag, som kan benytte sig af infrarødt lys (hvor man kan have frit syn til modtageren).
Modulet er lavet til at modtage et signal fra en fjernbetjening, hvor signalet er modulret på en 38 kHz bærebølge, som så filtreres væk, og det ønskede signal kommer ud af IR modtageren.
Modulet
Modulet er fra keyes-serien keyes-moduler, og har betegnelsen KY-022.
Stikforbindelser til IR modul
Benforbindelserne er som følger:
Ben | Navn | Funktion | PIC-ben |
---|---|---|---|
1 | - | GND | 10 |
2 | + | +5V forsyning | 9 |
3 | S | Signal Out | valgfrit 1-8 |
Blokdiagram over IR modtager
Internt i modulet er opbygningen ca. som skitseret her til venstre. Dette er ikke fra det aktuelle datablad, men fra en kreds med samme funktion.
Det første symbol er en IR-følsom photodiode, der er modtagelig over for infrarødt lys (der er desuden et lysfilter på, så andet lys ikke forstyrrer).
Input-kredsløbet er den del som tilpasser photodioden til den efterfølgende forstærker.
AMP er forstærkeren, der som navnet siger, forstærker signalet op - i nogle enheder er der også AGC (Automatic Gain Control) indbygget i denne forstærker, for at den ikke skal overstyres.
Bandpass er et båndpasfilter, der filtrerer andre frekvenser væk, så den er mest følsom over for 38 kHz. I Keyes versionen kan den fungere i et rimeligt bredt frekvensbånd.
Når man har signalet fornuftigt filtreret, så bliver det demoduleret, således at den efterfølgende transistor trækker lav, når der er 38 kHz signal til stedet, og den lader være når det ikke er der. De 33 k ohm sørger for at signalet er højt, når der ikke er 38 kHz lyssignal ind.
Specifikationer på IR modtager
Den aktuelle modtager har det kun været muligt at finde datablad på kinesisk, men der kan stadig læses de centrale data man har brug for, og hvordan det skal kobles op.
Der er skitseret hvordan modtageren skal kobles op:
Opkobling af IR modtageren mod en CPU
Dioden er en IR LED, der sidder i senderen.
Modtageren er firkanten med de 3 ben VCC, OUT og GND. Modstande og kondensatorerne sidder monteret på keyes-modulet, så man kan koble det direkte til PIC'en på den måde der er skitseret med CPU'en.
I databladet er der et mere dækkende blokdiagram:
Blokdiagram over IR-modtageren fra databladet
Data på IR modtageren er som angivet her:
Data | Betegnelse | Min | Typ | Max | Enhed |
---|---|---|---|---|---|
Forsyning | Vcc | 2.7 | 5 | 5.5 | V |
Centerfrekvens | f0 | 38 | kHz | ||
Båndbredde -3dB | fbw | 2 | 3,3 | 5 | kHz |
Halveringsvinkel | v1/2 | +/-45 | grader | ||
Rækkevidde | d@Std. transm. | 20 | m | ||
Forsyningsstrøm | Icc@5V | ---- | 0.4 | 1.5 | mA |
Low level output | VOL@5V | ---- | 0,2 | 0,4 | V |
High level output | VOH@5V | 4,5 | V | ||
Pulsbredde Lav | Tpwl | 500 | 600 | 700 | us |
Pulsbredde Høj | Tpwh | 500 | 600 | 700 | us |
Temperaturområde | topr | -20 | 25 | 80 | grader C |
IR Modtager på fjernebetjening
Hvis man tager en tilfældig fjernbetjening, og sender til IR modtageren, så vil man kunne måle et signal, som er bestemt af den fjernbetjening man anvender, men strukturen i dem er stort set den samme, nemlig at 0 og 1 er kodet ved hjælp af forskellige tidsforhold, og at de starter nogenlunde ensartet, men igen med små variationer i tidsforholdene[1], hvor en fjernbetjening med NEC-protokol vil sende følgende:
Hvis man ser på NEC protokollen[2], så kan man genkende at der kommer først en header på 9 ms og en pause på 4,5 ms. Efter dette kommer data og en pause, og så igen en repeat, der består af en header på 9 ms og en pause på 2,25 ms. Afstanden mellem de to blokke er godt nok lidt mindre end 110 ms, men ideen i signalet er klar nok.
Dette svarer til måden protokollen er stillet op på
Zoomer man lidt ind, så man kun har data, så kan man aflæse at der kommer følgende signaler:
Tolker man dette vil man få følgende 4 tal udtrykt som bytes:
0b0000_0000 = 0x00 0b1111_1111 = 0xFF 0b0011_1010 = 0x3A 0b1100_0101 = 0xC5
hvor første byte er address 0x00, og den næste byte er den inverterede. Den tredje byte er command og den sidste byte er den inverterede af command.
Grunden til der kommer både det rigtige tal og derefter det inverterede er at man kan modtage alle 4 byte, og hvis man ikke modtager præcist de inverterede af de to bytes, så er der gået et eller andet galt i transmissionen, og man er nødt til at forkaste resultatet - det gør at man er væsentlig mere sikker på at modtage det korrekte.
For lige at sikre at tiderne er nogenlunde som forventet i bittene vises her tiderne, hvor de bursts af 38 kHz der modtages er vist som lave signaler, mens de høje er pauserne imellem.
Det kan godt genkendes at hvert lave signal er ca. 560 us, og at periodetiden på et logisk 0 er ca. 1,12 ms mens periodetiden på et logisk 1 er ca. 2,25 ms, som måden protokollen er stillet op på her
IR-sending med PIC
For at kunne sende med PIC'en skal man have den til at lave en frekvens på ca. 38 kHz, hvilket kan komme til at belaste PIC'en ret meget, da det svarer til en periodetid på ca. 26 us, og da en PIC ved 4 MHz kan afvikle en maskininstruktion hvert us, så vil PIC'en ikke kunne lave meget andet, men det kunne godt lade sig gøre at skrive det på den måde.
Et alternativ er at sætte PIC'en op til at arbejde med PWM på en udgang, hvor perioden sættes op til 26 us, og man så slår sendingen til eller fra ved at skrive en duty-cycle ind, så man får passende pulser, når den skal sende, og en dutycycle på 0, når den ikke skal sende.
Koden til at initialisere og sætte PWM klar er som følger:
const bit u3_puls = true -- Definer at det skal være en kort 0,3 us puls
-- Ellers bliver pulsen 1,2 us
enable_digital_io() -- disable analog I/O (if any)
pin_c5_direction = output -- Det skal være C5, da vi anvender PWM
PR2 = 0x19 -- Sæt periodetiden til at være ca. 26 us (38 kHz)
CCP1CON = 0b0000_1100 -- Sæt op til at det kun er et PWM output
CCPR1L = 0 -- Sæt PWM værdien til 0% (slukket puls)
T2CON = 0b0000_0100 -- Enable timer 2, uden prescaler til 38 kHz
Ved at sætte en dutycycle på ca. 1%, så får man pulser på ca. 0,3 us med et mellemrum på ca. 26 us. Det ser ud som følger:
Hvis man går tættere på signalet, så kan man se at det er ca. 0,3 us:
Måden man får en dutycycle på 1% er ved at skrive følgende i koden:
CCP1CON_DC1B = 1
I en testopstilling er der blot sat en LD271 direkte på udgangen pin_C5 uden formodstand, så der løber kortsluningsstrømmen på ca. 30 mA i den infrarøde lysdiode.
I en testopstilling giver det en rækkevidde på ca 0,5 m.
Rækkevidden kunne forøges væsentligt ved at anvende en transistor, og pulse ca. 1A igennem IR-LED'en, ud fra det viste kredsløb.
Transistoren drives ved at sende signalet ind gennem R1, til at kunne levere ca. 1A gennem R2 og LED1.
Man skal passe på at man holder dutycycle nede på indgangen til transistoren, da man ellers let vil kunne brænde både modstand og LED af med den store strøm.
Kondensatoren på 1000uF er placeret der for at udglatte de strømspidser der trækkes fra forsyningen, så der ikke kommer så meget støj rundt i resten af kredsløbet.
En anden måde at forbedre rækkevidden på er ved at sætte en dutycycle op til ca. 4%, så får man pulser på ca. 1,2 us med et mellemrum på ca. 26 us. Det ser ud som følger:
Hvis man går tættere på signalet, så kan man se at det er ca. 1,2 us:
Måden man får en dutycycle på 4% er ved at skrive følgende i koden:
CCPR1L = 1
I en testopstilling er der blot sat en LD271 direkte på udgangen pin_C5 uden formodstand, så der løber kortsluningsstrømmen på ca. 30 mA i den infrarøde lysdiode.
I en testopstilling giver det med den længere puls en rækkevidde på ca. 1,5 m.
Afsendelse af pulstog med 38 kHz
Hvis man blot sender kontinuerligt 38 kHz, så vil IR modtageren holde op med at reagere, så man er nødt til at sende nogle pulstog (flere bursts), og holde pauser mellem dem, så der opbygges en test-kode for at sende dette.
Koden ser ud som følger:
forever loop
for 10 loop -- Lav 10 perioder á ca. 1 ms (10 ms i alt)
if u3_puls then -- Tænd for PWM output
CCP1CON_DC1B = 1 -- Enten med 1%, eller ca. 0,3 us
else
CCPR1L = 1 -- eller med 4%, altså ca. 1,2 us
end if
delay_10us(50) -- Lad de 38 kHz køre i 0,5 ms
if u3_puls then
CCP1CON_DC1B = 0 -- Sluk for PWM igen
else
CCPR1L = 0
end if
delay_10us(50) -- Hold pause i 0,5 ms
end loop
delay_1ms(10) -- vent 10 ms uden pulser
end loop
Koden ligger i denne ZIP-fil.
Ideen er at der loopes 10 gange, hvor der først sendes med 38 kHz i 0,5 ms, og derefter slukkes den i 0,5 ms, så der kommer 10 burst på hver 0,5 ms hen over en periode på 10 ms, hvorefter der holdes en pause på 10 ms.
Det er ikke til at måle dette på sendersiden, da pulserne bliver meget tynde, men modtageren reagerer fint på signalerne, som det kan ses her:
Kode til Arduino
I dette GitHub bibliotek ligger der eksempler på både sending og modtagelse, samt afkodning af forskellige typer fjernbetjeninger
Referencer
- ↑ http://www.sbprojects.com/knowledge/ir/index.php SB Projects, med generel forklaring, og dokumentation af forskellige protokoller
- ↑ http://www.sbprojects.com/knowledge/ir/nec.php SB Project NEC protokol
Moduler på Holstebro HTX | |||||||
---|---|---|---|---|---|---|---|
Tastaturer | Displays | AD-konvertering | I/O-ekspander | Serielt | Interface | Færdige | Andre |
RC-tast - AD-tast - M_tast | ALCD - LCD | ADC_holst - ADC mcp3201 - mcp3208 |
input - output | Seriel_holst - Serial hardware Serial hw int cts - Serial software |
Stepmotor - RFID RGB - RF-link - Afstand |
Humidity - Analog temp - Dig temp Accelerometer |
Rotary Encoder |
Oversigt over Hardware Moduler på Holstebro HTX