Infra Rood Remote Control Analyzer

In infra rood afstandbediening zijn meerdere soorten.
De belangrijkste zijn de Philips varianten RC-5 en RC-6 en diverse Japanse varianten die dicht bij elkaar komen zoals NEC en JVC.
De bovenstaande links verwijzen naar de site: http://www.sbprojects.com/-knowledge/ir/index.php die ook nog over meerdere systemen informatie geeft.
Zoals op de boven genoemde site beschreven, bestaat infra rood communicatie uit het versturen van licht puls treintjes, de meest gebruikte frequenties liggen tussen de 36 en 38Khz. Hiervoor zijn diverse ontvang modules verkrijgbaar, die bestaan uit een infra rood detector(diode), versterker, filter en demodulator.
Wat deze modules eigenlijk doen is het puls treintje omzetten in een blokgolf en verder alle storende signalen (zon, tl licht e.d.) zo veel mogelijk uitschakelen.
De ontvangst modules zoals TSOP1738 zijn eenvoudig aan te sluiten op een ingangs poort van een microcontroller. (wel is er soms een pull up weerstandje nodig). Het onderstaande schema laat zien hoe dit te doen op een PIC 18F25K22 of pin equivalent type.
28PIC basis print als kit met de 18F25K20 en 3,3V regulatorR1 en C2 dienen om de voedingsspanning van de TSOP1738 zoveel mogelijk te ontkoppelen van de hoofd voedings-spanning, daar de modules erg gevoelig zijn. R2 is een pull up weer-stand (de TSOP1738 heeft een interne pull up van 80K). Het 2×16 display, de LED en de speaker zijn optioneel. Alle output gaat ook via de seriële poort.

Bovenstaand schema is eenvoudig op het 28PIC moederbordje te realiseren.
In de 18F25K22 programmeren we een programmaatje dat de lengte van de pulstreintjes en de pauzes die daar op volgen laat zien. het programma laat tot 100 pulstreintjes zien (via seriële poort). Met het windows programma “Poort-tester” (Knutselaar’s simpele serial port terminal) kan de seriële output zichtbaar gemaakt worden. Het FTDI FT230 opsteek bordje kan hier goed gebruikt worden om een Com poort via een USB verbinding te creëren. Een tweede mogelijkheid is de PICkit2 Uart Tool (hoofdstuk 7) te gebruiken.
Op het 16×2 display worden de ontvangen bytes getoond, (in de seriële output ook overigens) dit zijn meestal 4 bytes. De tweede regel toont de vier bytes van een volgende verzending als deze binnen 200ms binnenkomt (sommige fabrikanten (pioneer) hebben onder bepaalde toesten een dubbel code zitten).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
'****************************************************************************
'*  Name    : IR remote control analyser                                    *
'*  Author  : Knutselaar.eu                                                 *
'*  Notice  : Copyright (c) 2012 Knutselaar.eu                              *
'*          : All Rights Reserved                                           *
'*  Date    : 10 May 2012                                                   *
'*  Version : 1.0                                                           *
'*  Compiler: Proton Basic of Amicus18                                      *
'*  Notes   : IR remote control timing naar serieele poort                  *
'*          : (gebruik SerialPort Tester 2.0 (download www.knutselaar.eu))  *
'*          : IR remote data naar display en serieele poort (NEC en         *
'*            aanverwanten.                                                 *
'*          : Werkt deels (alleen timing) voor RC5 and RC6                  *
'****************************************************************************
Device 18F25K22
                                                                 
CONFIG_START                                                    
     FOSC = INTIO67         ;Internal oscillator block, port function on RA6 and RA7  
     FCMEN = Off            ;Fail-Safe Clock Monitor disabled
     IESO = Off             ;internal external switchover mode
     ;PWRT = On             ;power-up timer For 18F25K20
     PWRTEN = On            ;power-up timer For 18F25K22
     BOREN = On             ;brown-out reset
     ;BORV = 27             ;brown-out reset value (2,7V) For 18F25K20
     BORV = 285             ;brown-out reset value (2,85V) for 18F25K22
     WDTEN = Off            ;watchdog timer
     WDTPS = 128            ;1:128 WDT prescalar
     PBADEN = Off           ;analog port B<4:0>
     STVREN = On            ;stack overflow reset
     LVP = Off              ;low voltage programming
     XINST = Off            ;Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
     Debug = Off            ;no debug
CONFIG_END

    XTAL 64
   
    HSERIAL_BAUD  = 9600          ; Transmissiesnelheid van de data over de bus
    HSERIAL_RCSTA = %10010000     ; Bit7:Enable serial port / Bit4:Continu ontvangen
    HSERIAL_TXSTA = %00100000     ; Bit5:Transmitpin ingeschakeld (TXEN (Transmit ENable) = 1)
    HSERIAL_CLEAR On  

    Symbol IR_PIN      = PORTB.0  ; 38Khz ir ontvanger op poort B.0
    Symbol Speaker     = PORTC.5
    Symbol LEDGreen    = PORTA.5

    Dim u             As Byte    ; serieel uit puls teller
    Dim v             As Byte    ; hulp variable
    Dim w             As Byte    ; byte teller
    Dim x             As Word    ; timing teller voor puls aan
    Dim y             As Word    ; timing teller voor puls uit
    Dim z             As Byte    ; puls teller
    Dim bitStart      As Byte
    Dim onArray[100]  As Word    ; puls tijd aan array
    Dim offArray[100] As Word    ; puls tijd uit array
   
    Dim a_bit         As Byte    ; eerste ontvangst byte
    Dim b_bit         As Byte
    Dim c_bit         As Byte
    Dim d_bit         As Byte    ; vierde ontvangst byte
    Dim e_bit         As Byte    ; eerste ontvangst byte tweede commando (binnen 200ms)
    Dim f_bit         As Byte
    Dim g_bit         As Byte
    Dim h_bit         As Byte    ; vierde ontvangst byte tweede commando (binnen 200ms)
    Dim x_bit         As Byte
    Dim lowLimit      As Word
    Dim highLimit     As Word
   
    OSCCON = %01110000           ; 16Mhz intern osc
    OSCTUNE= %01000000           ; 4x PLL aan geeft 64Mhz
    ANSELA = %00000000           ; 18F25K22 poort A digitaal
    ANSELB = %00000000           ; 18F25K22 poort B digitaal
    ANSELC = %00000111           ; 18F25K22 Poort C RX,TX,C5,SCL en SDA digitaal
    ;ALL_DIGITAL TRUE             ; Alle poorten digitaal voor 18F25K20
 
    Clear                        ; wis geheugen
 
    Cls                          ; init display

    Sound Speaker , [115,20]
         
    Print At 1, 1,  "Knutselaar.eu   "
    Print At 2, 1,  "IR remote tester"
   
    DelayMS 2000

loop:

    While IR_PIN = 1 : Wend
    High LEDGreen                   ; groen aan
    For z = 1 To 99
        For x = 1 To 2000           ; max 20 ms timer
            If IR_PIN = 1 Then
                onArray[z] = x
                GoTo skipx  
            End If
            DelayUS 9               ; 9us + ongeveer 1uS reken tijd
        Next x
        skipx:
        For y = 1 To 20000          ; max 200 ms timer
            If  IR_PIN = 0 Then
                offArray[z] = y
                GoTo skipy
            End If
            DelayUS 9
        Next y
        Low LEDGreen
        GoTo timeout                ; timeout
        skipy:
    Next z
   
timeout:
    x = 0
    lowLimit = 70
    highLimit = 130
    HSerOut ["on        off ",13]
    HSerOut [DEC4 onArray[1],"   ",DEC5 offArray[1]," start",13]     ' start puls
    If onArray[1] < 300 Then                                ' te korte start puls
        HSerOut [DEC4 onArray[2],"   ",DEC5 offArray[2]," start",13]
        bitStart = 3
    Else
        bitStart = 2
    End If
    HSerOut [13]
    For u = bitStart To z
        If offArray[u] > 1400 Then                          ' >14 ms geen puls
            HSerOut ["on        off ",13]                   ' nieuwe start puls
            v = u
            x = 0
        Else
            If u <> z Then HSerOut [DEC4 onArray[u],"   ",DEC5 offArray[u],"   ",Dec x,13]  ' laatste niet printen
            If u > 1 And u = v +1 Then
                HSerOut [13]
            Else
                x = x + 1
            End If
        End If

        Select x
            Case 1  
                If offArray[u] < lowLimit Then x_bit.0 = 0
                If offArray[u] > highLimit Then x_bit.0 = 1
            Case 2
                If offArray[u] < lowLimit Then x_bit.1 = 0
                If offArray[u] > highLimit Then x_bit.1 = 1
            Case 3
                If offArray[u] < lowLimit Then x_bit.2 = 0
                If offArray[u] > highLimit Then x_bit.2 = 1
            Case 4
                If offArray[u] < lowLimit Then x_bit.3 = 0
                If offArray[u] > highLimit Then x_bit.3 = 1
            Case 5
                If offArray[u] < lowLimit Then x_bit.4 = 0
                If offArray[u] > highLimit Then x_bit.4 = 1
            Case 6
                If offArray[u] < lowLimit Then x_bit.5 = 0
                If offArray[u] > highLimit Then x_bit.5 = 1
            Case 7
                If offArray[u] < lowLimit Then x_bit.6 = 0
                If offArray[u] > highLimit Then x_bit.6 = 1
            Case 8
                If offArray[u] < lowLimit Then x_bit.7 = 0
                If offArray[u] > highLimit Then x_bit.7 = 1
        End Select
        If x = 8 Then
            w = w + 1                    ' byte teller
            Select Case w
                Case 1
                    a_bit = x_bit
                Case 2
                    b_bit = x_bit
                Case 3
                    c_bit = x_bit
                Case 4
                    d_bit = x_bit
                Case 5
                    e_bit = x_bit
                Case 6
                    f_bit = x_bit
                Case 7
                    g_bit = x_bit
                Case 8
                    h_bit = x_bit
            End Select
        End If
        If x = 8 Then                      ' scheiding 8 bits
            HSerOut [13]
            x=0
        End If
    Next u
   
    If z > 4 Then
        Print At 1,1, HEX2 a_bit, " ", HEX2 b_bit, " ",HEX2 c_bit, " ",HEX2 d_bit,"       "
        Print At 2,1, HEX2 e_bit, " ", HEX2 f_bit, " ",HEX2 g_bit, " ",HEX2 h_bit,"       "
   
        HSerOut ["Data:",13]
        HSerOut [ HEX2 a_bit, " ", HEX2 b_bit, " ",HEX2 c_bit, " ",HEX2 d_bit,13 ]
        HSerOut [ HEX2 e_bit, " ", HEX2 f_bit, " ",HEX2 g_bit, " ",HEX2 h_bit,13 ]
    End If
   
    Clear
    Low LEDGreen
    Sound Speaker , [115,20]
    GoTo loop
   

End

Het bovenstaand programma werkt redelijk goed voor het NEC protocol en aanverwanten.
Dit soort protocollen bestaat uit een startpuls van ongeveer 9ms gevolgd door een pauze van +/- 4,5ms, daarna volgen pulsjes van ongeveer 0,5ms. de lengte van de pauzes die na deze korte pulsjes komen bepaald of er een “0” of “1” verzonden wordt. Totaal worden er op deze manier meestal 4 bytes verzonden (32 korte pulsjes). De eerste twee bytes vormen meestal het adres, het derde byte is meestal het commando, het vierde byte meestal het geinverteerde derde byte (ter controle), bij sommige wordt het vierde byte als extensie gebruikt en is er geen controle.
op http://learn.adafruit.com/ir-sensor vind je een soortgelijk programma voor de Arduino, het idee is dus niet helemaal ven mijzelf.

Download met .bas en .hex files voor de TSOP1738 en 18F25K22 plus schema TSOP17.zip




Hit Counter by Digits