October 31, 2024, 10:26:29 PM

News:

Got VSA?  Want to use your Prop-SX?  Now you can!  See the VSA section of the Library forum for Prop-SX code that works with VSA.


Talking Skull Program Prop-1 to Prop-2 Conversion

Started by jukingeo, November 04, 2007, 05:45:06 PM

Previous topic - Next topic

jukingeo

Hello,

I was looking over Jon's program for Brad Q over in the Prop-1 forum.  The post is labeled "Need A Program for a Talking Skull".  I found this interesting and something that I could use.

I liked the idea of syncing motor and the LED eyes from the audio source, but it would be cool to have the BS-2 move the head side to side and up and down.

Over the Halloween weekend I been following quite a few posts over in the Prop-1 Forum (as that is where most of the action was).  I found a few programs there that I was able to download and convert to the Prop-2 myself but this one proved to be a himdinger.

I believe I have done most of the Prop-1 to Prop-2 conversions correctly but I know that there are timing differences between the two controllers when servos are involved.

I have two servos that I have tested to run at about 412 to 1100, end to end MAX.  So I re-arranged most of the settings in the EEPROM (Data) table to reflect this.

I also put in a couple of protection "If Thens" right before the PULSE outputs to ensure that I was not exceeding my servo's ratings.

Now here is the problem.  The audio trigger works, but the servos go to their lowest end and stop.  I put a DEBUG command in that area of the program to see what the values are for the servos and they are stuck at 450...which is the minimum setting I requested.  Leaving the debug and commenting out my protection, I see that the program changes values...but in the low ranges.

So I can't see what I am doing wrong with this conversion.  Any help would be appreciated.

Here is the program and what I have done with it so far:

' =========================================================================
'
'   File...... Servo_Blender-MP3.BS1
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated... 12 APR 2007
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------
'
' Starts an external audio player and then controls the simultaneous
' movement of two (pan/tilt) servos.  Servo movement is stored in an EEPROM
' table with a "repeats" value for timing at the positions specified in the
' record (last byte).  The timing is approximately:
'
' 20 milliseconds x (repeats + 1)
'
' Mimimum: ~0.02 seconds
' Maximum: ~5.12 seconds
'
' Note that servos are mechanical and move slowly, so very small "repeats"
' values may expire before the servos reaches their target positions.


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


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

Audio        PIN  13                    ' audio start/stop
Trigger      PIN  14                    ' trigger input

Servo2       PIN  1
Servo1       PIN  0

pins         VAR OUTL


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

IsOn         CON  1
IsOff        CON  0

RecLen       CON  3                     ' record length (servos + 1)

EOS          CON  1000                  ' end of show marker


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

record       VAR   Word                 ' movement record
pntr         VAR   Word                 ' table byte pointer
s1Pos        VAR   Word                 ' servo 1 position
s2Pos        VAR   Word                 ' servo 2 position
repeats      VAR   Word                 ' repeats for record data


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

Reset:
  PINS = %00000000
  DIRL = %00100011                              ' make servo pins outputs

  record = 0
  GOSUB Get_Servo_Pos                           ' get "home" positions


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

Main:
  GOSUB Refresh_Servos
  IF Trigger = IsOff THEN Main                  ' wait for trigger

Start_Audio:
  HIGH Audio                                    ' "press" play button
  PAUSE 2000                                    '   for 2 seconds
  LOW Audio

Reset_Moves:
  record = 1                                    ' point to start of moves

Move_Engine:
  GOSUB Get_Servo_Pos                           ' get servo positions
  IF s1Pos = EOS THEN Show_End                  ' abort if at end

Servo_Hold:
  GOSUB Refresh_Servos
  IF repeats = 0 THEN New_Record                ' time left at this pos?
    repeats = repeats - 1                       ' yes, decrement timing
    GOTO Servo_Hold

New_Record:
  record = record + 1
  GOTO Move_Engine

Show_End:
  HIGH Audio                                    ' "press" play button
  PAUSE 2000                                    '   for 2 seconds
  LOW Audio

  GOTO Reset                                    ' clear everything


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

' Call with "record" set to table line to read

Get_Servo_Pos:
  pntr = record * RecLen                        ' point into table
  READ pntr, s1Pos                              ' read servo 1 value
  pntr = pntr + 1                               ' point to servo 2
  READ pntr, s2Pos
  pntr = pntr + 1                               ' point to repeats
  READ pntr, repeats                            ' read repeats
  RETURN

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

' Update servos -- time consumed is 19 to 21 ms

Refresh_Servos:
  DEBUG HOME, DEC4 s1Pos, CR, DEC4 s2Pos

'  IF s1Pos < 450 THEN s1Pos = 450
'  IF s1Pos > 1000 THEN s1Pos = 1000
'  IF s2Pos < 450 THEN s2Pos = 450
'  IF s2Pos > 1000 THEN s2Pos = 1000
  PULSOUT Servo1, s1Pos
  PULSOUT Servo2, s2Pos
  PAUSE 17                                      ' pad for loop timing
  RETURN


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

' Note on servo movement timing:
'
' Time spent on each record is 20 ms x (repeats + 1) so a repeats value
' of 0 is ~20 ms and a repeats value of 255 (max) is ~5.1 sseconds at that
' position.
'
'         s1   s2   rpts

Move_Table:
  DATA 500, 500, 450                        ' home position
  DATA 1000, 1000,  450                        ' start of movements
  DATA 600, 600,  450
  DATA 750, 850,  450
  DATA 900, 700,  450
  DATA EOS, 500, 450                         ' end here

  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455
  DATA EOS, 500, 455


JonnyMac

November 04, 2007, 06:25:41 PM #1 Last Edit: November 04, 2007, 06:43:34 PM by JonnyMac
The BS2 PULSOUT instruction has 5x the resolution of its BS1 counterpart so you're forced to use Word variables/values.  Here's a faithful translation (that I've tested and verified works) for you to study.

' =========================================================================
'
'   File...... Servo_Blender-MP3.BS2
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated... 12 APR 2007
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------
'
' Starts an external audio player and then controls the simultaneous
' movement of two (pan/tilt) servos.  Servo movement is stored in an EEPROM
' table with a "repeats" value for timing at the positions specified in the
' record (last byte).
'
' Note that servos are mechanical and move slowly, so very small "repeats"
' values may expire before the servos reaches their target positions.


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


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

Audio           PIN     15                      ' audio start/stop
Trigger         PIN     14                      ' trigger input
Servo2          PIN     9
Servo1          PIN     8


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

IsOn            CON     1
IsOff           CON     0

RecLen          CON     5                       ' record length (servos + 1)

EOS             CON     $FFFF                   ' end of show marker


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

record          VAR     Word                    ' movement record
pntr            VAR     Word                    ' table byte pointer
s1Pos           VAR     Word                    ' servo 1 position
s2Pos           VAR     Word                    ' servo 2 position
repeats         VAR     Byte                    ' repeats for record data


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

Reset:
  OUTH = %00000000
  DIRH = %10000011                              ' set outputs


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

Main:
  record = 0
  GOSUB Get_Servo_Pos                           ' get "home" positions
  GOSUB Start_Stop_MP3                          ' start the MP3
  record = 1                                    ' point to start of moves

Move_Engine:
  DO
    GOSUB Get_Servo_Pos                         ' get servo positions
    IF (s1Pos = EOS) THEN EXIT                  ' abort if at end
    DO WHILE (repeats > 0)                      ' count down repeats
      GOSUB Refresh_Servos
      repeats = repeats - 1
    LOOP
    record = record + 1                         ' point to next record
  LOOP

Show_End:
  record = 0                                    ' get home values
  GOSUB Get_Servo_Pos
  GOSUB Start_Stop_MP3                          ' stop the MP3

The_End:
  GOSUB Refresh_Servos
  GOTO The_End                                  ' wait for power down

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

' Call with "record" set to table line to read

Get_Servo_Pos:
  pntr = record * RecLen
  READ (Moves + pntr), Word s1Pos, Word s2Pos, repeats
  RETURN

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

' "Presses" MP3 player start/stop button while holding servos in
' home position.

Start_Stop_MP3:
  Audio = IsOn                                  ' press "play" button
  GOSUB Refresh_Servos
  repeats = repeats - 1                         ' for about 2 seconds
  IF repeats > 0 THEN Start_Stop_MP3
    Audio = IsOff
    RETURN

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

' Update servos -- time consumed is 19 to 21 ms

Refresh_Servos:
  PULSOUT Servo1, s1Pos
  PULSOUT Servo2, s2Pos
  PAUSE 17                                      ' pad for loop timing
  RETURN


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

' Note on servo movement timing:
'
' Time spent on each record is ~20 ms x (repeats + 1) so a repeats value
' of 0 is ~20 ms and a repeats value of 255 (max) is ~5.1 seconds at
' that position.
'
'               s1         s2         rpts

Moves   DATA    Word  750, Word  750,  60
        DATA    Word  500, Word  500,  30
        DATA    Word  500, Word 1000,  30
        DATA    Word 1000, Word 1000,  30
        DATA    Word 1000, Word  500,  30
        DATA    Word  EOS, Word  EOS, 255       ' end here
Jon McPhalen
EFX-TEK Hollywood Office

jukingeo

Quote from: JonnyMac on November 04, 2007, 06:25:41 PM
The BS2 PULSOUT instruction has 5x the resolution of its BS1 counterpart so you're forced to use Word variables/values.  Here's a faithful translation (that I've tested and verified works) for you to study.


Thank you Jon.   This program level is still above me as of now, I did remember to change the variables to word values but I guess it seems that the data section also needs to show that as well...so more then likely the values reverted to a rolled over byte.  Then I guess that was my problem then, right?

Since I got a couple servos over the weekend, I been having a ball programming with them.  I will try this program out when I get home.

I do have a couple questions for you right off the bat:

1) Why did the EEPROM section require all those repeated end codes for the Prop-1?  I see they are unnecessary for the Prop-2?
2) I am assuming that to change my range of motion all I have to do is alter the values in the Data section, correct?  (Or are there other pitfalls I have to take into consideration as I don't want to 'over-run' my servo stops).
3) I know that keeping a signal sent to the servos is important (I believe you mentioned in another post that the servos need to be refreshed every 20ms).  With that in mind, is it possible to add more servos?  Could other actions take place as long as they don't exceed this time requirement (e.g. opening/closing a valve for an arm movement, turning other devices on/off)?  (Yeah, I am shooting for the 'faux' multi-tasking again).

Thank you for your help. 

P.S. Oh! The PIR works great BTW!  I tried it out on a Prop-1 program that you created called "Hallway".  This was one of my first successful conversions to the Prop-2.  Awesome program!  I can see many uses for that one.



JonnyMac

November 05, 2007, 08:32:13 AM #3 Last Edit: November 05, 2007, 08:34:42 AM by JonnyMac
Quote from: jukingeo on November 05, 2007, 06:56:11 AM
1) Why did the EEPROM section require all those repeated end codes for the Prop-1?  I see they are unnecessary for the Prop-2?
2) I am assuming that to change my range of motion all I have to do is alter the values in the Data section, correct?  (Or are there other pitfalls I have to take into consideration as I don't want to 'over-run' my servo stops).
3) I know that keeping a signal sent to the servos is important (I believe you mentioned in another post that the servos need to be refreshed every 20ms).  With that in mind, is it possible to add more servos?  Could other actions take place as long as they don't exceed this time requirement (e.g. opening/closing a valve for an arm movement, turning other devices on/off)?  (Yeah, I am shooting for the 'faux' multi-tasking again).

Answers:

1) To show the amount of data one could store in that program -- helps in planning BS1 projects as the memory is so small.
2) Yes, that's correct -- put proper values into your DATA statements and you won't have to test them later (that just takes code)
3) You may add more servos; you'll have to drop the PAUSE value in the update section to account for the PULSOUT used by any additional servo(s) -- I use 1.5 ms per servo in my calculations

If you're going to do "faux mutlitasking" the core of the program should be redesigned; a lot of elements will work but it's not the best architecture for mixing servo motion in with other events.
Jon McPhalen
EFX-TEK Hollywood Office

jukingeo

Quote from: JonnyMac on November 05, 2007, 08:32:13 AM

Answers:

1) To show the amount of data one could store in that program -- helps in planning BS1 projects as the memory is so small.
2) Yes, that's correct -- put proper values into your DATA statements and you won't have to test them later (that just takes code)
3) You may add more servos; you'll have to drop the PAUSE value in the update section to account for the PULSOUT used by any additional servo(s) -- I use 1.5 ms per servo in my calculations

If you're going to do "faux mutlitasking" the core of the program should be redesigned; a lot of elements will work but it's not the best architecture for mixing servo motion in with other events.

Hello Jon,

Tried the program out tonight, worked great!  I made some adjustments as usual and of course added to the data section of the program (as it seemed kind of a short run).  Anyway, I am just experimenting right now. 

1) So basically then all those 'extra' data (EEPROM) lines you wrote were to just show the maximum additional program space in regards to the Prop-1.  Ok then...got it.

2) As I added the data lines I did 'check' first using the debug command and made sure everything was in line.  It is...so we are good.

3) Well, short of adding another servo or two...I did want to add some on/off relay events, perhaps for triggering pneumatic parts of the prop I would add later on, or perhaps a lighting change.  So I wasn't sure if that could be 'faked' or not...Could be a job for the SX, but if it can be done with the BS-2 then so be it.  Already this controller has surprised me with what it can all do.

So yeah, I would like a program that would be very adaptable in this context in the manner of head movement and perhaps limb movement or other 'effects' within the prop.  Then all I have to do is change a few bits of data here and there.  Thus I could use the program for a bucky head and arm movement, then adapt it to create a fire belching demon head with smoke coming out of its mouth while it's head is moving.

The demon head is a good example because it would involve a fog machine...an item that you would turn on for a pre-determined time.  However, I know this would be a no no in a servo refresh loop using a PAUSE command.  But I have seen you create programs with a timing 'check' within a loop such as this:

HIGH Fogger

fogTimer = fogTimer + 1

IF fogTimer = 10 THEN LOW Fogger

In this manner the servos could continue to be refreshed as the fogger continuously runs.  Then the If THEN line 'checks' the timing data (in this case the number 10 could be a variable) and the fogger shuts off when the timing fogTimer condition is satisfied.

I also have seen you put timing AND event information in a DATA table before as well. So I am guessing that this is very much possible and easily changeable in a data table.  If so then it could be easily altered for a different prop.

Finally I did also have a question about triggering the AP-8 with this program as well, but perhaps I should start a new thread in the AP-8 message board for that.

Thanx again for your help.  I will be playing with this program some more tonight so I can get a better understanding of it.

Geo


JonnyMac

November 06, 2007, 02:36:01 PM #5 Last Edit: November 06, 2007, 02:37:51 PM by JonnyMac
Here's a simple "faux multi-tasker" that will run four servos and eight digital outputs.  The important point is that with "faux" multitasking you must carefully weave everything together -- to try and use straight line code with a table-driven design generally doesn't work well [in my experience].

' =========================================================================
'
'   File...... Multi_Servo.BS2
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'              Copyright (c) 2007 EFX-TEK
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated...
'
'   {$STAMP BS2}
'   {$PBASIC 2.5}
'
' =========================================================================


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


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


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

Trigger         PIN     14                      ' if required

Servo4          PIN     11
Servo3          PIN     10
Servo2          PIN      9
Servo1          PIN      8

DigOuts         VAR     OUTL
DigOut7        PIN      7
DigOut6        PIN      6
DigOut5        PIN      5
DigOut4        PIN      4
DigOut3        PIN      3
DigOut2        PIN      2
DigOut1        PIN      1
DigOut0        PIN      1


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

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

REC_LEN         CON     10
EOS             CON     $FFFF                   ' end of show marker


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

recNum          VAR     Word                    ' record number
pntr            VAR     Word                    ' EEPROM pointer
pos1            VAR     Word                    ' servo positions
pos2            VAR     Word
pos3            VAR     Word
pos4            VAR     Word
tmpOuts         VAR     Byte
tix             VAR     Byte                    ' record timer


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

Reset:
  OUTS = %0000000000000000                      ' clear outputs
  DIRS = %0000111111111111                      ' configure I/O

  recNum = 0
  GOSUB Read_Record                             ' get starting positions


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

Main:
  GOSUB Refresh_Servos
  PAUSE 14
  IF Trigger = IsOff THEN Main                  ' wait for trigger

  recNum = 1                                    ' start at beginning

Play_Show:
  GOSUB Read_Record                             ' get new record
  IF (pos1 = EOS) THEN Reset                    ' show done?

  DO WHILE (tix > 0)                            ' run the record
    GOSUB Refresh_Servos
    PAUSE 14
    tix = tix - 1                               ' update record timer
  LOOP

  recNum = recNum + 1
  GOTO Play_Show


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

Read_Record:
  pntr = Show + (recNum * REC_LEN)
  READ pntr, Word pos1, Word pos2, Word pos3, Word pos4, tmpOuts, tix
  RETURN

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

Refresh_Servos:
  PULSOUT Servo1, pos1
  PULSOUT Servo2, pos2
  PULSOUT Servo3, pos3
  PULSOUT Servo4, pos4
  DigOuts = tmpOuts
  RETURN

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


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

'                    pos1       pos2        pos3       pos4   digouts   tix

Show    DATA    Word  750, Word  750,  Word  750, Word  750, %00000000, 255
        DATA    Word  500, Word  500,  Word  750, Word  750, %00000001,  50
        DATA    Word  500, Word 1000,  Word  750, Word  750, %00000010,  50
        DATA    Word  750, Word  750,  Word  750, Word  750, %00000100,  50
        DATA    Word  750, Word  750,  Word  750, Word  750, %00001000,  50
        DATA    Word  750, Word  750,  Word  750, Word  750, %00010000,  50
        DATA    Word  750, Word  750,  Word  750, Word  750, %00100000,  50
        DATA    Word  EOS, Word  750,  Word  750, Word  750, %00000000,   0
Jon McPhalen
EFX-TEK Hollywood Office

jukingeo

Quote from: JonnyMac on November 06, 2007, 02:36:01 PM
Here's a simple "faux multi-tasker" that will run four servos and eight digital outputs.  The important point is that with "faux" multitasking you must carefully weave everything together -- to try and use straight line code with a table-driven design generally doesn't work well [in my experience].


Thank You Jon,

I will play around with this program tomorrow.   It is amazing that you can make the multiple calls to the Data bank using the Read command and just keep adding on to what you need.  This will definitely provide enough outputs and servos to work with with most props.

Geo