Start:
PLP_A = %0011
PLP_B = %1000_0001
PLP_C = %0000_0000
TX = 1
OUTPUT TX
DELAY_MS 1
DELAY_MS 2500
TX_BYTE CR
VM_WAIT_PROMPT
VM_STOP
VM_WAIT_PROMPT
VM_VOLUME $00
VM_WAIT_PROMPT
As always, the pull-ups are enabled for unused pins;
this minimizes current consumption. Then, a 1 is written to
the TX line and it’s made an output. The reason to do it in
this order is to prevent creating a false start bit; if the pin
is made an output before having the 1 written to it, this
will look like a start bit to the VMUSIC2 player
A two-and-half second delay is inserted to allow the
VMUSIC2 player to power up. Then we “ping” the player
by sending a carriage return and waiting on the “>”
prompt as this lets us know that the player is ready. The
code for VM_WAIT_PROMPT is straightforward; it sits in
a loop waiting for the prompt character:
SUB VM_WAIT_PROMPT
DO
tmpB1 = RX_BYTE
LOOP UNTIL tmpB1 = “>”
ENDSUB
If the SX was reset after a power-up, there is the
possibility that a file is playing so we can kill it with
VM_STOP. Then, we reset the volume to the highest
level and drop into the heart of the program.
I added a simple pushbutton and LED to an SX Tech
board to provide the interface for my little experiment.
After power-up, the program waits for the button to be
pressed and stirs a random number that will be used later.
Main:
seed = RANDOMIZE seed
IF StartBtn = NotPressed THEN Main
The SX/B RANDOM function uses different algorithms
for bytes and words, so I wrapped RANDOM into a
unified function that looks like this:
FUNC RANDOMIZE
IF __PARAMCNT = 1 THEN
tmpW1 = __PARAM1
RANDOM tmpW1_LSB
ELSE
tmpW1 = __WPARAM12
RANDOM tmpW1
ENDIF
RETURN tmpW1
ENDFUNC
If a byte gets passed to the function, then that value is
STAMP APPLICATIONS
moved into tmp W1 and the RANDOM function is used
only on the LSB. When a word is passed, both bytes are
used. You can see the difference in how RANDOM is
handled by the compiler by looking at the List file (Ctrl-L in
the IDE). The function does, in fact, return two bytes, but
when the target is a byte variable only the LSB is used.
Induction_Delay:
FOR seconds = 1 TO 120
FOR tix = 1 TO 10
Led = tix.0
DELAY_MS 100
NEXT
seed = RANDOMIZE seed
NEXT
Induction:
VM_PLAY “induce”
VM_WAIT_START
Led = IsOn
VM_WAIT_PROMPT
After the button is pressed, there is a two-minute
delay before the sleep induction file is played. Within a
loop that handles the delay, another loop creates a one
second delay. I did this so that I could flash the LED at a
10 Hz rate while doing the delay.
Once the VM_PLAY command is issued, we may
want to verify that the player has actually started; we can
do this with VM_WAIT_START. This function watches the
RX line waiting on a specific string that indicates the start
of the audio — what we’re actually looking for is a time
position indicator which is a string that starts with “T $.”
SUB VM_WAIT_START
tmpB1 = RX_BYTE ToUpper
IF tmpB1 <> “T” THEN VM_WAIT_START
tmpB1 = RX_BYTE
IF tmpB1 <> “ “ THEN VM_WAIT_START
tmpB1 = RX_BYTE
IF tmpB1 <> “$” THEN VM_WAIT_START
ENDSUB
Finally, the program drops into a loop that inserts
about a 90 minute (plus or minus five minutes) delay before
playing the sleep file. The loop runs three times which
should get me through most of my normal sleep cycle.
Sleepnotize_Me:
FOR cycles = 1 TO 3
seed = RANDOMIZE seed
seconds = seed // 601
seconds = seconds + 5100
DO WHILE seconds > 0
FOR tix = 1 TO 10
Led = tix.0
DELAY_MS 100
NEXT
DEC seconds
seed = RANDOMIZE seed
LOOP
VM_PLAY “sleep”
VM_WAIT_START
Led = IsOn
VM_WAIT_PROMPT
NEXT
Led = IsOff
GOTO Main
September 2008 63