IR Remote Control Rx and Tx for Philips RC-5 Protocol.


Author Message
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 3407
Posted: 08:27am 01 Oct 2024      

RC-6 Rx and Tx
Although I don't have any RC-6 devices to test it on scope traces of the output match those published by others on the net.
Tested ok going from one PicoMite to another.
RC-6 has provision for 8 different modes but it appears all consumer devices use mode 0. There is little I could find on the other modes so Tx only supports mode 0.
The Rx Sub should however be able to show the mode number other modes but might not decode them correctly.
' "IR Philips RC-6 Mode 0 Rx & Tx.bas"
'Option explicit
Dim integer RxPin=MM.Info(pinno GP0), TxPin=MM.Info(pinno GP1) ' set GPxx for IR Tx & Tx
Dim Integer N = 44 ' expected maximum number of transitions, plus a few

Dim integer m, b(N), c(N\2), dev, key, r(N*2), Tend, Toggle, Type'Type = RC6 Mode or Field
Dim Float T
SetPin RxPin, intl, IR_RC6_Rx 'wait for IR activity to pull IRpin low
SetPin TxPin, DOUT

Print " To send commands un-comment the lines near the end of the program then:-"
Print " Toggle toggles between 0 and 1 on each Key press to distinguish from auto-repeat"
Print " Device = device code, 0 to 255"
Print " Key = Key code, 0 to 255." : Print
Print " Press a key on the IR remote control to record the RC-6 code" : Print

Sub IR_RC6_Rx
 T=Timer :Tend = T
 SetPin RxPin, off : SetPin RxPin, Din :m=1 :b(0)=0

 Do While m<(N-1)And(Timer-T<300) 'get pulses/pauses & convert to Manchester bits
  Do While (Pin(RxPin)=0)And(Timer-T<300) :Loop
  If (Timer-T)>3 Then Exit Do
  b(m)=1
  If m=11 Then 'toggle is double normal pulse
    If (Timer-T)>1.2 Then:Inc m :b(m)=1:EndIf
   Else
    If (Timer-T)>0.66 Then:Inc m :b(m)=1:EndIf
  EndIf
  T=Timer :Inc m
  Do While (Pin(RxPin)=1)And(Timer-T<300):Loop
   If (Timer-T)>1.6 Then Exit Do
   b(m)=0
  If m=10 Then 'toggle is double normal pause
    If (Timer-T)>1.33 Then:Inc m :b(m)=0:EndIf
   Else
    If (Timer-T)>0.66 Then:Inc m :b(m)=0:EndIf
  EndIf
  T=Timer :Inc m
 Loop

 SetPin RxPin, off' : b(N)=Timer-Tend : m=0 'disable interrupt while processing
 If b(4)+b(5)+b(6)+b(7)+b(8)=0 Then GoTo no.data
'  Print :Print "IR BitStream - b() ";:Math V_Print b()

 m=2
 Do While m<(N) 'convert pairs of Manchester half-bits to ordinary bits (oposite of RC-5)
  If (b(m)=0)And(b(m+1)=1) Then c(m\2-1)=0 '01 = 0
  If (b(m)=1)And(b(m+1)=0) Then c(m\2-1)=1 '10 = 1
  Inc m, 2
 Loop
 Print "c()=bits  ";:Math V_print c()
 Type = c(1)*4+c(2)*2+c(3) : toggle=c(4) : dev=0 : key=0

 'ctrl toggles on each key press to distinguish autorepeat from double press
 For m=5 To 12 : Inc dev,dev + c(m) : Next 'assemble Device code
 For m=13 To 20 : Inc key,key + c(m) : Next 'assemble Key code

 Print "Mode";type;"  Toggle";toggle;"  Dev";dev;"  Key";key :Print

'un-comment the following lines to re-transmit the received code to verify operation
'  Pause 3000
'  IR_RC6_Tx 1, toggle, dev, key 'resend the received code after 3S
'  Pause 83
'  IR_RC6_Tx 1, toggle, dev, key 'resend the received code after 3S
'  toggle=Not toggle

 no.data:
 T=0
 Math set 0, b()
 Math set 0, c()
 Pause 400 'block repeat codes
 SetPin RxPin, intl, IR_RC6_Rx 're-enable interrupt for next key

End Sub

Sub IR_RC6_Tx(toggle, dev, key) As integer
 toggle=toggle And 1 : dev=dev And 255 : key=key And 255 ': type=type And 7 'only uses Mode 0
 Local integer ord(19), bs(1993), m=0, n, z
 Math set 14, bs() 'load BitStream array with 36kHz half cycles (14uS)
 'assemble ordinary bit array
'  For n=3 To 0 Step -1 : ord(n) = (dev >> m) And 1 : Inc m :Next
'  ord(4)=toggle
 m=0 : For n=15 To 8 Step -1 : ord(n) = (key >> m) And 1 : Inc m :Next
 m=0 : For n=7 To 0 Step -1 : ord(n) = (dev >> m) And 1 : Inc m :Next

 Print "toggle";toggle,"dev";dev,"key";key,, "ord()  ";:Math V_print ord()
'convert ordinary bits to pairs of Manchester half-bits and load into BitStream array -
'merging adjacent high or low pairs of half-bits into long highs or long lows,
' without causing inversions in the BitStream

'half cycle at 36kHz = 14uS = 32 half cycles per short pulse, 65 per long pulse
  bs(193)=1333 : bs(225)=444 : bs(257)=444' : bs(289)=444 ' Start pulse + Mode=0 3 bits
 If toggle=0 Then bs(289)=889 'long pause - long pulse
 If toggle=1 Then bs(355)=889 'long pulse - long pause
 m=355
 If (toggle=1) And (ord(0)=1) Then bs(355)=444 : Inc m,32 : EndIf
 If (toggle=1) And (ord(0)=0) Then bs(355)=1333 : Inc m,32 : EndIf
 If (toggle=0) And (ord(0)=1) Then Inc m,32 : bs(m)=444 : EndIf
 If (toggle=0) And (ord(0)=0) Then bs(355)=444 :Inc m,32 : EndIf

 For n=0 To 15
  If (ord(n)=1)And(ord(n+1)=1) Then : bs(m)=444 : Inc m,32 : EndIf
  If (ord(n)=1)And(ord(n+1)=0) Then : bs(m)=889 : Inc m,32 : EndIf
  If (ord(n)=0)And(ord(n+1)=1) Then : Inc m,32 : bs(m)=444 : EndIf
  If (ord(n)=0)And(ord(n+1)=0) Then : bs(m)=444 : Inc m,32 : EndIf
 Next

'  BitBang BitStream TxPin, 868, bs() 'for ARMMiteF4
 Device BitStream TxPin, 868, bs() 'for PicoMite
 Pin(TxPin) = 0 'ensure correct polarity for next run
 Pause 83
 Device BitStream TxPin, 868, bs() 'for PicoMite
 Pin(TxPin) = 0 'ensure correct polarity for next run
'  Print : Math V_print bs() :Print

End Sub

Do 'un-comment the next 2 lines to send data
'  Input "Enter RC-6 Data:- toggle, Device, Key "; toggle,dev,key
'  IR_RC6_Tx toggle,dev,key
'  toggle = Not toggle
 Pause 300
Loop
End

Tx usage:-
IR_RC6_Tx toggle, device, key
.
Edited 2024-10-01 22:27 by phil99

Footnote added 2024-10-03 11:36 by phil99
Sub IR_RC6_Tx needed some tidying up, so here it is.
Sub IR_RC6_Tx(toggle, dev, key) As integer
 toggle=toggle And 1 : dev=dev And 255 : key=key And 255 'only uses Mode 0
 Local integer ord(16), bs(870), m=0, n
 Math set 14, bs() 'load BitStream array with 36kHz half cycles (14uS)
 'assemble ordinary bit array
 m=0 : For n=15 To 8 Step -1 : ord(n) = (key >> m) And 1 : Inc m :Next
 m=0 : For n=7 To 0 Step -1 : ord(n) = (dev >> m) And 1 : Inc m :Next

 Print "toggle";toggle,"dev";dev,"key";key,, "ord()  ";:Math V_print ord()
 'fixed 3 bit Field / Mode number = 0 for consumer electronics
 'convert ordinary bits to pairs of Manchester half-bits and load into BitStream array -
 'merging adjacent high or low pairs of half-bits into long highs or long lows,
 ' without causing inversions in the BitStream

 'half cycle at 36kHz = 14uS = 32 half cycles per short pulse, 65 per long pulse
  bs(193)=1333 : bs(225)=444 : bs(257)=444 ' Start pulse + Mode=0 3 bits
 If toggle=0 Then bs(289)=889 'long pause - long pulse for toggle bit
 If toggle=1 Then bs(355)=889 'long pulse - long pause
 m=355
 If (toggle=1) And (ord(0)=1) Then bs(355)=444
 If (toggle=1) And (ord(0)=0) Then bs(355)=1333
 If (toggle=0) And (ord(0)=1) Then bs(m+32)=444
 If (toggle=0) And (ord(0)=0) Then bs(355)=444
 Inc m,32

 For n=0 To 15
  If (ord(n)=1)And(ord(n+1)=1) Then bs(m)=444
  If (ord(n)=1)And(ord(n+1)=0) Then bs(m)=889
  If (ord(n)=0)And(ord(n+1)=1) Then bs(m+32)=444
  If (ord(n)=0)And(ord(n+1)=0) Then bs(m)=444
  Inc m,32
 Next

'  BitBang BitStream TxPin, 868, bs() 'for ARMMiteF4
 Device BitStream TxPin, 868, bs() 'for PicoMite
 Pin(TxPin) = 0 'ensure correct polarity for next run
 Pause 83
 Device BitStream TxPin, 868, bs() 'for PicoMite
 Pin(TxPin) = 0 'ensure correct polarity for next run
'  Print : Math V_print bs() :Print

End Sub