' =========================================================================
'
'   File....... Skelevision.BS2
'   Purpose.... Skelevision controller
'   Author..... Terry Simmons based on circuit design by R. Turley
'   Original Circuit.....http://forums.parallax.com/forums/default.aspx?f=21&m=61194
'   Started.... Aug 20, 2005
'   Updated.... Oct 2, 2005
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================

' -----[ Program Description ]---------------------------------------------
'The main part of this circuit is for dimming two 120 volt lamps for a
'Peppers Ghost type of illusion.

'The Stamp sends a serial 8 bit TriacTriggerValue (renamed front_light/rear_light)
'via the SHIFTOUT command To a serial-TO-parallel shift register (74LS164) which
'THEN sends it to an 8 Bit latch (74LS377).

'TriacTriggerValue sets the dimming from full on (0) to full off (227).

'This TTV number is fed into the Q inputs of a comparator (74LS682) from the
'8 bit latch which is enabled by a PULSOUT command on the TriacLatchEnable
'lines from the Stamp. The data is transfered when triggered by a zero crossing pulse.

'The P inputs of the comparator are fed from a ripple counter (CD4020) that cycles from
'0 to 255 every 120th second at every instance of zero crossing.

'When the output of the ripple counter (P) exceeds the TTV number (Q), the light
'is turned ON by the P>Q function of the comparator.

' -----[ Revision History ]------------------------------------------------
'  8/23/2005 Help from Jon Williams on the FOR...NEXT triac command
'  9/20/2005 Changed from Peppers Ghost to Skelevision, updated command names
'  9/21/2005 Added two routines
'  9/26/2005 Added remote speaker trigger
'  5.0 9/27/2005 Made light intensities a constant so levels could be set easilly
'  5.01 10/2/2005 Changed audio tracks
'  5.1 10/4/2005 Changed audio timings, added RANDOM to routine 2

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

Trigger                  	PIN     4        	  'low to trigger

TriacLatchEnable1        PIN     0       	  'Low PULSOUT enables front_light to be
                            			  'sent to the comparator on a zero cross pulse
TriacLatchEnable2        	PIN     1        	  'Low PULSOUT enables rear_light to be
                                          		 'sent to the comparator on a zero cross pulse

SerialData               	PIN     2         	 'Serial Data out
SerialClock             	PIN     3        	 'Clock Data out

remote_speaker           	PIN     9        	 'low triggers remote speaker
Aux3                     	PIN     6         	 'spare
motor                    	PIN     7        	 'hooked to relay high closes relay
Aux1                     	PIN     8        	 'hooked to relay high closes relay

ISDCE			PIN     11         'ChipCorder low to trigger
ISDEOM		PIN     12         'Input End-Of-Message is a low pulse
ISDA8                    	PIN     13         'ChipCorder A8
ISDA7                    	PIN     14         'ChipCorder A7
ISDA6                    	PIN     15         'ChipCorder A6

' -----[ Constants ]-------------------------------------------------------
IsHigh          	CON     1
IsLow           	CON     0

Sound0		CON     0                           'laugh and music
Sound1		CON     1                           'not used-0 spills over
Sound2		CON     2                           'lauch and chain
Sound3		CON     3                           'not used-2 spills over
Sound4		CON     4                           'growl and fingernail
Sound5		CON     5                           'not used-4 spills over
Sound6		CON     6
Sound7		CON     7

ron             	CON     125                         'rear light on intensity
fon             	CON     125                         'front light on intensity
roff            	CON     227                         'rear light off level
foff            	CON     227                         'front light off level

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

audio		VAR     Nib                     'audio select (0 - 7)
counter            	VAR     Nib                     'loop control
front_light        	VAR     Byte                    '0-227 sets front light intensity
rear_light         	VAR     Byte                    '0-227 sets rear light intensity

number             VAR     Word		'RANDOM will generate this number
delay              	VAR     Word		'Divide number by 150 to generate random delay

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

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

Reset:
  LOW Aux3
  LOW remote_speaker
  LOW motor
  LOW Aux1

  HIGH ISDCE                                   'ChipCorder control
  LOW  ISDA8
  LOW  ISDA7
  LOW  ISDA6

  HIGH TriacLatchEnable1	 'disables 8 bit latches
  HIGH TriacLatchEnable2

  front_light = fon		'turns front light on max
  GOSUB SendTriac1

  rear_light = roff 		'turns rear light off
  GOSUB SendTriac2

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

Wait_For_Trigger:
  DO
    IF (Trigger = IsLow) THEN Routine_1

  LOOP

'Routine 1 ######################################################################

Routine_1:

PAUSE 1500

  FOR front_light = fon TO foff STEP 10		'quickly fades out front light
  GOSUB SendTriac1
  NEXT
  PAUSE 500
  PULSOUT remote_speaker, 1000		'triggers remote speaker

  HIGH motor                                           		'turns on skeleton motor
  PAUSE 500

  FOR rear_light = roff TO ron STEP 30		'quickly fades up rear light
  GOSUB SendTriac2
  NEXT

  audio = Sound0                                       	'plays sound-laugh and music
  GOSUB Play_Audio

  GOTO wait_for_audio

  FOR rear_light =  ron TO roff  STEP 2		 'fades out rear light
  GOSUB SendTriac2
  NEXT
  LOW motor

  PAUSE 1000

  FOR front_light = foff TO fon STEP 1		'fades up front light
  GOSUB SendTriac1
  NEXT

PAUSE 5000

'Routine 2 ##########################################################################

DO
  IF (Trigger = IsLow) THEN Routine_2
  LOOP

  Routine_2:

  PAUSE 1000

  audio = Sound2                                      	'plays sound-2
  GOSUB Play_Audio

  front_light = foff
  GOSUB SendTriac1

  PAUSE 200

  PULSOUT remote_speaker, 1000		'triggers remote speaker
  HIGH motor                                          		'skeleton motor on

  PAUSE 1000

  '***********
  FOR counter = 0 TO 7                                	'flashes front/rear light eight times

  rear_light = ron
  GOSUB SendTriac2

  front_light = foff
  GOSUB SendTriac1

  RANDOM number
  delay = number / 150
  PAUSE delay

  front_light = fon
  GOSUB SendTriac1

  rear_light = roff
  GOSUB SendTriac2

  RANDOM number
  delay = number / 150
  PAUSE delay

  NEXT
  '***********

  LOW motor					 'stops skeleton motor

  PAUSE 5000

  'Routine 3 #######################################################################

  DO
  IF (Trigger = IsLow) THEN Routine_3
  LOOP

  Routine_3:

  PAUSE 1500

  front_light = foff                                   		'front light off
  GOSUB SendTriac1

  PAUSE 300

  PULSOUT remote_speaker, 1000		'triggers remote speaker

  audio = Sound4				 'sound effect-growl and fingernail

  GOSUB Play_Audio

  PAUSE 1000
  HIGH motor                                           		'skeleton motor on
  PAUSE 1000

  FOR counter = 0 TO 9
  rear_light = ron                                    		 'rear light on
  GOSUB SendTriac2
  PAUSE 100
  rear_light = roff
  GOSUB SendTriac2
  PAUSE 200
  NEXT

  FOR rear_light = roff TO ron STEP 2
  GOSUB SendTriac2
  NEXT

  PAUSE 1000

  FOR rear_light =  ron TO roff  STEP 2               'fades out rear light
  GOSUB SendTriac2
  NEXT

  FOR front_light = foff TO fon                       	'fades up front light
  GOSUB SendTriac1
  NEXT

  LOW motor

  PAUSE 1000

GOTO Wait_For_Trigger

' ======[ Subroutines ]=================================================

' This routine plays the selected message.
' put audio file (0 - 7) into 'audio'

Play_Audio:
  ISDCE = IsHigh			' make sure it's high
  ISDA6 = audio.BIT0			 ' set audio address
  ISDA7 = audio.BIT1
  ISDA8 = audio.BIT2
  PAUSE 25                                      	' let bus settle
  PULSOUT ISDCE, 50			' start the audio
  RETURN

'-------------------------------------------------------------------------
' This routine holds the program in place until the EOM
' (end of message) signal arrives from the ISD2560

wait_for_audio:
  DO : LOOP WHILE (ISDEOM = IsHigh)
  RETURN

'-------------------------------------------------------------------------
'These routines load the serial data, via the serial-to-parallel shift register, to
'the 8 Bit latch using SHIFTOUT.  PULSOUT enables the latch and data is sent to the
'comparator on a zero crossing pulse.

SendTriac1:
SHIFTOUT SerialData, SerialClock, MSBFIRST, [front_light]
PULSOUT   TriacLatchEnable1, 5000           'PULSOUT toggles low 10mS
RETURN

SendTriac2:
SHIFTOUT  SerialData, SerialClock, MSBFIRST, [rear_light]
PULSOUT   TriacLatchEnable2, 5000
RETURN