Interfacing with a sensor, IR remotes
The aim of this project is to work with an IR photodiode, capture its signal and play it back at random intervals. The secret subproject is to record the "volume-down" signal of a friend's TV and hide the device somewhere in the vicinity.
TV remote controls use infrared signals to signal TV-s. The data is modulated on a 38-40KHz carrier signal. In other words a 38KHz pulsed IR signal is sent that is turned on and off to modulate the bits sent over. For example it could be 14 on pulses and 14 off pulses to send a "0" and 28 on pulses and 14 off pulses to send a "1".
The reason for the carrier signal is to allow strict band-pass filtering at the receiver. Foreign IR sources like lamps (even regular incandescent lightbulbs involve the 50Hz AC power fluctuation, the sun, a big hot oven - they all add to the reading from the IR photodiode and would interfere if we say did amplitude based modulation.
At design there is a choice to pick a ready-made integrated IR circuit that incorporate the photodiode, the amplifier and the bandpass filter. These IC-s can be connected to the MCU almost directly and can pick up signals at 10 meters or more.
As my first project I chose to go with a raw photodiode and with no amplification whatsoever. The downside is that the signal is very weak and only works at 10-15 cm. The upside is that I can use the MCU to properly detect the carrier frequency and replicate it more accurately. Also I can use less voltage as opamps used to amplify the signal need more voltage to be stable.
This is the circuit I came up with:
The photodiode is placed in reverse - with IR light shining on it it will force reverse current and build up voltage. The voltage DC component is removed using the capacitor and the signal is sent on to the AVR's comparator. At point blank the signal can get up to 1V (with 3V batteries), so I set the comparator low level at around 100mV into the AIN1 pin.
For output I use the AVR's fast PWM with TIMER1. The LED I have can take lots of current in pulses so I've optimized my circuit to around 100mA and use a transistor for not stressing the AVR too much.
I store the signal into the EEPROM so it can be replayed even if the device is turned off. As the ATMEGA48 only has a 256 byte EEPROM I was slightly space constrained. In the end I decided on a simple data storage algorithm: 1 byte for delay count and 1 byte for pulse count, if either go over 127 then I use two bytes for each with the highest bit set (so effectively up to 2^15=32767). The frequency is assumed to be the same for a single recording and is stored as a 2 byte integer.
The small storage means that there is space for only couple of button presses. The signal storage format could be improved on this (easily 2-4x) but this is good enough for me for now.
I added a button for recording purposes and again put the circuit into a box:
I run the AVR ATMEGA48 at 8MHz. As usual here's the ISP socket and everything else:
This project was a lot simpler than my previous.
I tested the IR troll on devices from four different manufacturers: Sony, YAMAHA, Philips and HUMAX. It can record and play back any signal from any of those devices.
The entire source code for this application can be downloaded: irtroll-0.1.tar.gz.
Here's the IR troll in action. It replays the signal at random intervals (1-10 seconds).