Shop OBEX P1 Docs P2 Docs Learn Events
PBASIC question — Parallax Forums

PBASIC question

Just a quick question, and maybe this is my old habit of trying to combine programming steps, from 52 years of programming experience, across a dozen or so different BASIC dialects. Just to get this out of the way, "PIR" is defined as a bit variable. I'm trying to combine the following 2 statements into a single statement (these work):

PIR = IN0   ' Read state of pin-0 into PIR variable.
IF (PIR = 1) THEN GOSUB...

and this statement works:

IF (IN0 = 1) THEN GOSUB...

But this statement does not work:

IF ((PIR = IN0) = 1) THEN GOSUB...  ' Read pin-0 into PIR and evaluate if that quantity = 1

It seems to load into the stamp correctly, but PIR is always zero. I've been messing with this for a few hours now, and I guess I don't understand why the BS2 can't evaluate (PIR = IN0) and then evaluate if that quantity = 1, or am I somehow doing it wrong, combining the statements? I'm probably missing something simple, but I'm stumped!

Comments

  • You can't evaluate complex statements like that with the BASIC Stamp. Split that into separate lines.

    BTW... you can get sporadic output from the PIR, so it's really best to debounce the signal before trigger some behavior. I tend to use 25ms for safety (have used these in lots of haunted-house props and controls).

    Something like this:

    Check_Sensor:
      debounce = 0
      FOR x = 1 to 25
        debounce = (debounce + 1) * IN0
        PAUSE 1
      NEXT
      IF (debounce = 25) THEN...
    

    I don't like using direct pin constants as I'm doing here. I would use the PIN directive to assign PIR to IN0.

  • @JonnyMac said:
    You can't evaluate complex statements like that with the BASIC Stamp. Split that into separate lines.

    BTW... you can get sporadic output from the PIR, so it's really best to debounce the signal before trigger some behavior. I tend to use 25ms for safety (have used these in lots of haunted-house props and controls).

    Something like this:

    Check_Sensor:
      debounce = 0
      FOR x = 1 to 25
        debounce = (debounce + 1) * IN0
        PAUSE 1
      NEXT
      IF (debounce = 25) THEN...
    

    I don't like using direct pin constants as I'm doing here. I would use the PIN directive to assign PIR to IN0.

    Thanks Jon! I've got 3 PIR sensors on my desk, currently (OSEPP, Parallax, and a cheap one I got off Amazon). They all seem to give off random noise occasionally, right after a trigger. I've haven't had issues with false triggers or reflections, like some people have. You're absolutely right about debouncing; I just hadn't gotten to that part yet. I only started the project yesterday. While I'm not making a Haunted House, it IS for a Halloween prop: I have a realistic-looking plastic skeleton sitting in a "toe-pincher" coffin. The BS2 reads the PIR and turns on a vibrating bed-frame motor briefly (using a solid-state relay), for about 500ms. Just a quick "burp" to cause attention. I'm hoping the weather clears up! Even though Halloween's a few weeks off, I don't want my coffin to get soaked! It was a PITA to build, and I still have to paint it!

    As a test, I added your debounce method. After debouncing, I turn the SSR's LED on for 500ms, and then off, then I pause for 3 seconds, before returning to the main loop. Occasionally, it seems like I get multiple motion hits, and the LED turns on/off a 2nd time. Your thoughts?

    Jeff

  • @JonnyMac said:
    You can't evaluate complex statements like that with the BASIC Stamp. Split that into separate lines.

    BTW... you can get sporadic output from the PIR, so it's really best to debounce the signal before trigger some behavior. I tend to use 25ms for safety (have used these in lots of haunted-house props and controls).

    Something like this:

    Check_Sensor:
      debounce = 0
      FOR x = 1 to 25
        debounce = (debounce + 1) * IN0
        PAUSE 1
      NEXT
      IF (debounce = 25) THEN...
    

    Here's my program. I added an IF/THEN right after your "debounce = 0", so that if PIR =0, it ignores the debounce steps. I'm not certain of exactly why, but it seems to have helped with the multiple triggers.

  • It would be easier to evaluate your code by seeing it. Please post.

    Even under the best conditions, low-cost PIRs seem dodgy. There was a time when a haunt that a friend was helping was having odd problems with random triggering. It turned out there was a pipe in the wall the carried hot water and would, occasionally, be "seen" by the sensor. I tend to put cheap PIRs in a pipe cap with a short length of pipe to reduce their field of view.

  • JonnyMacJonnyMac Posts: 8,924
    edited 2021-10-09 00:48

    Here's another approach. Just a tip: whitespace and clean formatting are your friends. I start with a template (attached) to keep my code organized and tidy.

    This version shows how to randomize the run time of your SSR, from 500 to 1000 milliseconds. Even if you don't do this, what I find useful with Halloween props is randomizing a delay between the trigger detection and the activation of the prop. That way you can surprise those who think they know where your trigger is located.

    Have fun.

    ' -----[ Initialization ]--------------------------------------------------
    
    Reset:
      INPUT PIR
      LOW SSR                                       ' off
    
      HIGH LED                                      ' indicate warm-up
      PAUSE 40000
      LOW LED
    
      lottery = 1031                                ' seed random #
    
    
    ' -----[ Program Code ]----------------------------------------------------
    
    Main:
      debounce = 0                                  ' reset
    
    Check_Trigger:
      RANDOM lottery                                ' stir random #
      PAUSE 1
      debounce = (debounce + 1) * PIR               ' update debounce counter 
      IF (debounce < 25) THEN Check_Trigger         ' wait for valid trigger
    
      tenths = lottery // 6 + 5                     ' random, 5 to 10
    
    Run_Prop:
      SSR = IsOn
      PAUSE 100
      tenths = tenths - 1
      IF (tenths > 0) THEN Run_Prop
      SSR = IsOff
    
    Hold_Off:
      PAUSE 3000                                    ' prevent new trigger
    
      GOTO Main
    
Sign In or Register to comment.