Shop OBEX P1 Docs P2 Docs Learn Events
Trying to enhance IR_Remote object — Parallax Forums

Trying to enhance IR_Remote object

RsadeikaRsadeika Posts: 3,837
edited 2010-03-01 19:21 in Propeller 1
What I am trying to do is enhance the existing IR_Remote.spin object to allow for providing the device number. What I basically did was, in the E_IR_Remote.spin, is add a IRdev variable by masking off the IRcode for it. But, it seems that I am not getting what I expect, which sould be a 1 or 2, which designates the device number. I added the IRdev variable to the program, it did not contain it before hand. I am at a loss as to what to do next.

The program below works, the commented out stuff is what I tried to do to no avail. It seems that IRdev should be holding the device number, 1 or 2, in this case, but when I do the 'if IRdev == 1', that does not work, so I must be getting an unexpected value. I thought this would be simple, and straight forward, but, it is not. Anybody have any suggestions?

Ray


CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

  IRdetpin = 0

VAR
  byte IRcode
  byte IRdev

OBJ
  IRrem   : "E_IR_Remote"
  misc    : "tools"


PUB IRremote | cog, scode, scode2

  cog := IRrem.start(IRdetpin, @IRcode, @IRdev)
  if cog > 0
    repeat
      ''if IRcode <> IRrem#NoNewCode AND IRrem#NoNewDev
      if IRdev <> IRrem#NoNewCode and IRrem#NoNewDev
        ''scode2 := IRdev
        ''if IRdev == 1
          scode := IRcode

        ''if IRdev == 1      ''Check for device number 1 or 2
          IRrem.Start(IRdetpin, @IRcode, @IRdev)

            case scode
              IRrem#power  : Pwr_btn
              IRrem#chup   : Ch_up
              IRrem#one    : One

        ''if IRdev == 2
          ''IRrem.Start(IRdetpin, @IRdev, @IRcode)
          ''scode2 := IRcode
            ''case scode2
              ''IRrem#power2  : Pwr2_btn

PRI Pwr_btn
  LED1

PRI Ch_up
  LED1

PRI One
  LED1

PRI Pwr2_btn
  LED1

PUB LED1
  misc.high(1)
  misc.waitms(250)
  misc.low(1)






''E_IR_Remote.spin
CON
NoNewCode   = 255
NoNewDev    = 255
gapMin      = 2000
startBitMin = 2000
startBitMax = 2800
oneBitMin   = 1000
oneBitMax   = 1400

one   = 0

chup  = 16
power = 21

power2 = 21

VAR
  byte cog
  long stack[noparse][[/noparse]20]

PUB Start(Pin, addrMainCode, addrMainDev) : result

  stop
  byte[noparse][[/noparse]addrMainCode] := NoNewCode
  byte[noparse][[/noparse]addrMainDev]  := NoNewDev
  cog := cognew(getSonyCode(Pin, addrMainCode, addrMainDev), @stack) + 1
  result := cog

PUB stop
  if cog
    cogstop(cog~ -1)

PUB getSonyCode(Pin, addrMainCode, addrMainDev) | irCode, irDev, index, pulseWidth, lockID

  frqa := 1
  ctra := 0
  dira[noparse][[/noparse]Pin]~

  repeat
    ctra := (%10101 << 26) | (Pin)
    waitpne(0 << Pin, |< Pin, 0)
    phsa := 0
    waitpeq(0 << Pin, |< Pin, 0)
    waitpne(0 << Pin, |< Pin, 0)

    pulseWidth := phsa / (clkfreq / 1_000_000) + 1

  while (( pulseWidth < startBitMin) OR (pulseWidth > startBitMax))

  index := 0
  irCode := 0
  repeat
    ctra := (%10101 << 26) | (Pin)
    waitpne(0 << Pin, |< Pin, 0)
    phsa := 0
    waitpeq(0 << Pin, |< Pin, 0)
    waitpne(0 << Pin, |< Pin, 0)

    pulseWidth := phsa / (clkfreq / 1_000_000) + 1

   if (pulseWidth > oneBitMin) AND (pulseWidth < oneBitMax)
      irCode := irCode + (1 << index)
   index++
  while index < 11
  irCode := irCode & $7f   ''Masking of lower 7 bits
  irDev  := irCode & $f80  ''Masking of upper 5 bits?

  byte[noparse][[/noparse]addrMainCode] := irCode
  byte[noparse][[/noparse]addrMainDev]  := irDev   ''byte[noparse][[/noparse]addrMainDev] = upper 5 bits?


Comments

  • kuronekokuroneko Posts: 3,623
    edited 2010-02-27 13:43
    From a quick (most likely not complete) glance:

      irCode := irCode & $7f   ''Masking of lower 7 bits
      irDev  := irCode & $f80  ''Masking of upper 5 bits?
    
      byte[noparse][[/noparse]addrMainCode] := irCode
      byte[noparse][[/noparse]addrMainDev]  := irDev   ''byte[noparse][[/noparse]addrMainDev] = upper 5 bits?
    


    The second line will always result in 0 because you cleared the upper bits in line one (irCode). May I suggest something like this:

      irDev  := (irCode & $f80) >> 7  ''Masking of upper 5 bits?
      irCode := irCode & $7f          ''Masking of lower 7 bits
    


    If irCode is only 12bit in size then irCode >> 7 should be enough.

    HTH
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-27 14:41
    I made the changes as suggested by kureneko, thanks; when I use the device setting 1, the program works as expected. When I use the 'vcr' button, or 2, then nothing happens. It seems like the 'if IRdev == 1' is working, but the 'if IRdev == 2' is not working. I checked the SONY codes, and for device 2 (vcr button) the code numbers are the same for both device 1, and 2. So, there must be something wrong with my 'if' logic. I guess I need more suggestions.

    Ray



    
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      IRdetpin = 0
    
    VAR
      byte IRcode
      byte IRdev
    
    OBJ
      IRrem   : "E_IR_Remote"
      misc    : "tools"
    
    
    PUB IRremote | cog, scode
    
      cog := IRrem.start(IRdetpin, @IRcode, @IRdev)
      if cog > 0
        repeat
          if IRcode <> IRrem#NoNewCode AND IRrem#NoNewDev
    
            if IRdev == 1
              scode := IRcode
    
              IRrem.Start(IRdetpin, @IRcode, @IRdev)
    
                case scode
                  IRrem#power  : Pwr_btn
                  IRrem#chup   : Ch_up
                  IRrem#one    : One
    
             if IRdev == 2
               scode := IRcode
    
               IRrem.Start(IRdetpin, @IRdev, @IRcode)
    
                 case scode
                   IRrem#one2  : One2_btn
                   IRrem#two2  ; Two2_btn
    
    PRI Pwr_btn
      LED1
    
    PRI Ch_up
      LED1
    
    PRI One
      LED1
    
    PRI One2_btn
      LED1
    
    PRI Two2_btn
      LED1
    
    PUB LED1
      misc.high(1)
      misc.waitms(250)
      misc.low(1)
    
    
    
    




    ''E_IR_Remote
    
    CON
    NoNewCode   = 255
    NoNewDev    = 255
    gapMin      = 2000
    startBitMin = 2000
    startBitMax = 2800
    oneBitMin   = 1000
    oneBitMax   = 1400
    
    one   = 0
    
    chup  = 16
    power = 21
    
    'power2 = 21
    one2 = 0
    two2 = 1
    
    VAR
      byte cog
      long stack[noparse][[/noparse]20]
    
    PUB Start(Pin, addrMainCode, addrMainDev) : result
    
      stop
      byte[noparse][[/noparse]addrMainCode] := NoNewCode
      byte[noparse][[/noparse]addrMainDev]  := NoNewDev
      cog := cognew(getSonyCode(Pin, addrMainCode, addrMainDev), @stack) + 1
      result := cog
    
    PUB stop
      if cog
        cogstop(cog~ -1)
    
    PUB getSonyCode(Pin, addrMainCode, addrMainDev) | irCode, irDev, index, pulseWidth, lockID
    
      frqa := 1
      ctra := 0
      dira[noparse][[/noparse]Pin]~
    
      repeat
        ctra := (%10101 << 26) | (Pin)
        waitpne(0 << Pin, |< Pin, 0)
        phsa := 0
        waitpeq(0 << Pin, |< Pin, 0)
        waitpne(0 << Pin, |< Pin, 0)
    
        pulseWidth := phsa / (clkfreq / 1_000_000) + 1
    
      while (( pulseWidth < startBitMin) OR (pulseWidth > startBitMax))
    
      index := 0
      irCode := 0
      repeat
        ctra := (%10101 << 26) | (Pin)
        waitpne(0 << Pin, |< Pin, 0)
        phsa := 0
        waitpeq(0 << Pin, |< Pin, 0)
        waitpne(0 << Pin, |< Pin, 0)
    
        pulseWidth := phsa / (clkfreq / 1_000_000) + 1
    
       if (pulseWidth > oneBitMin) AND (pulseWidth < oneBitMax)
          irCode := irCode + (1 << index)
       index++
      while index < 11
      irDev  := (irCode & $f80) >> 7  ''Masking of upper 5 bits
      irCode := irCode & $7f   ''Masking of lower 7 bits
    
    
      byte[noparse][[/noparse]addrMainCode] := irCode
      byte[noparse][[/noparse]addrMainDev]  := irDev   ''byte[noparse][[/noparse]addrMainDev] = upper 5 bits
    
    
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-27 17:34
    I am not making very much progress here today. I wanted to get a visual of what is contained in IRdev, and IRcode when I press a button. I added FDS object, and added some lines to the Pwr_btn method. When I press the Pwr_btn on the remote, I get:
    1
    21
    255
    255
    on the screen. Now I cannot figure out where the 255's are coming from. I see I get 1 for the device number, 21 for the pwr_btn, which is correct. I still do not get anything from the device 2, that is the first problem; the second problem is, where is the 255 coming from. I sure could use more help on this.

    Ray


    PRI Pwr_btn
      LED1
      ser.dec(IRdev)
      ser.tx(10)
      ser.dec(IRcode)
      ser.tx(10)
    
    
    
  • jazzedjazzed Posts: 11,803
    edited 2010-02-27 23:02
    @Rsadeika ...
    Ray, look at the TvFavorites package in this thread:
    http://forums.parallax.com/forums/default.aspx?f=25&m=361625

    It contains TvRemote.spin - the file allows you to acquire a bit-stream from an IR detector and check for matches. The remote I tested was a Sony. The demo would display a set of waveforms and is for the Nokia/Phillips LCD/controller, but can be adapted with some work to other devices.

    Not sure if it will be of any help and some of the code is experimental (ignore commented parts in dat section[noparse]:)[/noparse], but it is at least an example that you could study.
  • ratronicratronic Posts: 1,451
    edited 2010-02-28 01:46
    @ Rsadeika, I modified Tom Doyle's code to run all the time in a cog so all you have to do is check in your routine the 'ircode' value and not have to start the cog each time you check the remote. I don't know whether this will help - but here is the changes I made.

    PUB getSonyCode(pin, addrMainCode) | irCode, index, pulseWidth, lockID·································
    {{·····································································································
    ·· Decode the Sony TV Remote key code from pulses received by the IR receiver··························
    }}·····································································································
    ·······································································································
    ·· ' wait for idle period (ir receiver output = 1 for gapMin)··········································
    ·· ' comment out "auto repeat" code if auto key repeat is desired······································
    ·······································································································
    ·· ' start of "auto repeat" code section·······························································
    ·· dira[noparse][[/noparse]pin]~··························································································
    ·· index := 0··························································································
    ·repeat {{DR - added this extra repeat to not let cog die and keep updating addrmaincode}}·············
    ·· repeat······························································································
    ···· if ina[noparse][[/noparse]Pin] == 1··················································································
    ······ index++·························································································
    ···· else······························································································
    ······ index := 0······················································································
    ·· while index < gapMin················································································
    ·· ' end of "auto repeat" code section·································································
    ·······································································································
    ·· byte[noparse][[/noparse]addrMainCode] := 255 {{DR - added this to 0 out addrmaincode when no buttons are pressed}}·····
    ·· frqa := 1···························································································
    ·· ctra := 0···························································································
    ·· dira[noparse][[/noparse]pin]~··························································································
    ·······································································································
    ·· ' wait for a start pulse ( width > startBitMin and < startBitMax· )·································
    ·······································································································
    ·· repeat······························································································
    ····· ctra := (%10101 << 26 ) | (PIN)····················· ' accumulate while A = 0····················
    ····· waitpne(0 << pin, |< Pin, 0)·····································································
    ····· phsa:=0············································· ' zero width································
    ····· waitpeq(0 << pin, |< Pin, 0)························ ' start counting····························
    ····· waitpne(0 << pin, |< Pin, 0)························ ' stop counting·····························
    ····· pulseWidth := phsa· / (clkfreq / 1_000_000) + 1··················································
    ·· while ((pulseWidth < startBitMin) OR (pulseWidth > startBitMax))····································
    ·······································································································
    ·· ' read in next 12 bits··············································································
    ·· index := 0··························································································
    ·· irCode := 0·························································································
    ·· repeat······························································································
    ····· ctra := (%10101 << 26 ) | (PIN)····················· ' accumulate while A = 0····················
    ····· waitpne(0 << pin, |< Pin, 0)·····································································
    ····· phsa:=0············································· ' zero width································
    ····· waitpeq(0 << pin, |< Pin, 0)························ ' start counting····························
    ····· waitpne(0 << pin, |< Pin, 0)························ ' stop counting·····························
    ····· pulseWidth := phsa· / (clkfreq / 1_000_000) + 1··················································
    ·······································································································
    ··· if (pulseWidth > oneBitMin) AND (pulseWidth < oneBitMax)···········································
    ······ irCode := irCode + (1 << index)·································································
    ··· index++····························································································
    ·· while index < 11····················································································
    ·······································································································
    ·· irCode := irCode & $7f·································· ' mask off upper 5 bits····················
    ·······································································································
    ·· byte[noparse][[/noparse]addrMainCode] := irCode········································································

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ···································Fix it, if ain't broke!


    D Rat

    Dave Ratcliff N6YEE
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-28 13:09
    I am not having much success trying to enhance the IR_Remote.spin object to make use of a device selection, where is Tom Doyle when you need him LOL? After staring at my lines of code that I added, the program should work the way I expect it to work, but it does not, so I do not know what to do next.

    Thanks.

    Ray
  • ratronicratronic Posts: 1,451
    edited 2010-02-28 16:19
    Ray, I added your mods to my code and they seem to work fine. Now I have to warn you that the code I attached does take up a cog all the time and returns 255 if no buttons are being pressed. Could you archive all of your code and post it?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ···································Fix it, if ain't broke!


    D Rat

    Dave Ratcliff N6YEE
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-02-28 17:46
    Attached is the compressed file, since I am working with BST, I included the project file. It will be interesting to see if it runs on your system. I like the way the original IR_Remote object uses a cog when it needs to, I will be running short on cogs, I want to have a least one cog that will be available on a when available basis. I hope you can find the problem, because I sure can't.

    Thanks

    Ray
  • ratronicratronic Posts: 1,451
    edited 2010-02-28 21:30
    Ray, I think what you need to do is immediatly assign the ircode and irdev variables to new one's right after your check for the nonewcode(255). Tom's code reuses those two variables each time you restart the cog. I did get #'s back from the serial terminal when pressing the power button with tv, but not with the vcr - after modding your code a little bit. Take a look at the code I am posting to see how I am using your enanced remote routine.

    Edit - then use the new variables to do the decision making, branching etc, not sure what you want to do so take a look at the example using your E_IR_Remote routine.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ···································Fix it, if ain't broke!


    D Rat

    Dave Ratcliff N6YEE

    Post Edited (ratronic) : 2/28/2010 11:30:33 PM GMT
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-03-01 10:21
    I tried your program, and it works just fine when I use the TV (1) setting. When I use the VCR (2) setting the only action that I get is on the VolUp, and VolDn buttons, and it shows that the device is number (1). I guess I will have to dig out my old basic stamp, the old reliable, and run the program that displays the code numbers for the key that is being pressed. I have to determine if it is the remote control that is going bad, or is it something else. I was thinking about using PropBASIC, but when jonnyMac made the conversion for the sircs program, he did not include the device setting. I know if I get diverted to PropBASIC, I will probably spend a whole bunch of time on it, and still screw it up, so I will go with a sure thing, the basic stamp.

    I hope this is working for everybody else, it's just a matter of time before I get it working correctly for me. I guess the official name for this object will be E_IR_Remote.spin, somewhere down the line I might come up with some other little feature to add.

    Ray
  • ratronicratronic Posts: 1,451
    edited 2010-03-01 13:01
    Ray, here is a short little program that will ID the device and function for the button pressed.

    Edit - only using a cog on demand with your E_IR_Remote routine.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ···································Fix it, if ain't broke!


    D Rat

    Dave Ratcliff N6YEE

    Post Edited (ratronic) : 3/1/2010 1:12:02 PM GMT
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-03-01 13:37
    Thanks, ratronic, for testing out my program, I am glad it is working for you. I just ran your program, and I am still getting the same results. It is starting to look like I may have a problem with my remote control, but I still want to confirm it. Off to see if I can find my basic stamp ...

    Thanks again

    Ray
  • ratronicratronic Posts: 1,451
    edited 2010-03-01 13:44
    You know, one thing to keep in mind is that remotes can put out for different devices than the one selected. I am using your program with a scientific atlanta remote which does those things - good luck - take care.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ···································Fix it, if ain't broke!


    D Rat

    Dave Ratcliff N6YEE
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-03-01 14:29
    If you want to check your remote controls I could provide you some piece of code which is work in progress, but it can read any remote control and it spits out a string which shows you the signal received. It only requires a TSOP and user I/O is done through the terminal connection.
  • BradCBradC Posts: 2,601
    edited 2010-03-01 14:35
    Rsadeika said...
    Attached is the compressed file, since I am working with BST, I included the project file. It will be interesting to see if it runs on your system.

    I'd never envisaged project files to be portable, so it's not likely it will work on other peoples system. The reason for that is the paths for the files in the project file are stored as absolute paths. I will now re-think that decision.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    You only ever need two tools in life. If it moves and it shouldn't use Duct Tape. If it does not move and it should use WD40.
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-03-01 14:44
    Thanks for the offer MagIO2, but since I do not know what a TSOP is, let alone how I would use one, your effort would be wasted on me. I still think there is a simpler way of checking out a remote control. It would be really nice if there was a program, associated with some processor, that would tell you if it is using SONY code, and then tell you the code number of each key that is pressed. There has to be a very simple way of doing this.

    Ray
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-03-01 15:06
    Well ... that's not my goal, but it's part of the way to reach my goal. I want to replace 5+ IR remote controls. All of differend brands. So I have to understand what they send. My way is to receive the signal and translate it into a) a timing table and b) a string representation. Based on the timing table and number of high and low send in the signal it should be possible to decide which Remote Control send the signal. The string itself can be used to find the key that's been pressed.

    Translating the signal into timing table and string already works.

    A TSOP is just as easy to handle as a IR receiving diode. It already filters out the carrier signal. What's your setup? Is the code above taking care of the carrier signal? Is your receiver a 2 pin IR diode or is it a 3 pin receiver?
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-03-01 15:41
    I am using the Panasonic PNA4602M 38.5kHz that Parallax sells, it is a 3 pin demodulator. I just looked at the program for the Basic Stamp, and it only provides info for the key codes, the seven bit signal, not the eleven bit signal that would contain the device code. Decisions, decisions, which processor should I use, and attempt to modify the code to get what I want?

    Ray
  • ratronicratronic Posts: 1,451
    edited 2010-03-01 15:50
    Ray, if I press the play key on my remote with the tv selected (device 1)·- your program shows me device 2, but if I press a channel # button it shows device 1 - thats the way a lot of these remotes are set up. I·think your program is ok it is just what the remote is putting out. Take care.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ···································Fix it, if ain't broke!


    D Rat

    Dave Ratcliff N6YEE
  • jazzedjazzed Posts: 11,803
    edited 2010-03-01 16:37
    There are a few A/V remote projects I have that work fine if I use the simple remotes (sony, panasonic, etc...), but I would prefer something more universal. Having a universal remote encoder/decoder is a neat idea, but practically and relatively speaking, it is a big task.

    The TvFavorites project with works great for simple remotes - See video www.youtube.com/watch?v=YalcMqkdHEU

    The more complicated ATT U-verse remote seems to have a mind of it's own ... the code bit-stream changes every time for the same button although it is similar each time. All other remotes I've tried had simple bit-streams for each button.

    The OBEX remote code provides different schemes it seems, so that is helpful if you have a big EEPROM or other media for program storage. I guess if you make an A/V (audio/video) IR related product, the limits should be clearly understood and stated for the consumer.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-03-01 17:40
    Rsadeika said...
    I am using the Panasonic PNA4602M 38.5kHz that Parallax sells, it is a 3 pin demodulator. I just looked at the program for the Basic Stamp, and it only provides info for the key codes, the seven bit signal, not the eleven bit signal that would contain the device code. Decisions, decisions, which processor should I use, and attempt to modify the code to get what I want?

    Ray

    Have a look at this:
    -- http://obex.parallax.com/objects/477/

    This object (with demo program) decodes SIRCS signals and reports the number of bits. This is important as TV remotes use 12-bit codes and DVD remotes use 20-bit codes (my Sony SLR's remote also sends 20-bit codes). Knowing the number of bits in the code lets you pull the device code and key code properly.

    I even wrote about this in my "Spin Zone" column:
    -- http://www.parallax.com/Portals/0/Downloads/docs/cols/nv/prop/col/nvp4.pdf

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • RsadeikaRsadeika Posts: 3,837
    edited 2010-03-01 19:21
    The remote control is not broken. I am using the three function remote that Parallax used to sell. In the remote pamphlet, it gives you the setup codes for the device button; on this particular remote, for the VCR, of the three code choices, you should choose '1003', that gives the most functional button choices. Then I used JonnyMac's sniffer program to get the particular button code. The device number for 'VCR' is 11, but when in that mode three of the buttons use a device number of 1. I have not verified any of this just yet, meaning I have not tried it in my program just yet. As for the third function button, CBL, it did not have a SONY listing, but it had other manufacturers listed, one of these days I may find out which one of the manufacturers uses SONY IR code, and then maybe I will have a third functional device button to work with. Now back to the program ...


    Ray
Sign In or Register to comment.