The first problem I faced was to work out if the IR signal was modulated or not (most are from what I've read), and if so what frequency it was modulated at.
The built in IR on the Proton development board is no good for this as it includes a built in demodulator fixed at 38Khz (if I remember). It will pick up outside of that range however its sensitivity reduces the further away you get from its primary frequency. In any case its important to know the real frequency the signal is modulated at if you want to retransmit it.
To work out the modulation frequency I used part of the CIR (http://www.ziplabel.com/cir) project. I don't recommend creating this project as the software won't run under XP/2k/NT and it gives you a modulated signal with no idea how long each pulse is. I only created the Receiver section, but connected D25-13 to the +5v rail and D25-18 to the common rail. I then connected D25-3 to C0 on the PICŪ. To get enough resolution on the signal I had to use a 20Mhz XTAL. I used the code attached with the re-send section disabled. I'd like to thank the PICŪ basic users site - I used the example timer code on that to make the signal recorder.
The results fed back to the serial port look a real mess, however all we are really interested in is a block of repeating numbers. These are always a 1 followed by a 0 in the left column. i.e.
1 - 92 0 - 45 1 - 92 0 - 45 1 - 92 0 - 45 ......
The ratio of a signal received to no signal received will depend on the output of your remote/device and the distance you hold it from the phototransistor. It isn't really relevant as all we are looking for is the peak-to-peak distance, this can be calculated by adding the 1 value to the 0 value, i.e. 92+45 in this case. The result is the total number of instruction cycles that the whole pulse took. In this case 137.
The figure we have at the moment is instruction cycles, so multiply this by 4 to give us the clock ticks. 137 * 4 = 548. Given that this is a 20Mhz clock divide 20,000,000 by 548. The result is the number of Hz your signal is modulated at. 36496Hz in this case. Therefore the signal I detected was modulated at 36.5Khz.
As a point of interest I looked at the board that originated the signal and noticed a crystal on it marked as 1.842Mhz. If you divide this by 50 you get 0.03684, very close to the frequency I detected. Tracing the ciruit I noticed this fed in to a binary adder which I guess generated the modulation. I'm not sure how much of the difference is down to my routine or the hardware being off slightly.
Now we have detected the modulation frequency, we know if we can get a valid signal from the Proton built in IR receiver. In my case its close enough that I can get a reasonable range, although I've dug around and found that these receivers are available in various frequencies, including 36.7Khz - ideal for my project.
The step I had to do is capture a signal and send it back out again. The challenge here is that the signal received has to be demodulated (easy enough using the built in receiver), stored, then re-modulated and retransmitted.
To achieve the re-modulation I used a very simple circuit. Not being an electronics expert some or all the resistors may not be required - but it works with them so I'm leaving them there! I connected C1 to a 200ohm resistor and then connected the other end of the resistor to the base on a transistor (BC549), then did the same with C2. I then connected the collector of one of the transistors to the emitter of the other transistor. The rest of the circuit looks something like this:
+5 ----- 40ohm ---- IRLED -- IRLED --- BC549 --- BC 549 ---- 0v
The two BC549s operate is an AND gate. I then used C1 to replay the received signal and C2 to generate the carrier frequency.
The 18F452 has a built in Pulse Width Modulator. Perfect for my needs! Now because of the way the phototransistor works its hard to know what the duty cycle to use is. I guessed it would be 50%. This seems quite common, although some signals use 25% to reduce power requirements. Duty cycle is the ratio of signal on to signal off within each pulse of the modulation.
The PWM is quite an odd thing to program. The first problem is that Proton+ doesn't support above 32767 as a frequency. However I need about 4000 above this! Therefore we have to do our own calculations and program the registers. In this case:
Code:
PR2=137 CCPR1L=68 TRISC.2=0 CCP1CON=%00001100 T2CON=%00000100
Once the frequency is being generated we can simply turn C1 on and off to send the modulated signal. All that is required is to turn it on and off for the required time periods.
I used the attached program to receive the signal, store it in memory and then retransmit it out after a short delay (in my case this was required as I'm using equipment that takes time to power up and is very sensitive so had to be off during the record stage. To make it easier I made various LEDs go on to indicate the status within the program. LED0 is lit when a signal is received, LED1 is lit when the signal is totally received or the IR buffer is full. LED2 is lit to indicate 5 seconds left before replay. Then LED4 is lit while the signal is sent.
The end result of this program is that by retransmitting the signal you should be able to see if the program received a valid signal or not. If it is valid then the data you received via the serial port will be a valid IR signal.
My next step was to work out what this IR signal contained. This is the result of one capture:
0 6
1 22397
0 1835
1 2417
0 1700
1 2297
0 1830
1 2152
0 2095
1 2032
0 1970
1 2032
0 2100
1 2147
0 8330
1 1907
0 4300
1 1907
0 4175
1 8387
0 1975
1 6312
0 33353
Fortunately for me it was quite simple. All the signals I received of a certain type were the same length. i.e. they lasted the same amount of time. After a quick look I realised that 1s were signified by a 2000 long pulse and 0s by a 2000 long zero state, and that was it! Obviously you have to allow a certain amount of error in the received signal either direction. Also I noticed there was always a 22000 long lead in pulse and a lead out pulse of at least 30000, although I don't think the system looks for this. There are many ways of encoding the 1s and 0s, check out the links at the end.
When I broke the bit stream down this is what resulted:
010101010101000010010011110111
It is made up of 3 bytes 8 bits long. Always with a leading 0 and trailing 1. i.e.
0 10101010 1 0 10000100 1 0 01111011 1
The way this system validates its code appears to be by inverting the byte. The 2nd byte is the inverse of the 3rd byte. The 1st byte appears to be a command type indicator. While the 2nd/3rd byte is the data.
I've investigated other packets of data sent over IR on this system, The above are very simple packets, however there are much more complex packets sent that use what I guess is a CRC.
Any feedback ( mjt@vex.netThis e-mail address is being protected from spam bots, you need JavaScript enabled to view it ) on this would be most welcome. This is the first time I'm posting something containing info rather than asking for help, so would like to know if anyone finds it helpful!
Mike
Code:
XTAL = 20
LCD_DTPIN = PORTD.4
LCD_RSPIN = PORTE.0
LCD_ENPIN = PORTE.1
LCD_INTERFACE = 4 ' 4-bit Interface
LCD_LINES = 2
LCD_TYPE = 0
SCL_PIN = PORTC.3
SDA_PIN = PORTC.4
SERIAL_BAUD = 19200
RSOUT_PIN = PORTC.6
RSOUT_MODE = TRUE
RSOUT_PACE = 1
RSIN_PIN = PORTC.7
RSIN_MODE = TRUE
HSERIAL_BAUD = 19200 ' Set baud rate to 9600
HSERIAL_RCSTA = %10010000 ' Enable serial port and continuous receive
HSERIAL_TXSTA = %00100100 ' Enable transmit and asynchronous mode
HSERIAL_CLEAR = On ' Enable Error clearing on received characters
KEYPAD_PORT = PORTB
CCP1_PIN = PORTC.2
CCP2_PIN = PORTC.1
Symbol T300 = 3313 NO_LIST
Symbol N300 = 3313 + $4000 NO_LIST
Symbol T600 = 1646 NO_LIST
Symbol N600 = 1646 + $4000 NO_LIST
Symbol T1200 = 813 NO_LIST
Symbol N1200 = 813 + $4000 NO_LIST
Symbol T2400 = 396 NO_LIST
Symbol N2400 = 396 + $4000 NO_LIST
Symbol T4800 = 188 NO_LIST
Symbol N4800 = 188 + $4000 NO_LIST
Symbol T9600 = 84 NO_LIST
Symbol N9600 = 84 + $4000 NO_LIST
Symbol OT2400 = 396 + $8000 NO_LIST ' Open True
Symbol OT1200 = 813 + $8000 NO_LIST ' Open True
Symbol OT9600 = 84 + $8000 NO_LIST ' Open True
Symbol OT300 = 3313 + $8000 NO_LIST ' Open True
Symbol ON2400 = 396 + $4000 + $8000 NO_LIST ' Open Inverted
Symbol ON1200 = 813 + $4000 + $8000 NO_LIST ' Open Inverted
Symbol ON9600 = 84 + $4000 + $8000 NO_LIST ' Open Inverted
Symbol ON300 = 3313 + $4000 + $8000 NO_LIST ' Open Inverted
Symbol HOME = 1 NO_LIST
Symbol BELL = 7 NO_LIST
Symbol BKSP = 8 NO_LIST
Symbol TAB = 9 NO_LIST
Symbol CR = 13 NO_LIST
ALL_DIGITAL = TRUE ' Set PORTA and PORTE to all digital
Symbol IRTRAN=PORTC.0
Input IRTRAN
Dim BufferPos As Byte
Dim BitLength[128] As Word
Dim BitState[128] As Byte
Dim IRCOUNT As Word
Dim IROLDSTATE As Byte
Dim IRNEWSTATE As Byte
Dim BufCounter As Byte
Dim TIMER1 As TMR1L.Word
Device 18F452
DelayMS 1000
RSOut "I AM AWAKE",13,10
CheckStart:
IRCOUNT=0
IROLDSTATE=0
IRNEWSTATE=0
BufferPos=1
Output PORTD.0
Low PORTD.0
Input IRTRAN
While IRTRAN=1 : Wend
High PORTD.0
Clear TIMER1
T1CON=%00000001
ReceiveLoop:
Input IRTRAN
While IRTRAN=1
If TIMER1>60000 Then GoTo ReceiveComplete
Wend
T1CON=%00000000
BitLength[BufferPos]=TIMER1
Clear TIMER1
T1CON=%00000001
BitState[BufferPos]=0
Inc BufferPos
Input IRTRAN
While IRTRAN=0
If TIMER1>60000 Then GoTo ReceiveComplete
Wend
T1CON=%00000000
BitLength[BufferPos]=TIMER1
Clear TIMER1
T1CON=%00000001
BitState[BufferPos]=1
Inc BufferPos
If BufferPos<50 Then GoTo ReceiveLoop
ReceiveComplete:
Output PORTD.1
Output PORTD.2
High PORTD.1
Low PORTD.2
For BufCounter=1 To BufferPos-1
RSOut HEX BitState[BufCounter],",", Dec BitLength[BufCounter],13,10
Next BufCounter
RSOut "IR Signal End",13,10
DelayMS 5000
High PORTD.2
DelayMS 5000
High PORTD.4
RSOut "Sending IR Signal..."
Output PORTC.2
Output PORTC.1
Low PORTC.2
Low PORTC.1
' HPWM 1,127,3686
PR2=137
CCPR1L=68
TRISC.2=0
CCP1CON=%00001100
T2CON=%00000100
For BufCounter=1 To BufferPos-1
BitLength[BufCounter]=(BitLength[BufCounter]/5)
Next BufCounter
DelayMS 200
For BufCounter=1 To BufferPos-1
If BitState[BufCounter]=0 Then Low PORTC.1 : Else High PORTC.1
DelayUS BitLength[BufCounter]
Next BufCounter
Low PORTC.1
Low PORTD.0
Low PORTD.1
Low PORTD.2
Low PORTD.4
RSOut "Sent.",13,10
GoTo CheckStart
Useful circuit:
http://www.ziplabel.com/cir
Good IR basics and info on different protocols:
http://www.xs4all.nl/~sbp/knowledge/ir/ir.htm
Some good info, explains the differenced between photodiodes and phototransistors:
http://www.onsemi.com/pub/Collateral/AN1016-D.PDF
A bit of info on RC5:
http://www.linuxtv.org/mailinglists/.../msg00669.html
http://www.vishay.com/docs/fmod_data_formats.pdf
How to use Timer1 on a PICŪ:
http://www.protongeeks.com
contributed by mjturner.


Menu
Recent Articles


Using PDS with SPI GLCD based on ST7565R Controller
Graphic LCDs based on the ST7565 are cheaper then GLCDs with other controllers. SPI requires only four pins. If the circuit