Shop OBEX P1 Docs P2 Docs Learn Events
Magic IR, universal IR record & playback object — Parallax Forums

Magic IR, universal IR record & playback object

Nick McClickNick McClick Posts: 1,003
edited 2012-01-06 11:46 in Propeller 1
I've been working on a home automation project for a while - Jon's Spin Zone column on Sony SIRCS got me started on IR control. It's an awesome & well documented object, problem was it only worked with SIRCS.

I looked at the other IR objects in the Object Exchange, & they supported NEC & RC5 IR formats, but I was having problems getting it to work with my TV. I needed something dumber, so I built my own object, Magic IR.

4941818371_ab4336ec4b.jpg

Magic IR stores any arbitrary IR code, as received from an IR receiver (I've been using this Vishay, but all others should work) with a max of 128 transitions. Store code is written in pasm, so the transition timing is as high resolution as possible. The stored IR code can then be played back.

Usage is pretty simple, there are just 2 methods;
CON              
 _clkmode        = xtal1 + pll16x
 _xinfreq        = 5_000_000
 
OBJ
 magicir : "magicir_010"
 
VAR
LONG code1[128], code1len

PUB main
magicir.storecode(0, @code1, @code1len)
'' store a code received at pin 0 at code1 with total 
'' transition count at code1len

repeat
  magicir.playcode(1,@code1,@code1len)
  waitcnt(clkfreq  + cnt)

'' playback a code with the IR LED connected to pin 1.  
'' Code is stored at code1, length at code1len

The storecode method starts a new cog - it will pause until the input pin goes low & will timeout after 1/8 second or 128 transitions have been received.

The playcode method runs in the existing cog - if you've just called storecode, it will pause until storecode completes. Once storecode is done, it will playback the code at 38kHz on the LED connected to the output pin.

This is my first object meant for others to use - it's attached. I also did a video demo. Any suggestions are welcome!

Comments

  • schillschill Posts: 741
    edited 2010-08-30 10:21
    This looks like something I'll need to play with.

    It fits in with a project I've been kicking around in the back of my mind but haven't found time to work on. Maybe this is the kick I needed.
  • KyeKye Posts: 2,200
    edited 2010-08-30 11:55
    That's a great idea for universal compatibility.
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-08-30 13:03
    Hi Nick!

    I did nearly the same thing a while back. It was close to be a candidate for the object exchange, but I paused with my propeller activity for a while. What are the differences:

    1. I did not measure the exact timing. Instead I read the signal to build up a timing table. In each IR signal you only have a limited amount of different high- and low-times if you allow some deviation. The longest timings are recognized as pause of the signal, so I only need to store 1 sequence in case of a normal code and 2 sequences in case there are alternating bits in the signal.
    2. The signal itself is stored as a list of indexes to this timing table but translated to a string where uppercase letters are pointing to a high time entry and the lowercase letters are pointing to a low time entry. For example:
    AaBaBaCb
    This way even human can read the signal.

    I think the main things are ... the timings are good in reading remote controls. If you have several sets of timings you can detect on the fly which remote control has been used and then search for the key pressed in the right list. For example I want to use an old remote control for easy functions and I found this nice IR keyboard which is of course much better for entering text.
    Playback of each code from a list is also easily possible with the recorded string and the timing table.

    If you are interested I could post what I have up to now.
  • Toby SeckshundToby Seckshund Posts: 2,027
    edited 2010-08-30 13:05
    Next up, the Prop version of "TV begone".


    I made a project that reacted to a remote command, and then put out another about two seconds latter, very amusing. SHE didn't think so though (it used one of those other sorts of chips).
  • RagtopRagtop Posts: 406
    edited 2012-01-05 13:04
    I have used MagicIR to dupe my television remote, but can't seem to get it to work with the cox cable box. It gets the code from the remote, but playback does nothing for the cable box.

    I am trying to make my own universal remote.

    Does Cox cable use some other protocol or freq?
  • RagtopRagtop Posts: 406
    edited 2012-01-06 11:46
    I created this object to make cut and pasting the codes into my program easier. It requires MagicIR, parallax serial terminal, a button connected to propeller, and an IR receiver.
    CON              
     _clkmode        = xtal1 + pll16x
     _xinfreq        = 5_000_000
     
      receiver = 0  'pin that is attached to ir receiver
      button = 1    'button that is connect to propeller pin 1 
    OBJ
     magicir : "magicir_010"
     DEBUG   : "Parallax Serial Terminal"
     
    VAR
    LONG code1[128], code1len
    long i,translen,x
    PUB main
       DEBUG.start(250000)
       dira[button]~ 
       DEBUG.clear
       DEBUG.Position(20,10)
       debug.str(string("Press Button to record"))
      repeat
           if ina[button]==1
             magicir.storecode(receiver, @code1, @code1len)
             waitcnt(clkfreq*3  + cnt)
             DEBUG.clear
             debug.str(string(13))
             debug.str(string(13))
             debug.str(string(13))
    
             x:=1
             debug.str(string("  name      long ")) 
              repeat i from 0 to code1len
    
                 x++
                 debug.dec(code1[i])
    
                  if x == 11
                     debug.str(string(13))
                      debug.str(string("            long ")) 
                       x:=1
                  elseif i == code1len
                    debug.str(string(13))
                    debug.str(string(13))
                    debug.str(string("length      long "))
                    debug.dec(code1len)
                    debug.str(string(13))    
                  else
                    debug.str(string(","))
                       
        
           repeat while ina[button]==0       'wait for button press to clear screen
          DEBUG.clear
          DEBUG.Position(20,10)
          debug.str(string("Press Button to record"))
    
Sign In or Register to comment.