November 23, 2024, 12:02:57 PM

News:

Be sure to checkout our Vixen interfaces in the Library forum -- if you want PC automation at near zero cost, EFX-TEK and Vixen is a great combination of tools.


Need Program Fix

Started by Lindiur, October 31, 2009, 10:57:51 AM

Previous topic - Next topic

Lindiur

Sorry about the late notice here but I am having trouble with a program. I can't seem to get the solenoid to turn on. No sucking sound when hooked up. Its a very simple program you would think but i guess its not for me. its just a grave popper. sequence is PIR detected sound on (cowlacious p/200) valve on (12vdc) and light on (3.42v). everything on for 10 seconds and then reset. 45 second wait for next trigger. using a 12v, 500ma transformer.

Here is the code. Dont know why the solenoid what trigger, everything else is working. Also when i plug the solenoid into the v+ and ground i can hear it working. Any help would be great.
' =========================================================================
'
'   File......
'   Purpose...
'   Author....
'   E-mail....
'   Started...
'   Updated...
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------
'
' Trigger :: Parallax-compatible PIR or N.O. button (mat switch, etc.)
'            -- connect N.O. button between P6.W and P6.R


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


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

SYMBOL  Trigger         = PIN6                  ' SETUP = DN
SYMBOL  CARP            = PIN5                  ' V+/OUT5 to V-Trig @ 12v

SYMBOL  Light             = PIN2
SYMBOL  Valve            = PIN0


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

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

SYMBOL  Yes              = 1
SYMBOL  No               = 0


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

SYMBOL  timer           = B2


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

Reset:
  PINS = %00000000                              ' reset pins
  DIRS = %00100101                              ' set output pins

  PAUSE 45000                                        ' PIR warm-up / delay


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

Main:
  timer = 0                                     ' reset timer

Check_Trigger:
  PAUSE 5                                       ' loop pad
  timer = timer + 5 * Trigger                   ' update timer
  IF timer < 100 THEN Check_Trigger             ' wait for 0.1 sec input


  CARP = IsOn                                   ' start audio
  PAUSE 500
  CARP = IsOff

  Valve = IsOn

  Light = IsOn
  PAUSE 10000                                   ' run for 10 seconds

  GOTO Reset


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


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


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

JonnyMac

Maybe you have a bad ULN output -- what is the wattage of your valve?  It should be 3w or less for the ULN.   Tell me what the wattage of your valve is and, if possible, I'll show you a different way to use the ULN to accommodate it.
Jon McPhalen
EFX-TEK Hollywood Office

Lindiur

The solenoid is a 12vdc and 5.4 watts.

JonnyMac

There's you're problem -- the ULN really won't tolerate too much more than 3w per channel.  

This is a slightly-advanced strategy that John and I have employed in the past with great success.  This involves a programming technique called masking, whereby we can turn multiple pins on or off at the same time.  That is critical if we're going to use two outputs to supply the current to a single valve.

I'm assuming OUT0 is blown so I've moved your wiring -- give this a go (but please don't ask me to explain it in detail today -- too busy!)

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


' -----[ Program Description ]---------------------------------------------
'
' Trigger :: Parallax-compatible PIR or N.O. button (mat switch, etc.)
'            -- connect N.O. button between P6.W and P6.R


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


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

SYMBOL  Trigger         = PIN6                  ' SETUP = DN
SYMBOL  CARP            = PIN5                  ' V+/OUT5 to V-Trig @ 12v

SYMBOL  Light           = PIN3                  ' V+/OUT3

SYMBOL  ValveB          = PIN2                  ' V+/OUT2 (connect to OUT1)
SYMBOL  ValveA          = PIN1                  ' V+/OUT1 (connect to OUT2)


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

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

SYMBOL  Yes             = 1
SYMBOL  No              = 0


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

SYMBOL  timer           = B2


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

Reset:
 PINS = %00000000                              ' reset pins
 DIRS = %00101110                              ' set output pins

 PAUSE 45000                                   ' PIR warm-up / delay


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

Main:
 timer = 0                                     ' reset timer

Check_Trigger:
 PAUSE 5                                       ' loop pad
 timer = timer + 5 * Trigger                   ' update timer
 IF timer < 100 THEN Check_Trigger             ' wait for 0.1 sec input

 CARP = IsOn                                   ' start audio
 PAUSE 500
 CARP = IsOff

 GOSUB Valve_On

 Light = IsOn

 PAUSE 10000                                   ' run for 10 seconds
 GOTO Reset


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

Valve_On:
 PINS = PINS | %00000110                       ' both pins on
 RETURN

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

Valve_Off:
 PINS = PINS &/ %00000110                      ' both pins off
 RETURN


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



Jon McPhalen
EFX-TEK Hollywood Office

Lindiur

Sorry for not understanding completely. Do I wire the valve to the v+ and the other wire goes to which out..... 1 or 2?

JonnyMac

Both!!!  It says so, right in the code.  ;D

Just to be absolutely clear you will connect one side of your valve to V+ and the other will go to OUT1 and OUT2.  By using two outputs and the switching techniques used in the program you can switch a little more current.
Jon McPhalen
EFX-TEK Hollywood Office

Lindiur

Cool!!!  ;D Thanks Jon for taking care of me. I can't say enough.

JackMan

Hi Guys,
    I'm new to the forum and fairly new to programming PBASIC. I'm pretty good with schematics, circuits, and computers and while I understand quite a bit with the PBASIC programming, at this point there's a lot that I don't understand. I'm looking forward to gaining knowledge in this area through the Forum. I purchased a Prop-1 a few weeks ago and have written the code for a few of my own props. Basic stuff that so far has worked without a hitch.  I have a quick question about the topic of this thread. The posted code seems a little over complicated for the task, is there a reason for all the extra stuff? The first program that I compiled was for the same type of prop described in this thread. The code I wrote is much shorter and works just fine.

' {$STAMP BS1}
' {$PBASIC 1.0}

SYMBOL Pir   = PIN6
SYMBOL Valve = 0
SYMBOL Audio = 1
SYMBOL IsOff = 0



Main:

     IF Pir = IsOff THEN Main
     HIGH Valve
     HIGH Audio
     PAUSE 5000
     LOW Valve
     LOW Audio
     PAUSE 50000
     GOTO Main

I realize I have a lot to learn but can someone explain why there would be a need for all the extra code in the examples? Thanks!

JonnyMac

Key points:

1. Deboucing a digital input is really important, especially with devices like PIRs (that are twitchy, anyway)
2. The pulse to the audio player should be short to prevent looping (unless looping is desired)

I've been programming a long time (30+ years) and do it every day -- we pros don't tend to complicate our lives, we lean toward code that is a simple as it can be while providing the reliability that everyone expects.  Your program is simple, and will work -- under perfect circumstances.  In an electrically-noisy environment or with a twitchy PIR you might get false starts.  If the audio track is less that 5000 milliseconds (5s) it will loop.  Neither of these conditions is desirable.

There's a fine line between simplicity and elegance -- strive for elegance.
Jon McPhalen
EFX-TEK Hollywood Office

JackMan

December 01, 2009, 01:31:01 PM #9 Last Edit: December 01, 2009, 01:34:07 PM by JackMan
The pulse to the audio player could be shortened and the code would still be extremely simple. I'm using a Cowlacious player, the length of the signal doesn't matter, the audio can't loop. I'm using a Parallax PIR that has its field of view choked down, connected to the Prop-1 in a Bucky Skeleton that I've converted into a talker with LED eyeballs that light up with each one-liner. The Cowlacious player currently has 16 phrases on it channeled into a home built audio-servo driver for the jaw movement. I have an external MP3 type speaker with built in amplifier mounted in Bucky's chest. The Prop-1, Cowlacious player, the audio-servo driver, and the servo are all contained within the skull, (very tight fit I might add).  I'm using the same simple code with a 60 second delay between triggers. I had this set up in my living room for quite some time along with TV, stereo, cordless telephones etc. and the Prop-1 never gave a false trigger. I'm not about to question your expertise by any means, but am I just lucky? I guess I need more explanation on "Deboucing a digital input" and exactly what part of your code relates to that. Thanks!

JonnyMac

Yes, you're lucky.  We sell a couple thousand Prop-1 controllers every year and I write a lot of code.  Your living room is not a terribly noisy environment from an electrical standpoint (i.e., radiated EMI).  But when you're dealing with a professional haunted house with miles of electrical wires running all kinds of signals, walkie-talkies in use, etc., things can get dicey.  Believe me, I developed the debounce code because of false starts with code like yours (that we had supplied).

And... I have an older Cowlacious board that DOES loop if the input is on longer the audio duration.  Part of our job here is to write code that will across a spectrum of user combinations, most that we cannot control.  So, your code works for you and your particular combination of components and installation -- my point is that it may not work (100% reliably) for others in their particularity setup.

Debouncing is a form of digital filter.  You can get spurious outputs from a PIR or into the controller from a radiated EMI pulse (walkie-talkie, etc.).  While these spurious pulses are very short, if they happen to occur when you're doing the [simple] PIR test then they can create a false start.  Again, we know this from experience.  By debouncing with a simple timing loop, we ensure that the output from the PIR (or other trigger device) is valid before activating the main prop code.

Let me say this again: I write code that is as simple as possible while being as reliable as our customers expect.  You don't have to go to the lengths I do... just be prepared for the possible consequences of "quick and easy" code.  I have enough scars to have learned my lessons well!  ;D
Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

This is the debouncing loop -- if forces the trigger input to be active for 100ms before allowing the prop to run:

Check_Trigger:
  PAUSE 5                                       ' loop pad
  timer = timer + 5 * Trigger                   ' update timer
  IF timer < 100 THEN Check_Trigger             ' wait for 0.1 sec input
Jon McPhalen
EFX-TEK Hollywood Office

JackMan

Hey thanks for the additional info, I can definitely see where a professional haunted house could cause some problems. If I have any false starts I'll know what needs to be fixed, I think. I don't really understand what the first and second line of the debounce code translates to but then again I have a lot to learn as far as code goes. I'm looking forward to gaining much knowledge in this area. 

JonnyMac

What the code does is make sure that when the Trigger input goes high that it stays high for at least 100ms -- this is considered a good input.  The real cool stuff is in this line:

  timer = timer + 5 * Trigger

Remember, PBASIC code is evaluated left-to-right.  So what this does is add 5 (the PAUSE value from the line above) to the variable timer; next is the cool part: Trigger is an input pin which can have one of two values: 0 (off) or 1 (on).  As long as the trigger input stays on the value of timer is maintained because anything multiplied by one stays the same.  If, however, the input drops out and is momentarily zero then the value of timer is reset because any value multiplied by zero becomes zero.

This is the part of the fun of programming.  Once you learn a few of these tricks they come easily and you'll create your own.
Jon McPhalen
EFX-TEK Hollywood Office

JackMan

Well, I'm usually pretty quick at grasping on to new things but I have to admit I'm struggling a little with understanding PBASIC code. I've read thru the list of commands in the HELP guide but I don't see a lot of the symbols and abbreviations used in some of the examples. What does the * symbol do?

timer = timer + 5 * Trigger

In this line, I'm assuming that the "<" means "is less than", but again, I don't see that in any of the documentation.

IF timer < 100 THEN Check_Trigger             

And in this example, what is pos? What is the purpose of PAUSE 19?

Setup:
  LOW Servo

Servo_Move:
  FOR pos = 60 TO 240 STEP 1
    PULSOUT Servo, pos
    PAUSE 19
  NEXT
  FOR pos = 240 TO 60 STEP -1
    PULSOUT Servo, pos
    PAUSE 19
  NEXT
  GOTO Servo_Move


Sorry if these seem like dumb questions, but I really want to understand what each and every entry does and what it translates to. You know that old saying, "Give a hungry man a fish.....feed him for a day. Teach a hungry man how to fish....feed him for a lifetime.
;D