Here’s a cheap way to build your own fully customisable infrared PC remote control. If you already have a suitable infrared remote control going spare you can build one of these for under £4, it will allow you to use most infrared remote controls to issue keyboard commands (single characters or a string) on your PC. Using a surplus remote control it could be used as a cheap media centre remote control with XBMC etc. or would be great for causing some mischief by covertly taking control of someone’s computer. I’ve tested it on several Linux and Windows boxes and one Mac and it has worked fine on them all so far.
At the heart is an 8 pin ATtiny85 microcontroller running at 16MHz using the internal oscillator with a Vishay TSOP31238 IR sensor handling the IR reception and USB implemented with V-USB. Each remote control button can trigger a single keyboard character or series if characters as well as meta keys such as shift and alt.
I couldn’t find any guides for using V-USB on the ATtiny85 under the Arduino environment so have detailed what I did in full here. Other than changing the default PIND, pin and timer settings the key seems to be that when using the internal oscillator like I am here it needs to be calibrated for each individual chip as the timing for USB is so critical.
Schematic and Stripboard layout
Here is the schematic for the USB infrared receiver:
and a stripboard layout:
Atmel ATtiny85-20PU Microcontroller
8 pin DIP socket
Vishay TSOP31238 IR sensor
100nF ceramic capacitor
1 x 2K2 resistor
2 x 68R resistors
2 x 3.6V Zener diodes (must be 0.5W or less)
Through hole male USB A connector
Stripboard, 18 holes by 6 rows
Getting your remote control codes
To get the codes from your chosen remote control I’ve provided a sketch in the above repository that can be run on an Arduino or compatible board which will output the code on the serial monitor as each button is pressed, it’s designed so that you can just plug the IR sensor straight into the headers across Ground, D13 and D11 as shown below:
Once the sketch is loaded on the Arduino open the serial monitor at 9600 baud and press each button on your remote control in turn and you will see the corresponding code output on the serial monitor, don’t worry if the code repeats for each button press. Simply copy and paste the codes into the TinyPCRemote sketch and define the key/s that you want it to press when detected, replacing the existing definitions and duplicating as necessary for as many buttons as you need. There will be an upper limit as to how many can be configured, limited by flash and RAM, I haven’t tested to find the limit but it should allow for plenty of codes.
The USB side of things is handled by V-USB, a very useful open source software-only implementation of the USB 1.1 standard for Atmel AVRs created by Objective Development. I used the vusb-for-arduino variant.
Unzip the file and copy the UsbKeyboard directory to your Arduino library location and restart the Arduino IDE if it was running. Now you need to edit a couple of files to change the port and pin numbers to be compatible with the ATtiny85.
Firstly edit usbconfig.h and under “Hardware Config” change
#define USB_CFG_IOPORTNAME D
#define USB_CFG_IOPORTNAME B
#define USB_CFG_DMINUS_BIT 4
#define USB_CFG_DMINUS_BIT 0
and under “Optional Hardware Config” change:
#define USB_CFG_PULLUP_IOPORTNAME D
#define USB_CFG_PULLUP_IOPORTNAME B
Note that we’re not actually connecting the pullup via a pin but this still needs to be set to a valid port in order to compile.
Optionally you can also change the manufacturer and device name in the following defines:
Finally, in UsbKeyboard.h change:
PORTD = 0; // TODO: Only for USB pins?
DDRD |= ~USBMASK;
PORTB = 0; // TODO: Only for USB pins?
DDRB |= ~USBMASK;
Programming the ATtiny85
Programming the ATtiny85 can be accomplished via an Arduino and the ArduinoISP sketch that is included in the examples section of the Arduino IDE or a dedicated ICSP device.
Calibrating the oscillator
The timing for USB is critical and the oscillator for each individual ATtiny85 chip will almost certainly need to be calibrated, to do this download TinyTuner from here and put it in your Arduino libraries directory. You are also going to need an FTDI adapter or some other sort of serial converter so you can read the output.
Connect your ATtiny85 up to the Arduino and use the burn bootloader function of the Arduino IDE to set it to run at 8MHz by choosing the “ATtiny85 @ 8MHz (internal oscillator;BOD disabled)” board setting under Tools > board and then using the Tools > Burn Bootloader option. Note that as with the ATtiny84 this doesn’t actually burn a bootloader, all we are doing is setting the relevant fuses to configure the microcontroller, in this case we are temporarily setting it to run at 8MHz as tiny-tuner won’t run at our final 16MHz speed.
Load the “Interactive_to_Serial_with_Details” TinyTuner sketch from the tiny-tuner examples onto the ATtiny85, connect PB3 (pin 2) to RXD on the FTDI adapter and PB4 (pin 3) to TXD as well as 5V and ground.
Now open a terminal app on your PC and connect to the port of the serial adapter, eg. on linux “miniterm.py /dev/ttyUSB1“, reset the ATtiny85 and you should get a welcome message, now repeatedly press x slowly (once a second or so is fine) until you get a result like:
Copy-and-paste the following line of code at the top of setup…
OSCCAL = 0x9C
Copy the result from tiny-tuner into the TinyPCRemote sketch replacing the OSCCAL = 0x9C; line in setup() as appropriate.
Once you have entered the OSCCAL calibration value and your remote control codes along with the resulting keys you want to be entered then you are ready to load the TinyPCRemote sketch onto the ATtiny85.
First use the burn bootloader function again to set the ATtiny 85 to 16MHz by using the “ATtiny85 @ 16MHz (internal PLL;4.3V BOD)” board setting then upload the sketch in the normal manner.
If you are testing it on a breadboard as I did when developing it then you will probably had to disconnect the connections to the Arduino for the USB to work, I got away with just disconnecting the SCK connection (wire from Arduino D13 to ATtiny pin 7/PB2).
If you now plug the the TinyPCRemote into a USB port hopefully pressing the remote control buttons will result in the corresponding characters appearing on your screen as if typed on your keyboard.
If not run dmesg and look for any errors, if everything is working you should see something like the following (I don’t know how you can view similar logs on Windows or Mac):
input: zorg.org TinyPCRemote as /devices/pci0000:00/0000:00:13.5/usb1/1-9/1-9.2/1-9.2.1/1-9.2.1:1.0/input/input18
generic-usb 0003:4242:E131.0006: input,hidraw2: USB HID v1.01 Keyboard [zorg.org TinyPCRemote] on usb-0000:00:13.5-9.2.1/input0
Note that I’ve changed the manufacturer and device names in usbconfig.h to be zorg.org and TinyPCRemote respectively.
If you get device descriptor read errors like:
usb 1-9.2.1: new low-speed USB device number 28 using ehci_hcd
usb 1-9.2.1: device descriptor read/64, error -32
then your computer is seeing the device but you probably have a timing problem. Make sure your ATtiny is set to 16MHz using the internal PLL and that you have calibrated it correctly using tiny-tuner.