Universal USB remote controller
Because if the thousands? requests I received I did some xtra coding, and now there exists a gadget to send IR remote signals from a PC or laptop via USB.
This was the idea:
The LED must be an IR type, GAAIAs, high output. I used an old one I bought in the eighties of last century, s web search found better more output for the same current ones, and higher current peak values. You do not want a too narrow emission angle, then pointing becomes an issue.
I used a (very common on ebay) USB to serial module, the 5 V USB powers the PIC and LED. Baudrate is 115200 Bd.
For my Humax box the address bytes are 0016, assuming it is high byte first that makes 16, and that is the default (saved in EEPROM). You can set that address for your box with A123ENTER for address 123 (example), save in EEPROM, range 0-65535.
You can send _any_ command code with: C123ENTER (0-255).
The S option is only for my humax and sets the channel directly, S997ENTER selects channel 997. See the source for how that is done, change the source for whatever you have.
Test mode is not implemented, the whole universe is a test.
Menu if you type 'h':
Panteltje (c) ir_pic-0.1 Commands AnnnnnENTER IR address, default 16 dec CnnnENTER IR command value h help (this) v print status SnnnENTER select channel Z9874ENTER enter test mode z disable test mode, default { channel down ] channel up
For the visually oriented here is what it looks like without housing:
And here is the asm, note the GPL and the things that happen to violators:
So what does it do?
Well if you actually build it, and figured out how to use it, and modified the code for your situation, and found out the IR codes for your stuff, then you can control any IR based 'thing' that uses the NEC protocol from the PC or laptop.
In my case I needed this as I record from the cable modem on the PC with a mpeg2 encoder card, and if there are 2 movies after each other on a different channel in the middle of the night or when you are not there, now the PC can set the channel, the recorder software already has a timer.
The idea of programming the on / off code (that is C0ENTER BTW for Humax) while walking down the street with a power IR LED has been discussed here, and has been done by others, and did switch TV sets off.
So behave. I get about 4 meters range with this old LED.
So that was just about 1.5 days coding and building. No I did not use MPlab, no I did not use a slimulator, no I did not make a peeseebee. All I used was my modified noppp programmer, my jppp18 programming soft, a 10 MHz analog scope, and my frequency counter (the 38 kHz right). It is all done timing with nops, routines called from serial interrupt. IF you ever start PIC programming you should really know that.
So study the code.
I did chose not to use the PWM output, soft timing is in a way more accurate. If you are Chinese and want an other fun product to market, feel free to use this code / design, and improve on it, but release source.
The PIC uses the internal oscillator, and runs on 64 MHz (4 x 16 MHz PLL) that makes accurate adjustment possible. And IR 38 kHz is not that critical.
CU
Finding your codes:
Since there are 65535 device addresses possible, and you do not even know the remote codes, trying them all (2^24) was not what I did. But it can be done ;-)
No, I wrote a simple program called 'ir.c' that reads parport pin 15 on the PC, that pin is connected to this:
--------------------- parport pin 5 | | | [ ] 3k9 \ --- | \ / \ |-------------- parport pin 15 --- | D1 | |/ ----| BC547B NPN |\/ | -------------- parport pin 25
D1 is an IR detection diode that has to be covered with IR transmissive paint or something to prevent other light to activate the transistor My mobo's parport delivers 3.3 V on pin 5 (software sets this high). The above circuit acts as a low-pass for the 38 kHz, and outputs low for 38 kHz present, and high for not present.
ir.c source:
Menu: Panteltje ir-0.1 Usage: ir [-c command_file] [-d hex] [-h] [-l] [-t] [-v int]
-c command_file.
-d hex parallel port address, default 0x378.
-h help (this help).
-l learn mode.
-t I/O test.
-v int verbose, prints functions and arguments.
So ir.c has a lean opd e(I almost wanted to write 'remember' but OK, sure funniest moment of the day so far), anyways Make a directory for the data,and for all this you need to be root, else no I/O. mkdir -p /root/.lremote/commands/ put the IR diode against your remote control, type nice -n -19 ./ir -l nice -9 to grab all resources, to get as little influence as possible from other stuff running. it will say: press ENTER to start. Hit ENTER, then immediately press the button on the remote you are curious about. After about a second reading pin 15 it will ask for a filename to save the data. I ran 6 test, on the same key (channel up), named those sequentially. panteltje12: ~ # l /root/.lremote/commands/ total 384
-rw-r--r-- 1 root root 62500 Feb 13 14:45 a.irc
-rw-r--r-- 1 root root 62500 Feb 13 14:45 b.irc
-rw-r--r-- 1 root root 62500 Feb 13 14:45 c.irc
-rw-r--r-- 1 root root 62500 Feb 13 14:45 d.irc
-rw-r--r-- 1 root root 62500 Feb 13 14:45 e.irc
-rw-r--r-- 1 root root 62500 Feb 13 14:45 f.irc
So those files (binary contain 0xff for no signal, and 0x00 for signal, and things in between for bad signals. If the task switch happens in the data acquisition time, than you get unusable data, so try many times.
I wrote a second 'helper' program to replace all those 0xff and 0x00 by zero and ones, 0 fro 0xff, and 1 for 0x00:
So now we have a text file f.ir In that text file replace all double line feeds with 1 line feed. Now replace the sequence line feed0 with just 0 Then you see this:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000; 0000 0000 = 0
111111111111111111111111111111111111111111111110000000000000000000000000000000000 11111111111111111111111111111111111111111111110000000000000000000000000000000000 11111111111111111111111111111111111111111111111000000000000000000000000000000000 11111111111111111111111111111111111111100000000000000000111111111111111111111111111111111111111111111110000000000000000000000000000000000
111111111111111111111111111111111111111111111111000000000000000000000000000000000 111111111111111111111111111111111111111111111110000000000000000000000000000000000 1111111111111111111111111111111111111111111111000000000000000000000000000; 0001 0000 = 16
111111111111111111111111111111111111111111111100000000000000000000000000000000000 111111111111111111111111111111111111111111111110000000000000000000000000000000000 111111111111111111111111111111111111111111111100000000000000000000000000000000000 11111111111111111111111111111111111111111111110000000000000000000000000000000000111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
111111111111111111111111111111111111111111111100000000000000000000000000000000000 111111111111111111111111111111111111111111111100000000000000000000000000000000000 1111111111111111111111111111111111111111110000000000000000000000000000000000; 0001 0000 = 16
1111111111111111111111111111111111111111111111100000000000000000000000000000000000 111111111111111111111111111111111111100000000000000000000000000000000000 11111111111111111111111111111111111111111111110000000000000000000000000000000000 111111111111111111111111111111111111111111111110000000000000000000000000000000000111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
11111111111111111111111111111111111100000000000000000000000 1111111111111111111111111111111111111111111111110000000000000000000000000000000000 1111111111111111111111111111111111111111111111100000000000000000000000000; 1110 1111 = 239
11111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 11111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000 111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111111111110000000000000000000000000000000000
111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1111111111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 11111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111
I added the numbers, BINGO, got the codes for channel up. In the NEC encoding a 'zero' is 10, and a one is 100 Since we were much faster sampling (PCI bus) use the ratio of ones and zeros. If you did it right you found leader, pause, 24 bits, and a short end signal
That is how I did it, there are simpler ways, but writing this all down took longer then coding it. Code rules.
There is more to it, but this should get you going.