May 17, 2024, 07:31:46 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.


Looking for some extra space. Help skin my cat.

Started by clinefx1, February 28, 2016, 07:03:33 PM

Previous topic - Next topic

clinefx1

Good evening, I got some working code here for a robot sculpture. That I mostly cobbled together.   It works and I'm fairly happy with it, but if there is any extra space I can get my hands on I'd use it. 

Its main components are:
a Pir detector
some RGB eyes
a shaker motor
an aux push button switch
and a led that lights when in wait mode

The program waits for motion then cycles to the next eye color and sound.
After a few times around dumps into a dance bit.  Or I can show off and direct it there with the aux button press. 
I'm looking for some extra space to set up cycle counts for the other sounds so that they don't play every time through.

Thanks,
Chris


' =========================================================================
'
'   Roudy Robot Code.BS1
'   Chris Cline
'   2/28/16
'  {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================
' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  Sio             = 7                     ' SETUP = out; no ULN

SYMBOL  PIR             = PIN6                  ' SETUP = DN (or out)
SYMBOL  Shaker          = PIN3
SYMBOL  blueeye         = 2
SYMBOL  greenEye        = 1
SYMBOL  RedEye          = 0
SYMBOL  detectled       = PIN4
SYMBOL  Vanity_switch   = PIN5


' -----[ Constants ]-------------------------------------------------------
SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0
SYMBOL  ScanDelay       = 10                    ' 10 ms scan delay
SYMBOL  Baud            = OT2400                ' remove B/R jumper
SYMBOL Disco_delay      = 50
SYMBOL ON_TIME          = 30000
' -----[ Variables ]-------------------------------------------------------

SYMBOL  pirTimer        = B5                    ' for debouncing
SYMBOL  ledOn           = B2
SYMBOL  ledOff          = B3
SYMBOL  level           = B4
SYMBOL  count           = B6
SYMBOL RUN_COUNT        = B7

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

Reset:
  PINS = %00000000
  DIRS = %00111111                              ' set outputs

  PAUSE 30000                                   ' let PIR warm-up

  pirTimer = 0                                  ' clear timer for scan

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

Main:

'-------------------------------------------
IF Vanity_switch = ison THEN Disco_Mode
GOSUB Pir_scan
'-------------------------------------------


'SECTION:1 Blue eyes
BLUE_EYES:

Blueeye_fadeup:
FOR level = 0 TO 255
PWM blueeye, level, 4
NEXT
HIGH blueeye

Play_Segment_0:
  SEROUT Sio, Baud, ("!AP8", %00, "P", 0)

  PAUSE ON_Time

Blueeye_fadedown:
FOR level = 255 TO 0 STEP -1
PWM blueeye, level, 4
NEXT
LOW blueeye
PAUSE 1000


'----------------------------------------
IF Vanity_switch = ison THEN disco_mode
GOSUB Pir_scan:
'----------------------------------------

'SECTION 2: Green eyes


GREEN_EYES:

Greeneye_fadeup:
FOR level = 0 TO 255
PWM Greeneye, level, 4
NEXT
HIGH Greeneye

Play_Segment_1:
  SEROUT Sio, Baud, ("!AP8", %00, "P", 1)

PAUSE ON_TIME

Greeneye_fadedown:
FOR level = 255 TO 0 STEP -1
PWM Greeneye, level, 4
NEXT
LOW Greeneye
PAUSE 1000


'-------------------------------------------
IF Vanity_switch = ison THEN disco_mode
GOSUB pir_scan
'-------------------------------------------

'SECTION 3: RED EYES

RED_EYES:

REDEYE_fadeup:
FOR level = 0 TO 255
PWM REDEYE, level, 4
NEXT
HIGH Redeye

shaker = ison

Play_Segment_2:
  SEROUT Sio, Baud, ("!AP8", %00, "P", 4)
PAUSE 3000
shaker = isoff


PAUSE ON_TIME

REDEYES_fadedown:
FOR level = 255 TO 0 STEP -1
PWM Redeye, level, 4
NEXT
LOW Redeye
PAUSE 1000

'---------------------------------------------
IF Vanity_switch = ison THEN disco_mode
'----------------------------------------------

'----Check how many times we've seen the same thing---------------------------------

RUN_COUNT = RUN_COUNT + 1
IF RUN_COUNT < 10 THEN Main              '10 times areound drops to disco
RUN_COUNT = 0

GOSUB pir_scan


Disco_Mode:


Play_Segment_5:
  SEROUT Sio, Baud, ("!AP8", %00, "P", 2)

Shaker = ison
Pattern_1:
    HIGH 0
    PAUSE disco_delay
    LOW 0
    HIGH 1
    PAUSE disco_delay
     LOW 1
     HIGH 2
    PAUSE disco_delay
    LOW 2
    PAUSE disco_delay
count = count + 1
IF count < 60 THEN Pattern_1
count = 0
shaker = isoff

GOTO Main



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



PIR_Scan:
IF Vanity_switch = ison THEN disco_mode

detectled = ison
PAUSE ScanDelay
pirTimer = pirTimer + ScanDelay * PIR         ' advance/clear timer

IF pirTimer < 25 THEN Pir_scan
detectled = isoff
pirTimer = 0                                  ' clear timer for scan
RETURN





JackMan

February 28, 2016, 09:04:59 PM #1 Last Edit: February 28, 2016, 09:28:34 PM by JackMan
Give this a try. Cleaned it up and saved you some space. I'm sure Jon can do better but this shaved off 8%.


' {$STAMP BS1}
' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  Sio             = 7                     ' SETUP = out; no ULN
SYMBOL  PIR             = PIN6                  ' SETUP = DN (or out)
SYMBOL  Vanity_switch   = PIN5
SYMBOL  detectled       = PIN4
SYMBOL  Shaker          = PIN3
SYMBOL  blueeye         = 2
SYMBOL  greenEye        = 1
SYMBOL  RedEye          = 0

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

SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0
SYMBOL  ScanDelay       = 10                    ' 10 ms scan delay
SYMBOL  Baud            = OT2400                ' remove B/R jumper
SYMBOL  Disco_delay     = 50
SYMBOL  ON_TIME         = 30000

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

SYMBOL  color           = B1
SYMBOL  Timer           = B2                    ' for debouncing
SYMBOL  ledOn           = B3
SYMBOL  ledOff          = B4
SYMBOL  level           = B5
SYMBOL  counter         = B6
SYMBOL  RUN_COUNT       = B7

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

Reset:
  PINS = %00000000
  DIRS = %00111111                              ' set outputs

  PAUSE 30000                                   ' let PIR warm-up
  RUN_COUNT = 0
  color = 0

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

Main:
PAUSE 1000

Wait:
IF Vanity_switch = IsOn THEN Disco_Mode
timer = 0                                     ' reset debounce timer
detectled = IsOn

Check_PIR:
  PAUSE 5                                       ' scan delay
  IF PIR = IsOff THEN Wait                      ' check trigger input
    timer = timer + 5                           ' update timer
  IF timer < 100 THEN Check_PIR                 ' wait for .01 second trigger
  detectled = IsOff
  BRANCH color, (BLUE_EYES, GREEN_EYES, RED_EYES)

BLUE_EYES:
FOR level = 0 TO 255
  PWM blueeye, level, 4
NEXT
HIGH blueeye
  SEROUT Sio, Baud, ("!AP8", %00, "P", 0)
  PAUSE ON_Time
FOR level = 255 TO 0 STEP -1
  PWM blueeye, level, 4
NEXT
color = color + 1
GOTO Main

GREEN_EYES:
FOR level = 0 TO 255
  PWM Greeneye, level, 4
NEXT
HIGH greeneye
  SEROUT Sio, Baud, ("!AP8", %00, "P", 1)
  PAUSE ON_TIME
FOR level = 255 TO 0 STEP -1
  PWM Greeneye, level, 4
NEXT
color = color + 1
GOTO Main

RED_EYES:
FOR level = 0 TO 255
  PWM Redeye, level, 4
NEXT
HIGH redeye
  shaker = IsOn
  SEROUT Sio, Baud, ("!AP8", %00, "P", 4)
  PAUSE 3000
  shaker = IsOff
  PAUSE ON_TIME
FOR level = 255 TO 0 STEP -1
  PWM Redeye, level, 4
NEXT
color = 0

'----Check how many times we've seen the same thing---------------------------------

RUN_COUNT = RUN_COUNT + 1
IF RUN_COUNT < 10 THEN Main              '10 times areound drops to disco

Disco_Mode:
RUN_COUNT = 0

Play_Segment_5:
  SEROUT Sio, Baud, ("!AP8", %00, "P", 2)
  Shaker = IsOn
  counter = 0

Pattern_1:
  FOR counter = 1 TO 60
    HIGH 0
    PAUSE disco_delay
    LOW 0
    HIGH 1
    PAUSE disco_delay
    LOW 1
    HIGH 2
    PAUSE disco_delay
    LOW 2
    PAUSE disco_delay
  NEXT
  shaker = IsOff

GOTO Main

JonnyMac

February 29, 2016, 11:40:25 AM #2 Last Edit: February 29, 2016, 12:23:09 PM by JonnyMac
I'm writing a version, too, but I'd love to seen an English language description of what you want. There are are redundant areas that I *think* can be turned into a subroutine if I just fully understood what you're trying to achieve. As we all think a bit differently, it's a good idea to explain what you're after along with the code you're working on.

In the meantime, have a look at this idea -- I think it's pretty close to what you're doing and uses fewer variables and only 51% of the memory. It should give some conservation ideas, anyway. Hint: Look for redundancies and attempt to exploit them.

' =========================================================================
'
'   File...... Roudy Robot Code.BS1
'   Purpose...
'   Author.... Chris Cline (assist from JonnyMac)
'   E-mail....
'   Started...
'   Updated... 29 FEB 2016
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


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


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


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

SYMBOL  Sio             = 7                     ' SETUP = out; no ULN
SYMBOL  PIR             = PIN6                  ' SETUP = DN (or out)
SYMBOL  VanitySwitch    = PIN5
SYMBOL  DetectLED       = PIN4
SYMBOL  Shaker          = PIN3
SYMBOL  BlueEye         = 2
SYMBOL  GreenEye        = 1
SYMBOL  RedEye          = 0


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

SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0

SYMBOL  ScanDelay       = 10                    ' 10 ms scan delay
SYMBOL  DiscoDelay      = 50
SYMBOL  OnTime          = 30000

SYMBOL  Baud            = OT2400                ' remove B/R jumper


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

SYMBOL  color           = B2
SYMBOL  pirTimer        = B3
SYMBOL  eyePin          = B3
SYMBOL  level           = B4
SYMBOL  sfx             = B5
SYMBOL  count           = B6

SYMBOL  delay           = W5


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

Reset:
  PINS = %00000000                              ' all off
  DIRS = %00111111                              ' P5..P0 are outputs

  color = 0


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

Main:
  pirTimer = 0
  DetectLED = IsOn

Check_PIR:
  IF VanitySwitch = IsOn THEN Disco_Mode
  PAUSE ScanDelay
  pirTimer = pirTimer + ScanDelay * PIR
  IF pirTimer < 250 THEN Check_PIR

Fade_Up:
  LOOKUP color, (BlueEye, GreenEye, RedEye), eyePin
  FOR level = 0 TO 255
    PWM eyePin, level, 4
  NEXT
  HIGH eyePin

Play_Audio:
  LOOKUP color, (0, 1, 4), sfx
  GOSUB Play_SFX
  PAUSE OnTime

Fade_Down:
  FOR level = 255 TO 0 STEP -1
    PWM eyePin, level, 4
  NEXT
  LOW eyePin
  PAUSE 1000

New_Color:
  color = color + 1
  IF color = 3 THEN Reset
    GOTO Main


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

Disco_Mode:
  sfx = 2
  GOSUB Play_SFX
  count = 0

Play_Pattern:
  PINS = %00001001                              ' shaker + red
  PAUSE DiscoDelay
  PINS = %00001010                              ' shaker + green
  PAUSE DiscoDelay
  PINS = %00001100                              ' shaker + blue
  PAUSE DiscoDelay
  count = count + 1
  IF count < 60 THEN Play_Pattern
  PINS = %00000000                              ' all off
  GOTO Reset


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

Play_SFX:
  SEROUT Sio, Baud, ("!AP8", %00, "P", sfx, 1)
  RETURN
Jon McPhalen
EFX-TEK Hollywood Office

JackMan

Jon's the GURU when it comes to efficient program writing for sure. Quick observation of one little tiny bit of code, I know when PWM is used to go from 0 -255 a HIGH PIN command is needed to keep the PIN high, but when PWM brings the PIN down to 0, is it necessary to follow that with a LOW PIN command?

JonnyMac

It really isn't; the PWM command leaves the pin in INPUT state which would kill and LED connected to it.
Jon McPhalen
EFX-TEK Hollywood Office

clinefx1

Wow! Thanks to both of you. Both programs run awesome.  You both are like coding rock stars.   I made a hardware change and decided to give the "lay it out in English" a shot. The change Ive made is adding a latching relay to the input side of pin5 and it gets it power from pin4.  I'm trading the "detect led" for this.  So now no matter when I press my showoff button it latches an external relay and holds that input until the code comes around.  Then when it get to it, the code sees the input on pin4, lows "out5", high  "out5" and continues to disco mode. 

The original reason I needed help was I was looking for space to set up some code to control how often the audio played. 
I'd like the eyes to cycle colors every time but not necessary fire the sound board. That is why I wanted to set up more counts so it wouldn't make noise every run. 


[ I/O Definitions ]

SYMBOL  Sio             = 7                   
SYMBOL  PIR             = PIN6               
SYMBOL  VanitySwitch    = PIN5
SYMBOL  Switchpower       = PIN4
SYMBOL  Shaker          = PIN3
SYMBOL  BlueEye         = 2
SYMBOL  GreenEye        = 1
SYMBOL  RedEye          = 0
------------------------------------------

On start up the switch power would go hot, giving me power to latch the external button press

If there is input on the vanity switch it would go to disco if not it goes to pir looking mode

Upon movement the blue eyes would fade up
Play audio seg "0" (this is a spot where I wanted to add a count so i can control how may loops it makes without out putting the audio.)
pause for an "on time"
Then fade down 

next it would check for a vanity input then motion
the next motion would trigger green eyes
and audio seg1  (this is a spot where I wanted to add a count so i can control how may loops it makes without out putting the audio.) 

next it would check for a vanity input then motion
the next motion would trigger red eyes
and audio seg4  (this is a spot where I wanted to add a count so i can control how may loops it makes without out putting the audio.)

if this is the 10th time its cycled to this point it would play disco mode
if not it goes home

If the vanity switch is triggered it needs to de-power the switchpower, resetting the latching relay, then high the switch power,  then run disco mode.

Thanks for any additional help you can offer

Chris 

JackMan

March 02, 2016, 07:20:55 AM #6 Last Edit: March 02, 2016, 09:12:38 AM by JackMan
Give this a try, I think it's what you want based on your description. It will run thru the eye colors and play audio on every 4th time the PIR triggers the program. Keep this an even number because you have an odd number of audio files. You can adjust the number in the line right above the AP8 SEROUT. (silent variable) This program only turns on the shaker when the RED eyes are on which is what your original program specified. (shaker is also on for "Disco") The program will cycle thru each color 10 times before automatically going to "Disco". That number is also adjustable to whatever you want. BTW, I'm no coding rockstar but Jon certainly is!


' {$STAMP BS1}
' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  Sio             = 7                     ' SETUP = out; no ULN
SYMBOL  PIR             = PIN6                  ' SETUP = DN (or out)
SYMBOL  Vanity_switch   = PIN5
SYMBOL  SwitchPower     = PIN4
SYMBOL  Shaker          = PIN3
SYMBOL  BlueEye         = 2
SYMBOL  GreenEye        = 1
SYMBOL  RedEye          = 0

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

SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0
SYMBOL  Baud            = OT2400                ' remove B/R jumper
SYMBOL  Disco_delay     = 50
SYMBOL  ON_Time         = 30000

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

SYMBOL  LedPin          = B1
SYMBOL  timer           = B2                    ' for debouncing
SYMBOL  sfx             = B3
SYMBOL  LedColor        = B4
SYMBOL  level           = B5
SYMBOL  counter         = B6
SYMBOL  cycle           = B7
SYMBOL  silent          = B8

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

Reset:
  PINS = %00000000
  DIRS = %00111111                              ' set outputs 0-5

  PAUSE 30000                                   ' PIR warm-up
  cycle = 0
  silent = 0

Led_Reset:
  LedColor = 0

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

Main:
  IF LedColor = 3 THEN Led_Reset
  PAUSE 1000
  SwitchPower = IsOn

Clear_Timer:
  IF Vanity_switch = IsOn THEN Disco_Mode
  timer = 0                                     ' reset debounce timer

Check_PIR:
  PAUSE 5                                       ' scan delay
  IF PIR = IsOff THEN Clear_Timer               ' check trigger input
    timer = timer + 5                           ' update timer
  IF timer < 100 THEN Check_PIR                 ' wait for .01 second trigger

Fade_Up:
  LOOKUP LedColor, (BlueEye, GreenEye, RedEye), LedPin
FOR level = 0 TO 255
  PWM LedPin, level, 4
NEXT
  HIGH LedPin
  silent = silent + 1
  IF silent < 4 THEN Shake_Mode
  LOOKUP LedColor, (0, 1, 4), sfx
  SEROUT Sio, Baud, ("!AP8", %00, "P", sfx)
  silent = 0
Shake_Mode:
  IF LedColor = 2 THEN Shake_It
Fade_Down:
  PAUSE ON_Time
FOR level = 255 TO 0 STEP -1
  PWM LedPin, level, 4
NEXT
  LedColor = LedColor + 1
  cycle = cycle + 1
  IF cycle < 30 THEN Main              '10 cycles thru all 3 colors drops to disco

Disco_Mode:
  counter = 0
  cycle = 0
  SwitchPower = IsOff
  SEROUT Sio, Baud, ("!AP8", %00, "P", 2)
  Shaker = IsOn
FOR counter = 1 TO 60
    HIGH 0
    PAUSE disco_delay
    LOW 0
    HIGH 1
    PAUSE disco_delay
    LOW 1
    HIGH 2
    PAUSE disco_delay
    LOW 2
    PAUSE disco_delay
NEXT
   shaker = IsOff
   GOTO Main

Shake_It:
   Shaker = IsOn
   PAUSE 3000
   Shaker = IsOff
   GOTO Fade_Down

clinefx1

Thanks Jackman and Jon.  This really helped.  I'm still tweaking a few things here and there as I see places for improvement.  Fyi I did need a "low the pin" line in the fade down because I'm using a led driver and it needs a full 0.  Thanks again.