November 21, 2024, 08:00:16 AM

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.


Doctors Patient program

Started by LPFreak1283, October 26, 2011, 12:41:05 PM

Previous topic - Next topic

JonnyMac

QuoteHow does defining lottery = 1031 make it the max number?

It doesn't, it just provides a seed for the psuedo-random algorithm.  We can make things random by running the RANDOM function inside a loop that is waiting for a trigger.  With the trigger happening at some random time, we will be at a random place in the psuedo-random sequence.

The modulus operator works like this: it returns the remainder of a division.  The way I think of it -- in this context -- is that it will always return a value between zero and the divisor minus one.  For example, if I want a random time between 10 and 20 seconds I would do something like this:

  RANDOM lottery
  delay = lottery // 10001 + 10000
  PAUSE delay


The first part of the delay equation will return a value between 0 and 10000 (10001 - 1); the second adds my minimum value. 

Again, in order to add true randomness to the RANDOM function, you need to be calling RANDOM when waiting around for something to happen.
Jon McPhalen
EFX-TEK Hollywood Office

LPFreak1283

So the timing for the sound and the servo movement during the scream segment is off.  I have tried adjusting the timer value and also the pause values for the servo's and it is either too short or just way too long.  What's going on with that??

JonnyMac

I don't have the parts to test your program but am going to write a version from scratch.  Integerating servos is really tough because you have to refresh them every 20ms or so -- this creates complications for timing, etc.  Do you know the duration of your sound file?  I assume that as you're using two files but a single, digital output, the "wimpering" sound has been assigned to the AMBIENT.WAV track.  Am I correct?
Jon McPhalen
EFX-TEK Hollywood Office

LPFreak1283

My scream sound file is 13 seconds long.  The ambient track is the whimpering sound.  I am using the vmusic2 again. 

JonnyMac

With the servo processing it's going to be really tough to watch for the end of the track so I will use timing instead.  This is not an easy program; servos are never easy with a Prop-1 or Prop-2, and the VMUSIC is a nightmare of a product (which is why EFX-TEK refuses to actively support it -- it is only done when our customers are in a bind).
Jon McPhalen
EFX-TEK Hollywood Office

LPFreak1283

Sorry for the touble.  I've used it on another prop and haven't had issues with it.  Maybe i'm lucky?

JonnyMac

Yes.  I've had them work, too, mostly -- but when the fail it can be an enormous pain to get them back (I've had to crack them open to "re-flash" the program).
Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

In wimper mode are you looking for random positions within your defined range (500 to 800) or just a random speed between those two endpoints?

In scream mode is the prop supposed to go between the extremes?
Jon McPhalen
EFX-TEK Hollywood Office

LPFreak1283

yes, random positions within the range...possibly like 600-900...

I just wanted the scream to be back and forth on the servo, not really too specific on the servo position.  Maybe 90 degrees total for the max range.

JonnyMac

October 31, 2011, 01:50:12 PM #24 Last Edit: October 31, 2011, 03:39:11 PM by JonnyMac
Give this a try.  Now... this is one of those "it's harder than it looks" programs.  Dealing with servos using the Prop-1 and Prop-2 is very tough.  This means that a state-machine is the best structure so that the servo gets updated every loop.  Execution paths are based on the current program state and other conditions, and are padded such that each program loop is about 20ms (this drives the timing of everything).

As I said, I don't have the gear available on my desk to test.  It compiles fine and I've looked it over very carefully.


Updated 31 OCT 2011, 2:40 PM PST

' =========================================================================
'
'   File...... patient.bs2
'   Purpose...
'   Author....
'   E-mail....
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


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


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

RX              PIN     15                      ' no ULN / SETUP = UP
TX              PIN     14                      ' no ULN / SETUP = UP
Sio             PIN     13                      ' no ULN / SETUP = UP
Trigger         PIN     12                      ' SETUP = DN / matswitch
Servo           PIN     8                       ' patient's head servo


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

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

#SELECT $STAMP
  #CASE BS2, BS2E, BS2PE
    T2400       CON     396
    T38K4       CON     6
    T9600       CON     84
  #CASE BS2SX, BS2P
    T2400       CON     1021
    T38K4       CON     45
  #CASE BS2PX
    T2400       CON     1646
    T38K4       CON     84
#ENDSELECT

SevenBit        CON     $2000
Inverted        CON     $4000
Open            CON     $8000
VMBaud          CON     Open + T9600            ' baud for vmusic
EFXBAud         CON     Open + T38K4            ' baud for rc4

VolMax          CON     $00
VolMin          CON     $FE

HeadCtr         CON     750
HeadLf          CON     800
HeadRt          CON     500

WhimperLts      CON     %0011                   ' whimper lts on RC-4 K1 and K2
ScreamLts       CON     %1100                   ' scream lts on RC-4 K3 and K4

WhimperSpd      CON     1                       ' servo speed for whimpering
ScreamSpd       CON     10                      ' servo speed for screaming

ScreamTime      CON     13000                   ' duration of scream audio

TrHoldOff       CON     15000                   ' 15s trigger hold-off


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

pos             VAR     Word                    ' present servo position
target          VAR     Word                    ' target servo position

state           VAR     Byte                    ' program state
lottery         VAR     Word                    ' random #

delay           VAR     Word                    ' general program delays
debounce        VAR     Byte                    ' trigger debounce


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

Power_Up:
  LOW Servo                                     ' setup servo pin
  pos = HeadCtr
  delay = 2500
  GOSUB Servo_Pause                             ' delay with servo
  GOSUB VM_Stop                                 ' stop if playing
  lottery = 1031

Reset:
  RANDOM lottery
  target = lottery // (HeadLf - HeadRt + 1) + HeadRt

  state = 0
  OUTL = 0
  HIGH state


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

Main:
  PULSOUT Servo, pos
  RANDOM lottery
  BRANCH state, [Setup, Holding, Whimpering, Screaming]


  ' set lights and start whimper sound
  ' -- serial transmissions consume ~18ms, hence no delay needed

Setup:
  HIGH 0
  SEROUT TX, VMBaud, ["VRF ambient.mp3", CR]
  SEROUT Sio, EFXBaud, ["!RC4", %00, "S", WhimperLts]
  delay = TrHoldOff
  state = 1
  OUTL = 0
  HIGH state
  GOTO Main


  ' in holding mode
  ' -- behaves like whimpering but ignores trigger input

Holding:
  IF (delay > 20) THEN                          ' still in hold-off period?
    delay = delay - 20                          ' update
    IF (pos = target) THEN                      ' if at target, make new one
      RANDOM lottery
      target = lottery // (HeadLf - HeadRt + 1) + HeadRt
    ELSEIF (pos < target) THEN
      pos = pos + WhimperSpd MAX target
    ELSE
      pos = pos - WhimperSpd MIN target
    ENDIF
  ELSE
    delay = 0
    debounce = 0
    state = 2
    OUTL = 0
    HIGH state
  ENDIF
  PAUSE 18
  GOTO Main


  ' watches for trigger while whimpering

Whimpering:
  debounce = (debounce + 20) * Trigger
  IF (debounce < 150) THEN                      ' still whimpering
    IF (pos = target) THEN
      RANDOM lottery
      target = lottery // (HeadLf - HeadRt + 1) + HeadRt
    ELSEIF (pos < target) THEN
      pos = pos + WhimperSpd MAX target
    ELSE
      pos = pos - WhimperSpd MIN target
    ENDIF
    PAUSE 17
  ELSE                                          ' have valid trigger
    SEROUT TX, VMBaud, ["VPF scream.mp3", CR]
    SEROUT Sio, EFXBaud, ["!RC4", %00, "S", ScreamLts]
    delay = ScreamTime
    target = HeadLf
    state = 3
    OUTL = 0
    HIGH state
  ENDIF
  GOTO Main


  ' move quickly between servo endpoints while screaming

Screaming:
  IF (delay < 20) THEN                          ' done?
    GOTO Reset                                  ' yes, start over
  ELSE
    delay = delay - 20                          ' update delay
    IF (pos = target) THEN                      ' check/update target
      IF (pos = HeadLf) THEN
        target = HeadRt
      ELSE
        target = HeadLf
      ENDIF
    ELSEIF (pos < target) THEN
      pos = pos + ScreamSpd MAX target
    ELSE
      pos = pos - ScreamSpd MIN target
    ENDIF
  ENDIF
  GOTO Main


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

' Replaces PAUSE -- keeps servo updated

Servo_Pause:
  DO WHILE (delay > 20)
    PULSOUT Servo, pos
    PAUSE 19
    delay = delay - 20
  LOOP
  PAUSE delay
  RETURN

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

VM_Stop:
  SEROUT TX, VMBaud, ["VST", CR]
  RETURN

' -------------------------------------------------------------------------
Jon McPhalen
EFX-TEK Hollywood Office

LPFreak1283

Thanks jon!

Here are some of the bugs ive found so far...

- after the scream, the program never resets and goes back to whimpering.  The strobe light is stuck on scare.
-Also, the head never speeds up during the scream.  it continues to randomly move and there is never a point where it speeds up.

- How long does the hold off period last?

- I have had to press the trigger twice for the scream to actually happen sound wise.  The lights trigger but i'm not sure if they re-trigger the second time.

JonnyMac

Do you have a Prop-1 Trainer that we can use to monitor the program state?
Jon McPhalen
EFX-TEK Hollywood Office

LPFreak1283

Oy not handy...If it werent 1/2 hour before trick or treating I would search for it  ;D

JonnyMac

No worries, snag the updated listing.  I found that I had left out the state 3 update which would put it into scream servo mode and use the scream timing.  If you can find a P1-T put in on the low group to show you what state the program is in.  I also backed of the trigger hold-off (period where trigger is ignored) to 15s.
Jon McPhalen
EFX-TEK Hollywood Office

LPFreak1283

4 years later I have an update on this prop!

I finally got the chance to sit and work on it after getting married and moving twice!  I'm all settled in my man cave and working on Halloween once again!!!!

I was taking a look at the code that was previously put up and I made it work perfectly!

Some changes that I had to make were:

-Played with the ScreamTime constant.  13000 (13 seconds, correct?) was nowhere near 13 seconds.  It was more like 3 seconds.  So I updated the number and kept loading the program back in and playing around.  52750 is the number that works absolutely perfectly.  I don't know why it works, but it does! 

-The ambient track kept playing even when the screaming was supposed to be playing.  Easy fix there as I put a call to the VM_Stop subroutine immediately before the scream track was loaded. 

-I played around with the relay lights and had to configure them to my needs.  I did make a special plug setup for the RC-4 which I will post in that forum.

I took a video of the patient in action!  I only have the strobe light from the main setup so I used woot! lights for the "spot" light placeholder.  Here it is:

https://youtu.be/KzLEZaZNGPY

I am slowly going to add some more tweaks to it to continue scaring the poop out of the kids!

Here is my updated code:

' =========================================================================
'
'   File...... patient.bs2
'   Purpose...
'   Author....
'   E-mail....
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


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


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

RX              PIN     15                      ' no ULN / SETUP = UP
TX              PIN     14                      ' no ULN / SETUP = UP
Sio             PIN     13                      ' no ULN / SETUP = UP
Trigger         PIN     12                      ' SETUP = DN / matswitch
Servo           PIN     8                       ' patient's head servo


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

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

#SELECT $STAMP
  #CASE BS2, BS2E, BS2PE
    T2400       CON     396
    T38K4       CON     6
    T9600       CON     84
  #CASE BS2SX, BS2P
    T2400       CON     1021
    T38K4       CON     45
  #CASE BS2PX
    T2400       CON     1646
    T38K4       CON     84
#ENDSELECT

SevenBit        CON     $2000
Inverted        CON     $4000
Open            CON     $8000
VMBaud          CON     Open + T9600            ' baud for vmusic
EFXBAud         CON     Open + T38K4            ' baud for rc4

VolMax          CON     $00
VolMin          CON     $FE

HeadCtr         CON     750
HeadLf          CON     800
HeadRt          CON     500

K1Lt            CON     %0001                   ' RC-4 K1
SpotLt          CON     %0010                   ' RC-4 K2
K3Lt            CON     %0100                   ' RC-4 K3
StrobeLt        CON     %1000                   ' RC-4 K4

WhimperSpd      CON     2                       ' servo speed for whimpering
ScreamSpd       CON     10                      ' servo speed for screaming

ScreamTime      CON     52750                   ' duration of scream audio

TrHoldOff       CON     15000                   ' 15s trigger hold-off


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

pos             VAR     Word                    ' present servo position
target          VAR     Word                    ' target servo position

state           VAR     Byte                    ' program state
lottery         VAR     Word                    ' random #

delay           VAR     Word                    ' general program delays
debounce        VAR     Byte                    ' trigger debounce


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

Power_Up:
  LOW Servo                                     ' setup servo pin
  pos = HeadCtr
  delay = 2500
  GOSUB Servo_Pause                             ' delay with servo
  GOSUB VM_Stop                                 ' stop if playing
  lottery = 1031

Reset:
  RANDOM lottery
  target = lottery // (HeadLf - HeadRt + 1) + HeadRt

  state = 0
  OUTL = 0
  HIGH state


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

Main:
  PULSOUT Servo, pos
  RANDOM lottery
  BRANCH state, [Setup, Holding, Whimpering, Screaming]


  ' set lights and start whimper sound
  ' -- serial transmissions consume ~18ms, hence no delay needed

Setup:
  HIGH 0
  SEROUT TX, VMBaud, ["VRF ambient.mp3", CR]
  SEROUT Sio, EFXBaud, ["!RC4", %00, "S", SpotLt]
  delay = TrHoldOff
  state = 1
  OUTL = 0
  HIGH state
  GOTO Main


  ' in holding mode
  ' -- behaves like whimpering but ignores trigger input

Holding:
  IF (delay > 20) THEN                          ' still in hold-off period?
    delay = delay - 20                          ' update
    IF (pos = target) THEN                      ' if at target, make new one
      RANDOM lottery
      target = lottery // (HeadLf - HeadRt + 1) + HeadRt
    ELSEIF (pos < target) THEN
      pos = pos + WhimperSpd MAX target
    ELSE
      pos = pos - WhimperSpd MIN target
    ENDIF
  ELSE
    delay = 0
    debounce = 0
    state = 2
    OUTL = 0
    HIGH state
  ENDIF
  PAUSE 18
  GOTO Main


  ' watches for trigger while whimpering

Whimpering:
  debounce = (debounce + 20) * Trigger
  IF (debounce < 150) THEN                      ' still whimpering
    IF (pos = target) THEN
      RANDOM lottery
      target = lottery // (HeadLf - HeadRt + 1) + HeadRt
    ELSEIF (pos < target) THEN
      pos = pos + WhimperSpd MAX target
    ELSE
      pos = pos - WhimperSpd MIN target
    ENDIF
    PAUSE 17
  ELSE                                          ' have valid trigger
    GOSUB VM_Stop
    SEROUT TX, VMBaud, ["VPF scream.mp3", CR]
    SEROUT Sio, EFXBaud, ["!RC4", %00, "S", StrobeLt]
    delay = ScreamTime
    target = HeadLf
    state = 3
    OUTL = 0
    HIGH state
  ENDIF
  GOTO Main


  ' move quickly between servo endpoints while screaming

Screaming:
  IF (delay < 20) THEN                          ' done?
    GOTO Reset                                  ' yes, start over
  ELSE
    delay = delay - 20                          ' update delay
    IF (pos = target) THEN                      ' check/update target
      IF (pos = HeadLf) THEN
        target = HeadRt
      ELSE
        target = HeadLf
      ENDIF
    ELSEIF (pos < target) THEN
      pos = pos + ScreamSpd MAX target
    ELSE
      pos = pos - ScreamSpd MIN target
    ENDIF
  ENDIF
  GOTO Main


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

' Replaces PAUSE -- keeps servo updated

Servo_Pause:
  DO WHILE (delay > 20)
    PULSOUT Servo, pos
    PAUSE 19
    delay = delay - 20
  LOOP
  PAUSE delay
  RETURN

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

VM_Stop:
  SEROUT TX, VMBaud, ["VST", CR]
  RETURN

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