EFX-TEK

TEK Talk => Prop-2 => Topic started by: LPFreak1283 on October 26, 2011, 12:41:05 PM

Title: Doctors Patient program
Post by: LPFreak1283 on October 26, 2011, 12:41:05 PM
I recently built a new prop and am stuck a the coding phase. 

a)Basically I would like a servo to randomly (if possible) turn between positions as if a patient on the table is confused as to where they are. 

b)Then, when a mat switch is triggered, the servo sweeps side to side as if the patient is in pain and screaming.   Then it would reset itself to the beginning.

I have a VMusic2 hooked up with 2 sound files (whimper, scream).  RX is pin 15, TX is pin 14

I also have a RC-4 hooked up with 4 lights.  2 of the lights will be on when part 'a' is running.  Then when part 'b' is triggered, the other two turn on.  That is on pin 13.

The matswitch is on pin 12 and the servo is pin 8.

Any help is appreciated!
Title: Re: Doctors Patient program
Post by: bsnut on October 26, 2011, 02:05:10 PM
I have this question for about this part of your program
Quote
a)Basically I would like a servo to randomly (if possible) turn between positions as if a patient on the table is confused as to where they are.
Does the servo need to move when the prop is waiting to be triggered? Otherwise, I don't for see any other questions right now.
Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 26, 2011, 02:10:40 PM
Yes, i would like it to bsnut
Title: Re: Doctors Patient program
Post by: bsnut on October 27, 2011, 03:56:01 AM
So, here is your program and may need to be tweaked a little bit to meet your need. It was based on VMusic program that Jon wrote, which was cut and pasted into your program. 

One thing, I can say it was fun to write, all 3 hours worth. I thank Jon for his code it was a big help.

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


' -----[ Program Description ]---------------------------------------------
'a)Basically I would like a servo to randomly (IF possible) turn between
'positions as if a patient on the table is confused as to where they are.
'
'b)Then, when a mat switch is triggered, the servo sweeps side to side as
' IF the patient is in pain AND screaming. Then it would reset itself to
' the beginning.
'
'Have a VMusic2 hooked up with 2 sound files (whimper, scream).
'RX is PIN 15, TX is PIN 14
'
'I also have a RC-4 hooked up with 4 lights.  2 of the lights will be ON
'when part 'a' is running.
'
'Then when part 'b' is triggered, the other two turn on.  That is on pin 13.
'
'The matswitch is on PIN 12 and the servo is PIN 8.
'
'
' -----[ 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
  #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
Baud            CON     Open + T38K4            ' fast baud for accessories


VolMax          CON     $00
VolMin          CON     $FE
Headcentered    CON     750                     ' head centered
Headleft        CON     1000                    ' head counterclockwise
Headright       CON     500                     ' head clockwise
Whimperlts      CON     %0011                   ' whimper lts on RC-4 K1 and K2
Screamlts       CON     %1100                   ' scream lts on RC-4 K3 and K4

Screamspeed     CON     20                      ' sets scream servo speed. change to meet
                                                ' your needs

Screamtime      CON     2080                    ' set "Screamtime" in millisecond to meet
                                                ' sound file run time

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

lottery         VAR     Byte                    ' randomize lottery value for servo speed
timer           VAR     Byte
servopos        VAR     Byte                    ' servo position var
servospeed      VAR     Byte                    ' servo speed var
whimperspeed    VAR     Byte                    ' whimper speed based on lottery value

idx             VAR     Byte                    ' loop controller
theMP3          VAR     Byte                    ' MP3 file pointer
char            VAR     Byte                    ' character value
eePntr          VAR     Word                    ' EEPROM memory pointer

mute            VAR     Byte

panCtrl         VAR     Word
muteLeft       VAR     panCtrl.BYTE0
muteRight      VAR     panCtrl.BYTE1

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

Reset:
  'OUTS = $0000                                  ' clear all outputs
  'DIRS = $3FFF                                  ' make P0-P13 outputs
  SEROUT Sio, Baud, ["!RC4", %00, "X"]          ' set RC-4 all off
  PAUSE 2250                                    ' let VMUSIC power up
  GOSUB VM_Stop                                 ' stop if playing
  GOSUB VM_Wait_Prompt
  FOR servopos = 1 TO 150
    PULSOUT Servo, Headcentered
    PAUSE 20
  NEXT

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

Main:
  timer = 0

Main_Preshow:
  RANDOM lottery                                   ' randomize lottery value
  whimperspeed = lottery // 25 + 10                ' set whimperspeed 100 to 350
  servospeed = whimperspeed                        ' set servospeed
  SEROUT Sio, Baud, ["!RC4", %00, "S", Whimperlts] ' set whimper lts on
  theMP3 = 0
  GOSUB VM_Play
  GOSUB VM_Wait_Start

  FOR servopos = Headleft TO Headright STEP servospeed
    PULSOUT Servo, servopos
    PAUSE 10
  NEXT

  FOR servopos = Headright TO Headleft STEP servospeed
    PULSOUT Servo, servopos
    PAUSE 10
  NEXT

  DO WHILE (timer < 100)                        ' wait for 0.1s signal
    PAUSE 5                                     ' loop pad
    timer = timer + 5 * Trigger                 ' update timer
  LOOP
  IF Trigger = 0 THEN Main_Preshow              ' do Main_Preshow if Trigger is false

Start_Show:
  GOSUB VM_Stop                                 ' stop VMusic if playing "whimper"
  theMP3 = 1
  GOSUB VM_Play
  GOSUB VM_Wait_Start
  SEROUT Sio, Baud, ["!RC4", %00, "S", Screamlts] ' set scream lts on
  servospeed = Screamspeed

Scream:
  timer = 0                                    ' reset "timer" to be reused

  DO
  FOR servopos = Headright TO Headleft STEP servospeed
    PULSOUT Servo, servopos
    PAUSE 10
  NEXT

  FOR servopos = Headleft TO Headright STEP servospeed
    PULSOUT Servo, servopos
    PAUSE 10
  NEXT
  timer = timer + 20
  LOOP UNTIL (timer = 2080)                    '
  GOTO Main


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

VM_Wait_Prompt:
  SERIN RX, Baud, [WAIT(">")]
  RETURN

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

' Pass file # (index in DATA table) to play in "theMP3"

VM_Play:
  SEROUT TX, Baud, ["VPF "]
  GOTO Play_MP3

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

' Pass file # (index in DATA table) to play in "theMP3"

VM_Repeat:
  SEROUT TX, Baud, ["VRF "]

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

' Pass file # (index in DATA table) to play in "theMP3"

Play_MP3:
  eePntr = (8 * theMP3) + Song_List

Send_Name:                                      ' send file title
  FOR idx = 1 TO 8                              ' max is 8 characters
    READ eePntr, char                           ' get a character
    IF char = 0 THEN Finish_Cmd                 ' if 0, we're at end
    SEROUT TX, Baud, [char]
    eePntr = eePntr + 1
  NEXT

Finish_Cmd:
  SEROUT TX, Baud, [".MP3", CR]                 ' send extention + CR
  RETURN

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

VM_Wait_Start:
  SERIN RX, Baud, [WAIT("T $")]
  RETURN

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

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

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

' Pass mute level (0 = loudest, 254 = muted) in "mute"

VM_Mute:
  mute = mute MAX VolMin                        ' limit per spec

  ' copy to pan register for future use

  muteLeft = mute
  muteRight = mute

  SEROUT TX, Baud, ["VSV ", DEC mute, CR]
  RETURN

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

' Pass levels (0 = loudest, 254 = muted) in "muteLeft" and "muteRight"
'
' NOTE: The VPF/VRF commands seems to reset volume levels so you must use
'       a pan command while the file is playing for it to work.
'
' NOTE: Over-use can result is unwanted audio "clicks" and "pops"

VM_Pan:
  muteLeft = muteLeft MAX $FE                     ' limit per spec
  muteRight = muteRight MAX $FE

  SEROUT TX, Baud, ["VWR $0B", HEX4 panCtrl, CR]
  RETURN


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

' File names are stored on 8-byte boundaries -- this is very important for
' correct program operation.  This strategy uses a little more EE space but
' is easier to update and maintain

Song_List       DATA    @$00, "whimper"         ' theMP3 = 0
                DATA    @$08, "scream"          ' theMP3 = 1

Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 27, 2011, 08:47:27 AM
Wow! Thanks!  I cant wait to get this loaded up to see it run!!
Title: Re: Doctors Patient program
Post by: bsnut on October 27, 2011, 12:40:05 PM
Yes, I would love see it work as well. But, I found minor mistake, that may not let your program work right and here it is. You don't need this code below and the way you fixed it, is do what I did below. Which is to comment it out. It should work after you do this.

  'OUTS = $0000                                  ' clear all outputs
  'DIRS = $3FFF                                  ' make P0-P13 outputs

Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 27, 2011, 06:20:41 PM
Here is my updated code.  It works with sound now.  I just had to add a line for the vmusic baud because the fast baud wasn't working.  Also, the servo doesn't move at all when the show starts, it just turns to a position and doesn't move until triggered to scream and then it moves to another position. 
Oh and the scream portion never returns to the main program after it is completed. 
' =========================================================================
'
'   File......Dotor Patient Prop.bs2
'   Purpose...
'   Author....
'   E-mail....
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------
'a)Basically I would like a servo to randomly (IF possible) turn between
'positions as if a patient on the table is confused as to where they are.
'
'b)Then, when a mat switch is triggered, the servo sweeps side to side as
' IF the patient is in pain AND screaming. Then it would reset itself to
' the beginning.
'
'Have a VMusic2 hooked up with 2 sound files (whimper, scream).
'RX is PIN 15, TX is PIN 14
'
'I also have a RC-4 hooked up with 4 lights.  2 of the lights will be ON
'when part 'a' is running.
'
'Then when part 'b' is triggered, the other two turn on.  That is on pin 13.
'
'The matswitch is on PIN 12 and the servo is PIN 8.
'
'
' -----[ 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
Headcentered    CON     750                     ' head centered
Headleft        CON     800                    ' head counterclockwise
Headright       CON     500                     ' head clockwise
Whimperlts      CON     %0011                   ' whimper lts on RC-4 K1 and K2
Screamlts       CON     %1100                   ' scream lts on RC-4 K3 and K4

Screamspeed     CON     20                      ' sets scream servo speed. change to meet
                                                ' your needs

Screamtime      CON     13000                    ' set "Screamtime" in millisecond to meet
                                                ' sound file run time

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

lottery         VAR     Byte                    ' randomize lottery value for servo speed
timer           VAR     Byte
servopos        VAR     Byte                    ' servo position var
servospeed      VAR     Byte                    ' servo speed var
whimperspeed    VAR     Byte                    ' whimper speed based on lottery value

idx             VAR     Byte                    ' loop controller
theMP3          VAR     Byte                    ' MP3 file pointer
char            VAR     Byte                    ' character value
eePntr          VAR     Word                    ' EEPROM memory pointer

mute            VAR     Byte

panCtrl         VAR     Word
muteLeft       VAR     panCtrl.BYTE0
muteRight      VAR     panCtrl.BYTE1

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

Reset:
  'OUTS = $0000                                  ' clear all outputs
  'DIRS = $3FFF                                  ' make P0-P13 outputs
  SEROUT Sio, EFXBaud, ["!RC4", %00, "X"]          ' set RC-4 all off
  PAUSE 2500                                    ' let VMUSIC power up
  GOSUB VM_Stop                                 ' stop if playing
  'GOSUB VM_Wait_Prompt
  FOR servopos = 1 TO 150
    PULSOUT Servo, Headcentered
    PAUSE 20
  NEXT

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

Main:
  timer = 0

Main_Preshow:
  RANDOM lottery                                   ' randomize lottery value
  whimperspeed = lottery // 25 + 10                ' set whimperspeed 100 to 350
  servospeed = whimperspeed                        ' set servospeed
  SEROUT Sio, EFXBaud, ["!RC4", %00, "S", Whimperlts] ' set whimper lts on
  theMP3 = 0
  GOSUB VM_Repeat
  'GOSUB VM_Wait_Start

  FOR servopos = Headleft TO Headright STEP servospeed
    PULSOUT Servo, servopos
    PAUSE 10
  NEXT

  FOR servopos = Headright TO Headleft STEP servospeed
    PULSOUT Servo, servopos
    PAUSE 10
  NEXT

  DO WHILE (timer < 100)                        ' wait for 0.1s signal
    PAUSE 5                                     ' loop pad
    timer = timer + 5 * Trigger                 ' update timer
  LOOP
  IF Trigger = 0 THEN Main_Preshow              ' do Main_Preshow if Trigger is false

Start_Show:
  GOSUB VM_Stop                                 ' stop VMusic if playing "whimper"
  theMP3 = 1
  GOSUB VM_Play
  'GOSUB VM_Wait_Start
  SEROUT Sio, EFXBaud, ["!RC4", %00, "S", Screamlts] ' set scream lts on
  servospeed = Screamspeed

Scream:
  timer = 0                                    ' reset "timer" to be reused

  DO
  FOR servopos = Headright TO Headleft STEP servospeed
    PULSOUT Servo, servopos
    PAUSE 10
  NEXT

  FOR servopos = Headleft TO Headright STEP servospeed
    PULSOUT Servo, servopos
    PAUSE 10
  NEXT
  timer = timer + 20
  LOOP UNTIL (timer = 13000)                    '
  GOTO Main


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

VM_Wait_Prompt:
  'SERIN RX, VMBaud, [WAIT(">")]
  RETURN

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

' Pass file # (index in DATA table) to play in "theMP3"

VM_Play:
  SEROUT TX, VMBaud, ["VPF "]
  GOTO Play_MP3

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

' Pass file # (index in DATA table) to play in "theMP3"

VM_Repeat:
  SEROUT TX, VMBaud, ["VRF "]
  GOTO Play_MP3

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

' Pass file # (index in DATA table) to play in "theMP3"

Play_MP3:
  eePntr = (8 * theMP3) + Song_List

Send_Name:                                      ' send file title
  FOR idx = 1 TO 8                              ' max is 8 characters
    READ eePntr, char                           ' get a character
    IF char = 0 THEN Finish_Cmd                 ' if 0, we're at end
    SEROUT TX, VMBaud, [char]
    eePntr = eePntr + 1
  NEXT

Finish_Cmd:
  SEROUT TX, VMBaud, [".MP3", CR]                 ' send extention + CR
  RETURN

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

VM_Wait_Start:
  'SERIN RX, VMBaud, [WAIT("T $")]
  RETURN

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

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

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

' Pass mute level (0 = loudest, 254 = muted) in "mute"

VM_Mute:
  mute = mute MAX VolMin                        ' limit per spec

  ' copy to pan register for future use

  muteLeft = mute
  muteRight = mute

  SEROUT TX, VMBaud, ["VSV ", DEC mute, CR]
  RETURN

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

' Pass levels (0 = loudest, 254 = muted) in "muteLeft" and "muteRight"
'
' NOTE: The VPF/VRF commands seems to reset volume levels so you must use
'       a pan command while the file is playing for it to work.
'
' NOTE: Over-use can result is unwanted audio "clicks" and "pops"

VM_Pan:
  muteLeft = muteLeft MAX $FE                     ' limit per spec
  muteRight = muteRight MAX $FE

  SEROUT TX, VMBaud, ["VWR $0B", HEX4 panCtrl, CR]
  RETURN


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

' File names are stored on 8-byte boundaries -- this is very important for
' correct program operation.  This strategy uses a little more EE space but
' is easier to update and maintain

Song_List       DATA    @$00, "ambient"         ' theMP3 = 0
                DATA    @$08, "scream"          ' theMP3 = 1
Title: Re: Doctors Patient program
Post by: bsnut on October 27, 2011, 07:44:53 PM
You did a good job fixing the buad rate problem. But, if you look at my program and yours you can see the problem with the servo movement. This could be causing your problem with servo movement. The code, I used was from a book I have "Whats a Microcontroller".
These are the numbers that were used.
Headcentered = 750
Headleft = 1000
Headright = 500
Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 27, 2011, 09:58:37 PM
I understand the servo position numbers were changed but I had a different servo I was testing with.  Even with the numbers changed back, the servo doesn't randomly move side to side like I wanted it to.  The code looks like it should move it but the servo moves to about 800-850 servo pos after starting and doesn't move again.  Then when i trigger, the servo turns and tries to rotate clockwise til it can't go any farther and sits there and vibrates.  It's so weird. 

Also, the program doesn't reload...
Title: Re: Doctors Patient program
Post by: bsnut on October 28, 2011, 02:17:42 AM
I did some hard searching on the forums when got home from work and found a random servo movements that Jon did in 2007 (added in) and this is your program missing the Scream part and see if the random servo movement matches your needs. The only thing that is left do is Scream part of moving the servo back and forth and hope Jon jumps in on the Scream part.

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


' -----[ Program Description ]---------------------------------------------
'a)Basically I would like a servo to randomly (IF possible) turn between
'positions as if a patient on the table is confused as to where they are.
'
'b)Then, when a mat switch is triggered, the servo sweeps side to side as
' IF the patient is in pain AND screaming. Then it would reset itself to
' the beginning.
'
'Have a VMusic2 hooked up with 2 sound files (whimper, scream).
'RX is PIN 15, TX is PIN 14
'
'I also have a RC-4 hooked up with 4 lights.  2 of the lights will be ON
'when part 'a' is running.
'
'Then when part 'b' is triggered, the other two turn on.  That is on pin 13.
'
'The matswitch is on PIN 12 and the servo is PIN 8.
'
'
' -----[ 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
Head            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 rc4s


VolMax          CON     $00
VolMin          CON     $FE
Headcentered    CON     750                     ' head centered
Headleft        CON     1000                    ' head counterclockwise
Headright       CON     500                     ' head clockwise
Whimperlts      CON     %0011                   ' whimper lts on RC-4 K1 and K2
Screamlts       CON     %1100                   ' scream lts on RC-4 K3 and K4

Screamspeed     CON     20                      ' sets scream servo speed. change to meet
                                                ' your needs

Screamtime      CON     2080                    ' set "Screamtime" in millisecond to meet
                                                ' sound file run time

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

lottery         VAR     Byte                    ' randomize lottery value for servo speed
timer           VAR     Byte
pos1            VAR     Byte                    ' head servo position var
dest1           VAR     Byte                    ' head servo destination
'whimperspeed    VAR     Byte                    ' whimper speed based on lottery value

idx             VAR     Byte                    ' loop controller
theMP3          VAR     Byte                    ' MP3 file pointer
char            VAR     Byte                    ' character value
eePntr          VAR     Word                    ' EEPROM memory pointer

mute            VAR     Byte

panCtrl         VAR     Word
muteLeft       VAR     panCtrl.BYTE0
muteRight      VAR     panCtrl.BYTE1

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

Reset:
'  OUTS = $0000                                  ' clear all outputs
'  DIRS = $3FFF                                  ' make P0-P13 outputs
  SEROUT Sio, EFXBAud, ["!RC4", %00, "X"]       ' set RC-4 all off
  PAUSE 2250                                    ' let VMUSIC power up
  GOSUB VM_Stop                                 ' stop if playing
  GOSUB VM_Wait_Prompt


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

Main:
  timer = 0

Main_Preshow:
  SEROUT Sio, EFXBAud, ["!RC4", %00, "S", Whimperlts] ' set whimper lts on
  theMP3 = 0
  GOSUB VM_Play
  GOSUB VM_Wait_Start

  Update_Head:
  RANDOM lottery
  IF pos1 <> dest1 THEN Update_Pos1             ' at destination?
    dest1 = lottery // 151 + 75                 ' yes, reset (75 to 225)

Update_Pos1:
  IF pos1 < dest1 THEN Go_CW1                   ' Decide if the servo should move CW or CCW
  pos1 = pos1 - 2                               ' Move servo CCW

Go_CW1:
  pos1 = pos1 + 1                               ' Move servo CW


Update_Servos:
  PULSOUT Head, pos1                            ' Move the servo


  IF Trigger = 0 THEN Main_Preshow              ' do Main_Preshow if Trigger is false

Start_Show:
  GOSUB VM_Stop                                 ' stop VMusic if playing "whimper"
  theMP3 = 1
  GOSUB VM_Play
  GOSUB VM_Wait_Start
  SEROUT Sio, EFXBAud, ["!RC4", %00, "S", Screamlts] ' set scream lts on


Scream:
  timer = 0                                    ' reset "timer" to be reused

  DO

  timer = timer + 20
  LOOP UNTIL (timer = 2080)                    '
  GOTO Main


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

VM_Wait_Prompt:
  SERIN RX, VMBaud, [WAIT(">")]
  RETURN

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

' Pass file # (index in DATA table) to play in "theMP3"

VM_Play:
  SEROUT TX, VMBaud, ["VPF "]
  GOTO Play_MP3

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

' Pass file # (index in DATA table) to play in "theMP3"

VM_Repeat:
  SEROUT TX, VMBaud, ["VRF "]

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

' Pass file # (index in DATA table) to play in "theMP3"

Play_MP3:
  eePntr = (8 * theMP3) + Song_List

Send_Name:                                      ' send file title
  FOR idx = 1 TO 8                              ' max is 8 characters
    READ eePntr, char                           ' get a character
    IF char = 0 THEN Finish_Cmd                 ' if 0, we're at end
    SEROUT TX, VMBaud, [char]
    eePntr = eePntr + 1
  NEXT

Finish_Cmd:
  SEROUT TX, VMBaud, [".MP3", CR]                 ' send extention + CR
  RETURN

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

VM_Wait_Start:
  SERIN RX, VMBaud, [WAIT("T $")]
  RETURN

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

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

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

' Pass mute level (0 = loudest, 254 = muted) in "mute"

VM_Mute:
  mute = mute MAX VolMin                        ' limit per spec

  ' copy to pan register for future use

  muteLeft = mute
  muteRight = mute

  SEROUT TX, VMBaud, ["VSV ", DEC mute, CR]
  RETURN

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

' Pass levels (0 = loudest, 254 = muted) in "muteLeft" and "muteRight"
'
' NOTE: The VPF/VRF commands seems to reset volume levels so you must use
'       a pan command while the file is playing for it to work.
'
' NOTE: Over-use can result is unwanted audio "clicks" and "pops"

VM_Pan:
  muteLeft = muteLeft MAX $FE                     ' limit per spec
  muteRight = muteRight MAX $FE

  SEROUT TX, VMBaud, ["VWR $0B", HEX4 panCtrl, CR]
  RETURN


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

' File names are stored on 8-byte boundaries -- this is very important for
' correct program operation.  This strategy uses a little more EE space but
' is easier to update and maintain

Song_List       DATA    @$00, "whimper"         ' theMP3 = 0
                DATA    @$08, "scream"          ' theMP3 = 1


Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 28, 2011, 09:09:46 AM
Something has gone horribly wrong with that program!  The sound never starts, which I don't know why it wouldn't.  The servo goes haywire and tries to turn itself off the charts. 

The pos1 and dest1 variables need to be set to Word for servo position numbers.  I read that on here somewhere and after chagning them with the old program, the servo worked, just not as expected. 

Also, I think the loop for the scream part is never reaching the GOTO Main statement.  It's very weird.
Title: Re: Doctors Patient program
Post by: bsnut on October 28, 2011, 07:24:44 PM
What I suggest is take the code that we know that's works and place the servo that you can get to work you and place it just below where the VMusic code is. The bummer part is, I can't help you test your code, because I'm at my overnite electrical maintenance job and will try to help as much as I can when I am back home.

Here is the topic that Jon posted some code for random servo movement, that I gave you in my last post. http://www.efx-tek.com/php/smf/index.php?topic=354.msg1653#msg1653

BTW, I found this link in the Completed Projects section http://www.efx-tek.com/php/smf/index.php?board=12.0 for random servo movement code that can help you out with the servo code and this is the code link. http://www.spiderspreyground.com/howto/dk-toepincher/Quad-Servo-Seek-to-random-6.txt

Title: Re: Doctors Patient program
Post by: bsnut on October 29, 2011, 08:58:35 AM
OK, I finally got it right you. I didn't check my code. My bad, sorry. 

The reason for the crazy servo movements. Because, I didn't SEED the variable "lottery", which is placed in the Initialization section of the program and done like this.

lottery = 1031

The reason for Seeding the variable "lottery" is to give the command RANDOM to max number to work with. 

Attached is the random servo program that I just tested for you and it works as programmed. I suggest you to load it on your Prop-2 only. That way you can test it to see if is what you are looking for. When you are happy, paste it into your code as talked about in the above post and if you want you can use this for both whimper and scream parts of your program.
Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 30, 2011, 10:24:08 AM
Here is some updated code to reflect the random servo movements.  However, i'm not getting exactly the movement I want but it is pseudo random. 

How does defining lottery = 1031 make it the max number? I'm confused by that and also the // modulus part.  I've adjusted the numbers and depending on how high or low I make them that reflects which side of the servo the random movements are on.  Right now, they are random on the 500 servopos side.  It's throwing me for a loop. 

The only problem with the code is that I get the startup, music plays, but no servo movement, no trigger works...Any idea? 

Anyhow here's the code:
' =========================================================================
'
'   File......Dotor Patient Prop.bs2
'   Purpose...
'   Author....
'   E-mail....
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------
'a)Basically I would like a servo to randomly (IF possible) turn between
'positions as if a patient on the table is confused as to where they are.
'
'b)Then, when a mat switch is triggered, the servo sweeps side to side as
' IF the patient is in pain AND screaming. Then it would reset itself to
' the beginning.
'
'Have a VMusic2 hooked up with 2 sound files (whimper, scream).
'RX is PIN 15, TX is PIN 14
'
'I also have a RC-4 hooked up with 4 lights.  2 of the lights will be ON
'when part 'a' is running.
'
'Then when part 'b' is triggered, the other two turn on.  That is on pin 13.
'
'The matswitch is on PIN 12 and the servo is PIN 8.
'
'
' -----[ 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
Headcentered    CON     750                     ' head centered
Headleft        CON     1000                    ' head counterclockwise
Headright       CON     500                     ' head clockwise
Whimperlts      CON     %0011                   ' whimper lts on RC-4 K1 and K2
Screamlts       CON     %1100                   ' scream lts on RC-4 K3 and K4

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

lottery         VAR     Word                    ' randomize lottery value for servo speed
timer           VAR     Word
delay           VAR     Word
pos1            VAR     Word
dest1           VAR     Word
servopos        VAR     Word

idx             VAR     Byte                    ' loop controller
theMP3          VAR     Byte                    ' MP3 file pointer
char            VAR     Byte                    ' character value
eePntr          VAR     Word                    ' EEPROM memory pointer

mute            VAR     Byte

panCtrl         VAR     Word
muteLeft       VAR     panCtrl.BYTE0
muteRight      VAR     panCtrl.BYTE1

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

Reset:
  SEROUT Sio, EFXBaud, ["!RC4", %00, "X"]          ' set RC-4 all off
  PAUSE 2500                                    ' let VMUSIC power up
  GOSUB VM_Stop                                 ' stop if playing
  FOR pos1 = 500 TO 1000
    PULSOUT Servo, pos1
    PAUSE 20
  NEXT

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

Main:
  timer = 0
  lottery = 1031
  dest1 = 500

Main_Preshow:
  RANDOM lottery                                   ' randomize lottery value
  dest1 = lottery // 151 + 875
  SEROUT Sio, EFXBaud, ["!RC4", %00, "S", Whimperlts] ' set whimper lts on
  theMP3 = 0
  GOSUB VM_Repeat

  IF pos1 <> dest1 THEN Update_Pos1             ' are we there yet?
  'dest1 = lottery // 375 + 700                  ' scale to 100 - 200
  dest1 = lottery // 151 + 875

Update_Pos1:
  IF pos1 < dest1 THEN Go_CW1
  pos1 = pos1 - 2

Go_CW1:
  pos1 = pos1 + 1

Update_Servos:
  PULSOUT Servo, pos1

  PAUSE 15

  DO WHILE (timer < 100)                        ' wait for 0.1s signal
    PAUSE 5                                     ' loop pad
    timer = timer + 5 * Trigger                 ' update timer
  LOOP
  IF Trigger = 0 THEN Main                      ' do Main_Preshow if Trigger is false

Start_Show:
  GOSUB VM_Stop                                 ' stop VMusic if playing "whimper"
  theMP3 = 1
  GOSUB VM_Play
  SEROUT Sio, EFXBaud, ["!RC4", %00, "S", Screamlts] ' set scream lts on
  timer = 0

Scream:
  'timer = 0                                    ' reset "timer" to be reused

  DO
  FOR servopos = Headright TO Headleft STEP 20
    PULSOUT Servo, servopos
    PAUSE 10
  NEXT

  FOR servopos = Headleft TO Headright STEP 20
    PULSOUT Servo, servopos
    PAUSE 10
  NEXT
  timer = timer + 20
  LOOP UNTIL (timer = 13000)

  GOTO Main


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

VM_Wait_Prompt:
  'SERIN RX, VMBaud, [WAIT(">")]
  RETURN

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

' Pass file # (index in DATA table) to play in "theMP3"

VM_Play:
  SEROUT TX, VMBaud, ["VPF "]
  GOTO Play_MP3

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

' Pass file # (index in DATA table) to play in "theMP3"

VM_Repeat:
  SEROUT TX, VMBaud, ["VRF "]
  GOTO Play_MP3

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

' Pass file # (index in DATA table) to play in "theMP3"

Play_MP3:
  eePntr = (8 * theMP3) + Song_List

Send_Name:                                      ' send file title
  FOR idx = 1 TO 8                              ' max is 8 characters
    READ eePntr, char                           ' get a character
    IF char = 0 THEN Finish_Cmd                 ' if 0, we're at end
    SEROUT TX, VMBaud, [char]
    eePntr = eePntr + 1
  NEXT

Finish_Cmd:
  SEROUT TX, VMBaud, [".MP3", CR]                 ' send extention + CR
  RETURN

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

VM_Wait_Start:
  'SERIN RX, VMBaud, [WAIT("T $")]
  RETURN

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

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

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

' Pass mute level (0 = loudest, 254 = muted) in "mute"

VM_Mute:
  mute = mute MAX VolMin                        ' limit per spec

  ' copy to pan register for future use

  muteLeft = mute
  muteRight = mute

  SEROUT TX, VMBaud, ["VSV ", DEC mute, CR]
  RETURN

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

' Pass levels (0 = loudest, 254 = muted) in "muteLeft" and "muteRight"
'
' NOTE: The VPF/VRF commands seems to reset volume levels so you must use
'       a pan command while the file is playing for it to work.
'
' NOTE: Over-use can result is unwanted audio "clicks" and "pops"

VM_Pan:
  muteLeft = muteLeft MAX $FE                     ' limit per spec
  muteRight = muteRight MAX $FE

  SEROUT TX, VMBaud, ["VWR $0B", HEX4 panCtrl, CR]
  RETURN


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

' File names are stored on 8-byte boundaries -- this is very important for
' correct program operation.  This strategy uses a little more EE space but
' is easier to update and maintain

Song_List       DATA    @$00, "ambient"         ' theMP3 = 0
                DATA    @$08, "scream"          ' theMP3 = 1
Title: Re: Doctors Patient program
Post by: bsnut on October 30, 2011, 07:15:24 PM
QuoteHow does defining lottery = 1031 make it the max
If you look in the Basic Stamp help file under random you will find this
about random
Quote
RANDOM generates pseudo-random numbers ranging from 0 to 65535.
They're called "pseudo-random" because they appear random, but are
generated by a logic operation that uses the initial value in Variable
to "tap" into a sequence of 65535 essentially random numbers.
If the same initial value, called the "seed", is always used, then
the same sequence of numbers is generated. The following example demonstrates this:

result  VAR     Word

Main:
  result = 11000                        ' set initial "seed" value
  RANDOM result                         ' generate random number
  DEBUG DEC ? result                    ' show the result on screen
  GOTO Main

In this example, the same number would appear on the screen over and over again.
This is because the same seed value was used each time; specifically, the first line
of the loop sets result to 11000. The RANDOM command really needs a different seed value
each time. Moving the "Result =" line out of the loop will solve this problem, as in:

result  VAR     Word

Setup:
  result = 11000                        ' set initial "seed" value

Main:
  RANDOM result                         ' generate random number
  DEBUG DEC ? result                    ' show the result on screen
  GOTO Main
  END

Here, result is only initialized once, before the loop. Each time through the loop,
the previous value of result, generated by RANDOM, is used as the next seed value.
This generates a more desirable set of pseudo-random numbers.

In applications requiring more apparent randomness, it's necessary to "seed" RANDOM
with a more random value every time. For instance, in the example program
(See Editor Help File),RANDOM is executed continuously (using the previous resulting
number as the next seed value) while the program waits for the user to press a button.
Since the user can't control the timing of button presses very accurately, the results
approach true randomness.
And here is the on the MOdulus operator as well from the help file
Quote
The Modulus operator (//) returns the remainder left after dividing one value by another.
Some division problems don't have a whole-number result; they return a whole number and
a fraction. For example, 1000 / 6 = 166.667. Integer math doesn't allow the fractional
portion of the result, so 1000 / 6 = 166. However, 166 is an approximate answer, because
166 * 6 = 996. The division operation left a remainder of 4. The // (double-slash)
returns the remainder of a given division operation. Naturally, numbers that divide
evenly, such as 1000 / 5, produce a remainder of 0.

What you may want to do is lower the PAUSE command from this PAUSE 15 to this PAUSE 7
due to the fact it takes time for the SEROUT to transmit it's data to VMusic and RC-4

I noticed this maybe causing the problem with the trigger and you may want to comment
this code out.

DO WHILE (timer < 100)                        ' wait for 0.1s signal
  PAUSE 5                                     ' loop pad
  timer = timer + 5 * Trigger                 ' update timer
LOOP

Also you can try changing this code from this

IF Trigger = 0 THEN Main                      ' do Main_Preshow if Trigger is false

to this

IF Trigger = 0 THEN Run_Preshow               ' do Run_Preshow if Trigger is false

and and add this label above the servo code
   
Run_Preshow:


IF pos1 <> dest1 THEN Update_Pos1             ' are we there yet?

Or, you try this with the servo code between DO WHILE..LOOP Statements for the preshow code.

DO WHILE (Trigger = 0)
'Insert servo code here
LOOP









Title: Re: Doctors Patient program
Post by: JonnyMac on October 31, 2011, 11:03:32 AM
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.
Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 31, 2011, 11:33:18 AM
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??
Title: Re: Doctors Patient program
Post by: JonnyMac on October 31, 2011, 11:48:02 AM
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?
Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 31, 2011, 11:52:05 AM
My scream sound file is 13 seconds long.  The ambient track is the whimpering sound.  I am using the vmusic2 again. 
Title: Re: Doctors Patient program
Post by: JonnyMac on October 31, 2011, 12:01:08 PM
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).
Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 31, 2011, 12:12:37 PM
Sorry for the touble.  I've used it on another prop and haven't had issues with it.  Maybe i'm lucky?
Title: Re: Doctors Patient program
Post by: JonnyMac on October 31, 2011, 12:55:44 PM
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).
Title: Re: Doctors Patient program
Post by: JonnyMac on October 31, 2011, 01:10:10 PM
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?
Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 31, 2011, 01:13:29 PM
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.
Title: Re: Doctors Patient program
Post by: JonnyMac on October 31, 2011, 01:50:12 PM
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

' -------------------------------------------------------------------------
Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 31, 2011, 02:14:39 PM
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.
Title: Re: Doctors Patient program
Post by: JonnyMac on October 31, 2011, 03:29:37 PM
Do you have a Prop-1 Trainer that we can use to monitor the program state?
Title: Re: Doctors Patient program
Post by: LPFreak1283 on October 31, 2011, 03:31:17 PM
Oy not handy...If it werent 1/2 hour before trick or treating I would search for it  ;D
Title: Re: Doctors Patient program
Post by: JonnyMac on October 31, 2011, 03:40:29 PM
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.
Title: Re: Doctors Patient program
Post by: LPFreak1283 on November 09, 2015, 11:58:33 AM
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 (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

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