November 23, 2024, 09:11:04 AM

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.


Simulated Lightning and sound generator

Started by livinlowe, October 29, 2007, 11:15:15 PM

Previous topic - Next topic

livinlowe

Well, I'm very proud of myself! I finallly quit 'lurking' in these forums and got me a halloween project made. It consists of a Prop-1, an AP8 and a RC4. The RC4 controls a light that simulates lightning. I have one track on the AP8 that is thunder, while the others are just scary noises. This program randomizes the lightning so it looks different every time, as well as plays random sounds that don't repeat until all the sounds are played.

Thanks, Jon, for all your help with everyone's questions. By reading your different posts, I was able to figure this program out! As always - YOU THE MAN!!!  ;D

Here is the program-

   ' =========================================================================
'
'   File...... Haunted_Lunchroom.BS1
'   Purpose...
'   Author.... Shawn Lowe (with lots of Jon Williams' & EFx-Tek's help)
'   E-mail....
'   Started... 15 OCT 07
'   Updated...
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------

' THIS PROGRAM SIMULATES LIGHTING, THEN PLAYS A THUNDER SOUND
' IT ALSO PLAYS SCARY SOUNDS RECORDED ON AN AP8, RANDOMLY,AND WILL
' NOT REPEAT THEM UNTIL THEY HAVE ALL BEEN PLAYED. THIS PROGRAM WAS
' USED FOR A HAUNTED BREAKROOM CONTEST WE HAD AT WORK

' -----[ Revision History ]------------------------------------------------


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

SYMBOL  Sio             = 7                      ' SETUP = out; no ULN
SYMBOL  PIR             = PIN6                   ' SETUP = DN (or Out)

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

SYMBOL  Baud            = OT2400                 'Prop-1 speed

SYMBOL  Yes             = 1
SYMBOL  No              = 0


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

SYMBOL  status          = B0                     ' This byte holds AP8
                                                 ' Status bits
SYMBOL    playing       = BIT7                   ' This indicates AP8
                                                 ' is playing (see docs)
SYMBOL  ScanDelay       = 10                     ' 10 ms Scan Delay
SYMBOL  last            = B1                     ' last played
SYMBOL  pirTimer        = B2
SYMBOL  Sfx             = B3
SYMBOL  playList        = B4                     ' sounds played
SYMBOL  mask            = B5                     ' bit mask for selection
SYMBOL  msDelayOff      = B6
SYMBOL  msDelayOn       = B7
SYMBOL  idx             = B8
SYMBOL  check           = B9                     ' for testing play list

SYMBOL  Lottery         = W5                     ' B10&B11--Don't Use



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

Reset:

  SEROUT Sio, Baud, ("!!!!!!!AP8", %00, "X")    ' stop on reset
  SEROUT Sio, Baud, ("!!!!!!!RC4", %00, "X")    ' Lights off on reset
  PAUSE 30000                                   ' let Pir stabilize
  pirTimer = 0
  Sfx = 0
'  DEBUG CLS                                    ' Used for debugging


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

Main:
  PAUSE ScanDelay
  pirTimer = pirTimer + ScanDelay * PIR          ' advance/clear timer
  'DEBUG pirTimer                                ' Used to see if PIR works
  IF pirTimer < 200 THEN Main

Select_Sound:

  RANDOM Lottery                                 ' re-stir random #
  Sfx = Lottery // 8                             ' select 0 to 7
  IF Sfx = last THEN Select_Sound                ' no repeats
  READ Sfx, mask
  check = playlist & mask                        ' bit test selection
  IF check > 0 THEN Select_Sound                 ' already played?
    playlist = playlist | mask                   ' no, update play list
    last = Sfx                                   ' save idx for next cycle

  'DEBUG Sfx                                     ' Used to see which sound plays
  IF Sfx = 2 THEN Light_Show                     ' Thunder? Flash lightning
  GOSUB Start_AP8
  GOSUB Let_AP8_Finish

Check_it:
  IF playList <> %11111111 THEN Main             ' all played?
    playList = %00000000                         ' reset play list
  GOTO Main

Light_Show:
  GOSUB Flash_Lightning                          ' Random Light flash
  GOSUB Start_AP8                                ' Play Thunder
  GOSUB Let_AP8_Finish                           ' AP8 done?

  GOTO Check_it                                  ' See if we played all sounds


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

START_AP8:
  SEROUT Sio, Baud, ("!AP8", %00, "P", Sfx)     ' play segment
  PAUSE 100
  RETURN

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

' Holds program until AP-8 is finished playing current segment

Let_AP8_Finish:
  SEROUT Sio, Baud, ("!AP8", %00, "G")          ' get status
  SERIN  Sio, Baud, status
  PAUSE 2000
  IF playing = Yes THEN Let_AP8_Finish
  RETURN
' -------------------------------------------------------------------------
' Toggles RC4 output randomly to simulate lightning

Flash_Lightning:
  FOR idx = 0 TO 3                               ' Flash lightning three times
    RANDOM Lottery
    msDelayOff = lottery // 201 + 50             ' Off delay 50 to 250 ms
    msDelayOn = lottery // 701 + 500             ' On delay 1/3 to 1 sec
    SEROUT Sio, Baud, ("!RC4", %00, "R", 1, Yes)
    PAUSE msDelayOn
    SEROUT Sio, Baud, ("!RC4", %00, "R", 1, No)
    PAUSE msDelayOff
  NEXT

  RETURN
' -------------------------------------------------------------------------


' -----[ User Data ]-------------------------------------------------------
Bit_Masks:
  EEPROM (%00000001, %00000010, %00000100, %00001000)
  EEPROM (%00010000, %00100000, %01000000, %10000000)

This program used 87% of the Prop-1's memory and all the variables so, not much more I could squeeze in.

Shawn
Shawn
Scaring someone with a prop you built -- priceless!

JonnyMac

Congrats, Shawn.

Since I've had a little more practice than you, let me show you a version of your program that should run the same, but only uses 78% of the code space.  The only thing I question is the very long delay (2000 ms) you have after checking the AP-8 status.  If this delay is needed it should probably be inserted in the main code after the call to that subroutine.  If you examine the program closely you'll see that you had opportunities to re-use code and minimize SEROUT stuff.



' =========================================================================
'
'   File...... Haunted_Lunchroom.BS1
'   Purpose...
'   Author.... Shawn Lowe (with lots of Jon Williams' & EFx-Tek's help)
'   E-mail....
'   Started... 15 OCT 07
'   Updated...
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------

' THIS PROGRAM SIMULATES LIGHTING, THEN PLAYS A THUNDER SOUND
' IT ALSO PLAYS SCARY SOUNDS RECORDED ON AN AP8, RANDOMLY,AND WILL
' NOT REPEAT THEM UNTIL THEY HAVE ALL BEEN PLAYED. THIS PROGRAM WAS
' USED FOR A HAUNTED BREAKROOM CONTEST WE HAD AT WORK

' -----[ Revision History ]------------------------------------------------


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

SYMBOL  Sio             = 7                      ' SETUP = out; no ULN
SYMBOL  PIR             = PIN6                   ' SETUP = DN (or Out)

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

SYMBOL  Baud            = OT2400                 'Prop-1 speed

SYMBOL  Yes             = 1
SYMBOL  No              = 0

SYMBOL  IsOn            = 1
SYMBOL  IsOff           = 0

SYMBOL  ScanDelay       = 10                     ' 10 ms Scan Delay


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

SYMBOL  status          = B0                    ' AP-8 status
SYMBOL   playing        = BIT7                  '  presently playing if 1

SYMBOL  relays          = B1
SYMBOL   strike         = BIT8
SYMBOL   K2             = BIT9
SYMBOL   K3             = BIT10
SYMBOL   K4             = BIT11

SYMBOL  sfx             = B2
SYMBOL  last            = B3                     ' last played
SYMBOL  playList        = B4                     ' sounds played
SYMBOL  mask            = B5                     ' bit mask for selection
SYMBOL  check           = B6                     ' for testing play list
SYMBOL  idx             = B7
SYMBOL  delay           = W4
SYMBOL  lottery         = W5                     ' B10 & B11 -- don't use


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

Reset:
  SEROUT Sio, Baud, ("!!!!!!!AP8", %00, "X", "!RC4", %00, "X")

  PAUSE 30000                                   ' let PIR stabilize
  delay = 0


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

Main:
  RANDOM lottery
  PAUSE ScanDelay
  delay = delay + ScanDelay * PIR               ' advance/clear timer
  IF delay < 200 THEN Main

Select_Sound:
  RANDOM lottery                                ' re-stir random #
  sfx = lottery // 8                            ' select 0 to 7
  IF sfx = last THEN Select_Sound               ' no repeats
  READ sfx, mask
  check = playlist & mask                       ' bit test selection
  IF check > 0 THEN Select_Sound                ' already played?
    playlist = playlist | mask                  ' no, update play list
    last = sfx                                  ' save idx for next cycle

  IF sfx <> 2 THEN Play_Audio
    GOSUB Flash_Lightning                       ' flash before thunder

Play_Audio:
  GOSUB Start_AP8
  GOSUB Let_AP8_Finish

Check_it:
  IF playList <> %11111111 THEN Reset           ' all played?
    playList = %00000000                        ' reset play list
    GOTO Reset


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

Start_AP8:
  SEROUT Sio, Baud, ("!AP8", %00, "P", sfx)     ' play segment
  RETURN

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

' Holds program until AP-8 is finished playing current segment

Let_AP8_Finish:
  PAUSE 100
  SEROUT Sio, Baud, ("!AP8", %00, "G")          ' get status
  SERIN  Sio, Baud, status
  IF playing = Yes THEN Let_AP8_Finish
  RETURN

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

' Toggles RC4 output randomly to simulate lightning

Flash_Lightning:
  FOR idx = 1 TO 3                              ' Flash lightning three times
    strike = IsOn
    GOSUB Set_RC4
    RANDOM lottery
    delay = lottery // 201 + 50                 ' off delay 50 to 250 ms
    PAUSE delay
    strike = IsOff
    GOSUB Set_RC4
    RANDOM lottery
    delay = lottery // 701 + 500                ' on delay 1/3 to 1 sec
    PAUSE delay
  NEXT
  RETURN


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

Set_RC4:
  SEROUT Sio, Baud, ("!RC4", %00, "S", relays)
  RETURN


' -----[ User Data ]-------------------------------------------------------

Bit_Masks:
  EEPROM (%00000001, %00000010, %00000100, %00001000)
  EEPROM (%00010000, %00100000, %01000000, %10000000)
Jon McPhalen
EFX-TEK Hollywood Office

livinlowe

Thanks, Jon! Yeah, yours is alot smoother. I noticed you changed the delay variable to a word sized variable. I was wondering why?

Shawn
Shawn
Scaring someone with a prop you built -- priceless!

JonnyMac

The delay variable gets used in your lightning simulation routine and in the "off" portion of that routine the value can be greater than 255, hence the need for a word.  You actually have a truncation error in your original program; I was simply going by the numbers you used.
Jon McPhalen
EFX-TEK Hollywood Office

livinlowe

Geez, now that you mention it, yep I do have a problem! Thanks for the info!
Shawn
Scaring someone with a prop you built -- priceless!