1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

JuneBug SIRC RX - Complete

Discussion in 'Microcontrollers' started by UTMonkey, Jan 14, 2008.

  1. UTMonkey

    UTMonkey New Member

    Joined:
    Oct 16, 2007
    Messages:
    450
    Likes:
    3
    Location:
    Chesterfield, Derbyshire - UK
    Hi Futz,

    I don't know how much has been changed to get it into the 16F but I would place a breakpoint after the RISE label.

    The first time you hit this breakpoint "should" be after the first pulse, TMR0L "should" contain the time delay between the fall and rise of the pulse.

    Does the 16F use a 16 bit TMR0? what is TMR0H doing?

    I love the 18F, it is my first chip but perhaps I should have cut my teeth on the 16F's?

    Anyway hope this helps.

    Mark

    p.s. shame we can't see the TTL that is coming out of your TSOP?
     
  2. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Quite a bit.

    It's 8 bit only, so TMR0 only.

    Try some. It's not like they're expensive or anything. You'll find the differences interesting. They're much more RISC than the 18F's. Takes more instructions to get the same work done. The 18F's are still RISC but edging a bit more toward CISC.
     
  3. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Next best thing! I put in a counter to count the number of pulses I was getting when I pressed a key on the remote. I got 39 pulses, so I made a 39 byte array and indexed into it to store the value of the 39 Time2's in a command. Here's what I get when I press the 1 key on the remote (all hex):

    13 - 1c 04 04 05 05 05 05 - 09 04 04 05 04
    13 - 1c 04 05 04 04 04 05 - 09 04 04 04 05
    13 - 1c 05 04 05 04 05 04 - 09 04 05 05 05

    I separated the sections the way I think SIRC is supposed to work - start/command/address. The $1c is what's killing the thing. Wonder what's going on there?

    Pressing the 5 key gets me:

    13 - 1c 04 09 04 04 04 04 - 09 04 04 04 04
    13 - 1c 04 09 04 04 04 04 - 09 04 04 04 04
    13 - 1c 04 09 04 04 04 04 - 09 04 04 04 04

    Everything looks fine except for that $1c. I can't understand how my code could botch that one and yet get the rest right, since it uses the same code to get every pulse length...

    EDIT: I wonder if it's somehow combining the start pulse length with the second pulse. That could maybe add up to $1c.
     
    Last edited: Feb 20, 2008
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.

    Got it! :D Stupid 18F btg commands. When I ported I accidentally set for rising edge both times.

    Now to chase down the rest of the bugs. :p
     
  6. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    Well, that was entertaining. :D Here's UTMonkey's program ported to Blueroom Firefly 16F88. Could still use some cleaning up, but it works.

    I didn't bother to do the LEDs properly. When waiting for a code LED1 is red and LED2 is green. When a code is received all LEDs are off. Press button 3 to reset.
    Code (text):
        LIST p=16F88
        INCLUDE "p16f88.inc"
        __CONFIG _CONFIG1,_INTRC_IO & _WDT_OFF & _LVP_OFF & _MCLR_ON & _BODEN_OFF
        ERRORLEVEL 0, -302
       

    btDone      equ 0x00
    btStart     equ 0x01
    btCommand   equ 0x02

        cblock  0x20
            dlen,Time2,BitCount,DeviceCode,CommandCode,IRStatus,Bit,ScratchCode
            w_temp,status_temp,pclath_temp,the_end
        endc       

        org 0x0000
        goto    Init

    ;*****
    ; ISR
        org 0x0008
    ISR movwf   w_temp
        swapf   STATUS,W
        clrf    STATUS
        movwf   status_temp
        movf    PCLATH,W
        movwf   pclath_temp
        clrf    PCLATH
       
        bcf PORTA,0         ;LEDs 1 & 2 off
        bcf PORTA,6
        bcf PORTA,7
        btfsc   IRStatus,btDone     ;has a code already been read?
        goto    isr_done
        banksel OPTION_REG      ;bank 1
        btfsc   OPTION_REG,INTEDG   ;check if falling or rising signal
        goto    Rise
        banksel TMR0            ;bank 0
        clrf    TMR0            ;reset timer
        banksel OPTION_REG      ;bank 1
        movlw   b'01010111'     ;Enable timer0, 256 prescaler, set RB0 rising edge
        movwf   OPTION_REG
        banksel PORTA           ;bank 0
        goto    isr_done
    Rise
        banksel TMR0            ;bank 0
        movf    TMR0,W          ;Put timer 0 value into storage
        movwf   Time2
        banksel OPTION_REG      ;bank 1
        bcf OPTION_REG,INTEDG   ;set for falling edge
        banksel PORTA           ;bank 0
    GetPulseWidth
        movlw   0x12            ;Check for start pulse, should be between 0x12 and 0x14
        subwf   Time2,W
        btfss   STATUS,C        ;Greater than 0x11?
        goto    CheckZero
        movlw   0x14
        subwf   Time2,W         ;Less than 0x15?
        btfsc   STATUS,C
        goto    IRError         ;Start Bit exceeds tolerance
    StartBit                ;We have a Start Bit
        btfsc   IRStatus,btStart    ;Check if already set (ERROR)
        goto    IRError
        bsf IRStatus,btStart    ;Flag IRStatus
        movlw   0x07
        movwf   BitCount
        goto    isr_done

    CheckZero
        movlw   0x04            ;Check for zero pulse. Should be between 0x4 and 0x6
        subwf   Time2,W
        btfss   STATUS,C        ;Greater than 0x3?
        goto    IRError
        movlw   0x06
        subwf   Time2,W
        btfsc   STATUS,C        ;Less than 0x7?
        goto    CheckOne
    ZeroBit btfss   IRStatus,btStart    ;Check if we have previously had Start Bit
        goto    IRError
        clrf    Bit
        call    ProcessBit
        goto    isr_done

    CheckOne
        movlw   0x09            ;Check for One Pulse. Should be between 0x9 and 0xB
        subwf   Time2,W
        btfss   STATUS,C        ;Greater than 0x8?
        goto    IRError
        movlw   0x0b
        subwf   Time2,W         ;Less than 0xC
        btfsc   STATUS,C
        goto    IRError
    OneBit  btfss   IRStatus,btStart    ;Check if we have previously had Start Bit
        goto    IRError
        movlw   0x01
        movwf   Bit
        call    ProcessBit
        goto    isr_done

    IRError clrf    IRStatus        ;clear variables
        clrf    DeviceCode
        clrf    CommandCode
        clrf    ScratchCode
        banksel OPTION_REG      ;bank 1
        bcf OPTION_REG,INTEDG   ;Interrupt on falling edge

    isr_done   
        banksel PORTA           ;bank 0
        clrf    PORTA
        movf    pclath_temp,W
        movwf   PCLATH
        swapf   status_temp,W
        movwf   STATUS
        swapf   w_temp,F
        swapf   w_temp,W
        bcf INTCON,INT0IF
        retfie
    ; End ISR
    ;********

    Init
        banksel OSCCON          ;bank 1
        movlw   0x7d            ;Set Internal 8MHz
        movwf   OSCCON
        bcf ANSEL,0         ;Set RA0 as digital
        movlw   b'00111110'
        movwf   TRISA
        bsf TRISB,0         ;Make RB0 Input
        bsf TRISB,4         ;Make RB4 Input
        banksel PORTA           ;bank 0
        bcf PORTA,0
        bcf PORTA,6
        bcf PORTA,7
    ;clear variables from Time2 to the_end
        movlw   Time2           ;point FSR to variables
        movwf   FSR
        movlw   the_end-Time2       ;set counter = # of vars to clear
        movwf   dlen            ;use dlen as counter
    zero    clrf    INDF            ;clear a variable
        incf    FSR,F           ;increment the pointer
        decfsz  dlen,F          ;finished?
        goto    zero            ;no, go again
    InitISR
        banksel OPTION_REG      ;bank 1
        movlw   b'00000111'     ;enable weak pullups on PORTB - Interrupt on falling edge
        movwf   OPTION_REG
        movlw   b'10010000'     ;Enable INT0 interrupt, Clear INT0 flag
        movwf   INTCON          ;Disable peripheral interrupts, enable global interrupt
        banksel PORTA           ;bank 0
       
    Main    bsf PORTA,0         ;Light LED 1
        bcf PORTA,6
        bsf PORTA,7
        btfss   IRStatus,btDone
        goto    Main
        bsf PORTA,0         ;Light LED 2
        bcf PORTA,6
        bcf PORTA,7
    WaitForRB2
        btfsc   PORTB,4
        goto    WaitForRB2
        clrf    IRStatus        ;clear variables
        clrf    DeviceCode
        clrf    CommandCode
        clrf    ScratchCode
        goto    Main

    ProcessBit
        btfss   Bit,0           ;Check if bit set
        goto    WriteZero
    WriteOne
        bsf ScratchCode,0x07
        goto    RotateRight
    WriteZero
        bcf ScratchCode,0x07
    RotateRight
        rrf ScratchCode,F
        btfss   STATUS,C
        goto    rr1
        bsf ScratchCode,7
        goto    rrdone
    rr1 bcf ScratchCode,7
    rrdone  decfsz  BitCount,F
        return

    WhichCode
        btfss   IRStatus,btCommand
        goto    CommandCodeDone
    DeviceCodeDone
        rrf ScratchCode,F       ;a couple of more rotations
        btfss   STATUS,C
        goto    zero1
        bsf ScratchCode,7
        goto    done1
    zero1   bcf ScratchCode,7
    done1   rrf ScratchCode,F
        btfss   STATUS,C
        goto    zero2
        bsf ScratchCode,7
        goto    done2
    zero2   bcf ScratchCode,7
    done2   movf    ScratchCode,W
        movwf   DeviceCode
        bsf IRStatus,btDone
        return

    CommandCodeDone
        movf    ScratchCode,W
        movwf   CommandCode
        bsf IRStatus,btCommand
        movlw   0x5
        movwf   BitCount
        clrf    ScratchCode
        return

        end
     
    Last edited: Feb 21, 2008
  7. UTMonkey

    UTMonkey New Member

    Joined:
    Oct 16, 2007
    Messages:
    450
    Likes:
    3
    Location:
    Chesterfield, Derbyshire - UK
    This is great, is it me or does it does the code look a lot smaller?
     
  8. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    It's you. :D The code is bigger.

    16F's have no BTG or MOVFF or CPFSGT/CPFSLT or RRNCF/RLNCF (have to move the carry yourself).

    18F will automatically save and restore registers for you on an ISR call, as long as you use RETFIE FAST to return. You have to do it all yourself on 16F.

    I even got rid of your clear_variables subroutine, adding yet another 4 or 5 lines to my version.

    There are a bunch of extra bank select lines in 16F code too.

    On the other hand my cblock is much more compact. Mine is 4 lines. Yours is 10.

    My code has a bit less vertical whitespace.
     
    Last edited: Feb 21, 2008
  9. blueroomelectronics

    blueroomelectronics Well-Known Member

    Joined:
    Jan 21, 2007
    Messages:
    12,536
    Likes:
    170
    Location:
    Toronto, Canada
  10. geko

    geko Active Member

    Joined:
    Mar 2, 2006
    Messages:
    411
    Likes:
    28
    Location:
    Rutland, England, UK
    I've put some code on my website for a Sony SIRC IR decoder for the 16F88 which can decode 12, 15 and 20 bit codes.

    I've tested it with a four different Sony remotes, including the one for my surround sound AV amp which generates 12, 15 and 20 bit codes.

    It is beta code but it seems to be working reliably now so I thought I'd put it up here for anyone whose interested in having a play + find any bugs:p

    http://picprojects.org.uk/projects/sirc/

    Pete
     
  11. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,161
    Likes:
    340
    Location:
    Brisbane Australia
    I had a play today with Swordfish and managed to get it reading a Sony Remote. It will send the device and command codes via RS232 to the PicKit USART tool.

    Code (text):

    {
    *****************************************************************************
    *  Name    : IR_Demo.BAS                                                    *
    *  Author  : Mike Webb                                                      *
    *  Notice  : Copyright (c) 2008 None                                        *
    *          : No Rights Reserved                                             *
    *  Date    : 4/03/2008                                                      *
    *  Version : 1.0                                                            *
    *  Notes   : Will decode a Sony remote and send the device and command      *
    *          : over RS232. Will also light LED if 1-6 are pressed.            *
    *****************************************************************************
    }
    Device = 18F1320
    Clock = 8               // 8MHz clock
    Config OSC = INTIO2, WDT = OFF, LVP = OFF

    Include "18F1320.bas"
    Include "Junebug.bas"
    Include "USART.bas"
    Include "Convert.bas"
    Include "IR.bas"

    Dim Command As Byte
    Dim DeviceCode As Byte

    OSCCON = $70            // 8 MHz clock
    SetBaudrate(br9600)
    While true
        ReadIR(Command,DeviceCode)    
        LED(Command+1)
        USART.Write("Device = ",DecToStr(DeviceCode),"  Command = ",DecToStr(Command),13,10)
        DelayMS (100)
    Wend
    End
     
    And the module,

    Code (text):

    {
    *****************************************************************************
    *  Name    : IR.BAS                                                         *
    *  Author  : Mike Webb.                                                     *
    *  Notice  : Copyright (c) 2008 None                                        *
    *          : No  Rights Reserved                                            *
    *  Date    : 4/03/2008                                                      *
    *  Version : 1.0                                                            *
    *  Notes   :                                                                *
    *          :                                                                *
    *****************************************************************************
    }

    Module IR

    Function GetPulse()As Byte
        GetPulse=0
        While(PORTB.0=1)
        Wend
        While(PORTB.0=0)
            DelayUS (100)
            GetPulse=GetPulse+1
        Wend
    End Function

    Public Sub ReadIR(ByRef pCMD As Byte,ByRef pDEV As Byte)
    Dim I As Byte
    Dim Pulse As Byte
    Dim Error As Boolean
    ADCON1.4 = 1                //ensure Portb.0 is digital
    TRISB.0=1                   //and is input
        Repeat
            error=false
            pCMD=0
            pDEV=0
            Repeat
                Pulse=GetPulse()
            Until pulse>20              //wait for start pulse > 2.0mS
            For I=0 To 6                //get 7 bit command code
                pCMD=pCMD>>1
                Pulse=GetPulse()        //get pulse length
                If Pulse > 15 Then      //if greater than 15 is error
                    error=true
                ElseIf pulse > 9 Then   //if between 10 and 15 is a 1 bit
                    //pCMD.6=1
                    pCMD=pCMD Or $40
                ElseIf pulse < 4 Then   //if less than 4 is error
                    error=true
                EndIf
            Next    
            For I=0 To 4                //get 5 bit device code
                pDEV=pDEV>>1
                Pulse=GetPulse()        //as above
                If Pulse > 15 Then
                    error=true
                ElseIf pulse > 9 Then
                    //pDEV.4 = 1
                    pDEV=pDEV Or $10
                ElseIf pulse < 4 Then
                    error=true
                EndIf
            Next    
        Until error=false
    End Sub
     
    The Junebug module is on Bill's site. Switches 1,2,3,4 & 6 have to be on.

    Mike.
     
    Last edited: Mar 4, 2008
  12. UTMonkey

    UTMonkey New Member

    Joined:
    Oct 16, 2007
    Messages:
    450
    Likes:
    3
    Location:
    Chesterfield, Derbyshire - UK
    BASIC looks pretty cool! what are it's downsides?
     
  13. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,161
    Likes:
    340
    Location:
    Brisbane Australia
    The same as any compiled language, it will not be as optimized as asm. After saying that, Swordfish seems to be very well written and appears to produce good fast code. The best bit, it's free. Well, it's free as long as you don't use more than 256 bytes of ram. So far I have not exceeded that limit except when I tried to use floating point. Why not download it and give it a try.

    Mike.
    I can't believe I just said that.:eek:
     

Share This Page