May 05, 2024, 07:55:20 AM

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.


Vex Transmitter to Prop-SX to Servos + PC (via Serial)

Started by JonnyMac, May 27, 2008, 07:24:22 PM

Previous topic - Next topic

JonnyMac

May 27, 2008, 07:24:22 PM Last Edit: June 24, 2008, 08:04:16 PM by JonnyMac
If you have one of those VEX Transmitter/Receiver kits this thread will show you how to connect the transmitter (directly) or receiver to the Prop-SX in order to drive four servos with the joysticks (the program presented ignores channels 5 and 6).  At the request of one of our friends this program also dumps the servo position values to a PC using the DB-9 connector on the Prop-SX. 

Step 1 :: Build a cable

This is the trickiest part.  The connectors on the VEX transmitter and receiver are narrow so you'll need a telephone headset extension (a regular phone extension won't work).  Cut this cable in half and splice it to servo extension cable.  Note that the diagram shows the socket -- you'll need to check your cable as it would be plugged into this port for corresponding wire colors (this depends on which end of the cable you use).




Step 2 :: Program the Prop-SX

Okay, this is the easy part.  Download the following program to your Prop-SX.  Note that P15 must have the ULN removed (either replace with a ULN2003 or clip pin 1 of the ULN2803), and move the P15 SETUP jumper to UP.  Plug your servos into P0-P3 and let 'er rip.  Note that you can change the baud rate setting to the PC to any value that the resonator you're using (I've got mine set for 20 MHz) will support.  The SX/B compiler will warn you if the specified FREQ will not support the desired baud rate.

Note: A resonator MUST be installed for serial communications to the PC (the internal oscillator is not accurate enough).

Minor updates to program: 24 JUN 2008

' =========================================================================
'
'   File...... VEX_Servos_EZ.SXB
'   Purpose...
'   Author.... Jon Williams, EFX-TEK
'              Copyright (c) 2008 EFX-TEK
'              Some Rights Reserved
'              -- see http://creativecommons.org/licenses/by/3.0/
'   E-mail.... jwilliams@efx-tek.com
'   Started...
'   Updated... 24 JUN 2008
'
' =========================================================================


' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------
'
' Note: Resonator must be installed for serial communications to PC


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


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

DEVICE          SX28, OSCXT2, TURBO, STACKX, OPTIONX, BOR42
FREQ            20_000_000
ID              "VexServo"


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

VexIn           PIN     RC.7 INPUT              ' P15, SETUP = UP, no ULN

ServoCtrl       PIN     RB                      ' servo control pins
Servo3         PIN     RB.3 OUTPUT
Servo2         PIN     RB.2 OUTPUT
Servo1         PIN     RB.1 OUTPUT
Servo0         PIN     RB.0 OUTPUT

TX              PIN     RA.3 OUTPUT             ' to PC


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

IsOn            CON     1
IsOff           CON     0

Yes             CON     1
No              CON     0

Baud            CON     "T57600"


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

flags           VAR     Byte

tix             VAR     Word                    ' for counting timing cycles
idx             VAR     Byte                    ' loop index

tmpB1           VAR     Byte                    ' for subs/funcs
tmpB2           VAR     Byte
tmpW1           VAR     Word
tmpW2           VAR     Word

svoData         VAR     Byte (4)                ' bank servo data
pos            VAR     svoData(0)              ' position table
pos0           VAR     svoData(0)
pos1           VAR     svoData(1)
pos2           VAR     svoData(2)
pos3           VAR     svoData(3)


' =========================================================================
'  INTERRUPT
' =========================================================================


'  RETURNINT


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


' -------------------------------------------------------------------------
' Subroutine / Function Declarations
' -------------------------------------------------------------------------

DELAY_US        SUB     1, 2                    ' replaces PAUSEUS
DELAY_MS        SUB     1, 2                    ' replaces PAUSE

TX_BYTE         SUB     1                       ' transmit a byte
TX_STR          SUB     2                       ' transmit a string


' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
  PLP_A = %1000                                 ' pull-up unused pins
  PLP_B = %00001111
  PLP_C = %10000000

  TX = 1                                        ' tx to idle
  DELAY_MS 10                                   ' let receiver clear

  TX_STR ID_Tag

Main:
  tix = 0
  DO WHILE tix < 300                            ' wait for sync pulse
    IF VexIn = 0 THEN
      INC tix
      PAUSEUS 10
    ELSE
      tix = 0
    ENDIF
  LOOP


Release_Sync:
  DO WHILE VexIn = 0                            ' wait for end of sync
  LOOP


Get_Servos:
  ServoCtrl = %0000_0001                        ' start servos
  FOR idx = 0 TO 3                              ' loop through four servos
    tix = 0                                     ' clear counter
    DO WHILE VexIn = 1                          ' hold for framing pulse
    LOOP
    DO
      PAUSEUS 10
      INC tix_LSB                               ' update timing count
    LOOP UNTIL VexIn = 1                        '  until pulse finished
    pos(idx) = tix_LSB + 50                     ' update postion (add framing)
    ServoCtrl = ServoCtrl << 1                  ' next serov
    ServoCtrl.4 = 0                             ' limit to four servos
  NEXT


Update_PC:
  TX_BYTE $FF
  TX_BYTE pos0
  TX_BYTE pos1
  TX_BYTE pos2
  TX_BYTE pos3


  GOTO Main


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

' Use: DELAY_US duration
' -- duration is in microseconds
' -- replacement for PAUSE

SUB DELAY_US
  IF __paramcnt = 1 THEN                        ' byte value passed
    tmpW1 = __param1
  ELSE                                          ' word value passed
    tmpW1 = __wparam12
  ENDIF
  PAUSEUS tmpW1
  ENDSUB

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

' Use: DELAY_MS duration
' -- duration is in milliseconds
' -- replacement for PAUSE

SUB DELAY_MS
  IF __paramcnt = 1 THEN                        ' byte value passed
    tmpW1 = __param1
  ELSE                                          ' word value passed
    tmpW1 = __wparam12
  ENDIF
  PAUSE tmpW1
  ENDSUB

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

' Use: TX_BYTE aByte

SUB TX_BYTE
  SEROUT TX, Baud, __param1
  ENDSUB

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

' Use: TX_STR [String | Label]
' -- pass embedded string or DATA label

SUB TX_STR
  tmpW1 = __wparam12                            ' get address

  DO
    READINC tmpW1, tmpB1                        ' read a character
    IF tmpB1 = 0 THEN EXIT                      ' if 0, string complete
    TX_BYTE tmpB1                               ' send the byte
  LOOP
  ENDSUB

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


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


' -------------------------------------------------------------------------
' User Data
' -------------------------------------------------------------------------

ID_Tag:
  DATA  "VEX Decoder", 13, 10, 0

Jon McPhalen
EFX-TEK Hollywood Office

JonnyMac

Just a follow-up on this: I put a scope on the VEX output and found that each servo frame is every 18.5 milliseconds; this matters if you're taking the data to be exported to another program, or recording it to playback later (as I'm doing with a VEX/Prop-SX/Waldo project).
Jon McPhalen
EFX-TEK Hollywood Office

davisgraveyard

This works GREAT!   I was able to animate my 3-axis skull with the VEX transmitter cabled to a Prop-SX. 

I am able to capture the data that is being sent out the serial port on the SX.   I have the 50hz resinator installed.
The code has baud set to T57600 so I am trying it at that speed.  I need to do some evaluation of the data and see if we can put it in some normalized format.  I will let you know.

Jeff

JonnyMac

That's great news, Jeff.  It will be really cool if there is a way for you to capture the data and export it for programs like VSA and Vixen -- I'm sure a lot of folks would enjoy that.
Jon McPhalen
EFX-TEK Hollywood Office

davisgraveyard

Ok, on first inspection we are going to need a little change in your program.   We need to send some sort of sync byte.  since you are sending the 4 bytes that represent the state of the 4 servos lets send a byte or two after that that we can use as a separator and also a sync byte so if we loose data (which is what I am seeing now) we can get back on track.    I can work on speeding up the capture side but it would be nice to identify the packets easier.   If the valid range for pos(idx) is 0-255 then maybe we send 00 as a header?

What would you suggest?

Jeff

davisgraveyard

Never mind.  I see the &FF in the code.  Let me work with the capture a bit more and see if I can clean up the data loss first.  I am seeing a lot of missing FF's that should be there.

Jeff

JonnyMac

Jeff,

You should see position values of 100 to 200 (plus/minus a bit) so $FF is used for sync -- this value would never show up as a servo position.
Jon McPhalen
EFX-TEK Hollywood Office

davisgraveyard

I have a couple of questions.

I see that you set the Baud rate to 57600?   

Baud            CON     "T57600"

Are you just wanting to be as fast as possible?

Just to make sure the sync byte $FF you are sending is a value of 255 correct?

So far all my tests are showing a LOT of dropped data.  I often see less than 3 values between the 255 sync bytes or a bunch of bytes (12 or more) before the next sync byte.

Lastly, if I run the program on the Prop-SX for a while it eventually just hangs and no longer talks to the servos.  I reset the board and everything is fine.  It seems to happen more often when I am moving the servos a lot.  Any ideas?

Jeff


 



JonnyMac

Yes on the baud rate and sync values.  There's actually a fair bit of time after the last servo pulse so you could drop the baud rate if you think that will help.  Since the sync pulse detect section is looking for a 3 ms low, you have about 5 milliseconds to send your data.  At 19.2K you can get everything out in 2.6 ms -- this is about as low as I'd go.

I've never seen the SX program hang, and I've left it running on my bench overnight more than once.  Unfortunately, I forgot to bring my VEX transmitter to MHC, so I won't be able to experiment until next week (in between trips).  I'll try to write a little VB program that receives the packets and indicates possible errors.

I'm not sure what could be happening on the SX side as this is a butt-simple program, and relies on the VEX transmitter for timing.
Jon McPhalen
EFX-TEK Hollywood Office

davisgraveyard

The hanging doesn't happen all the time.  And it only seems to happen when moving the servos with the vex so letting it run overnight would probably work.  Just like you I don't know what could be happening in the code but you can tell when the servos stop being serviced. 

There are a lot of options with the VB Serial Code.  Can you shed a little light on what the Prop-SX serial port expects?  Things like DTS, RTS, Flow Control.  Are we connecting at 8-N-1?  Any other details?

Jeff



JonnyMac

The program doesn't know or not if the joysticks are moving because it's simply measuring pulses and sending those values -- unless the VEX output is doing something weird that is being masked by the slowness of the servo movement.  I'll connect it to a scope and watch while moving the joysticks.  I may have to trigger the scope with the SX to sync with the frame as the frame rate of the output doesn't match a standard o-scope timebase.

The serial is straight 8N1 -- no magic, especially if you're just receiving data from the board.  If you're transmitting to it you have to filter anything you send from your input buffer (legacy issue from the Prop-2 board [which uses the same PCB layout] that we will remove in the next version of the Prop-SX).

How are you parsing the data from your buffer?  I would do this:

-- look for $FF in the stream
-- grab the four bytes that follow
-- are any of these four bytes $FF?
   -- if yes, there is a frame error and I would duplicate the previous packet to the output data
   -- I would attempt to re-align on the new $FF
-- is the next byte in the stream $FF
  -- if no, there is a frame error... not sure what I'd do about this one

Each packet of five bytes comes in every 18.5 milliseconds or so -- should be plenty of time for a PC to deal with it.  That said, the PC programming that I do tends to be very simple and capturing a bunch of data like this is something I haven't done. 
Jon McPhalen
EFX-TEK Hollywood Office

davisgraveyard

Thanks for all the quick responses.  I know you are at MHC and busy this weekend so I didn't expect too much of a response.

I'll see if I can figure out a patern on the hanging.  It is so random though.  I can go for quite a while where it doesn't do it at all.  Would the fact that I am using the teather port in the back of the VEX instead of using the reciever matter?

All my data capture tests have been straight dumps of the recieve buffer to a file.  I am then parsing the file to find the packets.  Based on what I am seeing so far if I follow your parsing logic on the recieve buffer I'd throw away almost all the data.  There seems to be very few packets with a $FF and 4 valid bytes.    But now that I think of it maybe that is the problem.  I might be thinking there is more data than there really is and the rest is just noise?   I'll take a closer look.

All my serial experience on the PC has been mostly modem communications and talking to hardward devices that have some sort of ACK/NAK protocol like credit card processing.    I haven't done any real time high speed data collection.   

Jeff




livinlowe

June 13, 2008, 11:23:57 AM #12 Last Edit: June 13, 2008, 01:35:23 PM by livinlowe
Jon-
I don' think this is a big deal but is this a typo in your program?:

svoData         VAR     Byte (4)                ' bank servo data
pos            VAR     svoData(0)              ' position table
pos0           VAR     svoData(0)
pos1           VAR     svoData(1)
pos2           VAR     svoData(2)
pos3           VAR     svoData(3)

You've got two svoData(0) zero's there, I think there should just be one?

EDIT:Looking at some of your other Prop-sx programs, it appears you do this quite frequently so, Nevermind!  :)
Shawn
Scaring someone with a prop you built -- priceless!

JonnyMac

It is deliberate, Shawn, and here's why: You could access each position value individually...

pos0 = 150
pos1 = 150
pos2 = 150
pos3 = 150


... or you could access them in a loop:

FOR idx = 0 TO 3
  pos(idx) = 150
NEXT


Aliasing different names to the same location is a frequent trick.
Jon McPhalen
EFX-TEK Hollywood Office

HauntedWolf

Quote from: davisgraveyard on June 10, 2008, 06:59:32 PM
This works GREAT!   I was able to animate my 3-axis skull with the VEX transmitter cabled to a Prop-SX. 

I am able to capture the data that is being sent out the serial port on the SX.   I have the 50hz resinator installed.
The code has baud set to T57600 so I am trying it at that speed.  I need to do some evaluation of the data and see if we can put it in some normalized format.  I will let you know.

Jeff

Jeff, did you use the VEX that we got at the RMG?
Robert

Haunted Wolf Hollow - http://www.hauntedwolfhollow.com