November 23, 2024, 03:41:47 PM

News:

Got VSA?  Want to use your Prop-SX?  Now you can!  See the VSA section of the Library forum for Prop-SX code that works with VSA.


Debounce PIR

Started by Jadams, July 31, 2010, 09:33:59 AM

Previous topic - Next topic

Jadams

Following is a program I'm using to turn on and off lights and sounds as different inputs are triggered.  I'm working on a 'scan inputs' version but in the meantime, I can't figure how to debounce the PIR.  I don't want it to sit and wait for the PIR to trigger on PIN4.  It needs to continually check 5 and 6 also.  Everything works as I want except for some false triggers from the PIR which is probably from the hot weather.

Thanks

' =========================================================================
'
'   File...... ShopSecurity.BS1
'   Purpose... Announce visitor at door, flood lights on with beam break after dark
'   Author....
'
'
'   E-mail....
'   Started...
'   Updated...
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------


' -----[ Revision History ]------------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  Sio             = 7                     ' SETUP = out; no ULN
SYMBOL  Trigger         = PIN6                  ' Light Beam NC Relay - Normal=on   Tripped=off
SYMBOL  Sensor          = PIN5                  ' Light=on  Dark=off
SYMBOL  PIR             = PIN4                  ' PIR at doorway
SYMBOL  LED             = PIN2                  ' LED on means it's dark outside
SYMBOL  FlickerLight    = PIN1                  ' Signal for doorway
SYMBOL  Relay           = PIN0                  ' Relay for outside lights
' -----[ Constants ]-------------------------------------------------------

SYMBOL  Baud            = OT2400
SYMBOL  IsOn            = 1
SYMBOL  IsOff           = 0
SYMBOL  Yes             = 1
SYMBOL  No              = 0
SYMBOL  Light           = 1
SYMBOL  Dark            = 0


' -----[ Variables ]-------------------------------------------------------
SYMBOL  status          = B0
SYMBOL  playing         = BIT7                 ' 1 when AP-8 is playing
SYMBOL  reps            = B2



' -----[ Initialization ]--------------------------------------------------

Reset:
  PINS = %00000000                              ' clear all outputs
  DIRS = %00000111                              ' P0, P1, P2 = outputs

  SEROUT Sio, Baud, ("!!!!!!!AP8", %00, "X")    ' stop audio if playing

  PAUSE 20000                                   ' PIR warmup




' -----[ Program Code ]----------------------------------------------------

Main:
        LED = IsOff
        IF Sensor = Dark THEN LED_On

Check_Trigger:

    IF Trigger = IsOn THEN Check_PIR              'NC relay

        GOSUB Start_AP8_2                         'Light Beam
        PAUSE 250
        GOSUB Let_AP8_Finish
        PAUSE 500

     IF Sensor = Light THEN Main                  ' if it's dark drop down
        Relay = IsOn                              ' turn on outside light
        PAUSE 10000
        Relay = IsOff


        GOTO Main

Check_PIR:

     PAUSE 1500
     IF PIR = IsOff THEN Main                       'Door PIR

        GOSUB Start_AP8_0
        PAUSE 250
        GOSUB Let_AP8_Finish
        PAUSE 500

        GOTO Main
LED_On:

         Led = IsOn                                 ' turn LED on

         GOTO Check_Trigger

' -----[ Subroutines ]-----------------------------------------------------

Start_AP8_0:                               'Door PIR
  SEROUT Sio, Baud, ("!AP8", %00, "P", 0)   ' play segment
  FOR reps = 1 TO 10
        FlickerLight = IsOn
        PAUSE 300
        FlickerLight = IsOff
        PAUSE 300
        NEXT

  RETURN

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

Start_AP8_2:                                  ' Light Beam
  SEROUT Sio, Baud, ("!AP8", %00, "P", 2)     ' play segment
  FOR reps = 1 TO 5
        FlickerLight = IsOn
        PAUSE 300
        FlickerLight = IsOff
        PAUSE 300
        NEXT

  RETURN

' -------------------------------------------------------------------------
  ' Holds program until AP-8 is finished playing current segment

Let_AP8_Finish:
  SEROUT Sio, Baud, ("!AP8", %00, "G")          ' get status
  SERIN  Sio, Baud, status
  IF playing = Yes THEN Let_AP8_Finish
  RETURN

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



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


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


' -----[ User Data ]-------------------------------------------------------
Jim Adams

JonnyMac

Do me a favor... just explain what you want the program to do and let me write it from scratch; the way my (twisted) brain works that's a far easier process.  It also provides the opportunity to compare your coding style with mine.
Jon McPhalen
EFX-TEK Hollywood Office

Jadams

I wasn't expecting a rewrite, but thanks for your time.  The inputs and outputs are the way I have it configured today.

Inputs:

P7 = AP-8
P6 = NC relay from light beam, when beam is broken relay opens.
P5 = Photo Resistor – Checking for Light/Dark condition, when it's light outside output is high, dark = low
P4 = PIR

Outputs:

P2 = LED
OUT0 = Relay for 120v lights
OUT1 = WickLED



1.  When dark outside
     a.  LED is on, otherwise off.

2.  When light beam is broken
     a.   AP-8 plays segment 0
     b.   WickLED flashes 5 times and if it's dark outside, 120v lights come on for 10 seconds, then off.

3.  When PIR detects motion
     a.  AP-8 plays segment 2
     b.  WickLED flashes 10 times


Jim Adams

Jadams

In case anyone can help with the debounce issue with multiple inputs, I have made some minor changes to the outputs from the above post.

Inputs:

P7 = AP-8
P6 = NC relay from light beam, when beam is broken relay opens.
P5 = Photo Resistor – Checking for Light/Dark condition, when it's light outside output is high, dark = low
P4 = PIR

Outputs:

OUT3 = Green
OUT2 = Red
OUT1 = Yellow
OUT0 = Relay for 120v lights




1.  When dark outside
     a.  Red is on, otherwise off.

2.  When light beam is broken
     a.   AP-8 plays segment 0
     b.   Yellow flashes 10 times and if it's dark outside, 120v lights come on for 20 seconds, then off.

3.  When PIR detects motion
     a.  AP-8 plays segment 2
     b.  Green flashes 10 times


Thanks
Jim Adams

JonnyMac

August 09, 2010, 08:51:13 AM #4 Last Edit: August 09, 2010, 08:57:56 AM by JonnyMac
Okay, here you go.  Now... my gut tells me that this is not what you want, however, it is what you described.  The problem with describing programs step-by-step -- in psuedo-code, as it were -- is that one often lists things serially that are supposed to be happening in parallel.  I have this idea that you actually want the Green and Yellow LEDs to flash WHILE the AP-8 is playing, not after.  

In future, please trust that I can translate your English description of the programs behavior to the code you want.  What I mean is, describe the behavior that you want to see from the program, not the way you think the code show work.

If I'm right and want the LEDs to flash while the AP-8 is playing, just move the call to Wait_AP8 to after the flashing loop.

' =========================================================================
'
'   File......
'   Purpose...
'   Author....
'   E-mail....
'   Started...
'   Updated...
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------
'
' P6 : Connect NC contacts between P6.W and P6.B; when relay is active and
'      contacts open, P6 goes high.
'
' P5 : Configure photoresistor circuit so that input goes high when dark
'
'      +5 ---[fixed]--- P5.W ---[photoresistor]--- P5.B
'
' Remove ULN2803 pins 1, 2, and 3.


' -----[ Revision History ]------------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  Sio             = 7                     ' SETUP = UP; no ULN

SYMBOL  LightBeam       = PIN6                  ' SETUP = UP; no ULN
SYMBOL  Darkness        = PIN5                  ' no ULN
SYMBOL  PIR             = PIN4

SYMBOL  Green           = PIN3
SYMBOL  Red             = PIN2
SYMBOL  Yellow          = PIN1
SYMBOL  Lights          = PIN0


' -----[ Constants ]-------------------------------------------------------

SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0

SYMBOL  Yes             = 1                     ' for active-high in/out
SYMBOL  No              = 0

SYMBOL  Baud            = OT2400


' -----[ Variables ]-------------------------------------------------------

SYMBOL  triggers        = B0
SYMBOL   trBeam         =  BIT6                 ' debounced trigger bits
SYMBOL   trDark         =  BIT5
SYMBOL   trPIR          =  BIT4

SYMBOL  status          = B1
SYMBOL   playing        =  BIT15

SYMBOL  idx             = B2


' -----[ Initialization ]--------------------------------------------------

Power_Up:
  PINS = %00000000                              ' clear all
  DIRS = %00001111                              ' make P0-P3 outputs

  SEROUT Sio, Baud, ("!!!!!!!AP8", %00, "X")    ' re-sync AP-8

Reset:
  PAUSE 20000                                   ' re-trigger delay


' -----[ Program Code ]----------------------------------------------------

Main:
  triggers = %01110000                          ' arm triggers
  FOR idx = 1 TO 20                             ' debounce, 100ms
    PAUSE 5
    triggers = triggers & PINS                  ' re-scan inputs
  NEXT

  Red = trDark                                  ' if dark, Red is on

  IF trBeam = Yes THEN Show_Y                   ' beam broken?
  IF trPIR = Yes THEN Show_G                    ' PIR detect?
  GOTO Main


Show_Y:
  idx = 0
  GOSUB Play_AP8                                ' play segment 0
  GOSUB Wait_AP8                                ' wait until done
  FOR idx = 1 TO 10                             ' flash
    Yellow = IsOn
    PAUSE 250
    Yellow = IsOff
    PAUSE 250
  NEXT
  Lights = IsOn                                 ' 120 lights on
  PAUSE 20000
  Lights = IsOff
  GOTO Reset


Show_G:
  idx = 2
  GOSUB Play_AP8                                ' play segment 2
  GOSUB Wait_AP8                                ' wait until done
  FOR idx = 1 TO 10                             ' flash
    Green = IsOn
    PAUSE 250
    Green = IsOff
    PAUSE 250
  NEXT
  GOTO Reset


' -----[ Subroutines ]-----------------------------------------------------

' Play AP-8 segment specified in "idx"

Play_AP8:
  SEROUT Sio, Baud, ("!AP8", %00, "P", idx)
  RETURN

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

' Waits while AP-8 is playing

Wait_AP8:
  PAUSE 25
  SEROUT Sio, Baud, ("!AP8", %00, "G")
  SERIN  Sio, Baud, (status)
  IF playing = Yes THEN Wait_AP8
    RETURN


' -----[ User Data ]-------------------------------------------------------


Jon McPhalen
EFX-TEK Hollywood Office

Jadams

You have it just right.  The lights can flash after the AP-8 plays, it's not important in this application.  The lights are for visual, in case there is high noise in the area, or I'm not in the area where the lights are located, I can hear the sound. 

I will have to change my photo resistor configuration.  I have it now so 'light' goes high.  That's a minor change.

Thanks for your help.
Jim Adams

JonnyMac

You're welcome. 

When you're doing multiple triggers it's best that they use the same polarity (active high is easiest) so that you can debounce them all in one throw.
Jon McPhalen
EFX-TEK Hollywood Office

Jadams

I have a couple of questions:

I've seen this in your codes before, will you explain this logic please?

      triggers = triggers & PINS                  ' re-scan inputs

   
I understand why no ULN on P7, but why not on P6 and P5?

Thanks for the lessons.
Jim Adams

JonnyMac

The debounce loop is a *little* tricky and works using AND logic. 

1 AND 1 = 1
1 AND 0 = 0

I preload the triggers variable with a value that "arms" the trigger bits.  That variable is ANDed with the input and inputs that are high will stay 1; any that are low will be forced to 0 and will stay that way through the cycle.  At the end of the cycle any bits that are still 1 indicate a valid trigger input.

No ULN on P6 because you're pulling it high when the relay is relaxed and you don't want to be fighting against the pull-down in the ULN.  Same for the P5 input; you don't want the ULN resistors impacting that circuitry.
Jon McPhalen
EFX-TEK Hollywood Office