April 25, 2024, 05:49:40 PM

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.


Kenton Avenue 2008 Haunt file

Started by tds234, August 17, 2008, 08:53:12 PM

Previous topic - Next topic

tds234

Hi Jon,
I was hoping that you might take a look at this file and suggest some improvements. It's a work in progress.

Specifically, the cross-fade subroutine (i.e. the line "crossFade 2,3") does not work and I just cannot see it.

I also occasionally miss queues from the uMP3 when it is playing but I think that' related to how slow (2400 baud) I am running it from when it was hooked to a Prop-1.

Finally, I am out of debug space so any suggestions on how to tighten it up to get it 'debuggeable' again would be very welcome.

Thanks in advance for any help!

Freshly Doug

' =========================================================================
'
'   File...... Kenton Avenue Haunt 2008.SXB
'   Purpose... SX/B Programming Template
'   Author....  TDS2.0
'   E-mail....  TDS2@scrimager.com
'   Started...
'   Updated...
'
' =========================================================================


' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

'DEVICE          SX28, OSC4MHZ, TURBO, STACKX, OPTIONX, BOR42
'FREQ            4_000_000

DEVICE          SX28, OSCXT2, TURBO, STACKX, OPTIONX, BOR42
FREQ            20_000_000

ID              "TDS2.0"

' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------
Sio1             PIN     RB.7                    ' talk to EFX devices
Sio2             PIN     RB.6                    ' talk to Rogue MP3 player
Sio3 PIN RB.5 ' listen to Rogue MP3 player
Flicker PIN RB.4 ' talk to Prop1-1 for flicker
ShowTrigger PIN RB.3 ' used to trigger the show
RandomShow PIN RB.2 ' used to enable random show when main show not running
Hold1 PIN RB.1   OUTPUT
ShowBlink PIN RB.0 OUTPUT ' blink the LED when show going, solid when random show going, out otherwise

UsedRB PIN RB OUTPUT
UnusedRC PIN RC INPUT PULLUP

' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------
BaudMode1        CON     "OT38400"
BaudMode2        CON     "OT2400"

' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------
tmpB1           VAR     Byte                    ' for subs/funcs
tmpB2           VAR     Byte
tmpB3 VAR Byte
cnt VAR Byte
tmpW1           VAR     Word
ser VAR Byte
strings VAR Byte
result VAR Byte
cntparty VAR Byte
fadeCnt VAR Byte
charIn VAR Byte
retry VAR Byte

' -------------------------------------------------------------------------
  INTERRUPT
' -------------------------------------------------------------------------

ISR_Start:
  ' ISR code here

ISR_Exit:
  RETURNINT ' {cycles}                                 


' =========================================================================
  PROGRAM Start
' =========================================================================

Pgm_ID:
  DATA  "2008 Kenton Avenue Haunt Show", 0

' -------------------------------------------------------------------------
' Configuration
' -------------------------------------------------------------------------
' RC-4 %00 Pneumatic channels
' RC-4 %01 string light on/off channels (string 1 - 4)
' RC-4 %10
' FC-4 %00 faders for 4 channels of lights (light 1 - 4)
' DC-16 %00 1-8 Power on for skulls and show devices 9-16 power on for party devices

' skull 1 (MAX)     DCpower1, light1, Pneumo 1
' skull1 (Mortimer) DCpower2, light2, Pneumo 2
' Tomb              DCpower3, light3, Pneumo 3
' mummy             DCpower4, light4, Pneumo 4

' -------------------------------------------------------------------------
' Subroutines / Jump Table
' -------------------------------------------------------------------------

RX_BYTE         FUNC    1, 0                    ' receive a byte
TX_BYTE         SUB     1                       ' transmit a byte
TX_STR          SUB     2                       ' transmit a string
DELAY_MS        SUB     1, 2                    ' delay in milliseconds

Blink SUB 1

LoopUntilAudioDone SUB 0

FlickerOn SUB 0
FlickerOff SUB 0

PartyOn SUB 0
PartyOff SUB 0

CheckForSongPlaying Func 1, 0

'FC-4 Channels 1 - 4
FadeUp SUB 1
FadeDown SUB 1
FadeTwoUp SUB 2
FadeTwoDown SUB 2

CrossFade SUB 2

'AllFadeDown SUB 0

DCPowerOn SUB 1
DCPowerOff SUB 1

'RC-4 1
PneumoOn SUB 1
PneumoOff SUB 1

'RC-4 2
StringToggle SUB 1

'RC-4 3

'Rogue1
PlayTrack SUB 1

ResetShow SUB 0

' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
  ' initialization code here
  OUTPUT ShowBlink
  strings = 0  'all off

  Random result
  pause 5_000

  ResetShow
'Reset:
'  PAUSE 10000                                    ' let uMP3 start
'  SEROUT TX, Baud, ("ST R 5", 13)
'  SEROUT TX, Baud, ("ST H 1",13)
'  DEBUG "start"

Retry = 10

Prod_uMP3:

Retry = retry - 1
if retry < 1 then goto Main
  ser = 2
  TX_BYTE 13                         ' send CR
  charIn = RX_BYTE
                       
' get response
  IF charIn <> ">" THEN goto Prod_uMP3                 ' wait for ">"
  'DEBUG "ok1", CR

Main:
  ' main code here

' -------------------------------------------------------------------------
  ' act 1
' -------------------------------------------------------------------------

  ' host talks
  Blink 1
 
  ' flicker lights on
  'FlickerOn
  ' turn on skull 1
  DCPowerOn 1
  ' fade up skull 1 light
  FadeUp 1
  ' trigger pneumo channel 1
  PneumoOn 1
  Pause 2_000
  ' trigger track 1 MP3
  PlayTrack 1
  Pause 1_000
  LoopUntilAudioDone
  pause 250

' -------------------------------------------------------------------------
  'act 2
' -------------------------------------------------------------------------

  ' two skull dialog
  Blink 2

  ' fade up skull 2 light
  FadeUp 2
  DCPowerOn 2
  ' trigger pneumo channel 2
  PneumoOn 2
  Pause 2_000
  ' dialog plays
  PlayTrack 2
  Pause 1_000
  LoopUntilAudioDone
  Pause 50

  'fade both skulls
  'FadeTwoDown 1, 2
  FadeDown 1
  Pause 1_000
  'FadeDown 2

' -------------------------------------------------------------------------
  'act 3
' -------------------------------------------------------------------------

  'party song
  Blink 3

  'trigger track 3 MP3
  PlayTrack 3
  'checkPlay:
  pause 1_000

  FadeDown 2

  cntParty = 0
  cntParty = CheckForSongPlaying
  do while cntParty = 1
PartyOn ' turns party stuff on and off randomly
        pause 500
  cntParty = CheckForSongPlaying
        pause 250
  Loop
  Pause 50

  'doneNow:
  PartyOff

' -------------------------------------------------------------------------
  'act 4
' -------------------------------------------------------------------------

  'two skull dialog
  Blink 4

  ' fade up skull 1 light
  FadeUp 1
  ' trigger track 4 MP3
  PlayTrack 4
  Pause 2_000
  FadeUp 2

  LoopUntilAudioDone
 
  ' cross fade light 2 to light 3 tomb
  CrossFade 2, 3
  ' trigger pneumo channel 2 off
  PneumoOff 2

' -------------------------------------------------------------------------
  'act 5
' -------------------------------------------------------------------------

  ' tomb collapse
  Blink 5

  PlayTrack 5
  Pause 500
  ' trigger pneumo 3
    DCPowerOn 3
    PneumoOn 3

  LoopUntilAudioDone

  ' cross fade light 3 to light 4 mummy
  CrossFade 3, 4
  pause 500
  DCPowerOff 3

' -------------------------------------------------------------------------
  'act 6
' -------------------------------------------------------------------------

  ' skull and mummy dialog
  Blink 6
  'pause for track playing
  PlayTrack 6
  Pause 500

  ' trigger pneumo 4 mummy
  DCPowerOn 4
  'Pause 250
  PneumoOn 4

  LoopUntilAudioDone

  PneumoOff 4
  DCPowerOff 4

' -------------------------------------------------------------------------
  'act 7
' -------------------------------------------------------------------------

  ' max and mort finish
  Blink 7

  PlayTrack 7
  Pause 250

  PneumoOn 2
  CrossFade 4, 2
  ' loop for a while
  LoopUntilAudioDone

  'reset for next show
  'fade down skull 1 light and skull 2 light

  'AllFadeDown

  ResetShow

  'FlickerOff

  GOTO Main
' -------------------------------------------------------------------------

SUB ResetShow

ser = 1
TX_STR "!RC4"
        TX_BYTE %00
        TX_BYTE "X"
TX_STR "!RC4"
        TX_BYTE %01
        TX_BYTE "X"
TX_STR "!RC4"
        TX_BYTE %10
        TX_BYTE "X"

TX_STR "!DC16"
        TX_BYTE %00
        TX_BYTE "X"
TX_STR "!FC4"
        TX_BYTE %00
        TX_BYTE "X"

ENDSUB


SUB LoopUntilAudioDone
  cntParty = 0
  cntParty = CheckForSongPlaying
  do while cntParty = 1
        pause 500
  cntParty = CheckForSongPlaying
  Loop
ENDSUB

SUB Blink
  tmpB1 = __PARAM1     
  for tmpB2 = 1 to tmpB1
    Low ShowBlink
    pause 150
    High ShowBlink
    pause 150
  next
  pause 500
ENDSUB

SUB FlickerOn
  Flicker = 1
ENDSUB

SUB FlickerOff
  Flicker = 0
ENDSUB


SUB PartyOn
ser = 1
' calculate a new strings setting
random result
tmpB3 = result & %00001111
StringToggle tmpB3
' every four tries ( about 4 seconds )
' choose a random party favor to toggle

ENDSUB

SUB PartyOff
ser = 1
strings = %0000

'StringToggle strings
'Blink 1
FOR cnt = 1 to 8
   DCPowerOff cnt
next
ENDSUB

SUB PlayTrack
  ser = 2
  tmpB1 = __PARAM1
  if tmpB1 = 1 then
    TX_STR "PC F /K1.MP3"
    TX_BYTE 13
  ENDIF

  if tmpB1 = 2 then
    TX_STR "PC F /K2.MP3"
    TX_BYTE 13
  ENDIF

  if tmpB1 = 3 then
    TX_STR "PC F /K3.MP3"
    TX_BYTE 13
  ENDIF
  if tmpB1 = 4 then
    TX_STR "PC F /K4.MP3"
    TX_BYTE 13
  ENDIF
  if tmpB1 = 5 then
    TX_STR "PC F /K5.MP3"
    TX_BYTE 13
  ENDIF

  if tmpB1 = 6 then
    TX_STR "PC F /K6.MP3"
    TX_BYTE 13
  ENDIF

  if tmpB1 = 7 then
    TX_STR "PC F /K7.MP3"
    TX_BYTE 13
  ENDIF

ENDSUB

'sets all strings to given setting
'SEROUT Sio, OT2400, ("!RC4", %00, "S", %0001)
'SEROUT Sio, OT2400, ("!RC4", %00, "R", 4, 1)
SUB StringToggle
  ser = 1
  tmpB1 = __PARAM1     
  TX_STR  "!RC4"                                ' header
  TX_BYTE %01                                   ' address
  TX_BYTE "S"                                   ' set command
  TX_BYTE tmpB1                                 '
ENDSUB

Func CheckForSongPlaying
   ser = 2
   tmpB1 = 0
    TX_STR "PC Z"
    TX_BYTE 13
    tmpB1 = RX_BYTE
    'if tmpB1 <> "P" then goto NoMore
    'tmpB2 = RX_BYTE
    'tmpB2 = RX_BYTE
    'NoMore:
    if tmpB1 <> "P" then
tmpB3 = 0
    else
tmpB3 = 1
        tmpB2 = RX_BYTE
        tmpB2 = RX_BYTE
    endif
   RETURN tmpB3

'used to switch on DC selenoids from DC-16 board
'SEROUT Sio, OT2400, ("!DC16", %11, "P", 7, 1)
SUB DCPowerOn
ser = 1
  tmpB2 = __PARAM1                              '
  TX_STR  "!DC16"                               ' header
  TX_BYTE %00                                   ' address
  TX_BYTE "P"                                   ' set command
  TX_BYTE tmpB2                                 '
  TX_BYTE 1   

ENDSUB

'used to switch off DC selenoids from DC-16 board
SUB DCPowerOff
  ser = 1
  tmpB2 = __PARAM1                              '
  TX_STR  "!DC16"                               ' header
  TX_BYTE %00                                   ' address
  TX_BYTE "P"                                   ' set command
  TX_BYTE tmpB2                                 '
  TX_BYTE 0       
ENDSUB

'SEROUT Sio, OT2400, ("!RC4", %00, "R", 4, 1)
SUB PneumoOn
  ser = 1
  tmpB2 = __PARAM1                              ' get relay bits
  TX_STR  "!RC4"                                ' header
  TX_BYTE %00                                   ' address
  TX_BYTE "R"                                   ' set command
  TX_BYTE tmpB2                                 ' relay bits
  TX_BYTE 1       
  ENDSUB

SUB PneumoOff
  ser = 1
  tmpB2 = __PARAM1                              ' get relay bits
  TX_STR  "!RC4"                                ' header
  TX_BYTE %00                                   ' address
  TX_BYTE "R"                                   ' set command
  TX_BYTE tmpB2                                 ' relay bits
  TX_BYTE 0       
  ENDSUB


'SEROUT Sio, OT2400, ("!FC4", %00, "F", 1, 0, 255, 20)

SUB FadeUp
  ser = 1
  tmpB2 = __PARAM1                              ' get relay bits
  TX_STR  "!FC4"                                ' header
  TX_BYTE %00                                   ' address
  TX_BYTE "F"                                   ' set command
  TX_BYTE tmpB2                                 ' relay bits
  TX_BYTE 0       
  TX_BYTE 255                                 
  TX_BYTE 4                                                 

  ENDSUB


SUB FadeDown
  ser = 1
  tmpB2 = __PARAM1                              ' get relay bits
  TX_STR  "!FC4"                                ' header
  TX_BYTE %00                                   ' address
  TX_BYTE "F"                                   ' set command
  TX_BYTE tmpB2                                 ' relay bits
  TX_BYTE 255       
  TX_BYTE 1                                 
  TX_BYTE 4                                                 

  ENDSUB

'SEROUT Sio, OT2400, ("!FC4", %00, "L", 2, 128)
SUB FadeTwoDown
  ser = 1
  tmpB1 = __PARAM1                             
  tmpB2 = __PARAM2

  for fadeCnt = 256 to 1 step - 1
    TX_STR  "!FC4"                                ' header
    TX_BYTE %00                                   ' address
    TX_BYTE "L"                                   ' set command
    TX_BYTE tmpB1                                 ' relay bits
    TX_BYTE fadeCnt       
    pause 50
    TX_STR  "!FC4"                                ' header
    TX_BYTE %00                                   ' address
    TX_BYTE "L"                                   ' set command
    TX_BYTE tmpB2                                 ' relay bits
    TX_BYTE fadeCnt       
  Next
  pause 50
  ENDSUB

SUB FadeTwoUp
ENDSUB



'SEROUT Sio, OT2400, ("!FC4", %00, "C", 0, 1, 2, 40)
Sub CrossFade
  ser = 1
  tmpB1 = __PARAM1                              '
  tmpB2 = __PARAM2
  TX_STR  "!!FC4"                                ' header
  TX_BYTE %00                                   ' address
  TX_BYTE "C" 
  TX_BYTE 0                              ' set command
  TX_BYTE tmpB1                                 
  TX_BYTE tmpB2                                 
  TX_BYTE 8                                                 

  ENDSUB

'AllFadeDown SUB 0

' Use: byteVal = RX_BYTE
' -- receive "byteVal" at "BaudMode" on pin "Sio"

FUNC RX_BYTE
  tmpB1 = 0
  IF ser = 1 then
    SERIN Sio1, BaudMode1, tmpB1
  ELSE
SERIN Sio3, BaudMode2, tmpB1, 2000, No_Char 
  ENDIF
 
  goto normalEnd
  No_Char:
  ser = 0
  normalEnd: 
  RETURN tmpB1
  ENDFUNC

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

' Use: TX_BYTE byteVal
' -- transmit "byteVal" at "BaudMode" on pin "Sio"

SUB TX_BYTE
  IF ser = 1 then
    SEROUT Sio1, BaudMode1, __PARAM1
  ELSE
    SEROUT Sio2, BaudMode2, __PARAM1
  ENDIF
 
ENDSUB

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

' Use: TX_STR [string | label]
' -- "string" is an embedded string constant
' -- "label" is DATA statement label for stored z-String

SUB TX_STR
  tmpW1 = __WPARAM12                            ' get address of string
  DO
    READINC tmpW1, tmpB1                        ' read a character
    IF tmpB1 = 0 THEN EXIT                      ' if 0, string complete
    TX_BYTE tmpB1                               ' send character
  LOOP
  ENDSUB

' Use: DELAY_MS milliseconds

SUB DELAY_MS
  IF __PARAMCNT = 1 THEN
    tmpW1 = __PARAM1
  ELSE
    tmpW1 = __WPARAM12
  ENDIF
  PAUSE tmpW1
  ENDSUB

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


JonnyMac

August 17, 2008, 09:48:57 PM #1 Last Edit: August 17, 2008, 10:00:38 PM by JonnyMac
The formatting is somewhat messy -- by my standards -- which makes it difficult for me to evaluate.  I'm going to reformat it and clean up the obvious stuff like the empty interrupt which could be causing problems, and the selective baud rate on your transmit and receive routines when there is really no need for it (that I can see).  When I'm done reformatting I'll post the code and you can see how I might approach things differently.

One the the easiest ways to reduce code space is to replace all the PAUSE calls with the DELAY_MS subroutine; that will save a bunch of space.
Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

August 18, 2008, 12:12:24 AM #2 Last Edit: August 18, 2008, 12:41:46 AM by JonnyMac
Okay, have a look at the listing I've attached.  It's not a rewrite of your whole program, just [most of] the core routines that you'll use to build the operational program.  I think if you study it for an hour or so my logic will make sense.  I have a lot of experience with SX/B and I've learned where I can use internal variables versus user variables -- often the use of internal variables saves conflicts when calling routine to routine.

You'll notice that I've added in a lot of flexibility to the routines; this will prevent you from writing redundant routines that simple consume extra code space.

Let me show you a simple example of wasted space:
SUB FlickerOn
  Flicker = 1
  ENDSUB

SUB FlickerOff
  Flicker = 0
  ENDSUB


The definitions and calls to these subroutines use more space than required; a better way -- yet still humanly readable -- is like this:
Flicker = IsOn
Flicker = IsOff


Instead of using subroutines, the listing I've attached has constants for IsOn and Isoff. 

I hope you find the attached code useful and educational.  Above all, notice that the listing is ridiculously neat and orderly; most bugs and errors are created in listings that are difficult for the eye to follow.  It doesn't take any extra time to format a listing properly (by my definition), but it can save you hours of frustrating bug hunting.
Jon McPhalen
EFX-TEK Hollywood Office

tds234

Ok, I've pared it down quite a bit and done some cleanup.
I think the earlier issue with crossfading is with not having a sufficient load on the FC-4 outputs.
This is for those interested in reading some (not good and certainly not as clean as the Mac man's, but working) code,...

' =========================================================================
'
'   File...... Kenton Avenue Haunt 2008.SXB
'   Purpose... SX/B Programming Template
'   Author....  TDS2.0
'   E-mail....  TDS2@scrimager.com
'   Started...
'   Updated...
'
' =========================================================================


' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

'DEVICE          SX28, OSC4MHZ, TURBO, STACKX, OPTIONX, BOR42
'FREQ            4_000_000

DEVICE          SX28, OSCXT2, TURBO, STACKX, OPTIONX, BOR42
FREQ            20_000_000

ID              "TDS2.0"

' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------
Sio1             PIN     RB.7                    ' talk to HIgh Voltage EFX devices
Sio2             PIN     RB.6                    ' talk to Rogue MP3 player
Sio3 PIN RB.5 ' listen to Rogue MP3 player
'Flicker PIN RB.4 ' talk to Prop1-1 for flicker
ShowTrigger PIN RB.3 INPUT ' used to trigger the show
'RandomShow PIN RB.2 INPUT ' used to enable random show when main show not running
Sio4 PIN RB.2     ' used to talk to Low Voltage EFX devices
PIR PIN RB.1   INPUT ' used to trigger show if motion detected
ShowBlink PIN RB.0 OUTPUT ' blink the LED when show going, solid when random show going, out otherwise

Flicker PIN RC.0  OUTPUT ' switch selenoid for flicker
LEDboard        PIN     RC.1  OUTPUT 'switch selenoid for LED lights
Speaker1 PIN RC.2 OUTPUT
Speaker2 PIN RC.3 OUTPUT
Speaker3 PIN RC.4 OUTPUT


'UsedRB PIN RB OUTPUT
'UnusedRC PIN RC INPUT PULLUP

' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------
BaudMode1        CON     "OT38400"
BaudMode2        CON     "OT2400"

IsOn            CON     1
IsOff           CON     0

' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------
tmpB1           VAR     Byte                    ' for subs/funcs
tmpB2           VAR     Byte
tmpB3 VAR Byte
cnt VAR Byte
tmpW1           VAR     Word
ser VAR Byte
strings VAR Byte
result VAR Byte
cntparty VAR Byte
fadeCnt VAR Byte
charIn VAR Byte
retry VAR Byte
idx VAR Byte
dcHigh VAR Byte

' =========================================================================
 PROGRAM Start
' =========================================================================

Pgm_ID:
 DATA  "2008 Kenton Avenue Haunt Show", 0

' -------------------------------------------------------------------------
' Configuration
' -------------------------------------------------------------------------
' RC-4 %00 Pneumatic channels
' RC-4 %01 string light on/off channels (string 1 - 4)
' RC-4 %10
' FC-4 %00 faders for 4 channels of lights (light 1 - 4)
' DC-16 %00 1-8 Power on for skulls and show devices 9-16 power on for party devices

' skull 1 (MAX)      DCpower1, light1, Pneumo 1
' skull 2 (Mortimer) DCpower2, light2, Pneumo 2
' Tomb               DCpower3, light3, Pneumo 3
' mummy              DCpower4, light4, Pneumo 4

' -------------------------------------------------------------------------
' Subroutines / Jump Table
' -------------------------------------------------------------------------

RX_BYTE         FUNC    1, 0                    ' receive a byte
TX_BYTE         SUB     1                       ' transmit a byte
TX_STR          SUB     2                       ' transmit a string
DELAY_MS        SUB     1, 2                    ' delay in milliseconds

Blink SUB 1

LoopUntilAudioDone SUB 0

'FlickerOn SUB 0
'FlickerOff SUB 0

PartyOn SUB 0
PartyOff SUB 0

CheckForSongPlaying Func 1, 0

'FC-4 Channels 1 - 4
FadeUp SUB 1
FadeDown SUB 1
FadeTwoUp SUB 2
FadeTwoDown SUB 2

CrossFade SUB 2

'AllFadeDown SUB 0

DCPowerOn SUB 1
DCPowerOff SUB 1

'RC-4 1
PneumoOn SUB 1
PneumoOff SUB 1

'RC-4 2
StringToggle SUB 1

'RC-4 3

'Rogue1
PlayTrack SUB 1

ResetShow SUB 0

' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
 ' initialization code here
 OUTPUT ShowBlink
 INPUT ShowTrigger

 ShowBlink = IsOff
 Flicker = IsOff
 LEDBoard = IsOff
 strings = 0  'all off

Blink 6

 Random result
 Delay_MS 20_000 ' let PIR stabilize

 gosub ResetShow


'Reset:
'  Delay_MS 10000                                    ' let uMP3 start
'  SEROUT TX, Baud, ("ST R 5", 13)
'  SEROUT TX, Baud, ("ST H 1",13)
'  DEBUG "start"

Retry = 10

Prod_uMP3:

Blink 1

Retry = retry - 1
if retry < 1 then goto Main
 ser = 2
 TX_BYTE 13                         ' send CR
 charIn = RX_BYTE
                     
' get response
 IF charIn <> ">" THEN goto Prod_uMP3                 ' wait for ">"
 'DEBUG "ok1", CR

Main:
 ' main code here
delay_MS 1_000
Blink 1

Random result 'stir it up

 cnt = 0

CheckShowTrigger:

'check for show trigger
 if ShowTrigger <> IsOn then goto Main
 cnt = 0
 ' debounce trigger
 do while ShowTrigger = IsOn
   cnt = cnt + 1
   delay_ms 50
   if cnt > 5 then exit
 loop
 if cnt > 4 then goto MainShow

 Blink 6
 goto Main

MainShow:
' -------------------------------------------------------------------------
 ' act 1
' -------------------------------------------------------------------------

 ' host talks
 Blink 1
 Speaker1 = IsOn
 ' flicker lights on
 Flicker = IsOn
 ' turn on skull 1
 DCPowerOn 1
 ' fade up skull 1 light
 FadeUp 1
 ' trigger pneumo channel 1
 PneumoOn 1
 Delay_MS 2_000
 ' trigger track 1 MP3
 PlayTrack 1
 Delay_MS 1_000
 LoopUntilAudioDone
 Delay_MS 250

' -------------------------------------------------------------------------
 'act 2
' -------------------------------------------------------------------------

 ' two skull dialog
 Blink 2

 Speaker2 = IsOn
 ' fade up skull 2 light
 FadeUp 2
 DCPowerOn 2
 ' trigger pneumo channel 2
 PneumoOn 2
 Delay_MS 2_000
 ' dialog plays
 PlayTrack 2
 Delay_MS 1_000
 LoopUntilAudioDone
 Delay_MS 50

 'fade both skulls
 'FadeTwoDown 1, 2
 FadeDown 1
 Delay_MS 1_000
 'FadeDown 2
 DCPowerOff 1
 DCPowerOff 2

' -------------------------------------------------------------------------
 'act 3
' -------------------------------------------------------------------------

 'party song
 Blink 3
 DCPowerOn 3 'turn on both speakers
 LEDboard = IsOn
 'trigger track 3 MP3
 PlayTrack 3
 'checkPlay:
 Delay_MS 1_000

 FadeDown 2

 dcHigh = 0
 cnt = 0
 cntParty = 0
 cntParty = CheckForSongPlaying

 do while cntParty = 1
PartyOn ' turns party stuff on and off randomly
       Delay_MS 500
  cntParty = CheckForSongPlaying
       Delay_MS 250
 Loop
 Delay_MS 50

 DCPowerOff 3

 'doneNow:
 PartyOff
 LedBoard = IsOff
' -------------------------------------------------------------------------
 'act 4
' -------------------------------------------------------------------------

 'two skull dialog
 Blink 4
 DCPowerOn 1
 DCPowerOn 2

 ' fade up skull 1 light
 FadeUp 1
 ' trigger track 4 MP3
 PlayTrack 4
 Delay_MS 2_000
 FadeUp 2

 LoopUntilAudioDone
 
 ' cross fade light 2 to light 3 tomb
 'CrossFade 2, 3
 FadeDown 2
 DCPowerOff 1
 DCPowerOff 2
 Pause 2_000
 FadeUp 3

 ' trigger pneumo channel 2 off
 PneumoOff 2

' -------------------------------------------------------------------------
 'act 5
' -------------------------------------------------------------------------

 ' tomb collapse
 Blink 5
 DCPowerOn 3 'Turn on both speakers

 PlayTrack 5
 Delay_MS 500
 ' trigger pneumo 3
 'DCPowerOn 3
 PneumoOn 3

 LoopUntilAudioDone

 ' cross fade light 3 to light 4 mummy
 'CrossFade 3, 4
 FadeDown 3

 DCPowerOff 3

 Pause 2_000
 FadeUp 4

 Delay_MS 500
 'DCPowerOff 3

' -------------------------------------------------------------------------
 'act 6
' -------------------------------------------------------------------------

 ' skull and mummy dialog
 Blink 6
 DCPowerOn 1
 Speaker2 = IsOff
 Speaker3 = IsOn

 ' trigger pneumo 4 mummy
 DCPowerOn 4
 PneumoOn 4

 Delay_MS 500

 'Delay_MS for track playing
 PlayTrack 6
 Delay_MS 500

 LoopUntilAudioDone

 PneumoOff 4
 DCPowerOff 4

' -------------------------------------------------------------------------
 'act 7
' -------------------------------------------------------------------------

 ' max and mort finish
 Blink 7

 Speaker3 = IsOff
 Speaker2 = IsOn

 PlayTrack 7
 Delay_MS 250

 PneumoOn 2
 DCPowerOn 2

 'CrossFade 4, 2
 FadeDown 4
 Pause 2_000
 FadeUp 2

 ' loop for a while
 LoopUntilAudioDone

 'reset for next show
 'fade down skull 1 light and skull 2 light
 FadeDown 2
 Pause 2_000
 FadeDown 1
 'AllFadeDown

 ResetShow

 'FlickerOff

 GOTO Main
' -------------------------------------------------------------------------

SUB ResetShow

Flicker = IsOff

ser = 1
       for idx = 0 to 3
 TX_STR "!RC4"
         TX_BYTE idx
         TX_BYTE "X"
         delay_ms 100
       next

TX_STR "!DC16"
       TX_BYTE %00
       TX_BYTE "X"
       delay_ms 100

TX_STR "!FC4"
       TX_BYTE %00
       TX_BYTE "X"
       delay_ms 100

ENDSUB


SUB LoopUntilAudioDone
 cntParty = 0
 cntParty = CheckForSongPlaying
 do while cntParty = 1
       Delay_MS 500
  cntParty = CheckForSongPlaying
 Loop
ENDSUB

SUB Blink
 tmpB1 = __PARAM1    
 for tmpB2 = 1 to tmpB1
   Low ShowBlink
   Delay_MS 150
   High ShowBlink
   Delay_MS 150
 next
 Delay_MS 500
ENDSUB

SUB StringToggle
 ser = 1
 'tmpB1 = __PARAM1  
 'watch __PARAM1  
 TX_STR  "!RC4"                                ' header
 TX_BYTE %01                                   ' address
 TX_BYTE "S"                                   ' set command
 TX_BYTE __PARAM1                                 '
ENDSUB

SUB PartyOn
ser = 1
' calculate a new strings setting
random result
tmpB3 = result & %00001111
' every four tries ( about 4 seconds )
 
 ser = 1
 TX_STR  "!RC4"                                ' header
 TX_BYTE %01                                   ' address
 TX_BYTE "S"                                   ' set command
 TX_BYTE tmpB3                                 '
 delay_ms 50

 cnt = cnt + 1
 cnt = cnt // 4
 if cnt = 0 then
   ' turn on each DC output one at a time
   'SEROUT Sio, OT2400, ("!DC16", %11, "H", %00000011)  
   DCHigh = DCHigh << 1
   DCHigh = DCHigh + 1
   ser = 3
   TX_STR  "!DC16"                                ' header
   TX_BYTE %00                                   ' address
   TX_BYTE "H"                                   ' set command
   TX_BYTE dcHigh                                 '
   delay_ms 50
 endif
 
ENDSUB

SUB PartyOff
ser = 1
strings = %0000

ser = 1
TX_STR  "!RC4"                                ' header
TX_BYTE %01                                   ' address
TX_BYTE "S"                                   ' set command
TX_BYTE %0000                                 '
delay_ms 500

'Blink 1
FOR cnt = 8 to 16
  DCPowerOff cnt
next
ENDSUB

SUB PlayTrack
 ser = 2
 tmpB1 = __PARAM1
 if tmpB1 = 1 then
   TX_STR "PC F /K1.MP3"
   TX_BYTE 13
 ENDIF

 if tmpB1 = 2 then
   TX_STR "PC F /K2.MP3"
   TX_BYTE 13
 ENDIF

 if tmpB1 = 3 then
   TX_STR "PC F /K3.MP3"
   TX_BYTE 13
 ENDIF
 if tmpB1 = 4 then
   TX_STR "PC F /K4.MP3"
   TX_BYTE 13
 ENDIF
 if tmpB1 = 5 then
   TX_STR "PC F /K5.MP3"
   TX_BYTE 13
 ENDIF

 if tmpB1 = 6 then
   TX_STR "PC F /K6.MP3"
   TX_BYTE 13
 ENDIF

 if tmpB1 = 7 then
   TX_STR "PC F /K7.MP3"
   TX_BYTE 13
 ENDIF

ENDSUB


Func CheckForSongPlaying
  ser = 2
  tmpB1 = 0
   TX_STR "PC Z"
   TX_BYTE 13
   tmpB1 = RX_BYTE
   'if tmpB1 <> "P" then goto NoMore
   'tmpB2 = RX_BYTE
   'tmpB2 = RX_BYTE
   'NoMore:
   if tmpB1 <> "S" then
tmpB3 = 1
       tmpB2 = RX_BYTE
       tmpB2 = RX_BYTE
   else
tmpB3 = 0
       'tmpB2 = RX_BYTE
       'tmpB2 = RX_BYTE
   endif
  RETURN tmpB3

'used to switch on DC selenoids from DC-16 board
'SEROUT Sio, OT2400, ("!DC16", %11, "P", 7, 1)
SUB DCPowerOn
ser = 3
 tmpB2 = __PARAM1                              '
 TX_STR  "!DC16"                               ' header
 TX_BYTE %00                                   ' address
 TX_BYTE "P"                                   ' set command
 TX_BYTE tmpB2                                 '
 TX_BYTE 1  

ENDSUB

'used to switch off DC selenoids from DC-16 board
SUB DCPowerOff
 ser = 3
 tmpB2 = __PARAM1                              '
 TX_STR  "!DC16"                               ' header
 TX_BYTE %00                                   ' address
 TX_BYTE "P"                                   ' set command
 TX_BYTE tmpB2                                 '
 TX_BYTE 0        
ENDSUB

'SEROUT Sio, OT2400, ("!RC4", %00, "R", 4, 1)
SUB PneumoOn
 ser = 1
 tmpB2 = __PARAM1                              ' get relay bits
 TX_STR  "!RC4"                                ' header
 TX_BYTE %00                                   ' address
 TX_BYTE "R"                                   ' set command
 TX_BYTE tmpB2                                 ' relay bits
 TX_BYTE 1        
 ENDSUB

SUB PneumoOff
 ser = 1
 tmpB2 = __PARAM1                              ' get relay bits
 TX_STR  "!RC4"                                ' header
 TX_BYTE %00                                   ' address
 TX_BYTE "R"                                   ' set command
 TX_BYTE tmpB2                                 ' relay bits
 TX_BYTE 0        
 ENDSUB


'SEROUT Sio, OT2400, ("!FC4", %00, "F", 1, 0, 255, 20)

SUB FadeUp
 ser = 1
 tmpB2 = __PARAM1                              ' get relay bits
 TX_STR  "!FC4"                                ' header
 TX_BYTE %00                                   ' address
 TX_BYTE "F"                                   ' set command
 TX_BYTE tmpB2                                 ' relay bits
 TX_BYTE 0        
 TX_BYTE 255                                
 TX_BYTE 4                                                  

 ENDSUB


SUB FadeDown
 ser = 1
 tmpB2 = __PARAM1                              ' get relay bits
 TX_STR  "!FC4"                                ' header
 TX_BYTE %00                                   ' address
 TX_BYTE "F"                                   ' set command
 TX_BYTE tmpB2                                 ' relay bits
 TX_BYTE 255        
 TX_BYTE 1                                
 TX_BYTE 4                                                  

 ENDSUB

'SEROUT Sio, OT2400, ("!FC4", %00, "L", 2, 128)
SUB FadeTwoDown
 ser = 1
 tmpB1 = __PARAM1                              
 tmpB2 = __PARAM2

 for fadeCnt = 256 to 1 step - 1
   TX_STR  "!FC4"                                ' header
   TX_BYTE %00                                   ' address
   TX_BYTE "L"                                   ' set command
   TX_BYTE tmpB1                                 ' relay bits
   TX_BYTE fadeCnt        
   Delay_MS 50
   TX_STR  "!FC4"                                ' header
   TX_BYTE %00                                   ' address
   TX_BYTE "L"                                   ' set command
   TX_BYTE tmpB2                                 ' relay bits
   TX_BYTE fadeCnt        
 Next
 Delay_MS 50
 ENDSUB

SUB FadeTwoUp
ENDSUB



'SEROUT Sio, OT2400, ("!FC4", %00, "C", 0, 1, 2, 40)
Sub CrossFade
 ser = 1
 tmpB1 = __PARAM1                              '
 tmpB2 = __PARAM2
 TX_STR  "!!FC4"                                ' header
 TX_BYTE %00                                   ' address
 TX_BYTE "C"  
 TX_BYTE 0                             ' set command
 TX_BYTE tmpB1                                
 TX_BYTE tmpB2                                
 TX_BYTE 8                                                  

 ENDSUB

'AllFadeDown SUB 0

' Use: byteVal = RX_BYTE
' -- receive "byteVal" at "BaudMode" on pin "Sio"

FUNC RX_BYTE
 tmpB1 = 0
 IF ser = 1 then
    SERIN Sio1, BaudMode1, tmpB1
 ELSE
SERIN Sio3, BaudMode2, tmpB1, 1000, No_Char  
 ENDIF
 
 goto normalEnd
 No_Char:
 ser = 0
 normalEnd:  
 RETURN tmpB1
 ENDFUNC

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

' Use: TX_BYTE byteVal
' -- transmit "byteVal" at "BaudMode" on pin "Sio"

SUB TX_BYTE
 IF ser = 1 then
   SEROUT Sio1, BaudMode1, __PARAM1
 ELSE
   IF ser = 2 then
    SEROUT Sio2, BaudMode2, __PARAM1
   ELSE
       SEROUT Sio4, BaudMode1, __PARAM1
   ENDIF
 ENDIF
 
ENDSUB

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

' Use: TX_STR [string | label]
' -- "string" is an embedded string constant
' -- "label" is DATA statement label for stored z-String

SUB TX_STR
 tmpW1 = __WPARAM12                            ' get address of string
 DO
   READINC tmpW1, tmpB1                        ' read a character
   IF tmpB1 = 0 THEN EXIT                      ' if 0, string complete
   TX_BYTE tmpB1                               ' send character
 LOOP
 ENDSUB

' Use: DELAY_MS milliseconds

SUB DELAY_MS
 IF __PARAMCNT = 1 THEN
   tmpW1 = __PARAM1
 ELSE
   tmpW1 = __WPARAM12
 ENDIF
 PAUSE tmpW1
 ENDSUB

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