November 24, 2024, 10:56:23 PM

News:

Be sure to checkout our Vixen interfaces in the Library forum -- if you want PC automation at near zero cost, EFX-TEK and Vixen is a great combination of tools.


Code help for AP-16

Started by hauntcast, September 15, 2013, 08:13:29 PM

Previous topic - Next topic

hauntcast

I recently purchased an AP-16 to replace the v2 music hack that I was using. Jon or John can you please change the code below to work with the AP-16?
The Prop is a Monster in the Box.


' {$STAMP BS1}
' {$PBASIC 1.0}

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

SYMBOL  Ping            = 7                     ' PING))) Sensor no ULN

SYMBOL  TX              = 0                     ' to vmusic.R; no ULN
SYMBOL  RX              = 1                     ' to vmusic.T; no ULN

SYMBOL  Base            = 2                     ' controls solenoid for base
SYMBOL  Lid             = 3                     ' controls solenoid for lid


' -----[ Constants ]-------------------------------------------------------

SYMBOL  Trigger         = 1                     ' 10 uS trigger pulse
SYMBOL  Scale           = 10                    ' raw x 10.00 = uS

SYMBOL  RawToIn         = 889                   ' 1 / 73.746 (with **)

SYMBOL  IsHigh          = 1                     ' for PULSOUT
SYMBOL  IsLow           = 0

SYMBOL  Baud            = T2400                ' Baud for vmusic


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

SYMBOL  rawDist         = W1                    ' raw measurement
SYMBOL  refDist         = W2                    ' reference distance
SYMBOL  measDist        = W3                    ' measured distance

SYMBOL  char            = B8                    ' character value
SYMBOL  theMP3          = B9                    ' MP3 file pointer
SYMBOL  eePntr          = B10                   ' EEPROM memory pointer

SYMBOL  counter         = B11                   ' counter for FOR...NEXT


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

' MP3 files are stored in root of SD card
' Table below needs only name, followed by a zero
' Keep names short to conserve EE space

MP3s:
  EEPROM ("gr1", 0)                             ' file #0 (pointer 0)
  EEPROM ("gr2", 0)                             ' file #1 (pointer 4)
  EEPROM ("gr3", 0)                             ' file #2 (pointer 8)


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

Reset:
  PAUSE 5000                                    ' let vmusic2 start
  SEROUT TX,Baud, ("VST",13)                    ' stop anything that's playing


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

Main:
  GOSUB Get_Sonar                               ' get sensor value.
  refDist = rawDist ** RawToIn                  ' set ref value to inches.

Wait:                                           ' check if audience present.
  FOR counter = 1 TO 2                          ' confirm trigger has been
    PAUSE 125                                   ' triggered for 1/4 second
    GOSUB Get_Sonar                             ' 125ms x 2
    measDist = rawDist ** RawToIn
    IF measDist >= refDist THEN Wait
  NEXT

ShakeLid:
  theMP3 = 0                                    ' Play 1st sound
  GOSUB Play_MP3

  FOR counter = 1 TO 8                          ' Shake the lid 4x.
    TOGGLE Lid
    PAUSE 100
  NEXT

  PAUSE 1500

CheckDistance:                                  ' Check if audience still present,
  GOSUB Get_Sonar                               ' if still present, continue.
  measDist = rawDist ** RawToIn                 ' if further away, jump to Finale.
  IF measDist >= refDist THEN Finale

ShakeBase:
  theMP3 = 1                                    ' Play 2nd sound
  GOSUB Play_MP3

  FOR counter = 1 TO 4                          ' Shake the base 2x.
    TOGGLE Base
    PAUSE 200
  NEXT

  PAUSE 1500

Finale:
  theMP3 = 2                                    ' Play 3rd sound
  GOSUB Play_MP3

  FOR counter = 1 TO 6
    TOGGLE Lid
    PAUSE 100
    TOGGLE Lid
    PAUSE 125
    TOGGLE Base
    PAUSE 200
    TOGGLE Base
    PAUSE 200
  NEXT

  PAUSE 15000                                   ' Wait 15 seconds before playing again

  GOTO Reset

  END


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

' This subroutine triggers the Ping sonar sensor and measures
' the echo pulse.  The raw value from the sensor is converted to
' microseconds based on the Stamp module in use.  This value is
' divided by two to remove the return trip -- the result value is
' the distance from the sensor to the target in microseconds.

Get_Sonar:
  LOW Ping                                      ' make trigger 0-1-0
  PULSOUT Ping, Trigger                         ' activate sensor
  PULSIN  Ping, IsHigh, rawDist                 ' measure echo pulse
  rawDist = rawDist * Scale                     ' convert to uS
  rawDist = rawDist / 2                         ' remove return trip
  RETURN

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

' Put file # to play in "vmusic2"
' -- add starting location(s) of file names manually

Play_MP3:
  LOOKUP theMP3, (0, 4, 8), eePntr

Send_Cmd:
  SEROUT TX, Baud, ("VPF ")                     ' start play command

Send_Name:                                      ' send file title
  READ eePntr, char
  eePntr = eePntr + 1
  IF char = 0 THEN Finish_Cmd
    SEROUT TX, Baud, (char)
    GOTO Send_Name

Finish_Cmd:
  SEROUT TX, Baud, (".mp3", 13)                 ' send extention + CR
  RETURN

Wait_For_Stop:                                  ' let song finish
  SERIN RX, Baud, char
  IF char <> ">" THEN Wait_For_Stop
  LOW Lid
  LOW Base
    RETURN

JonnyMac

September 15, 2013, 09:21:25 PM #1 Last Edit: September 20, 2013, 09:37:26 AM by JonnyMac
This is just a straight port of the code -- give it a try. It compiles, but I don't know if your original program worked as intended.

Note that I modified a couple connections to conform with our standard programming practices.



' {$STAMP BS1}
' {$PBASIC 1.0}

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

SYMBOL  Sio             = 7                     ' SETUP = UP (no ULN)

SYMBOL  Ping            = 6                     ' SETUP = DN

SYMBOL  Lid             = 3                     ' solenoid for lid
SYMBOL  Base            = 2                     ' solenoid for base


' -----[ Constants ]-------------------------------------------------------

SYMBOL  Yes             = 1
SYMBOL  No              = 0

SYMBOL  Trigger         = 1                     ' 10 uS trigger pulse
SYMBOL  Scale           = 10                    ' raw x 10.00 = uS

SYMBOL  RawToIn         = 889                   ' 1 / 73.746 (with **)

SYMBOL  IsHigh          = 1                     ' for PULSOUT
SYMBOL  IsLow           = 0

SYMBOL  Baud            = OT2400                ' Baud for vmusic


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

SYMBOL  status          = B0
SYMBOL   playing        =  BIT7

SYMBOL  rawDist         = W1                    ' raw measurement
SYMBOL  refDist         = W2                    ' reference distance
SYMBOL  measDist        = W3                    ' measured distance

SYMBOL  char            = B8                    ' character value
SYMBOL  theWAV          = B9                    ' MP3 file pointer
SYMBOL  eePntr          = B10                   ' EEPROM memory pointer

SYMBOL  counter         = B11                   ' counter for FOR...NEXT


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

' WAV files are stored in root of SD card
' Table below needs only name, followed by a zero
' Keep names short to conserve EE space

WAVs:
  EEPROM ("gr1", 0)                             ' file #0 (pointer 0)
  EEPROM ("gr2", 0)                             ' file #1 (pointer 4)
  EEPROM ("gr3", 0)                             ' file #2 (pointer 8)


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

Power_Up:
  PAUSE 3000                                    ' let AP-16+ boot up

Reset:
  PINS = %00000000                              ' all off
  DIRS = %00001100                              ' set outputs

  SEROUT Sio, Baud, ("!AP16", %00, "X")         ' stop if playing


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

Main:
  GOSUB Get_Sonar                               ' get sensor value.
  refDist = rawDist ** RawToIn                  ' set ref value to inches.

Wait:                                           ' check if audience present.
  FOR counter = 1 TO 2                          ' confirm trigger has been
    PAUSE 125                                   ' triggered for 1/4 second
    GOSUB Get_Sonar                             ' 125ms x 2
    measDist = rawDist ** RawToIn
    IF measDist >= refDist THEN Wait
  NEXT

Shake_Lid:
  theWAV = 0                                    ' Play 1st sound
  GOSUB Play_WAV

  FOR counter = 1 TO 8                          ' Shake the lid 4x.
    TOGGLE Lid
    PAUSE 100
  NEXT

  PAUSE 1500

Check_Distance:                                 ' Check if audience still present,
  GOSUB Get_Sonar                               ' if still present, continue.
  measDist = rawDist ** RawToIn                 ' if further away, jump to Finale.
  IF measDist >= refDist THEN Finale

Shake_Base:
  theWAV = 1                                    ' Play 2nd sound
  GOSUB Play_WAV

  FOR counter = 1 TO 4                          ' Shake the base 2x.
    TOGGLE Base
    PAUSE 200
  NEXT

  PAUSE 1500

Finale:
  theWAV = 2                                    ' Play 3rd sound
  GOSUB Play_WAV

  FOR counter = 1 TO 6
    TOGGLE Lid
    PAUSE 100
    TOGGLE Lid
    PAUSE 125
    TOGGLE Base
    PAUSE 200
    TOGGLE Base
    PAUSE 200
  NEXT

  PAUSE 15000                                   ' Wait 15 seconds before playing again

  GOTO Reset

  END


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

' This subroutine triggers the Ping sonar sensor and measures
' the echo pulse.  The raw value from the sensor is converted to
' microseconds based on the Stamp module in use.  This value is
' divided by two to remove the return trip -- the result value is
' the distance from the sensor to the target in microseconds.

Get_Sonar:
  LOW Ping                                      ' make trigger 0-1-0
  PULSOUT Ping, Trigger                         ' activate sensor
  PULSIN  Ping, IsHigh, rawDist                 ' measure echo pulse
  rawDist = rawDist * Scale                     ' convert to uS
  rawDist = rawDist / 2                         ' remove return trip
  RETURN

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

' Put file # to play in AP-16+
' -- add starting location(s) of file names manually

Play_WAV:
  LOOKUP theWAV, (0, 4, 8), eePntr              ' adjust for names in table

Send_Cmd:
  SEROUT Sio, Baud, ("!AP16", %00, "PW")        ' start play command

Send_Name:                                      ' send file title
  READ eePntr, char
  eePntr = eePntr + 1
  IF char = 0 THEN Finish_Cmd
    SEROUT Sio, Baud, (char)
    GOTO Send_Name

Finish_Cmd:
  SEROUT Sio, Baud, (13, 1)                      ' CR +1 play
  RETURN

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

Wait_For_Stop:                                  ' let song finish
  PAUSE 25
  SEROUT Sio, Baud, ("!AP16", %00, "G")
  SERIN  Sio, Baud, status
  IF Playing = Yes THEN Wait_For_Stop
    LOW Lid
    LOW Base
    RETURN
Jon McPhalen
EFX-TEK Hollywood Office

hauntcast

Thanks for that code. Do I connect the ap16 to P7 and the PING to P6? I connected the Ping to P6 and the green light on the ping is on, but it isn't triggering the Prop 1 as it did before. Any thoughts?

JonnyMac

Yes. Make sure that you have the ULN chip "fixed" for P7 use and that the P7 jumper is in the UP position. The P6 jumper should be in the DN position.

This thread explains configuring the ULN chip for serial communications:
-- http://www.efx-tek.com/php/smf/index.php?topic=130.0
Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

I was just looking through your code again and found I erred on the translation. If you look in the section called Finish_Cmd you'll see that the file name is terminated with CR (13). For the AP-16+ we need to tell it how many times to play the file. The code that commands The AP-16+ to play should look like this:

' Put file # to play in AP-16+
' -- add starting location(s) of file names manually

Play_WAV:
  LOOKUP theWAV, (0, 4, 8), eePntr              ' adjust for names in table

Send_Cmd:
  SEROUT Sio, Baud, ("!AP16", %00, "PW")        ' start play command

Send_Name:                                      ' send file title
  READ eePntr, char
  eePntr = eePntr + 1
  IF char = 0 THEN Finish_Cmd
    SEROUT Sio, Baud, (char)
    GOTO Send_Name

Finish_Cmd:
  SEROUT Sio, Baud, (13, 1)                     ' *** updated for AP-16+ ***
  RETURN



I'm sorry I didn't see that the first time. The coffee just kicked in and it stood right out.

Jon McPhalen
EFX-TEK Hollywood Office

hauntcast

So, I should be using a ULN 2003 which is what I have installed?

hauntcast

The Ping Trigger is now working and the audio file plays, but the file seems to be cut short. It's not playing the full file. Am I missing something? I created a 16 Bit 44100 Wav file the original 128kbps MP3.

JonnyMac

You have fixed times in your program. When a new play command is issued, it will override the last. You may need to tweak the running portion of the code to match the length of your audio files.

BTW... if you are willing to rename your files SFX00.WAV, SFX01.WAV, etc., the code can be simplified. The additional bonus is that you can use the SELECT knob and START button on the AP-16+ to test the file.

Finally, there are indications of shaking etc., but they used fixed timing to which can get monotonous. If you'll describe what this prop is and how you want it to behave, I can touch up the program to use random timing which tends to be more interesting.
Jon McPhalen
EFX-TEK Hollywood Office

hauntcast

The prop is a monster in the box with one pneumatic cylinder attached to the lid of the box and one attached to the bottom.

hauntcast

I am willing to rename the files to SFX00.WAV, SFX01.WAV, etc... How can I simplify the code?

The grr1 and grr2 file is :14 and grr3 is :11 seconds.

JonnyMac

If you analyze the original code your timing loops were far short of your audio timing.

Here's a variation that should help, and uses random behavior for different look. It also simplifies starting a file using the builting "PS" (Play SFX) command of the AP-16+

' {$STAMP BS1}
' {$PBASIC 1.0}

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

SYMBOL  Sio             = 7                     ' SETUP = UP (no ULN)

SYMBOL  Ping            = 6                     ' SETUP = DN

SYMBOL  Lid             = 3                     ' solenoid for lid
SYMBOL  Base            = 2                     ' solenoid for base


' -----[ Constants ]-------------------------------------------------------

SYMBOL  Yes             = 1
SYMBOL  No              = 0

SYMBOL  Trigger         = 1                     ' 10 uS trigger pulse
SYMBOL  Scale           = 10                    ' raw x 10.00 = uS

SYMBOL  RawToIn         = 889                   ' 1 / 73.746 (with **)

SYMBOL  IsHigh          = 1                     ' for PULSOUT
SYMBOL  IsLow           = 0

SYMBOL  Baud            = OT2400                ' Baud for vmusic


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

SYMBOL  status          = B0
SYMBOL   playing        =  BIT7

SYMBOL  thePin          = B1

SYMBOL  idx             = B2
SYMBOL  theWAV          = B3

SYMBOL  rawDist         = W3                    ' raw measurement
SYMBOL  refDist         = W4                    ' reference distance
SYMBOL  measDist        = W5                    ' measured distance

SYMBOL  timer           = W3                    ' for shake timing
SYMBOL  delay           = W4                    ' toggle timing
SYMBOL  lottery         = W5                    ' random #


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

Power_Up:
  PAUSE 3000                                    ' let AP-16+ boot up

Reset:
  PINS = %00000000                              ' all off
  DIRS = %00001100                              ' set outputs

  SEROUT Sio, Baud, ("!AP16", %00, "X")         ' stop if playing


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

Main:
  GOSUB Get_Sonar                               ' get sensor value.
  refDist = rawDist ** RawToIn                  ' set ref value to inches.

Wait:                                           ' check if audience present.
  RANDOM lottery                                ' stir random #
  FOR idx = 1 TO 2                              ' confirm trigger has been
    PAUSE 125                                   ' triggered for 1/4 second
    GOSUB Get_Sonar                             ' 125ms x 2
    measDist = rawDist ** RawToIn
    IF measDist >= refDist THEN Wait
  NEXT

Shake_Lid:
  theWAV = 0                                    ' Play 1st sound
  GOSUB Play_WAV

  thePin = Lid                                  ' shake lid for ~13s
  timer = 13000
  GOSUB Shake_It
  PAUSE 1500                                    ' quiet about 1.5s

Check_Distance:                                 ' Check if audience still present,
  GOSUB Get_Sonar                               ' if still present, continue.
  measDist = rawDist ** RawToIn                 ' if further away, jump to Finale.
  IF measDist >= refDist THEN Finale

Shake_Base:
  theWAV = 1                                    ' Play 2nd sound
  GOSUB Play_WAV

  thePin = Base                                 ' shake base for ~13s
  timer = 13000
  GOSUB Shake_It
  PAUSE 1500                                    ' quiet about 1.5s

Finale:
  theWAV = 2                                    ' Play 3rd sound
  GOSUB Play_WAV

  timer = 11000                                 ' match SFX02 timing

Shake_Both:
  RANDOM lottery
  thePin = lottery & %00001100                  ' randomze lid & base
  PINS = PINS &/ %00001100 | thePin             ' update outputs
  IF timer <= 100 THEN Done
    PAUSE 100
    timer = timer - 100
    GOTO Shake_Both

Done:
  PAUSE 15000                                   ' Wait 15 seconds before playing again
  GOTO Reset


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

' This subroutine triggers the Ping sonar sensor and measures
' the echo pulse.  The raw value from the sensor is converted to
' microseconds based on the Stamp module in use.  This value is
' divided by two to remove the return trip -- the result value is
' the distance from the sensor to the target in microseconds.

Get_Sonar:
  LOW Ping                                      ' make trigger 0-1-0
  PULSOUT Ping, Trigger                         ' activate sensor
  PULSIN  Ping, IsHigh, rawDist                 ' measure echo pulse
  rawDist = rawDist * Scale                     ' convert to uS
  rawDist = rawDist / 2                         ' remove return trip
  RETURN

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

' Put file # to play in AP-16+
' -- add starting location(s) of file names manually

Play_WAV:
  SEROUT Sio, Baud, ("!AP16", %00, "PS", theWAV, 1)
  RETURN

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

' Shake one output -- defined by "thePin"

Shake_It:
  TOGGLE thePin
  RANDOM lottery
  delay = lottery // 101 + 100                  ' random, 100 to 200
  IF timer < delay THEN Shake_Exit
    PAUSE delay
    timer = timer - delay
    GOTO Shake_It

Shake_Exit:
  PAUSE timer
  LOW thePin
  RETURN


' -----[ EEPROM Data ]-----------------------------------------------------
Jon McPhalen
EFX-TEK Hollywood Office

hauntcast

Everything seems to be working great. Thank you for your help.