Shop OBEX P1 Docs P2 Docs Learn Events
SX/B IR remote control — Parallax Forums

SX/B IR remote control

RsadeikaRsadeika Posts: 3,837
edited 2005-12-09 07:42 in General Discussion
This is a very basic (no pun intended) program. To be best used with an SX tech board, Parallax remote control (Sony codes), IR detector, and LED.

Problems: sluggish response time between button push and LED turning on; and if somebody tests it, maybe other stuff.
I welcome coding suggestions, and improvements. This uses the latest SX/B compiler.

****code
' =========================================================================
'
'·· File...... Test1.sxb
'·· Purpose... SX/B IR Remote control
'·· Author....·
'·· E-mail....·
'·· Started...
'·· Updated...
'
' =========================================================================

'
' Program Description
'

'
' Device Settings
'
DEVICE········· SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ··········· 4_000_000

'
' IO Pins
'

'
' Constants
'

'
' Variables
'
·led1 var rb.0
·irpin var rc.0
·irpulse var byte
·temp1 var byte
·idx var byte
remotecode var byte
'
· INTERRUPT
'
ISR_Start:
· ' ISR code here
ISR_Exit:
· RETURNINT ' {cycles}································

' =========================================================================
· PROGRAM Start
' =========================================================================


'
' Subroutine Declarations
'
·ledon sub
·getcode sub
·processcode sub 1
·gofore sub· 'ChUp button
·goback sub· 'ChDn button
·goleft sub··· 'Vol- button
·goright sub··· 'Vol+ button
'
' Program Code
'
Start:
do
·'ledon·· 'Turn on LED
·getcode
·processcode remotecode
·'goto stop
loop

getcode:
'pause 1000· 'Turn on LED, to make sure I got here
·'ledon
remotecode = 0
irpulse = 0
do· ''*******Get start pulse
·pulsin irpin, 0, irpulse
loop while irpulse < 240 'Does not work with 220
''*****Get bits
pulsin irpin, 0, irpulse
if irpulse > 120 then
·remotecode.0 = 1
endif
pulsin irpin, 0, irpulse
if irpulse > 120 then
· remotecode.1 = 1
endif
pulsin irpin, 0, irpulse
if irpulse > 120 then
·remotecode.2 = 1
endif
pulsin irpin, 0, irpulse
if irpulse > 120 then
·remotecode.3 = 1
endif
pulsin irpin, 0, irpulse
if irpulse > 120 then
·remotecode.4 = 1
endif
pulsin irpin, 0, irpulse
if irpulse > 120 then
·remotecode.5 = 1
endif
pulsin irpin, 0, irpulse
if irpulse > 120 then
·remotecode.6 = 1
endif


return remotecode
processcode:
'pause 1000
'ledon
if remotecode = 16 then· ' If ChUp button
gofore· 'Turn on the LED
endif
if remotecode = 17 then·· 'If ChDn button
goback
endif
if remotecode = 18 then
goright
endif
if remotecode = 19 then
goleft
endif
return
ledon:
·tris_b=0
·led1 = 0
·pause 1000
·led1 = 1
return
gofore:
·pause 1000· 'Turn on LED to make sure I got here
ledon
return
goback:
· pause 1000
· ledon
return
goleft:
· pause 1000
· ledon
return
goright:
· pause 1000
· ledon
return

stop:
sleep

Comments

  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-11-25 17:36
    I think the "sluggishness" is coming from the PAUSE statements you've inserted into your program before you activate the LED.· You should also remove the INTERRUPT section so that it doesn't interfere (probably why you're timing isn't quite working) and you can simplify the receipt of the SIRCS code in a loop.

    Since I like to put my money (coding skills) where my [noparse][[/noparse]big]·mouth (theory suggestions) is I've written and tested a simple program that waits for the SIRCS code.· I decided to include the command and device code in the program, and it's written so the device code portion can easily be stripped out, that way you could rewrite the program so you could do this: keyCode = GET_IRCS; right now it uses global vars.· Note that I've created a shell for PULSIN so that it's only expanded once -- this saves a lot of code space.

    I've got this program running on my PDB and it's very responsive.·

    [noparse][[/noparse]Edit] I've added a scope capture of a Sony IR stream when pressing "0" (zero) on a TV remote. [noparse][[/noparse]/Edit]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax

    Post Edited (Jon Williams (Parallax)) : 11/25/2005 10:17:51 PM GMT
    941 x 734 - 394K
  • RsadeikaRsadeika Posts: 3,837
    edited 2005-11-25 18:01
    Jon,

    I'm impressed, I spent the last three days trying to handle the first seven bits, you , in notime come up with a solution for all twelve bits. But, I think that I am getting better.
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-11-25 18:22
    Well, I've probably got a few more miles on my sneakers hence a few more ticks in the toolbox.... Hopefully the code will simplify your project. And here's a hint: always use shell subroutines for "big" SX/B commands (like I did for PAUSEUS, PAUSE, and PULSIN) as this will save a lot of code space and it actually allows you to add features to the command (like my WAIT routines that can work with or without the multiplier byte).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax

    Post Edited (Jon Williams (Parallax)) : 11/25/2005 6:26:37 PM GMT
  • RsadeikaRsadeika Posts: 3,837
    edited 2005-11-25 18:28
    Thanks again Jon. Now, on to my next big idea, how do I get this to run as a task in the background.
  • RsadeikaRsadeika Posts: 3,837
    edited 2005-11-25 19:26
    Thanks again Jon. Now onto my next big idea, how do I get this to run as a task in the background.
  • RsadeikaRsadeika Posts: 3,837
    edited 2005-11-25 20:34
    The medium picture for my project is: I would like to have an SX52 proto board act as the main "brain", an SX28 proto board act as a slave "brain". On the slave "brain", I will have devices, such as an IR demodulator that is always responding to or waiting for IR signals. Some object detectors that will start working when it gets a signal from the remote to go into "roamiing" mode, in constant communication with the main "brain",·..., etc. For the main "brain" , all the I/O could be used for future expansion, like more ram, main controler of all slave "brains" (interprocessor communication in real time), ..., etc. Basically I am after distributed processing on a micro processor scale. For now that is the direction.
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-11-26 07:10
    This took a bit of banging my head against the computer (though it looks easy now....) -- here's an SIRCS decoder that works in the interrupt.· For this one I copped-out and ignore the device code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • RsadeikaRsadeika Posts: 3,837
    edited 2005-11-26 14:15
    Jon,
    Thanks. After doing a cursory look, first impressions of sircs_isr, SLICK. Looks like a potential article for N&V; needs lots of explanation for the assembly parts. I will have to put on my thinking cap for this one.
    ?Some where in the asm code resides a pulsin command?
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-11-26 15:09
    To be honest with you, I actually started with high-level SX/B in the interrupt and it works fine too (that segment attached) -- I just wanted to trim it down to the lowest number of cycles.· You'll notice that I used 26 uS as the interrupt time; this was a deliberate choice as it works well for creating a 9600 baud UART in the interrupt as well.· If you look closely you'll see that when the IR line is low the variable called bitWidth gets incremented -- this is the equivalent of PULSIN, albeit with 26 uS resolution.

    Here's what the ISR does:

    · -- data is not already available
    ····· -- if not already receiving data from IR device
    ········· -- wait for IR line to go low, then initialize everything
    ······--·when receiving
    ········· -- if IR line is low update the bit width counter
    ········· -- when IR line goes high
    ··············-- if on start bit (bitCount = 0)
    ················· -- test for proper width; if okay move to next bit otherwise reset process
    ··············-- if on data bit (bitCount > 0)
    ················· -- shift workspace value right
    ··················-- set workspace.6 if bit was "1" width
    ············· -- ignore IR line until it goes low again (for next bit)
    ··········--··when eight bits received
    ·············· -- move workspace to output var and set flags

    The reason this is a little tricky is that SIRCS uses a variable bit width with a fixed idle time this means that the code has to watch for the IR line to go high to know that we're at the end of a bit, measure it, then what for the IR line to go back low to start measuring the next bit -- this is the reason why the rxBit flag is used (it lets us ignore the IR line idle time between bits).

    This works, but I'm not saying it's the best way to do it.· Perhaps my friends Guenther, Bean, PeterM or others will chime in and show us where we can do this more efficiently.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • RsadeikaRsadeika Posts: 3,837
    edited 2005-11-27 17:45
    After reading a few of the posts, it looks like their·are more questions being asked about PBASIC vs SX/B. Here are my thoughts, on the subject. After whining, moaning and groaning, Jon stepped up and wrote the IR remote program for me. Now, after looking at his code, and comparing it to the PBASIC code, I simply did not learn the use of the pulsin command, in the PBASIC application. So, now I can say that if I new the use of the commands correctly (and some other stuff), then I could say that SX/B is just as easy, or hard to learn as PBASIC. So, if you are starting from scratch, then you could dive right into SX/B with no problems, since you will be learning the correct use of the commands. If you have a good grasp of PBASIC, then you could dive right in.

    I seem to have confused, ease of use with learning. Ease of use, meaning, the difficulty in typing in somebody elses functioning code, hitting run, and have it work correctly. While learning involves knowing what the commands do or can do. Since, I had my first lesson, with this program, I can say, that SX/B is just as doable as PBASIC. Make sure you know the difference between ease of use and learning.
  • RsadeikaRsadeika Posts: 3,837
    edited 2005-11-28 14:11
    Jon,
    I had a chance to test both versions of the program you kindly provided. They work as expected, using my LED on/off concept. I have two questions, for now, concerning the ISR version.
    1, In the ISR, you use two values, #74, #34. I have looked at these values from a decimal and binary perspective, and it·is not making sense to me. Do these, somehow represent the 2.4, 1.2, 0.6 ms requirements, or am I way off.

    2. In the RETURNINT, you place a value of 104 -> 26 us @ 4 MHz. You mention that it will work for a 9600 baud UART. If I change the processor freq value, will both items get messed up. I kind of see maybe the 9600 baud being affected, but the IR portion should be good at any freq change. Am I correct in these assumptions.

    Thanks
  • PJMontyPJMonty Posts: 983
    edited 2005-11-28 17:20
    Jon,

    The ISR you wrote for decoding SIRCS data looks solid and quite compact. I wrote a SIRCS decoder as part of a much bigger project a year ago. In my case, dues to the way the rest of the project worked, I created a software timer that ran at .1 ms. This gave me a way to time incoming pulses with .1 ms resolution. For what it's worth, here is the pertinent part of the comment block for my code:

    ; To decode, watch the input bit and wait for it to go low.  It should be held low for 
    ; 2.4 ms followed by .6 ms of high.  After that, the data starts coming in.  The key to
    ; decoding the remaining bits is to time the length of the lows that happen.  Technically,
    ; if it's low for .6 ms, it's a zero, and if it's low for 1.2 ms, it's a one.  All of these
    ; timings are subject to jitter and inaccuracy caused by the time base used in the cheap 
    ; remotes.  Because of this, I use 1 ms as a cutoff.  Below it is a zero, above it is a one.
    ; This (should) give me better handling of off timed pulses.   
    
    



    I'm not sure if this will give you any new ideas, but you never know. In re-reading my comments, I realize I should change my cutoff value from 1 ms to .9 ms to actually be in the middle of .6 ms and 1.2 ms.
      hanks, PeterM
  • RsadeikaRsadeika Posts: 3,837
    edited 2005-11-28 23:01
    As posted earlier, the program runs as expected. The next thing I wanted to try·is, how does it run as a stand alone. So, after re-testing, I unpluged the com cable from the SXkey, leaving the SXkey on board, pluged in the power, and it does not work, the program that is. I tried a small test program, turning on an LED, in the stand alone hook up, that seems to work. Anybody have any ideas as to what is going on. I also tried it with a crytal plugged in, and no SXkey, that did not work either. I ran the non ISR version of the program.

    Thanks
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-11-29 01:37
    Make sure the DEVICE directive is set for OSCXT2 and you put 4 MHz resonator in the circuit when you want to run stand-alone.· If you change the FREQ directive for the ISR version, you will have to update the ISR (value after RETURNINT)·so that it runs every 26 uS, otherwise you'll need to update all the values as well.

    About those values... the start bit is supposed to be 2400 uS.· 2400 / 26 = 92 -- I use 90% of that (83) since that is still longer than a "1" bit period and gives the code a little flexibility with a remote that might not have perfect timing.· Same for the "1" bit test; in this case I split the difference between the two bit times, use 900.· (INT) 900 / 26 = 34.· The code checks to see if the current bit time is less than this value -- the only time that should ever happen is if the bit is a valid zero.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • RsadeikaRsadeika Posts: 3,837
    edited 2005-11-29 17:14
    I think that this is the appropriate place for this. Maybe a techinical response by the pros would be appropriate. I tried running the IR program in a stand-alone setup, this time what I was getting is what appears to be a random response, and sometimes no response,·to my button press on the remote, meaning somtimes my LED would go on, and·sometimes not. After reading in the FAQ download, in the description of the different crystal selections, their is notation to RFI. Now I am thinking could the external crystal·be affecting the IR·demodulator in any way, or any other aspect of the circuit. Since I will be experimenting with other devices such as object detectors, bluetooth, ..., etc, maybe I should get this problem resolved now, while it is still manageable. Any thoughts would be appreciated.

    Thanks
  • PJMontyPJMonty Posts: 983
    edited 2005-11-29 17:56
    Rsadeika,

    Just checking to make sure you're familiar with the difference between programming for debug and programming for standalone running and how to do that in the IDE, right?
      Thanks, PeterM
  • RsadeikaRsadeika Posts: 3,837
    edited 2005-11-29 19:35
    PeterM,

    Their is more to it than just making a choice of Run or Program? When I Run it with the SX-key in place the program executes as expected, when I execute it in stand-alone, I run into problems. I am in the midst of trying to narrow down an explanation of why I am getting these two different results. Maybe I need a page number, of some documentation,·that deals with programming for stand-alone applications, if their is indeed a difference. I guess, maybe an explanation in the FAQ may be in helpfull.

    When you mention debug, is this a third choice of coding style. Maybe I am getting boged down in syntax, I am not sure at this point. This is getting to be a lot more complicated than doing a simple LED on/off application.
  • PJMontyPJMonty Posts: 983
    edited 2005-11-29 22:33
    Rsadeika,

    Run->Debug : Compiles or assembles the code and adds additional code which allows the SX key to control the chip. It then programs the chip, and starts the debugger. This is only used to run the code with the SxKey attached and the debugger running. Any external clock source (resonator, crystal, or TTL chip) must be removed from the SX in order for the debugger to work correctly.

    Run->Debug Again : Similar to the Run-Debug except that it doesn't program the chip, but merely starts the debugger and assumes that the that the chip has already been programmed via Run->Debug and that the code in the chip is the same as the code in the IDE. This is used to avoid the time spent programming the chip when you haven't made any changes to the code but merely want to run it again.

    Run->Program : Compiles or assembles the code and then programs the chip without the extra code used for control by the SxKey. After programming, power to the SX should be removed and an external clock source must be added in order for the chip to be able to run unless the internal 32 Khz, 128 KHz, 1 MHz, or 4 MHz clock is enabled by a DEVICE directive. The SxKey will not generate a clock for the SX chip and it should not be attached except during the programming phase. It is possible to to program the chip with a resonator in place.
      Thanks, PeterM
  • RsadeikaRsadeika Posts: 3,837
    edited 2005-11-29 22:56
    Thank You, PeterM,

    For a begginer like myself, that explanation, does not leave any room for second guessing, very good.
  • John BondJohn Bond Posts: 369
    edited 2005-12-09 07:42
    Hey!! Google is my friend (did someone once say that?). Actually Google didn't help but the search engine on your website did.

    Looking for some SX code to read a Sony remote and, before posting my question, I did a search. Thanks Jon for your code and expert advice. You answered the questions I didn't even think to ask.

    John Bond
Sign In or Register to comment.