'PICAXE code for decoding 32-bit Infrared remote control sequences. PICAXE must run at 8MHz. 'Timing of commands is critical. Commands and code structure have been carefully selected for ' fastest execution and smallest programme space due to 256-byte limitation of 08M, 14M and 20M. 'PulseOut command (commented out) can be used to observe synchronisation of PICAXE with IR pulse train ' 'v0.1 18-Jun-2008 206 bytes Initial demonstration routine by Peter Gee. ' #PICAXE 08M ' Symbol Start = 1 'Start pin goes high when header starts Symbol NotReady = 1 'Clock pin is idle high Symbol Ready = 0 'Clock pin is active low Symbol One = 0 'Data pin is low when a '1' is detected ' Symbol SynchPulse = 20 '100uS output pulse for debugging Symbol ValidData = $FF 'Data byte + complement byte = $FF means data is valid ' 'ymbol ValidDevice= $0D0D 'Akai VCR Device ID 'ymbol ValidDevice= $20DF ' LG TV Device ID Symbol ValidDevice= $B4B4 ' LG DVD Device ID 'ymbol ValidDevice= $7689 ' LG VCR Device ID ' Symbol Accumulator= b0 Symbol DummyReg = b1 'Register used to allow a short command for delay (~167uS) ' Symbol DeviceID = w2 Symbol DeviceIDLo = b4 'Storage for Symbol DeviceIDHi = b5 ' four Symbol Command = b6 ' bytes Symbol Complement = b7 ' of data ' Symbol Header = w4 Symbol HeaderLo = b8 'Optional timer for IR Header start pulse Symbol HeaderHi = b9 'Optional timer for IR Header 'off' period before first pulse of 32-bit data train ' Symbol CheckSum = b10 ' Symbol OutPin = 0 'Leg 7 O Blue wire (debug outputs and error indication only) Symbol StartPin = pin1 'Leg 6 I/O White wire Detects start pulse Symbol DataPin = pin2 'Leg 5 I/O Green wire Detects Data as 1 or 0 Symbol ClockPin = pin3 'Leg 4 I Yellow wire Performs input clocking 'ymbol SynchPin = 4 'Pin available for debugging of timing on sound card oscilloscope 'ymbol DataOutPin = 4 'Pin available for transmission of data to another processor ' Init: SetFreq m8 ' MainLoop: Header = 0 '[2]Clear 2 byte-regs in 1 (saves 2 bytes) ' WaitHeader: If StartPin <> Start Then Goto WaitHeader '[4]Wait for Header ' 'From now on, timing is critical!! ' ' **** (Any) header has been detected ' 'PulsOut SynchPin, SynchPulse '[3]100uS Pulse (Grey wire) PulsOut cmd o/head is 235 (+ 100)uS ' PulsOut can be placed anywhere but will affect timing! HdrLoPeriod:Inc HeaderLo '[2]Available low period is shortened due to delayed start pulse indication If ClockPin = Ready Then Goto HdrLoPeriod '[4]Determine length of header pulse HdrHiPeriod:Inc HeaderHi '[2] If ClockPin = NotReady Then Goto HdrHiPeriod '[4]Determine length of header 'off' (high) period. Bit-stream starts now ' StartPulse: If ClockPin = Ready Then Goto StartPulse '[3]Wait for end of initial 'data' pulse (carrier burst) ' ' **** Receive 4 bytes of data ' Gosub Get1Byte 'First Byte 443uS (overhead of the Call/Return only) Byte0Bit0: If ClockPin = NotReady Then Goto Byte0Bit0 '[4]272uS minimum Wait for clock pulse If DataPin = One Then '[3] 288uS minimum Test for 0 or 1 Bit0 = 1 '[2] 174uS) EndIf DeviceIDHi = Accumulator '[2]194uS Save first byte ' Gosub Get1Byte 'Get first 7 bits of second byte Byte1Bit0: If ClockPin = NotReady Then Goto Byte1Bit0 If DataPin = One Then Bit0 = 1 EndIf DeviceIDLo = Accumulator ' Gosub Get1Byte 'Get first 7 bits of third byte Byte2Bit0: If ClockPin = NotReady Then Goto Byte2Bit0 If DataPin = One Then Bit0 = 1 EndIf Command = Accumulator ' Gosub Get1Byte 'Get first 7 bits of forth yte Byte3Bit0: If ClockPin = NotReady Then Goto Byte3Bit0 If DataPin = One Then Bit0 = 1 EndIf 'Timing is critical until this point Complement = Accumulator ' CheckSum = Command + Complement 'Check validity: b10 should be $FF if valid Debug '[2]Comment out if not debugging Pause 220 '[2]Delay ensures that repeat header is ignored ' If DeviceID = ValidDevice And CheckSum = ValidData Then 'Transmit command to main processor Else 'Reception error occurred (or other IR remote device used) Pause 300 PulsOut OutPin, 200 Pause 200 PulsOut OutPin, 200 EndIf Goto MainLoop ' ' **** Subroutines ***** ' ' Get1Byte: Load bits 7 to 1 into b0 ' Timing is critical when running at 8 MHz ' ' A whole '0' (low + high) should take 1.15mS ' A whole '1' (low + high) should take 2.3 mS ' Get1Byte: Accumulator = 0 '[2]Clear accumulator BBit7: If ClockPin = NotReady Then Goto BBit7 '[4]272uS minimum Wait for clock pin in 'Ready' state If DataPin = One Then '[3]288uS minimum Check data pin for a 'one' indication Bit7 = 1 '[2]174uS If so, set the appropriate bit of accumulator EndIf ' 560uS (for 0) or 734us (for 1) minimum to receive/decode 1 bit DummyReg = 0 '[2]Small delay ~167uS to ensure previous clock has restord ' BBit6: If ClockPin = NotReady Then Goto BBit6 If DataPin = One Then Bit6 = 1 EndIf DummyReg = 0 ' BBit5: If ClockPin = NotReady Then Goto BBit5 If DataPin = One Then Bit5 = 1 EndIf DummyReg = 0 ' BBit4: If ClockPin = NotReady Then Goto BBit4 If DataPin = One Then Bit4 = 1 EndIf DummyReg = 0 ' BBit3: If ClockPin = NotReady Then Goto BBit3 If DataPin = One Then Bit3 = 1 EndIf DummyReg = 0 ' BBit2: If ClockPin = NotReady Then Goto BBit2 If DataPin = One Then Bit2 = 1 EndIf DummyReg = 0 ' BBit1: If ClockPin = NotReady Then Goto BBit1 If DataPin = One Then Bit1 = 1 EndIf 'Can't do the bit0 test here due to the overheads of the 'Return' and also, saving the byte ' so, while 'Return' is performed between bits 1 and 0 (now), ' other overheads are performed at the end of bit 0 reception (calling routine). Return