Sending universal remote keycodes
Is there a way to use a Prop to send universal remote keycodes to control a TV? Is there a list of supported codes for something other then sony? Please help as this is needed in a project I am working on now!
Thanks in advance!
··············· -- Micro
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Computers are microcontrolled.
Robots are microcontrolled.
I am microcontrolled.
But you·can·call me micro.
If it's not Parallax then don't even bother.
I have changed my avatar so that I will no longer be confused with others who use generic avatars (and I'm more of a Prop head then a BS2 nut, anyway)
Thanks in advance!
··············· -- Micro
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Computers are microcontrolled.
Robots are microcontrolled.
I am microcontrolled.
But you·can·call me micro.
If it's not Parallax then don't even bother.
I have changed my avatar so that I will no longer be confused with others who use generic avatars (and I'm more of a Prop head then a BS2 nut, anyway)

Comments
first thing to do is to search through the obex with suitable keywords like "remote"
there is the IR Kit
IR Kit contain objects to get and buffer key codes from virtually any IR remote, identify and obtain timing information, transmit IR codes, and understand IR transmission codes. (IR_kit.zip)
best regards
Stefan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Computers are microcontrolled.
Robots are microcontrolled.
I am microcontrolled.
But you·can·call me micro.
If it's not Parallax then don't even bother.
I have changed my avatar so that I will no longer be confused with others who use generic avatars (and I'm more of a Prop head then a BS2 nut, anyway)
to analyze the bitstream and the timing it is good to use the file ir_capture
as this gives information about how many bits and the timing
now the code to send is specific about some things
it is adjusted for a 38 kHz carrier-frequency. On common IR-remote-controls the carrierfrequency varies from 36 to 40 kHz
the code to send is only the file ir_tx_nec which is specific to NEC
I'm not familiar with IR-signals but I guess that the bitstreams vary between brands
from this quick overview I came to the conclusion that the description in the obex promises more than the code can do
to record really ANY kind of IR-bitsequences the IR-capture can be used as a start.
you will have to record the on/off-timings of each key and combine this with a send-routine
that switches on/off the IR-Led with the recorded timings before
if you have access to the specification of the bitstream like how does
- the leadin
- the databits
- the leadout
look like
you can write your own asm-driver more directly.
so there are two levels:
level 1: you know the carrierfrequency and can use a carrier-to-bitstream-decoder device and simply sample the bitstream
level 2: analyse the carrierfrequency of the IR-remote-control by the propeller using a photo-diode with an amplification-circuit
and demodulate the carrierfrequency by software
maybee a way inbetween level 1 and 2 is to analyse the carrierfrequency and switch the bitstream-sample IO-pin between
different pins which were connected to three different hardware-carrierdecoders for 36 kHz, 38 KHz and 40 kHz
this is no ready to use IR-recording-object nor a complete explaining of IR-signals but I hope this helps some steps
best regards
Stefan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Computers are microcontrolled.
Robots are microcontrolled.
I am microcontrolled.
But you·can·call me micro.
If it's not Parallax then don't even bother.
I have changed my avatar so that I will no longer be confused with others who use generic avatars (and I'm more of a Prop head then a BS2 nut, anyway)
{{ TvRemote.spin: used to handle IR stream from remote control Copyright (c) 2008 John Steven Denson (jazzed) See MIT license terms below }} {{ This version saves a bitstream as ones/zeros. Matches are determined by counting hi/low bit times. Counting and saving the high/low time would be easier in many ways: 1) more data can be recorded - only 32 bytes per stream in some cases; 2) more than one stream can be saved for newer remotes; 3) capture is less complicated and can save the first stream in tact; 4) matching would be easier - just find count +/- some error number; 5) replaying would be easier.... }} {{ Test Code }} { CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 SCS = 27 SCK = 26 SDIO = 25 SRST = 24 IRIN = 16 BLEN = 255 obj d : "spiasm-lcd-65k" sf : "snprintf" 'dbg: "PASDebug" '<---- Added for Debugger var byte b[noparse][[/noparse]BLEN+1] byte irbuf[noparse][[/noparse]IRBUFLEN+1] PUB main | n, mx, my, slen, strn, r 'dbg.start(31,30,@entry) start(IRIN, @irbuf, IRBUFLEN) d.start(d#PHILIPS, SCK, SCS, SDIO, SRST) d.clear(d#WHITE) d.setfgcolor(d#BLUE) d.setbgcolor(d#TRANSPARENT) printf(string($d," Bitstream Match Tester",$d),0) d.setfgcolor(d#YELLOW) 'd.setbgcolor(d#TRANSPARENT) 'd.cls n~ repeat repeat r := acquire(1000) while r r := match(@irbmatch,0) if r sf.snprintf(@b,BLEN,string("Mismatch %d",$d),p(r)) else sf.snprintf(@b,BLEN,string("Match %d",$d),p(r)) bytemove(@irbmatch,@irbuf,IRBUFLEN) show(irbuffp,IRBUFLEN) d.drawString(@b,d#END_COL>>1-12,d#END_PAGE-8) repeat PUB show(buf,len) | n, m, mx, my, left, top, j, k, v1, v2, vt1, vt2, hl, ht, r, c d.clear(d#BLUE) { repeat mx from 0 to 10 repeat my from 0 to 3 d.fillRectangle(d#CYAN,mx<<2,my*(d#FONTHEIGHT+1)+d#FONTHEIGHT+2,1,d#FONTHEIGHT) } mx~ my~ left:= 2 top := d#FONTHEIGHT/3 ht := d#FONTHEIGHT/3 c := d#WHITE m := 4 repeat n from 0 to len-1 if n and (n // 4) == 0 mx~ my++ r := byte[noparse][[/noparse]buf+n] repeat j from 0 to 7 v1 := r & $80 >> j if v1 v1 := 1 vt1 := my*(ht+2)+top vt2 := my*(ht+2)+(1-v1)*(ht)+top hl := mx<<2+left if v1 <> v2 d.fillRectangle(c,hl,vt1,0,ht) d.fillRectangle(c,hl+1,vt2,3,1) v2 := v1 mx++ if m++ // 16 < 4 d.fillRectangle(d#ORANGE,hl+4,vt1+1,0,3) else d.fillRectangle(d#BLACK,hl+4,vt1+1,0,3) if (n // $84) == $80 waitcnt(clkfreq*2+cnt) mx~ my := -1 d.clear(d#BLUE) PUB printf(fmt, args) sf.snprintf(@b,BLEN,fmt,args) d.str(@b) PUB p(v) sf.p(v) } obj def: "TvDefines" CON IRBUFLEN = def#IRBUF_LEN DAT ' following vars up to ircog must be in order irpin long 0 ' ir pin mask command long 0 ' ir command irbuffm long 0 ' local buffer for matching irvalid long 0 ' valid status pointer irbytes long 0 ' bit buffer length pointer irbuffp long 0 ' bit byte buffer pointer ircog long 0 ' cog storage irbmatch byte 0 [noparse][[/noparse]IRBUFLEN+1] CON CMD_MASK = $7 CMD_ACQUIRE = $1 CMD_MATCH = $2 CMD_SEND = $4 PUB start(pin,bufp,buflen) {{ @param pin - pin number to use for IR receive @param valp - ir valid status pointer @param buflen - maximum buffer length in bytes @param bufp - reference to buffer pointer }} irpin := 1 << pin irbuffm:= @irbmatch irbuffp:= bufp irbytes:= buflen ircog := cognew(@entry, @irpin) + 1 waitcnt(clkfreq/20+cnt) PUB stop cogstop(ircog~ - 1) PUB getIrMatchBuffPtr return @irbmatch PUB getIrCurrentBuffPtr return @irbuffp PUB acquire(mstime) {{ acquire a bitstream and put in startup buffer }} command := CMD_ACQUIRE repeat while command waitcnt(clkfreq/10+cnt) return irvalid PUB match(buffp,len) {{ compare buffp bitstream with startup buffer @param buffp - caller's current buffer }} irbuffm := buffp command := CMD_MATCH repeat while command return irvalid PUB send(bufp, len) {{ send buffp bitstream to IR tx LED @param buffp - caller's current buffer or startup buffer ????? }} command := CMD_SEND repeat while command DAT '' ''---------------------------------------------------------------------- ''PASM code and interfaces ''PASM HW interface uses only CLK, CS, DAT ''Reset and initialization to be done with external code and CMD_SEND COMMAND/DATA '' entry org 0 'save for PASD debugger 'long $34FC1202,$6CE81201,$83C120B,$8BC0E0A,$E87C0E03,$8BC0E0A,$EC7C0E05,$A0BC1207,$5C7C0003,$5C7C0003,$7FFC,$7FF8 mov bp, par rdlong pm, bp ' get pinmask add bp, #4 mov cp, bp ' get command pointer add bp, #4 mov mp, bp ' set match buffer read pointer (char**) add bp, #4 mov vp, bp ' get irvalid pointer add bp, #4 mov lp, bp ' get buffer len pointer add bp, #4 ' last word passed is buffer read pointer (char*) andn dira, pm 'or dira, #1 cmdloop rdlong cmd, cp wz if_z jmp #cmdloop 'switch cmd test cmd, #CMD_ACQUIRE wz if_nz jmp #cmdAcquire test cmd, #CMD_MATCH wz if_nz jmp #cmdMatch test cmd, #CMD_SEND wz if_nz jmp #cmdSend ' command done cmddone mov cmd, #0 wrlong cmd, cp jmp #cmdloop ''---------------------------------------------------------------------- '' cmdAcquire '' '' Most if not all controllers send more than one stream of ir bits. '' If only one stream is sent, user can hold the remote button or '' press multiple times. '' '' On the first pass, find edges and adjust the sample period '' On the second pass, read the bits '' cmdAcquire mov rc, #0 wrlong rc, vp call #autobaud wrlong rc, vp tjnz rc, #cmdDone call #readir wrlong rc, vp jmp #cmdDone ''---------------------------------------------------------------------- '' cmdMatch '' check if two bitstreams match '' cmdMatch call #ismatch wrlong rc, vp jmp #cmdDone ''---------------------------------------------------------------------- '' cmdSend '' send IR bitstream '' cmdSend jmp #cmdDone ''---------------------------------------------------------------------- '' autobaud '' @return non-zero if ok, else error '' autobaud mov t1, tcnt 'set timeout ... look for start bit or outa, #1 loloop test pm, ina wz ' wait for lo input ... modulation makes ir det output low if_nz djnz t1, #loloop cmp t1, #0 wz if_z mov rc, #1 if_z jmp #autobaud_ret ' timed out xor outa, #1 mov t1, cnt ' save cnt mov t2, t1 'set timeout { hiloop test pm, ina wz ' wait for hi input if_z djnz t2, #hiloop cmp t2, #0 wz if_z mov rc, #2 if_z jmp #autobaud_ret ' timed out sub t1, t2 wc,wz ' get difference between t1-2 count. if sub fails exit if_be mov rc, #0 ' let caller know there was a problem if_be jmp #autobaud_ret shr t1, #4 ' take XX samples add t1, #30 mov scnt,t1 } mov scnt,#$60 '#70 '#$80 ' just use a fixed sample rate shl scnt,#3 ' newer remote uses 2 different streams to mean same thing :< { ' wait for data to stop changing ' mov last, #0 mov t3, #0 mov t2, #0 ' data chmloop mov t1, #8 ' read byte ctr chbloop mov t0, scnt ' tick counter loop djnz t0, #loop ' wait for count down ... could use waitcnt instead test pm, ina wc addx t2, t2 ' read and shift a bit ... end up with first bit in msb djnz t1, #chbloop add last, #1 cmp t2, #$ff wz if_z add t3, #1 cmp t3, #60 wz if_b jmp #chmloop add last, #10 mov mcnt, scnt shl mcnt, #2 ' adjust middle of pulse cnt } mov t0, #$80 shl t0, #14 add t0, cnt waitcnt t0, t0 xor outa, #1 autobaud_ret ret ''---------------------------------------------------------------------- '' ismatch finds a "statistical" match of buffers '' @return 0 if ok, else error '' ismatch mov rc, #0 ' check match mov t1, #0 ' store for first byte mismatch offset rdlong t2, last ' get max buffer len rdlong tp, bp ' bp is not disposable rdlong dp, mp ' get max buffer len m2loop rdbyte t3, tp rdbyte t4, dp add t1, #1 ' bits same ? cmp t3, t4 wz if_e jmp #mskip ' if difference of byte bits is < 2...4 ???? skip check mov t0, #8 mov bt, #1 mov ac, #0 m2bloop test bt, t3 wz if_nz add ac, #1 ' add bits shl bt, #1 djnz t0, #m2bloop mov t0, #8 mov bt, #1 m2bloop2 test bt, t4 wz if_nz sub ac, #1 ' subtract bits shl bt, #1 djnz t0, #m2bloop2 abs ac, ac shr ac, #2 wz ' bit count about the same? if_z jmp #mskip mov rc, t1 ' mismatch jmp #mchklen mskip add tp, #1 add dp, #1 if_z djnz t2, #m2loop mchklen cmp t1, #IRBUFLEN wz,wc ' if past buffer no error if_ae mov t1, #0 if_ae mov rc, t1 ismatch_ret ret ''---------------------------------------------------------------------- '' read ir '' @return 0 if ok, else error '' readir mov t1, tcnt 'set timeout ... look for start bit rdloloop test pm, ina wz ' wait for lo input ... modulation makes ir det output low if_nz djnz t1, #rdloloop cmp t1, #0 wz if_z mov rc, #8 if_z jmp #autobaud_ret ' timed out 'mov t0, last rdlong t0, lp rdlong tp, bp :mloop mov t1, #8 ' read byte :bloop mov t2, scnt :loop djnz t2, #:loop ' wait for count down ... could use waitcnt instead test pm, ina wc addx t3, t3 ' read and shift a bit ... end up with first bit in msb sub t1, #1 wz if_nz jmp #:bloop add tp, #1 wrbyte t3, tp mov t3, #0 djnz t0, #:mloop readir_ret ret ''---------------------------------------------------------------------- '' constants '' tcnt long 5000000 '10000000 ''---------------------------------------------------------------------- '' variables '' bp res 1 ' buffer pointer lp res 1 ' buffer length pointer dp res 1 ' data tmp pointer mp res 1 ' match buffer pointer vp res 1 ' valid pointer cp res 1 ' command pointer pm res 1 ' pin mask cmd res 1 ' command word scnt res 1 ' sample time count mcnt res 1 ' middle of pulse count bt res 1 ' bit cnt ac res 1 ' accumulator time res 1 ' for loading waitcnt first res 1 ' first 0's byte index last res 1 ' last 0's byte index tp res 1 ' temp pointer t0 res 1 ' temp var 0 t1 res 1 ' temp var 1 t2 res 1 ' temp var 2 t3 res 1 ' temp var 3 t4 res 1 ' temp var 4 rc res 1 ' return code {{ TERMS OF USE: MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. }}▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230
Post Edited (jazzed) : 8/15/2009 4:50:02 PM GMT