' {$STAMP BS2}
' {$PBASIC 2.5}
counter VAR Word
counter2 VAR Word
counter3 VAR Word
timer VAR Word
effecttime VAR Word
cycle VAR Byte
dir VAR Byte
maxcycle VAR Byte
effectnumber VAR Byte

'This code was developed by Colin McCloy, a.k.a. BoomDog. If you have any questions,
'you can message me at the forum at WickedLasers.com or email me at mccloy.13@osu.edu


'counter(_,2,3) - keeps track of various data within a subroutine. Different usage for each
effect.
'timer - counts cycles since reset, which occurs at the change of a new effect
'effecttime - amount of cycles that the current effect will run.
'cycle - internal subroutine counter used to figure how long a certain motion should last.
Different usage for each effect.
'dir - direction of the cycle counter. 1 is normally increasing and 2 is normally decreasing.
'maxcycle - limits to store maximum bounds of the cycle.
'effectnumber - current effect ID. Each effect has a number ID.

'Do not change the following lines (Calibration and settings)
'**************************************************************************
cycle=32767
GOSUB calibrate
cycle=25
dir=1
counter2=1
counter3=1
timer=0
effecttime=50
effectnumber=1
'**************************************************************************

'Effects:
' 1.EFFECTBox
' 2.EFFECTPulseBox
' 3.EFFECTCircle
' 4.EFFECTBetterCircle
' 5.EFFECTShrinkSky
' 6.EFFECTBounceSky
' 7.EFFECTRegSky

DO
SELECT effectnumber 'Will execute the case that is currently in 'effectnumber'
CASE 1
effecttime=20
cycle=70
GOSUB EFFECTBox
CASE 2
effecttime=150
GOSUB EFFECTPulseBox
CASE 3
effecttime=15
cycle=10
GOSUB EFFECTCircle
CASE 4
effecttime=15
cycle=10
GOSUB EFFECTBetterCircle
CASE 5
effecttime=50
GOSUB EFFECTShrinkSky
CASE 6
cycle=70 '<---Must change internal settings in subroutine to take effect!
GOSUB EFFECTBounceSky
CASE 7
cycle=70
GOSUB EFFECTRegSky
ENDSELECT

'The following changes effects and monitors time on current effects
timer=timer+1
IF (timer=effecttime) THEN
timer=0
effectnumber=effectnumber+1
IF (effectnumber>7) THEN
effectnumber=1
ENDIF
ENDIF

LOOP

'Calibration pushes the mirrors to maximum cycle to ensure consistant results
Calibrate:
FOR counter = 0 TO cycle
GOSUB MXHigh
NEXT
FOR counter = 0 TO cycle
GOSUB MXLow
NEXT
FOR counter = 0 TO cycle
GOSUB MYHigh
NEXT
FOR counter = 0 TO cycle
GOSUB MYLow
NEXT
RETURN

'Simple box
EFFECTBox:
GOSUB MYHigh
GOSUB MXHigh
GOSUB MYLow
GOSUB MXLow
RETURN

'Beam follows each side of the box 3 times before moving to the next side
EFFECTPulseBox:
IF(dir=1)THEN
cycle=cycle+2
ELSE
cycle=cycle-2
ENDIF

IF(cycle>60)THEN
dir=2
ELSEIF(cycle<10) THEN
dir=1
ENDIF

GOSUB MYHigh
GOSUB MXHigh
GOSUB MYLow
GOSUB MXLow
RETURN


'Rather boxy attempt at a circle
EFFECTCircle:
'1
GOSUB MXHigh
GOSUB MXHigh
GOSUB MYLow
GOSUB MXHigh
GOSUB MYLow
GOSUB MXHigh
GOSUB MYLow
GOSUB MYLow

'2
GOSUB MYLow
GOSUB MYLow
GOSUB MXLow
GOSUB MYLow
GOSUB MXLow
GOSUB MYLow
GOSUB MXLow
GOSUB MXLow

'3
GOSUB MXLow
GOSUB MXLow
GOSUB MYHigh
GOSUB MXLow
GOSUB MYHigh
GOSUB MXLow
GOSUB MYHigh
GOSUB MYHigh

'4
GOSUB MYHigh
GOSUB MYHigh
GOSUB MXHigh
GOSUB MYHigh
GOSUB MXHigh
GOSUB MYHigh
GOSUB MXHigh
GOSUB MXHigh
RETURN

'Same as above, but better results
EFFECTBetterCircle:
'1
GOSUB MXHigh
GOSUB MYLow
GOSUB MXHigh
GOSUB MYLow
GOSUB MXHigh
GOSUB MYLow
GOSUB MXHigh
GOSUB MYLow

'2
GOSUB MYLow
GOSUB MXLow
GOSUB MYLow
GOSUB MXLow
GOSUB MYLow
GOSUB MXLow
GOSUB MYLow
GOSUB MXLow

'3
GOSUB MXLow
GOSUB MYHigh
GOSUB MXLow
GOSUB MYHigh
GOSUB MXLow
GOSUB MYHigh
GOSUB MXLow
GOSUB MYHigh

'4
GOSUB MYHigh
GOSUB MXHigh
GOSUB MYHigh
GOSUB MXHigh
GOSUB MYHigh
GOSUB MXHigh
GOSUB MYHigh
GOSUB MXHigh
RETURN

'Liquid sky that shrinks in width to a single beam, and then rapidly expands again.
EFFECTShrinkSky:
IF(dir=1)THEN
cycle=cycle+15
ELSE
cycle=cycle-15
ENDIF

IF(cycle>100)THEN
dir=2
ELSEIF(cycle<16) THEN
dir=1
ENDIF
GOSUB MXHigh
GOSUB MXLow
RETURN


'This effect creates a 'sprinkler head' effect, where the beam moves across a single axis, but
'bounces' off of one
'side, and slows down on the other.
EFFECTBounceSky:
GOSUB MXHigh
GOSUB MXLow
counter2=counter2+1
IF (counter2>1)THEN
counter2=0
cycle=20
counter3=counter3+1
IF (dir=1)THEN
GOSUB MYHigh
ELSE
GOSUB MYLow
ENDIF

IF (counter3=6)THEN
counter3=1
IF (dir=1)THEN
dir=2
ELSE
dir=1
ENDIF
ENDIF
cycle=70
ENDIF
RETURN

'Normal liquid sky effect
EFFECTRegSky:
GOSUB MXHigh
GOSUB MXLow
RETURN



'M*(HIGH/LOW) - Subroutines that send out the specific commands to move the mirrors. Each will
move the mirrors as
'far as the predetermined cycle. The PULSOUTs send single pulses to the given pins for the
durations listed.
'The pulse durations are different for X and Y (notice 1 for X and 5 for Y). This is because I
had inconsistant
'results with my galvos until I made this difference. You may need to change these for optimal
performance,
'which would preferably be constant A for X and same constant A for Y.
MXHigh:
HIGH 0
FOR counter = 1 TO cycle
PULSOUT 1,1
NEXT
RETURN

MXLow:
LOW 0
FOR counter = 1 TO cycle
PULSOUT 1,1
NEXT
RETURN

MYLow:
HIGH 2
FOR counter = 1 TO cycle
PULSOUT 3,5
NEXT
RETURN

MYHigh:
LOW 2
FOR counter = 1 TO cycle
PULSOUT 3,5
NEXT
RETURN