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:16am 23 Sep 2024      

To go with the NEC protocol here is Philips RC-5
Sub IR_RC5_Rx and Sub IR_RC5_Tx are the useful bits in this program.
The rest just reads and decodes the Manchester protocol, sending the result to the console.
Then transmits the IR code 3 seconds later to the device so you can verify that it is correct. The codes it produces match the published ones so it should be ok.

The older version of RC-5 sends a Start pulse, a Control bit to distinguish a double press from auto-repeat, a 5 bit device code and a 6 bit key code.
As that only gives 64 key codes the current version has a Field bit between the Start and Control bits to provide another 64 key codes.
Field = 1 for keys 0 to 63
Field = 0 for keys 64 to 127
Control alternates between 0 and 1 on each key press.

Sub IR_RC5_Tx should work with all the above but the devices I have (Philips audio system & Schaub Lorenz TV) both use Start = 1 & Field = 1 so the others are untested.
For old devices that don't use the Field bit set the Start bit to 0 and the Field bit to 1. The Field bit becomes the Start bit.

Usage: IR_RC5_Tx start, field, control, device, key
Eg: IR_RC5_Tx 1,0,17,63 turns on the sterio and IR_RC5_Tx 1,1,17,12 turns it off.

If you want to modify the subs for your own projects there are plenty of comments and diagnostic prints to help.
' "IR Philips RC-5 code Rx & Tx.bas"
'Option explicit
Dim integer RxPin=MM.Info(pinno GP1), TxPin=MM.Info(pinno GP0) ' set GPxx for IR Tx & Tx
Dim Integer N = 29 ' expected maximum number of transitions, plus a few

Dim integer m, b(N), c(N\2), dev, key, r(N*2), strt=1, Tend
Dim Float T
SetPin RxPin, intl, IR_RC5_Rx 'wait for IR activity to pull IRpin low
SetPin TxPin, DOUT : Dim integer ctrl '<-- only needed for Sub IR_RC5_Tx demo

Print " To send commands un-comment 2 lines in the loop at the end of the program then:-"
Print " Start = 1 for new RC-5, Start = 0 for original (obsolete) RC-5"
Print " Field = 1 for Key codes 0 to 63, Field = 0 for Key codes 64 to 127"
Print " Control toggle between 0 and 1 on each Key press to distinguish from auto-repeat"
Print " Device = device code, 0 to 31"
Print " Key = Key code, 0 to 63. Field = 0 shifts these up by 128" : Print
Print " Press a key on the IR remote control to record the RC-5 code" : Print

Sub IR_RC5_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)>2.2 Then Exit Do
  b(m)=1:If (Timer-T)>1.6 Then:Inc m :b(m)=1:EndIf
  T=Timer :Inc m
  Do While (Pin(RxPin)=1)And(Timer-T<300):Loop
  If (Timer-T)>2.2 Then Exit Do
   b(m)=0:If (Timer-T)>1.6 Then:Inc m :b(m)=0:EndIf
  T=Timer :Inc m
 Loop

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

 If b(N-2)=0 And b(N-3)=0 Then strt = 0 'detect obsolete RC-5 code (no field bit)
 If b(N-2)=1 Xor b(N-3)=1 Then strt = 1 'detect new RC-5 code (with field bit)
 If strt = 0 Then
  For m=(N-2) To 0 Step -1
   b(m+2)=b(m)
  Next
  b(0)=0 : b(1)=0
 EndIf
 m=2
 Do While m<(N) 'convert pairs of Manchester half-bits to ordinary bits
  If (b(m)=0)And(b(m+1)=1) Then c(m\2-1)=1
  If (b(m)=1)And(b(m+1)=0) Then c(m\2-1)=0
  Inc m, 2
 Loop
 Print "c()=bits  ";:Math V_print c()
 field=c(0): ctrl=c(1): dev=0: key=0

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

 If strt=1 Then Print "field";field;"  control";ctrl;"  dev";dev;"  key";key
 If strt=0 Then Print "old RC-5 no field.   control";ctrl;"  dev";dev;"  key";key

'  Pause 3000 : IR_RC5_Tx 1, field, ctrl, dev, key 'resend the received code after 3S
'  ctrl=Not ctrl

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

End Sub

Sub IR_RC5_Tx(strt, field, ctrl, dev, key) As integer
 strt=strt And 1 : field=field And 1 : ctrl=ctrl And 1 : dev=dev And 31 : key=key And 63
 Local integer ord(14), bs(900), m=0, n, z
 Math set 14, bs() 'load BitStream array with 36kHz half cycles (14uS)
 'assemble ordinary bit array
 For n=6 To 2 Step -1 : ord(n) = (dev >> m) And 1 : Inc m :Next
 m=0
 For n=12 To 7 Step -1 : ord(n) = (key >> m) And 1 : Inc m :Next
 If strt = 0 Then field = 1
 ord(0)=field : ord(1)=ctrl

'  Print "f";field,"c";ctrl,"dev";dev,"key";key,, "ord()";:Math V_print ord()' :Print
' Print "  b() ";:Math V_Print b()' :Print
'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 = 64 or 65 half cycles per short pulse, 129 per long pulse
  m=0
 If strt=1 Then m=64 'Else m=1 'm=65 -> start pulse
 If (field=1)And(strt=1) Then : bs(65)=889 :Inc m,65 : EndIf
 If (field=0)And(strt=1) Then : Inc m,64 : bs(m)=889 : EndIf

 If strt = 0 Then m=65

 For n=0 To 11
  If (ord(n)=1)And(ord(n+1)=1) Then : bs(m)=889 : Inc m,64 : EndIf
  If (ord(n)=1)And(ord(n+1)=0) Then : Inc m,64 : bs(m)=889 : EndIf
  If (ord(n)=0)And(ord(n+1)=1) Then : bs(m)=1778 : Inc m,64 : EndIf
  If (ord(n)=0)And(ord(n+1)=0) Then : bs(m)=889 : Inc m,64 : EndIf
 Next
 Inc m

'  BitBang BitStream TxPin, m, bs() 'for ARMMiteF4
 Device BitStream TxPin, 832+66*strt, bs() 'for PicoMite
 Pause 88
 Device BitStream TxPin, 832+66*strt, 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-5 Data:- Start, Field, Control, Device, Key ";strt,field,ctrl,dev,key
 'IR_RC5_Tx strt,field,ctrl,dev,key
 Pause 400
Loop
End

Getting the BitStream to work properly with Manchester half-bits realy taxed my geriatric brain. Senility is advancing.

Edit 29/09/2024
The code above has been edited. A closer inspection of the output for the old version of RC-5 was not quite right. Should now be ok, but still can't test on an actual device.
However sending from one Pico to another does work and scope pics of the data appear to match the specification.

Also added automatic detection of old RC-5 to IR_RC5_Rx Sub.
Output when receiving.
RUN
Press a key on the IR remote control to record the RC-5 code
field 1  control 0  dev 1  key 53
field 1  control 1  dev 1  key 0
field 1  control 0  dev 17  key 63
field 1  control 1  dev 17  key 7
field 1  control 0  dev 18  key 63
old RC-5 no field.   control 1  dev 28  key 0
field 0  control 0  dev 20  key 63
field 0  control 1  dev 20  key 8
field 0  control 0  dev 20  key 54
field 1  control 1  dev 20  key 63

Edited 2024-09-29 14:31 by phil99