May 02, 2024, 07:09:27 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.


Random Servo and LED

Started by uncle, March 17, 2010, 12:30:55 PM

Previous topic - Next topic

uncle

Jon-

I almost posted this in the Expanding LED Controller thread, but then decided it would need its own thread.

I have a simple 2-axis eye (standard micro servos) that I would like to use with the "Cylon" program.  But not synchronized.  Ideally it would have the Cylon program calmly lighting back and forth 5 LED's with the eye not moving. 

Upon receiving a signal from a switch (mat etc) I would like to see the LED's fire in an almost frantic random sequence, AND the eye to start looking around in another almost frantic random manner at the same time, And play a 10 sec (or so) audio file from a VMusic player (which I know you hate).  So the whole random sequence would run for about the length of the audio file. At the end of this sequence it would reset to the calm Cylon lighting.

What little I have learned so far of SX programming leads me to think that servos, LEDs, and randomness might be doable, but throwing in the VMUsic may bugger it up.  Could the SX do the rest,  and send a signal out through a Pin to activate a nearby Prop-1 with the VMusic run by that?

JonnyMac

It could be done on the Prop-SX, though the code will take some time.  If you can give me until after Transworld I'll do that for you.  Sorry to delay you, it's the first big trade show of the year and we have a lot of stuff on our plates.
Jon McPhalen
EFX-TEK Hollywood Office

uncle

No rush at all.  I wish I was going to Transworld!

uncle

Jon-

For now, could we drop the VMusic portion and just have the calm then frantic portions?  I am considering a new audio product that is rumored to be available shortly  ;) but depending on physical space limitations, I may not be able to incorporate either one.

The LED's are on Out0-4 leaving the rest available for the 2 servo's, mat switch, etc.

JonnyMac

Let me get my legs back under me -- that said, I'll start porting modules that work to a demo program.

One of the troubles with the VMUSIC is that it pumps out timing info while it plays which means you need to be pulling that from the buffer; I'll try to make that easy, but what you're asking for is a little involved (not complaining, just being truthful up front).
Jon McPhalen
EFX-TEK Hollywood Office

uncle

March 31, 2010, 01:37:52 PM #5 Last Edit: March 31, 2010, 01:42:51 PM by uncle
Jon-

There is no rush.  If I had gone to Transworld, I think I would have taken several days off afterwards.

JonnyMac

Thanks for the understanding; I'm climbing back into the saddle, albeit very slowly....
Jon McPhalen
EFX-TEK Hollywood Office

uncle

Jon-

Obviously I have been pretty busy this summer and am only just now getting back to this project.  You had kindly sent me the program below, but unfortunately I have had no success in getting the servos to move.

' =========================================================================
'
'   File...... crazy_cylon.sxb
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'   E-mail....
'   Started...
'   Updated...
'
' =========================================================================


' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Conditional Compilation Symbols
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

ID              "cylon"

DEVICE          SX28, OSCXT2, BOR42
FREQ            20_000_000


' -------------------------------------------------------------------------
' I/O Pins
' -------------------------------------------------------------------------

Remote      PIN   RC.7 OUTPUT      ' P15 - SETUP = DN
Trigger      PIN   RC.6 INPUT      ' P14 - SETUP = DN

Servo2      PIN   RC.1 OUTPUT      ' P9
Servo1      PIN   RC.0 OUTPUT      ' P8

Eyes      PIN   RB   OUTPUT      ' P0/OUT0 to P4/OUT4


' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

IsOff      CON   0
IsOn      CON   1


' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

pos1      VAR   Byte         ' servo 1 position
pos2      VAR   Byte         ' servo 2 position

cylonTix   VAR   Byte         ' timer divider for cylon
cylonIdx   VAR   Byte         ' for pattern

x1Timer      VAR   Byte
x2Timer      VAR   Word

tmpB1      VAR   Byte
tmpB2      VAR   Byte
tmpB3      VAR   Byte
tmpW1      VAR   Word
tmpW2      VAR   Word


' =========================================================================
' INTERRUPT {option} {rate}
' =========================================================================

ISR_Start:

ISR_Exit:
' RETURNINT


' =========================================================================
' Subroutine / Function / Task Declarations
' =========================================================================

DELAY_MS   SUB   2, 2,     Word, Word
DELAY_US10   SUB   2, 2,     Word, Word

UPDATE_SERVOS   SUB   2, 2
UPDATE_CYLON   SUB

RANDOMIZE   FUNC   2, 1, 2, Word, Byte, Word


' =========================================================================
  PROGRAM Start
' =========================================================================

Start:
  PLP_A = %0000               ' set pull-ups for inputs
  PLP_C = %1100_0011

  pos1 = 150               ' center
  pos2 = 150

  cylonIdx = 0               ' start of pattern
  cylonTix = 5               ' force immediate update

Main:
  x1Timer = 0               ' debounce trigger
  DO
    UPDATE_SERVOS pos1, pos2         ' refresh servos
    UPDATE_CYLON                            ' update cylon "eyes"
    IF Trigger = IsOn THEN
      x1Timer = x1Timer + 20
    ELSE
      x1Timer = 0
    ENDIF   
  LOOP UNTIL x1Timer >= 100

  Remote = IsOn               ' start external


Go_Wild:
  FOR x2Timer = 1 TO 150                          ' 15 secs in 0.1s units
    RANDOMIZE cylonIdx
    Eyes = Eyes & %11100000                         ' clear old
    cylonIdx = cylonIdx & %00011111
    Eyes = Eyes | cylonIdx                         ' random eyes

    RANDOMIZE pos1
    pos1 = pos1 MIN 60            ' fix limits
    pos1 = pos1 MAX 240

    RANDOMIZE pos2
    pos2 = pos1 MIN 60            ' fix limits
    pos2 = pos1 MAX 240

    FOR x2Timer = 1 TO 5                         ' create 0.1s delay
      UPDATE_SERVOS pos1, pos2
    NEXT
   
    Remote = IsOff                            ' end external pulse
  NEXT
 
  GOTO Start


' -------------------------------------------------------------------------
' Subroutine / Function / Task Code
' -------------------------------------------------------------------------

' Use: DELAY_MS milliseconds
' -- shell for PAUSE

SUB DELAY_MS
  PAUSE __wparam12
  ENDSUB

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

' Use: DELAY_US10 delay
' -- delay in 10us units

SUB DELAY_US10
  us10      VAR   tmpW1

  us10 = __wparam12
  DO WHILE us10 > 0
    PAUSEUS 10
  LOOP
  ENDSUB

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

' UPDATE_SERVOS pos1, pos2
' -- refreshes servos and creates 20ms pad

SUB UPDATE_SERVOS
  svo1      VAR   tmpB1
  svo2      VAR   tmpB2
  svoDelay   VAR   tmpW2

  svo1 = __param1
  svo2 = __param2
 
  Servo1 = IsOn               ' refresh servo 1
  DELAY_US10 svo1
  Servo1 = IsOff
 
  Servo2 = IsOn               ' refresh servo 2
  DELAY_US10 svo2
  Servo2 = IsOff

  svoDelay = 2000 - svo1
  svoDelay = svoDelay - svo2
  DELAY_US10 svoDelay

  ENDSUB

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

' Use: UPDATE_CYLON
' -- updates cylon eye pattern
' -- assumes called every 20ms; divider updates eyes every 100ms

SUB UPDATE_CYLON
  INC cylonTix
  IF cylonTix >= 5 THEN            ' time for update
    READ Cylon + cylonIdx, tmpB1                      ' yes, get pattern
    Eyes = Eyes & %11100000                         ' clear old pattern
    Eyes = Eyes | tmpB1            ' update new
    INC cylonIdx                            ' update pattern index
    IF cylonIdx = 8 THEN                         ' at end of pattern?
      cylonIdx = 0                            ' yes, reset
    ENDIF
    cylonTix = 0                            ' restart divider
  ENDIF
  ENDSUB

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

FUNC RANDOMIZE
  IF __paramcnt = 1 THEN
    RANDOM __param1
    __param2 = 0
  ELSE
    RANDOM __wparam12
  ENDIF
  RETURN __wparam12
  ENDFUNC

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




' =========================================================================
' User Data
' =========================================================================

Cylon:
  DATA   %00001, %00010, %00100, %01000
  DATA  %10000, %01000, %00100, %00010

JonnyMac

Sorry, things have been crazy for us (a good thing), and with the retirement of the SX chip I have spent a lot more time with the Propeller (the AP-16+ is just the start of many new cool things to come).  

That's to say that it took me a while to get my head wrapped back around the SX.  In order to facilitate testing, I moved the servos to P0 and P1, and the "eyes" to P8-P12.

I have run this code and it seems to do what you want.  We can make updates from here.

' =========================================================================
'
'   File...... crazy_cylon.sxb
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'   E-mail....
'   Started...
'   Updated... 19 SEP 2010
'
' =========================================================================


' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Conditional Compilation Symbols
' -------------------------------------------------------------------------


' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

ID              "cylon"

DEVICE          SX28, OSCXT2, BOR42
FREQ            20_000_000


' -------------------------------------------------------------------------
' I/O Pins
' -------------------------------------------------------------------------

Remote          PIN     RC.7 OUTPUT             ' P15 - SETUP = DN
Trigger         PIN     RC.6 INPUT              ' P14 - SETUP = DN

Eye5            PIN     RC.4 OUTPUT             ' P12/OUT12
Eye4            PIN     RC.3 OUTPUT             ' P11/OUT11
Eye3            PIN     RC.2 OUTPUT             ' P10/OUT10
Eye2            PIN     RC.1 OUTPUT             ' P9/OUT9
Eye1            PIN     RC.0 OUTPUT             ' P8/OUT8

Servo2          PIN     RB.1 OUTPUT             ' P1
Servo1          PIN     RB.0 OUTPUT             ' P0


' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

IsOff           CON     0
IsOn            CON     1


' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

pos1            VAR     Byte                    ' servo 1 position
pos2            VAR     Byte                    ' servo 2 position

lottery         VAR     Byte                    ' random value

cylonTix        VAR     Byte                    ' timer divider for cylon
cylonIdx        VAR     Byte                    ' for pattern lookup

x1Timer         VAR     Byte                    ' loop timers
x2Timer         VAR     Byte

tmpB1           VAR     Byte                    ' work vars
tmpB2           VAR     Byte
tmpW1           VAR     Word
tmpW2           VAR     Word


' =========================================================================
' Subroutine / Function / Task Declarations
' =========================================================================

DELAY_MS        SUB     2, 2,    Word, Word
DELAY_US10      SUB     2, 2,    Word, Word

UPDATE_SERVOS   SUB     2, 2
UPDATE_CYLON    SUB

RANDOMIZE       FUNC    2, 1, 2, Word, Byte, Word


' =========================================================================
 PROGRAM Start
' =========================================================================

Start:
 PLP_A = %0000                                 ' set pull-ups for inputs

 cylonIdx = 0                                  ' start of pattern
 cylonTix = 5                                  ' force immediate update

 lottery = 31


Main:
 pos1 = 150                                    ' center servos
 pos2 = 150

 x1Timer = 0                                   ' debounce trigger
 DO
   lottery = RANDOMIZE lottery
   UPDATE_SERVOS pos1, pos2                    ' refresh servos
   UPDATE_CYLON                                ' update cylon "eyes"
   IF Trigger = IsOn THEN
     x1Timer = x1Timer + 20
   ELSE
     x1Timer = 0
   ENDIF
 LOOP UNTIL x1Timer >= 100

 Remote = IsOn                                 ' start external pulse


Go_Wild:
 FOR x1Timer = 1 TO 150                        ' ~15 secs in 0.1s units
   lottery = RANDOMIZE lottery                 ' re-stir
   tmpB1 = lottery & %00011111                 ' limit to eye ports
   RC = RC & %11100000                         ' clear old eyes
   RC = RC | tmpB1                             ' random eyes


   IF x1Timer.0 THEN                           ' update every other cycle
     pos1 = RANDOMIZE lottery
     pos1 = pos1 MIN 60                        ' fix limits
     pos1 = pos1 MAX 240

     pos2 = RANDOMIZE lottery
     pos2 = pos2 MIN 60                        ' fix limits
     pos2 = pos2 MAX 240
   ENDIF

   FOR x2Timer = 1 TO 5                        ' create 0.1s delay
     UPDATE_SERVOS pos1, pos2
   NEXT

   Remote = IsOff                              ' end external pulse
 NEXT

 GOTO Start


' -------------------------------------------------------------------------
' Subroutine / Function / Task Code
' -------------------------------------------------------------------------

' Use: DELAY_MS milliseconds
' -- shell for PAUSE

SUB DELAY_MS
 PAUSE __wparam12
 ENDSUB

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

' Use: DELAY_US10 delay
' -- delay in 10us units

SUB DELAY_US10
 us10          VAR     tmpW1

 us10 = __wparam12
 DO WHILE us10 > 0
   PAUSEUS 10
   DEC us10
 LOOP
 ENDSUB

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

' UPDATE_SERVOS pos1, pos2
' -- refreshes servos and creates 20ms pad

SUB UPDATE_SERVOS
 svo1          VAR     tmpB1
 svo2          VAR     tmpB2
 svoDelay      VAR     tmpW2

 svo1 = __param1
 svo2 = __param2

 Servo1 = IsOn                                         ' refresh servo 1
 DELAY_US10 svo1
 Servo1 = IsOff

 Servo2 = IsOn                                         ' refresh servo 2
 DELAY_US10 svo2
 Servo2 = IsOff

 svoDelay = 2000 - svo1
 svoDelay = svoDelay - svo2
 DELAY_US10 svoDelay

 ENDSUB

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

' Use: UPDATE_CYLON
' -- updates cylon eye pattern
' -- assumes called every 20ms; divider updates eyes every 100ms

SUB UPDATE_CYLON
 INC cylonTix
 IF cylonTix >= 5 THEN                         ' time for update
   READ Cylon + cylonIdx, tmpB1                ' yes, get pattern
   RC = RC & %11100000                         ' clear old pattern
   RC = RC | tmpB1                             ' update new
   INC cylonIdx                                ' update pattern index
   IF cylonIdx = 8 THEN                        ' at end of pattern?
     cylonIdx = 0                              ' yes, reset
   ENDIF
   cylonTix = 0                                ' restart divider
 ENDIF
 ENDSUB

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

FUNC RANDOMIZE
 IF __paramcnt = 1 THEN
   RANDOM __param1
   __param2 = 0
 ELSE
   RANDOM __wparam12
 ENDIF
 RETURN __wparam12
 ENDFUNC


' =========================================================================
' User Data
' =========================================================================

Cylon:
 DATA  %00001, %00010, %00100, %01000
 DATA  %10000, %01000, %00100, %00010
Jon McPhalen
EFX-TEK Hollywood Office

uncle

Still nothing.  When I power up the SX, the servos move fractionally but that is it.  The eyes don't light up, nor is there any further servo movement.  I have a trigger on P14, but nothing on P15.  What function does the P15 remote have?

I don't believe this program calls for a resonator, but thought I would mention that I do not have one in place just in case that helps with the problem.

JonnyMac

If you're not using an SX-Key then you need to have a 20MHz resonator installed -- that's in the DEVICE definition.  The SX-Blitz cannot generate a clock.

I have no idea what the P15 "remote" is for; I assume you asked me for it when we talked ages ago; it's not in use in this program.  Which does work, by the way; I spent an hour checking everything using a Trainer and an X/Y servo mechanism.
Jon McPhalen
EFX-TEK Hollywood Office

uncle

Yay!  It works!  I have adjusted the servo positions and timing for the pecularities of my servos and it is working just as hoped. 

And of course I just found my notes from a few months ago reminding me that Device definition was for the resonator.  DOH!!

In this prop, I also have a Prop-1 running a few separate LED's, and with a mat switch that activates a VMusic on that Prop-1.  Is it possible to use the "remote" from the SX to activate the Prop-1 in place of the mat switch?

JonnyMac

Yes, all you have to do is activate the remote pin as it's setup as an output.  Here's the thing, though: if you're going to use one of our WRB cables you need to clip the red wire out.  If you don't the 5v systems on the separate controllers could conflict with each other.  Other than that, it's easy as a high pulse out of the Prop-SX will look like an active-high output on the Prop-1.
Jon McPhalen
EFX-TEK Hollywood Office

uncle

I have SX P15 W and B connected to Prop-1 P5 W and B (VMusic is on P6 and P7), but the Prop-1 is not activating.  P5 did work with a NO switch.  What simple step am I missing?

JonnyMac

The trigger may not be long enough -- copy and pasted just the trigger section from your Prop-1 code so I can see it.
Jon McPhalen
EFX-TEK Hollywood Office