By mjturner
January 2004
Given that I was seeking help here for Infrared signals I
thought it best to post what I had discovered.
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 picbasic 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:
PR2=137
CCPR1L=68
TRISC.2=0
CCP1CON=%00001100
T2CON=%00000100
Notice that 137 has shown up again. This is the figure I got earlier from adding
the 1 and 0 time periods together. As I'm still using a 20Mhz XTAL the number
matches. The 68 comes from dividing 137 by 2. This results in a 50% duty cycle
(approx). If you wanted a 25% then divide 137 by 4.
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.net)
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
Download program
For reference on IR I'd recommend the following
| 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...2/msg00669.html http://www.vishay.com/docs/fmod_data_formats.pdf |
| How to use Timer1 on a pic: | http://users.picbasic.org/index.php...wtodetail&id=30 |
( Last revision : 7/01/04)