November 22, 2024, 01:54:41 AM

News:

You can now use Vixen to program your Prop-1 and Prop-2 controllers!  Get started quickly and easily, without having to learn PBASIC.  Details in the Library forum.


My Mourner prop for 2008

Started by LPFreak1283, April 07, 2008, 12:21:02 PM

Previous topic - Next topic

LPFreak1283

Okay, Here goes!  I wrote this program for the Halloween prop that i am building this year.  I first tried to make it work with a prop-1 only because I had two available.  However, after researching, i found that it wouldn't work.  Queue the prop-2.

What will happen with my prop will be:
1. The prop-2 looks for the matswitch to be triggered.  When that happens, the RC-4 will trigger a spot light and a motor that will make the mourner appear to be weeping.  Also, the AP-8 will turn on sobbing sounds.  This will run for 20 seconds (should be plenty of time for the kids to get close). 

2. Then the suspense will kick in.  The AP-8 will stop but she'll still be weeping.  This happens for 5 seconds.

3. I then have the opportunity to trigger a switch that will prevent the scare from happening.  The reason I did this was because we have alot of toddlers and small children around our neighborhood and just getting them up the driveway is tough. 

4. If the trigger is not on, the RC-4 will turn off the spot and weep, and turn on the fog and strobe light.  Meanwhile, the head will spin around via a heavy-duty servo 180 degrees while blowing the fog out of her mouth.  The AP-8 will switch to a scream.  This runs for 5 seconds. 

5. Then the whole program goes back to the beginning. 

I hope all is well with my code.  I have done a bit of coding in VB6, so i'm not new to coding, just to this language!

I hope to start buying what I need soon!  I can't wait to start working on her!

' =========================================================================
'
'   File....... Mourner.BS2
'   Purpose.... Halloween 2008 Project
'   Author..... FrontYardHaunters.com
'   E-mail..... SabresNut42383@roadrunner.com
'   Started.... April 6, 2008
'   Updated....
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


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


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

Sio           PIN            15                     'Setup = out;no uln
MatSwitch     PIN            14
HandHeld      PIN            13
Servo         PIN            8

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

T2400         CON           396
T38K4         CON           6
Open          CON           $8000
Baud          CON           Open + T38K4            ' baud jumper out of RC4 & AP8
Addr          CON           %00                     '%00-%01

IsOn         CON            1
IsOff        CON            0

SpotWeep     CON            %0011                   'K1 & K2 relays on
StrobeFog    CON            %1100                   'K3 & K4 relays on

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


' -----[ EEPROM Data ]-----------------------------------------------------


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

Reset:
  GOSUB RC4_Reset
  GOSUB AP8_Reset
  PULSOUT Servo, 500                                  'Reset servo forward

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

Main:
  IF MatSwitch = IsOff THEN                           'Check for victims
  GOTO Main
  ENDIF

Lights:
  SEROUT Sio, Baud, ["!RC4", Addr, "S", SpotWeep]     'Spot on, Weep on
  GOTO Cry

Cry:
  SEROUT Sio, Baud, ["!AP8", Addr, "L", 0, 0]         'Start weeping and loop
  PAUSE 20000                                         'Pause 20 seconds
  GOTO Suspense

Suspense:
  SEROUT Sio, Baud, ["!AP8", Addr, "X"]               'Stops weeping
  PAUSE 5000                                          'Pause 5 seconds
  IF HandHeld = IsOn THEN
  GOTO Scare                                          'Scare the crap out of the kids
  ELSE
  GOTO Cry                                            'Don't scare the kids
  ENDIF

Scare:
  PULSOUT Servo, 1000                                 'Spin head around
  SEROUT Sio, Baud, ["!RC4", Addr, "S", StrobeFog]    'Switch lights to Fog on, Strobe on
  SEROUT Sio, Baud, ["!AP8", Addr, "P", 1]            'Start screaming
  PAUSE 5000                                          'Pause 5 seconds
  GOTO Reset

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

RC4_Reset:
  SEROUT Sio, Baud, ["!RC4", Addr, "X"]                'All relays off

AP8_Reset:
  SEROUT Sio, Baud, ["!AP8", Addr, "X"]                'Stop sounds if on

JonnyMac

The program looks fine with two areas to consider:

1. (easy) You might want to debounce the trigger input.  Create a byte variable called timer and use this bit of code:

Main:
  timer = 0
  DO
    PAUSE 5
    timer = timer + 5 * MatSwitch
  LOOP WHILE (timer < 100)


This will force the mat switch input to be active and stable for 100 milliseconds which prevents false triggering.

2 (hard) Servos need to be updated every 20 milliseconds, especially if they're under any kind of load.  You are not doing that, and to add proper updating to the program will take a new approach.  If you find the servo does not behave as you want, I'll write a new program for you that is state-driven.  This will ensure that the servo gets updated appropriately and will hold position.
Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

Another note: PBASIC programs follow a linear path unless you redirect them so you don't need this kind of structure:

  GOTO Cry

Cry:


Without the GOTO the program will still end up at Cry.  PBASIC is different from VB in this regard.
Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

One more note: for 38.4k the B/R jumper must be installed on the RC-4 and AP-8.
Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

April 07, 2008, 01:23:00 PM #4 Last Edit: April 07, 2008, 01:24:56 PM by JonnyMac
Okay, here's a state-driven version to try.  This will keep the servo updated.  Now, notice that there are no long PAUSE commands; this is accomplished by setting a variable called timer which is decremented by 20 ms through the top of the loop as the servo is being refreshed.

In your program you have a choice between scaring and crying.  If you don't elect to scare the program ends up in a loop until you do.  This version will reset after Cry is called the second time -- I suspect this is what you want, otherwise the prop will cry all night once triggered and if you disconnect the hand-held input.

This program compiles, but may need some adjustments; please test carefully.

' =========================================================================
'
'   File....... Mourner.BS2
'   Purpose.... Halloween 2008 Project
'   Author..... FrontYardHaunters.com
'   E-mail..... SabresNut42383@roadrunner.com
'   Started.... April 6, 2008
'   Updated.... by Jon Williams for state-driven operation
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


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


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

Sio             PIN     15                      ' SETUP = out; no ULN
MatSwitch       PIN     14
HandHeld        PIN     13
Servo           PIN     8


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

T2400           CON     396
T38K4           CON     6
Open            CON     $8000
Baud            CON     Open + T38K4            ' B/R in of RC4 & AP8

Addr            CON     %00                     ' %00-%01

IsOn            CON     1
IsOff           CON     0

SpotWeep        CON     %0011                   ' K1 & K2 relays on
StrobeFog       CON     %1100                   ' K3 & K4 relays on


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

state           VAR     Byte                    ' program state
pos             VAR     Word                    ' servo position
debounce        VAR     Byte
timer           VAR     Word


' -----[ EEPROM Data ]-----------------------------------------------------


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

Reset:
  LOW Servo                                     ' ensure proper polarity
  pos = 500
  PULSOUT Servo, pos

  GOSUB RC4_Reset
  GOSUB AP8_Reset

  debounce = 0
  timer = 0


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

Main:
  PULSOUT Servo, pos
  PAUSE 18

  IF (timer > 0) THEN
    timer = timer - 20
    GOTO Main
  ENDIF

  BRANCH state, [trigger, Lights, Cry, Suspense, Choose, Cry, Scare, Reset]
  state = 0


Trigger:
  debounce = debounce + 20 * MatSwitch
  IF (debounce >= 100) THEN
    state = 1
    timer = 0                                   ' no delay before next state
  ENDIF
  GOTO Main


Lights:
  SEROUT Sio, Baud, ["!RC4", %00, "S", SpotWeep]
  state = 2
  timer = 0
  GOTO Main


Cry:
  SEROUT Sio, Baud, ["!AP8", %00, "L", 0, 0]
  IF (state = 2) THEN
    state = 3
    timer = 20000
  ELSE
    state = 7
    timer = 5000
  ENDIF
  GOTO Main


Suspense:
  SEROUT Sio, Baud, ["!AP8", %00, "X"]
  state = 4
  timer = 5000
  GOTO Main


Choose:
  IF (HandHeld = IsOn) THEN
    state = 6                                   ' scare
    pos = 1000                                  ' spin head
  ELSE
    state = 5                                   ' cry (again
  ENDIF
  timer = 0
  GOTO Main


Scare:
  SEROUT Sio, Baud, ["!RC4", %00, "S", StrobeFog]
  SEROUT Sio, Baud, ["!AP8", %00, "P", 1]
  state = 6
  timer = 5000
  GOTO Main


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

RC4_Reset:
  SEROUT Sio, Baud, ["!!!!!!!RC4", Addr, "X"]   ' all off

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

AP8_Reset:
  SEROUT Sio, Baud, ["!!!!!!!AP8", Addr, "X"]   ' stop audio
Jon McPhalen
EFX-TEK Hollywood Office

LPFreak1283

Holy Smokes!  All these notes and no ink! 

I was under the impression that only the the PIR needed debouncing due to the light sensor.  I never do see many people with a matswitch.  Oh well, it's fixed.  When I looked at the note about the GOTO's, I didn't understand it at first.  Then I looked through your code and read the note again.  I feel stupid.  That makes perfect sense. 

In regards to the jumper being out of the AP-8 and RC4, I wrote the same program I had for the prop-1 that needed the jumpers out.  I forgot about it when writing for the prop-2.

I totally blew past the infinite loop.  Even after looking at my code for a bit i didn't see it, but it makes perfect sense. 

I'll try your code out when I get some stuff to work with.  I don't have the prop-2, RC4, or AP8 yet.  I figured i'd submit my work and see what ya thought.  Thanks so much!

LPFreak1283

LPFreak1283

Quick question Jon,
I am looking for a way to slow down my servo movement for two movements.

I start with the servo at 250 (facing forward)
Then I have the servo rotate to 500 (slightly to the left)
Then it rotates back to 250
Then snaps to the left at 700

I want to have the servo go slower to the slightly left position and slower back to facing forward. 

I am looking to get a kind of checking over your shoulder movement where it is slow, then wait for 2-3 seconds, then back again. 

any help is appreciated.  Thanks!  Cory

Caretaker.CCI

Try this thread

http://www.efx-tek.com/php/smf/index.php?topic=616.msg3264#msg3264

Jon wrote it for the Prop-1 but could easily be modified to run on the Prop-2

Greg

JonnyMac

May 22, 2008, 09:13:00 AM #8 Last Edit: May 22, 2008, 09:15:28 AM by JonnyMac
This becomes a little bit tricky; you have to add a target position value and a rate at which you will move.  Give me a little time to mull it over to see if I can find a clean way to add it into your program.

Question: Does this looking over the shoulder activity take place while waiting on a trigger?
Jon McPhalen
EFX-TEK Hollywood Office

LPFreak1283

No, I plan on having it done during the suspense phase.  Here is some updated code that I have been working on.

' =========================================================================
'
'   File....... Mourner.BS2
'   Purpose.... Halloween 2008 Project
'   Author..... FrontYardHaunters.com
'   E-mail..... SabresNut42383@roadrunner.com
'   Started.... April 6, 2008
'   Updated.... by Jon Williams for state-driven operation
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


' -----[ Revision History ]------------------------------------------------
'1.00   - Original program
'1.01   - Jon Williams updated for state-driven operation
'2.00   - My update removing AP-8 and adding VMusic2

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

Sio             PIN     15                      ' Remove Setup; no ULN
TX              PIN     14                      ' SETUP = UP; no ULN
MatSwitch       PIN     13                      ' SETUP = DN; no ULN
HandHeld        PIN     12                      ' SETUP = DN; no ULN
Servo           PIN     8


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

T9600           CON     84
T38K4           CON     6
Open            CON     $8000
BaudRC4         CON     Open + T38K4            ' B/R in RC4
BaudVM2         CON     Open + T9600            ' VM2 baud rate

Addr            CON     %00                     ' %00-%01

IsOn            CON     1
IsOff           CON     0

Spot            CON     %0001                   ' K1 relay on
Weep            CON     %0010                   ' K2 relay on
SpotWeep        CON     %0011                   ' K1 % K2 realys on
StrobeFog       CON     %1100                   ' K3 & K4 relays on




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

state           VAR     Byte                    ' program state
pos             VAR     Word                    ' servo position
debounce        VAR     Byte
timer           VAR     Word


' -----[ EEPROM Data ]-----------------------------------------------------


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

Reset:                                          'state=8
  PAUSE 5000                                    'allow VMusic2 to initialize
  SEROUT TX, BaudVM2, ["VST",CR]                'stop anything that's playing
  LOW Servo                                     ' ensure proper polarity
  pos = 500
  PULSOUT Servo, pos

  GOSUB RC4_Reset

  debounce = 0
  timer = 0


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

Main:
  PULSOUT Servo, pos
  PAUSE 18

  IF (timer > 0) THEN
    timer = timer - 20
    GOTO Main
  ENDIF

  BRANCH state, [trigger, Weep, Cry, Suspense, Choose, Cry, Scare, Cry_Done, Reset]
  '                             0        1         2        3              4           5       6          7             8
  state = 0


Trigger:                                         ' state=0
  debounce = debounce + 20 * MatSwitch
  IF (debounce >= 100) THEN
    state = 1
    timer = 0                                    ' no delay before next state
  ENDIF
  GOTO Main


Weep:                                            ' state=1
  SEROUT Sio, BaudRC4, ["!RC4", Addr, "S", Weep] ' start weep motor
  state = 2                                      ' goto cry
  timer = 0                                      ' go now
  GOTO Main


Cry:                                             ' state=2 and 5
  SEROUT  Tx, BaudVM2, ["VRF weep.mp3", CR]      ' Play file Weep.mp3 and repeat
  IF (state = 2) THEN                            ' check current state
    state = 3                                    ' goto suspense
    timer = 20000                                ' but wait 20 seconds before going
  ELSE
    state = 8                                    ' goto Reset
    timer = 30000                                ' but wait 30 seconds before going
  ENDIF
  GOTO Main


Suspense:                                        ' state=3
  SEROUT Tx, BaudVM2, ["VP", CR]                 ' Pause weeping
  SEROUT Sio, BaudRC4, ["!RC4", Addr, "R", IsOff]' Stops weep motor
  'Head turn slightly to left (pos = 500)
  'Pause 3-4 seconds
  'Head turns back to forward
  state = 4
  timer = 0
  GOTO Main


Choose:                                          ' state=4
  IF (HandHeld = IsOn) THEN
    state = 6                                    ' scare
    pos = 700                                    ' spin head
  ELSE
    state = 5                                    ' cry (again)
  ENDIF
  timer = 0
  GOTO Main


Scare:                                           ' State = 6
  SEROUT Sio, BaudRC4, ["!RC4", Addr, "S", StrobeFog] ' Turn strobe and fog on, everything else off
  SEROUT TX, BaudVM2, ["VPF scream.mp3", CR]          ' Scream
  state = 7                                           ' goto Cry_Done
  timer = 5000                                   ' But wait 5 seconds before going
  pos = 250                                      ' Turn head back forward
  GOTO Main

Cry_Done:                                         ' state=7
  SEROUT Tx, BaudVM2, ["VRF weep.mp3", CR]        ' Start weeping again
  SEROUT Sio, BaudRC4, ["!RC4", Addr, "S", SpotWeep] ' Start weep motor
  timer = 30000                                   ' Pause 30 Seconds
  state = 8                                       ' goto Reset


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

RC4_Reset:
  SEROUT Sio, BaudRC4, ["!!!!!!!RC4", Addr, "S", Spot]   ' Just the spot on

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

'AP8_Reset:
'  SEROUT Sio, Baud, ["!!!!!!!AP8", Addr, "X"]   ' stop audio

JonnyMac

What servo values are you using for your head?  On a BS2 the normal range would be 500 (full CW) to 1000 (full CCW) with 750 being centered.  Let me know where you want to head to start and the movement and timing during the suspense section.

Just so you know, I'm ditching the state version of the program in favor of an approach that has each section manually call the servo refresh routine.  This routine will update the timer if that is running.  There is also a subroutine called Servo_Pause which is a replacement for the PAUSE instruction.  Servo_Pause will do the delay (specified in timer) and refresh the servo.  This version makes implementing the head movement in the suspense section easier to follow.

Also, since you don't seem to be using any feedback from the VMUSIC player you could crank the baud rate up to 38.4K and then just have one baud constant in the program.
Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

May 22, 2008, 01:10:41 PM #11 Last Edit: May 23, 2008, 03:15:24 PM by JonnyMac
Give this a shot -- you'll need to update the servo movement loops in the suspense section.  After setting the limits you can use the STEP value to speed things back up.  If you need it even slower, let me know.

[EDIT] Updated to use skipScare flag:

' =========================================================================
'
'   File....... Mourner.BS2
'   Purpose.... Halloween 2008 Project
'   Author..... FrontYardHaunters.com
'   E-mail..... SabresNut42383@roadrunner.com
'   Started.... April 6, 2008
'   Updated.... 22 MAY 2008 - Jon Williams
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


' -----[ Revision History ]------------------------------------------------
'
' 1.00   - Original program
' 1.01   - Jon Williams updated for state-driven operation
' 2.00   - My update removing AP-8 and adding VMusic2
' 2.01   - back to linear with subs for delays and servo processing


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

Sio             PIN     15                      ' Remove Setup; no ULN
TX              PIN     14                      ' SETUP = UP; no ULN
MatSwitch       PIN     13                      ' SETUP = DN; no ULN
HandHeld        PIN     12                      ' SETUP = DN; no ULN
Servo           PIN     8


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

T9600           CON     84
T38K4           CON     6
Open            CON     $8000
OT38K4          CON     Open + T38K4            ' B/R in RC4
OT9600          CON     Open + T9600            ' VM2 baud rate

IsOn            CON     1
IsOff           CON     0

AllOff          CON     %0000
Spot            CON     %0001                   ' K1 relay on
Weep            CON     %0010                   ' K2 relay on
SpotWeep        CON     %0011                   ' K1 % K2 realys on
StrobeFog       CON     %1100                   ' K3 & K4 relays on


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

pos             VAR     Word                    ' servo position
timer           VAR     Word                    ' for delays

skipScare       VAR     Bit                     ' don't use Scare section


' -----[ EEPROM Data ]-----------------------------------------------------


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

Reset:
  LOW Servo
  pos = 750
  timer = 2500
  GOSUB Servo_Pause

  skipScare = IsOff

  SEROUT TX, OT9600, ["VST", CR]                ' stop VMUSIC player
  GOSUB RC4_Reset                               ' clear RC-4


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

Main:
  timer = 100                                   ' preload debounce time
  DO WHILE timer > 0
    GOSUB Refresh_Servo
    IF (MatSwitch = IsOff) THEN                 ' if no input
      timer = 100                               ' reload debounce timer
    ENDIF
  LOOP


Cry:
  GOSUB Refresh_Servo
  SEROUT Sio, OT38K4, ["!RC4", %00, "S", Weep]
  GOSUB Refresh_Servo
  SEROUT  TX, OT9600, ["VRF weep.mp3", CR]
  timer = 20000
  GOSUB Servo_Pause


Suspense:
  SEROUT TX, OT9600, ["VP", CR]                 ' pause weeping
  SEROUT Sio, OT38K4, ["!RC4", %00, "S", AllOff]

  ' turn head slowly to left

  FOR pos = 750 TO 500 ' STEP 2
    GOSUB Refresh_Servo
  NEXT

  timer = 3500
  GOSUB Servo_Pause

  ' turn head back to center

  FOR pos = 500 TO 750 ' STEP 2
    GOSUB Refresh_Servo
  NEXT

  IF (skipScare = IsOn) THEN Finish


Choose:
  IF (HandHeld = IsOn) THEN
    GOTO Scare
  ELSE
    skipScare = IsOn
    GOTO Cry
  ENDIF


Scare:
  GOSUB Refresh_Servo
  SEROUT Sio, OT38K4, ["!RC4", %00, "S", StrobeFog]
  GOSUB Refresh_Servo
  SEROUT TX, OT9600, ["VPF scream.mp3", CR]
  pos = 250
  timer = 5000
  GOSUB Servo_Pause


Finish:
  SEROUT TX, OT9600, ["VRF weep.mp3", CR]
  GOSUB Refresh_Servo
  SEROUT Sio, OT38K4, ["!RC4", %00, "S", SpotWeep]
  timer = 30000
  GOSUB Servo_Pause
  GOTO Reset


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

RC4_Reset:
  SEROUT Sio, OT38K4, ["!!!!!!!RC4", %00, "S", Spot]

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

' Use as a replacement for PAUSE
' -- keeps servo in desired position
' -- load "timer" with desired delay

Servo_Pause:
  DO WHILE timer > 19
    GOSUB Refresh_Servo
  LOOP
  RETURN

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

' Updates servo and decrents timer for time used

Refresh_Servo:
  PULSOUT Servo, pos
  PAUSE 18
  timer = timer - 20
  RETURN
Jon McPhalen
EFX-TEK Hollywood Office

LPFreak1283

Doesn't this new routine put us back into the infinite loop scenario?

I did change the code a bit:

I declared a variable (pee) as Byte which (I think) will help the routine finish instead of loop through cry and suspense.
Then in the Reset, I had pee = IsOff (which under constants is 0)

Then I added a line into the choose section:
Choose:
  IF (HandHeld = IsOn) THEN
    GOTO Scare
  ELSE
    GOTO Cry
    pee = IsOn
  ENDIF

Then I added this right after the suspense section after the servo has turned back to center

' turn head back to center

  FOR pos = 500 TO 750 ' STEP 2
    GOSUB Refresh_Servo
  NEXT

  IF (pee = IsOn) THEN
    GOTO Finish
  Endif


That should work right?

JonnyMac

Good catch -- you should start helping me write programs for other forum members!  :D
Jon McPhalen
EFX-TEK Hollywood Office

LPFreak1283

Hahaha  :D

As Dr. Evil would say, "Riiiight"