PIC10F200 Automated IR Light Switch


Closed Thread
Results 1 to 8 of 8
  1. #1
    Join Date
    Jul 2003
    Posts
    2,405

    Smile PIC10F200 Automated IR Light Switch

    I know it's not BASIC, but this little gadget comes in handy for folks that are just too lazy (like myself)
    to turn on/off light switches all the time.

    It's pretty simple stuff, and heavily commented, but if you have questions let me know.
    Code:
    ;************************************************************************
    ;*  Name      : IR_SWITCH.asm                                           *
    ;*  Author    : Bruce Reynolds                                          *
    ;*  Date      : Feb 8th, 2006                                           *
    ;*  Version   : 1.0                                                     *
    ;*  Notes     : PIC10F200 Automatic IR Appliance Switch	                *
    ;*  Assembler : MPASMWIN v5.01                                          *
    ;*  Operation : GP0 modulates an IR LED at 40kHz by generating 'Cycles' *
    ;*  : number of 40kHz pulses. GP2 samples the IR detector output after  *
    ;*  : each carrier burst period. A logic 0 on the IR detector output    *
    ;*  : indicates a target is within range reflecting IR energy back onto *
    ;*  : the IR detector. After 6 Hits in approximately 2 seconds GP1 will *
    ;*  : turn on to drive a relay controlling 1 or more lights.            *
    ;*  : After OffTime number of samples with no Hits, approx 11 seconds,  *
    ;*  : the drive output on GP1 is turned back off.                       *
    ;*  : As long as the target is within range the output will remain on.  *
    ;*  : When target leaves the area, after ~11 seconds, it turns back off *
    ;&  : providing an auto light switch by sensing presence / no presence. *
    ;************************************************************************
    
        title       "Infrared automatic light switch"
        processor   10F200
    
        include     <P10F200.inc>
    
        __CONFIG    _IntRC_OSC & _WDT_OFF & _CP_OFF & _MCLRE_OFF
    
        #define IRLED GPIO,0        ; IR LED drive output pin
        #define IRDET GPIO,2        ; IR detector input pin
    	
        #define LightOn bsf GPIO,1  ; turn drive output on
        #define LightOff bcf GPIO,1 ; turn drive output off
    
        ; OffTime = 45 = approx 11 seconds. Adjust as required
        #define OffTime D'45'   ; delay before turn off of drive output
    
        ; MAX_HITS = 6 = approx 2 seconds before turn on if target present
        #define MAX_HITS D'6'   ; MAX object hits before drive output turns on
    
        ; setup RAM variable space
        cblock 0x10         ; user RAM starts at 0x10 for 10F200/204
          DelayTime:3       ; reserve 3 locations for delay counters
          Cycles            ; # of carrier cycles to generate IR signal
          OffDelay          ; time counter for output drive turn off delay
          Hits              ; holds recorded # of target Hits
        endc
    
        org   0x00
        goto  Init         ; initialize I/O & peripherals
    
    Main:
        movlw  D'50'        ; generate 50 x 40kHz carrier cycles
        movwf  Cycles       ; load carrier cycle count
        call   Pulse        ; generate carrier burst
    
        movlw  D'1'         ;
        call   Delay2       ; delay between carrier bursts/target checks
        goto   Main         ; loop to Main
    	
        ; infrared LED connection
        ; GPIO,0 ----\/\/\/\----|<|---- +5V DC
        ;              420     IR LED
    
    Pulse                   ; send 'Cycles' number of 40kHz bursts
        bcf    IRLED        ; 1uS turn on IR LED here
        goto   $+1          ; 2us
        goto   $+1          ; 2uS
        goto   $+1          ; 2us
        goto   $+1          ; 2uS
        goto   $+1          ; 2us
        goto   $+1          ; 2uS (13uS with IR LED on)
        bsf    IRLED        ; 1uS turn off IR LED here
        goto   $+1          ; 2us
        goto   $+1          ; 2uS
        goto   $+1          ; 2us
        goto   $+1          ; 2us
        decfsz Cycles,f     ; 1uS decrement Cycles count, end pulse if Cycles = 0
        goto   Pulse        ; 2uS/1uS (25uS total = 40kHz)
        
        ; goto Pulse above is 1uS once Cycles = 0, so it takes 8uS after the LED
        ; is off before we test the IR detector output. This is plenty fast since
        ; it takes a while for the detector output to settle after ending the IR
        ; carrier burst.
    
        btfsc  IRDET        ; test detector output. If 0, target in range, CountHits
        goto   AlarmOff     ; else jump to AlarmOff & count down turn-off period
    	
    CountHits
        incf   Hits,f       ; target detected, increment Hits count
        movlw  MAX_HITS     ; load MAX_HITS for comparison with current Hits count
        subwf  Hits,w       ; if Hits = MAX_HITS then turn on drive output
        skpnc               ; if no carry, skip over LightOn, has not reached MAX_HITS
        LightOn             ; carry true, Hits = MAX_HITS, now turn on drive output
        clrf   OffDelay     ; reset OffDelay period after all Hits
        retlw  0            ; return to caller
    
    AlarmOff
        incf   OffDelay,f   ; increment time until turn off
        movlw  OffTime      ; load OffTime for comparison with current OffDelay count
        subwf  OffDelay,w   ; if OffDelay = OffTime, then turn drive output off
        skpnc               ; if no carry, skip over LightOff, has not reached OffTime
        LightOff            ; carry true, turn off output, OffTime period has expired
        clrf   Hits         ; reset Hits count when no target is detected
        retlw  0            ; return to caller
    
    Delay					  ; 
        movlw   D'2'          ; 2 = a delay period of approximately 500mS
    
    Delay2                    ; 
        movwf   delaytime     ; pre-load W & enter at Delay2 for different delays
        movlw   D'232'        ;
        movwf   delaytime+1   ;
        movlw   D'255'        ;
        movwf   delaytime+2   ;
    Dloop
        clrwdt                ; 1
        decfsz  delaytime+2,f ; 1
        goto    $-2           ; 2/1
        decfsz  delaytime+1,f ; 1
        goto    $-4           ; 2/1
        decfsz  delaytime,f   ; 1
        goto    $-6           ; 2/1
        retlw   0             ; 2
    
    Init
        movwf   OSCCAL      ; load factory osccal value at start-up
        bcf     OSCCAL,0    ; do NOT output osc/4 on GP2 (IR sensor input)
        movlw   b'00000001' ; IR LED on GP0 off on power-up
        movwf   GPIO        ; load port latches
        movlw   b'00000100' ; GP2 = IR sensor input, rest outputs
        tris    GPIO        ; set I/O directions
        movlw   b'11011000'	; wake-up on pin change disabled, weak pull-ups off
                            ; Timer0 clock select on GP2 internal
        option              ; write to OPTION_REG
    
        ; clear all user RAM/variables on boot
    
        movlw  0x10         ; initialize pointer
        movwf  FSR          ; to RAM start
    
    ClearNext
        clrf   INDF         ; clear RAM location @ INDF
        incf   FSR,f        ; increment pointer to next location
        btfsc  FSR,4        ; have we cleared location 0x10 yet..?
        goto   ClearNext    ; nope, keep clearing
                            ; yep, all done, continue
    	
        ; approximately ~500mS power-up delay period for
        ; stabilization time
    
        call   Delay
        goto   Main
    
        end
    I recommend using a solid state relay for AC lights/appliances if you have one in your parts bin, but a
    mechanical relay will work as well. You can find a few thousand relay drive circuits on any decent
    search engine.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Hi Bruce,

    Very interesting. It's amazing what you can do with 256 Words, and 16 bytes.

    I was just wondering what the range is. Is it something that can cover a room. Or, is it more for when you sit in your favorite reading chair?

    What comes to mind for me are the automatic sinks and toilets at the airport where you have to be 6 inches from the sensor. Hopefully, it can do better than that?
    <br>
    DT

  3. #3
    Join Date
    Jul 2005
    Posts
    65


    Did you find this post helpful? Yes | No

    Smile

    Hi Bruce

    Another amazing on the list

    Another thing on mind, which if implemented could be really nice feature...If its possible to add toggle feature such that another PIC10F200 is used as the receiver to switch on/off the light upon receiving the IR signal, so that it becomes remote light switch as well.

    Thanks

  4. #4
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Hi Darrel,

    Had to find some use for those itty-bitty 10F surface mount samples I had.

    The whole board with regulator, PIC, resistor, etc, fit onto the back of the IR detector. Just ran wires off to the LED.

    With 15mA through the LED I'm getting around 4' trip distance. You could get a lot more than that with higher LED current or a small array of LED's.

    Now the wife wants one for triggering some aggravating "someone left the toilet seat up again" message...;o}.

    P.S. Nice job on the instant interrupt routines. Handy stuff.

    Note: In the above comments, so no one gets confused, this;
    ; goto Pulse above is 1uS once Cycles = 0, so it takes 8uS after the LED
    ; is off before we test the IR detector output
    should read 10uS after the LED is off. I moved the bsf IRLED up a tad to adjust the LED duty-cycle.

    You can just move this up or down to adjust it as needed. Just spaced out changing the comment text.
    Last edited by Bruce; - 11th February 2006 at 00:36.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Hah! Why do we always have to move the seat?

    You could make the device say "Please return the seat to the Up-right position" if it's left down.

    Think I'm going to play with this little guy. Haven't had a chance to mess with the 10F's yet.

    Are you using the TSOP1140 IR detector module?

    Darrel

    P.S. Thanks! (interrupts)
    Wait till I get through the 18F version. That one's even better.

  6. #6
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Yeah i used the TSOP1140, but any el-cheapo IR module should work pretty much the same for this low-budget gadget.

    I used it because there was room on the back to attach my tiny little PCB with the rest of my parts. The surface mount version 10F200 parts are like a grain of salt.

    Just don't sneeze when you have em in front of you. Lost 4 of my samples.

    P.S. Thanks! (interrupts)
    Wait till I get through the 18F version. That one's even better
    You're welcome. I figured you were already working on the 18F version once you posted the 18F USART_Init macro, then modified it with CHK?RP for the 14-bit core...;o}

    Keep em comin.


    .
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    I figured you were already working on the 18F version once you posted the 18F USART_Init macro, then modified it with CHK?RP for the 14-bit core...;o}
    .
    Busted! &nbsp;
    <br>
    DT

  8. #8
    Dr Bob's Avatar
    Dr Bob Guest


    Did you find this post helpful? Yes | No

    Default Ir Led

    Quote Originally Posted by crematory View Post
    Hi Bruce

    Another amazing on the list

    Another thing on mind, which if implemented could be really nice feature...If its possible to add toggle feature such that another PIC10F200 is used as the receiver to switch on/off the light upon receiving the IR signal, so that it becomes remote light switch as well.

    Thanks
    You could always the IRLED as an IR receiver

Similar Threads

  1. PIC16F877A pwm use for IR transmission
    By mcbeasleyjr in forum General
    Replies: 0
    Last Post: - 11th July 2009, 18:51
  2. automated 4-stroke kill switch using PIC
    By mitchf14 in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 14th January 2009, 21:08
  3. Using LEDs as light sensors
    By skimask in forum Code Examples
    Replies: 3
    Last Post: - 30th December 2006, 22:19
  4. Light switch sensing
    By George in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 20th July 2006, 22:56
  5. how to get pic to pic communication
    By kinsiro in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 30th August 2005, 17:12

Members who have read this thread : 2

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts