Shop Learn
SIRC P2 FlexBASIC explore — Parallax Forums

SIRC P2 FlexBASIC explore

Below is the JonnyMac sirc driver code, not sure, how or where to begin with a FlexBASIC version.

I tried a a very simple start:

dim sirc as class using "jm_sircs_rx.spin2"

dim ir_pin%

ir_pin% = sirc.start(9)  ' Using pin 9
print ": ";ir_pin%           ' Print something when the remote key is pressed.

What I would like to do is have a small program that will map the universal remote keys.

Thanks

Ray

'' =================================================================================================
''
''   File....... jm_sircs_rx.spin2
''   Purpose.... Sonry SIRCS protocol receiver
''   Author..... Jon "JonnyMac" McPhalen
''               Copyright (c) 2020 Jon McPhalen
''               -- see below for terms of use
''   E-mail..... jon.mcphalen@gmail.com
''   Started....
''   Updated.... 19 JUL 2020 
''
'' =================================================================================================

{{

    Example IR Connection (e.g., PNA4602M)

             ┌───┐
             │(*)│ 3.3v
             └┬┬┬┘  
       ir ───┘│└───┘
               

    Note: 500K pull-down can be added to IR input to detect bad/missing sensor

    Protocol Reference:
    -- http://www.sbprojects.com/knowledge/ir/sirc.php

    Bit Formatting:
                    Command    Device     Extended
    -- 12-bit       6..0       11..7 
    -- 15-bit       6..0       14..7 
    -- 20-bit       6..0       11..7      19..12

    This object does not include bit error detection (e.g., detect collisions between
    multiple IR signals).

}}


con { fixed io pins }

  RX1      = 63  { I }                                          ' programming / debug
  TX1      = 62  { O }                                           

  SF_CS    = 61  { O }                                          ' serial flash
  SF_SCK   = 60  { O }                                           
  SF_SDO   = 59  { O }                                           
  SF_SDI   = 58  { I }


con

  IR_DISABLE = -1
  IR_ENABLE  =  0


var

  long  cog                                                     ' cog id

  long  irpin

  long  ircode                                                  ' rx'd code
  long  irbits                                                  ' bits in code


pub null()

'' This is not a top-level object


pub start(p) : result 

'' Start SIRCS receiver on pin p

  stop()                                                        ' stop if running on another pin

  irpin  := ircode := p                                         ' set pin        
  irbits := 2_400 * (clkfreq / 1_000_000)                       ' ticks in 2.4ms

  cog    := coginit(COGEXEC_NEW, @rx_sircs, @ircode) + 1        ' start sircs cog  

  repeat                                                         
  until (irbits == IR_DISABLE)                                  ' wait for cog to initialize

  return cog


pub stop()

'' Stops SIRCS receiver cog if running

  if (cog)
    cogstop(cog-1)
    cog := 0

  longfill(@ircode, 0, 2)


pub enable()

'' Enables SIRCS receive process

  longfill(@ircode, IR_ENABLE, 2)


pub disable()

'' Disable SIRCS receive process

  longfill(@ircode, IR_DISABLE, 2) 


pub rx() : result1, result0

'' Enables and waits for ir input
'' -- warning: blocks until IR code received!
'' -- does not remove code/bits from buffer

  enable()                                                      ' allow ir rx
  repeat until (irbits > 0)                                     ' wait for code

  return ircode, irbits 


pub rxcheck() : result1, result0

'' Returns code and bit count if available, -1 if none
'' -- must have previously been enabled
'' -- does not remove code/bits from buffer

  if (irbits > 0)                                               ' if code ready
    return ircode, irbits
  else
    return -1, 0


pub sensor_check() : result

'' Returns true if sensor is pressent
'' -- scans IR input for up to 3ms
'' -- sensor pin should have hi-z (~500K) pull-down

  repeat 20
    if (pinread(irpin) == 1)                                    ' sensor pin pulled up?
      return true                                               ' if yes, sensor is present
    waitus(150) 


dat { sircs receiver }

                org

rx_sircs        setq      #2-1                                  ' read pin & timing from hub
                rdlong    irp, ptra

                fltl      irp                                   ' clear pin to input state

                mov       t0, starttix
                shr       t0, #4                                ' t0 = 1/16th starttix
                sub       starttix, t0                          ' test is 15/16ths nominal timing
                mov       bit1tix, starttix                     ' "1" bit == 1/2 start bit
                shr       bit1tix, #1

                mov       rxcode, ##IR_DISABLE                  ' tell hub cog is setup
                mov       bitcount, ##IR_DISABLE 

done            setq      #2-1                                  ' write results to hub
                wrlong    rxcode, ptra

wait_enable     rdlong    t0, ptra                              ' look for enable signal
                tjnz      t0, #wait_enable

get_start       getct     tfall                                 ' mark 1->0
                testp     irp                           wc
    if_c        jmp       #get_start                            ' wait for 1->0 transition

wait_start      getct     trise                                 ' mark 0->1
                testp     irp                           wc
    if_nc       jmp       #wait_start                           ' wait for 0->1 transition

check_start     mov       tdelta, trise                         ' calculate pulse width
                subs      tdelta, tfall
                cmps      tdelta, starttix              wcz     ' validate against start pulse width
    if_b        jmp       #wait_start

                mov       rxcode, #0                            ' clear results
                mov       bitcount, #0

get_bits        getct     tdelta                                ' wait for start of data bit (1->0)
                testp     irp                           wc
    if_nc       mov       tfall, tdelta                         ' detected, mark time & continue
    if_nc       jmp       #wait_bit
                subs      tdelta, trise                         ' time-out (end of data bits)?
                cmps      tdelta, bit1tix               wcz
    if_b        jmp       #get_bits

                jmp       #update_code                          ' time-out, clean-up bits

wait_bit        getct     trise                                 ' wait for end of data bit (0->1)
                testp     irp                           wc
    if_nc       jmp       #wait_bit          

check_bit       mov       tdelta, trise
                subs      tdelta, tfall
                cmps      tdelta, bit1tix               wcz
                shl       rxcode, #1                            ' make space for bit
    if_a        or        rxcode, #1                            ' write new bit
                add       bitcount, #1                          ' update count      
                jmp       #get_bits

update_code     rev       rxcode                                ' correct lsbs
                mov       tdelta, #32
                sub       tdelta, bitcount
                shr       rxcode, tdelta
                jmp       #done

' -------------------------------------------------------------------------------------------------

irp             res       1                                     ' ir input pin
starttix        res       1                                     ' ticks in start bit

bit1tix         res       1                                     ' "1" bit timing

rxcode          res       1                                     ' recieved SIRCS code
bitcount        res       1                                     ' bits in code          

tfall           res       1                                     ' for bit & idle timing
trise           res       1
tdelta          res       1

t0              res       1                                     ' work vars                                                                   
t1              res       1                                     

                fit       496


con { license }

{{

  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 NON-INFRINGEMENT. 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.

}}

Comments

  • I don't have the hardware to test this, nor am I that familiar with SIRCS, but Jon's code is (as usual) clearly laid out and pretty well documented. The "start()" method returns the number of the helper COG, not a key code. To read the buttons it looks like you need the "rx()" method. So your program would look something like:

    dim sirc as class using "jm_sircs_rx.spin2"
    
    dim as integer cognum, code, bits
    
    cognum = sirc.start(9)  ' Using pin 9
    print "started cog "; cognum
    do
       code, bits =  sirc.rx()
       print "received "; bits; " bit long code, value = "; code
    loop
    

    Again, I haven't tested this so it may not work as-is, but that's the general gist of how it should go.

    As always, when trying to interface with a new Spin device driver, the first step is to read the code and the comments, and figure out roughly what the methods do.

  • Below is some test code to see if the SIRC is working as expected, yes it is. I left the code that is used for mapping in place.

    I mapped the Universal remote that Parallax sells, as follows:
    Pwr - 149 ENTER - 139
    '1 '- 128 Prev Chnl - 187
    '2' - 129 Ch Up - 144
    '3'- 130 Ch Dn - 145
    '4'- 131 Vol <- - 147 '5'- 132 Vol -> - 146
    '6'- 133 MUTE - 148
    '7'- 134
    '8'- 135
    '9' - 136
    '0'- 137

    Ray

    sub ir_remote()
    
        'cognum = sirc.start(9)  ' Using pin 9
        'print "started cog "; cognum
        sirc.start(9)
    
        do
    
            code, bits =  sirc.rx()
            select case code
            case 144    ' Ch Up key
                pinhi 57
            case 145    ' Ch Dn key
                pinlo 57  
            end select
    
            'code, bits =  sirc.rx()
            'print "received "; bits; " bit long code, value = "; code
    
        loop
    end sub
    
    
  • JonnyMacJonnyMac Posts: 7,924
    edited 2021-12-12 06:11

    @Ray: You will only be able to read Sony codes with my object -- it won't help you identify any mode that may come out of a universal remote. That said, once you understand how it works, you could write a universal decoder. The IR library used by the Schmarschmino gang does in fact use a mechanism for detecting the IR protocol. This is useful for detecting unknown signals, but very inefficient when you have a known protocol. Once you get a grip on how I'm doing SIRCS receiving, you could probably port the Arduino library code (it's all about measuring pulses and the delays between them).

    Here's a video that explains SIRCS transmit and receiving on the P2:
    --

    I've attached the files discussed during that presentation.

Sign In or Register to comment.