Faster Serial Communication - A Question for the Gurus!

Hi,

I was wondering if there was a simple way (probably not) or if someone else has already done it, to change from the standard:

#0P1500

I was thinking by sending in a single 16 bit (i dont even know if 16bit serial communication is possible) with the first 5 bits representing the servo number (0 to 32) and the next 11 bits representing the servo position between 0 to 2000. For example in a single serial send you have:

|Start bit|16Data bits|Stop bit|

Instead of sending first the # then the servo number, then position, etc. Any method similar to this that is faster than the “#0P1500” method would be great.

The reason i am asking is that i need to be sending the SSC-32 alot of fast independent position updates for 25 servos at at least 50Hz or greater (for each servo!) and i have tried sending from the PC at 115200Baud the “#0P1500” method but it is too slow. Either the Baud rate cannot handle it or at lower serial transfer updates there is too much servo jitter.

Any help or any firmware that has already been updated for a faster means of servo positioning would be appreciated.

Thanks.

If you don’t mind fooling with the SSC-32 firmware, there’s no reason why you can’t change the serial comms to work with binary instead of ASCII.

You can NOT easily do it the way you described (actually sending 16-bit words), but you CAN easily send two 8-bit binary values, which is only slightly slower. Your PC can do this without difficulty (you’d have to write your own SW on the PC, though).

You may also need to optimize some things in the SSC-32 code to speed things up. That is, it’s possible that just increasing the comm throughput would not be enough - you might need to bypass some unneeded features in the SSC so that it can focus on only the 25 servos.

Pete

The reason ASCII protocol was chosen over binary was because of the power of the commands. Speed and Timed moves mean it isn’t necessary to update the positions as fast. Furthermore because you can send the servo controller all of the servos destination positions and initiate the movements with a CR there are no problems with the first servo updated starting to move before the last servo that is updated. Even if you need to closely monitor and constantly update the servos positions this can still be done effectively with the ASCII protocol. You simply set the destination position as a target, and update to the new destination while the servo is moving. This is how RIOS works to control the L5 and L6 arms. BTW, there are no jitter issues with the SSC-32 firmware, your methodology is creating the problem.

However…

If you insist on sending the servo positions in a fast as hell binary way, it’s already in there. Use the MiniSSC-II emulation command structure. Just send it 255, servo to move (0-31), and position (0-254). You loose the speed and timed move functionality though. A giant step backwards for servo based bots… Hope this helps…

Firstly, thanks saipan59, you confirmed what a friend told me yesterday, that i’ll have to do it with two 8 bit chunks and not with a single 16 bit chunk. I’m writing my own software in good old C in DJGPP so i can send the SSC-32 whatever i want really! Messing with the firmware on the SSC-32 however seems a bit messy at the moment, and i dont have CodeVisionAVR (not freeware, how sad) which i read you need to compile the firmware code after custom editing. If RobotDude’s idea doesnt update as fast as i need it to even though the output from the servos will now be silky smooth, i might have to edit the firmware. (i hope its not too difficult!)

Secondly, thanks RobotDude for mentioning that idea, which i didn’t think about at all. Everything i have ever done in robotics has been a constant fast update of positions to whatever i’m controlling, and even though you said the MiniSSC-II emulation command structure allows for super fast communication, it seems like i can only achieve 255 position resolution as opposed to 2000 with the ASCII protocols. So i believe to follow, for example, a sin wave, i would have to constantly work out the future position (possibly 60msec in advance), compute velocity and send this to the SSC-32, so the servo output becomes a combination of linear ramps, which should be mostly ok (i hope at this stage) and definately provide a smooth output at the servo. Its a very smart idea, but hi res, fast binary position updates would be nice too! :laughing: would make a nice powerful addition to the next version of the firmware. 8)

115.2Kbps = 14.4KBps
/50hz = 288 bytes per 20ms frame
/9? bytes per servo position update = 32 servo updates/20ms frame

That’s assuming it can parse commands as fast as you can serve them up at 115200bps.

In my opinion not ideal, but it looks like it will just barely squeak by. The whole timed trajectory thing is cool, but I think difficult to take advantage of effectively. I’ve got an 18 servo hex and update all positions every 20ms from the master. That makes things very simple. Every frame send a 36byte packet with a couple header flags. That way all the logic/math/geometry is in the same place, in the code that reads sensors and spits out points. Just my $0.02 :slight_smile:

We are doing this with the EH3-R combo kit. SSC-32, Bot Board and Atom 28. Laurents program updated the trajectory every 170mS. This is while calculating the IK in real time. Anyway it is able to walk in any direction (translation) or turn (rotation) and any combination of the two, while reading a Sony PS2 game controller in real time. So it works well. Disclaimer, I didn’t write the program, so I don’t know how difficult it was to effectively take advantage of this method of control. :wink:

Hi there,

to send command to the SSC-32 @ high rate :

  • group commands, don’t send many single command with
    like “#20P1500” “#21P1500” etc…
    use “#20P1500 #21P1500 #22P1500 …” rather

  • kill spaces, so “#20P1500#21P1500#22P1500 …” is better

  • try to connect servos by group of pins, there’s pins groups on the SSC-32, so, pins 0 to 7, pins 8 to 15, 16 to 23 and 24 to 31 are groups.
    servos within a group will be updated at exactly the same time, the next group will be updated a little bit later (a very little bit) and so on…
    anyway, all groups are updated at the same rate(the output signal kept and handled by the SSC-32 internally), but 8 by 8.

  • don’t try to update servos at 50Hz.
    33Hz or 25Hz is enough, because servos are not so fast and not so precise.
    the EH3-R program update the servos @5.88Hz (every 170ms…yup Robot Dude :wink: )

  • try to interpolate your trajectories as much as you can, in order to decrease the update rate.

  • always use the “Time (T)” command when you update servos at a known rate.
    so, if you are updating @25Hz, use “#20P1500#21P1500#22P1500…T40”
    try to modify this value to fit perfectly the program refreshing rate (i’m using a “smooth” slider to fine adjust this value during play mode in the RIOS software)
    with the correct “T” value => no more shakes

  • use the 115 200bps serial port speed

  • enable fifo buffer

  • if you can adjust the buffer size, don’t use a too big buffer (128KB is too much)…16KB is great

  • sending data from the PC to a SSC-32 at a constant rate…is time critical !,
    so, stop any process, program, P2P, DSL download, HD use…etc…on your PC while sendind data to the SSC-32.

  • try to send positions update, only if positions were ‘really changed’, updating a servo to pos 1500, 50 times a second for 10 seconds,
    use serial port bandwidth for nothing
    (remember the SSC-32 is refreshing servos signal and keep the last position for you…yeah yeah you know that…)
    so, don’t send 25 servos positions each time if it’s not needed, only send useful data to the SSC-32, it will prevent the serial bus to overflow.

  • with most of analog servos, don’t update position if the moves is < 5uS from the previously sent position, most of the times, the analog servos won’t move anyway. this rule must be applied with very high updating rate.

haaa, i need a beer !

apart from connecting up a mouse to the serial port, this is the first time i have used hardcore serial communication. from what i’ve learnt searching around on the web, baud rate is the maximum number of signal changes you can have on a line per second. so, 115200 Baud which is what i’m using with the SSC-32 is the maximum number of signal changes. This includes the start and stop bits, parity, etc. (if used). So, correct me if i’m wrong, but when sending the SSC-32 a single ASCII character, this consists of: 1 start bit, 8 data bits, 1 stop bit. = 10 total bits

So this means that i can send 115200/10 = 11520 maximum ASCII characters to the SSC-32 per second?

Now sending the ASCII strings as such “#25P1500” consists of 9 ASCII characters. So thats 11520/9 = 1280 servo positions per second.

(i know that the carriage return is only needed at the end of all the servo position strings but this is how i ORIGINALLY did it before RobotDude clarified it for me.)

Now updating my 25 servos as fast as the baud rate will allow means that 1280/25 = 51.2 Hz is attainable. ok, i should be happy…

But… for some reason, and as i said this is my first time using serial communication seriously, i found that i could only update each servo at about half of what i calculated above, so at about 25Hz. Any faster and the PC would lock up, seemed like i was trying to force too much data through the PC serial port or something and it couldnt handle it…???

One more thing, Laureatus thanks for the extra ideas! You said:

Is it better to use the Time command instead of the Speed command or doesnt it matter? Thanks.

Speed command is used to limit the speed of one or more servos…

Time command is used to synchronize all the servos within the command line :

  • it calculate servo speed for each of them (servo with more travel to perform have speed increase)
  • it will try to move all the servos to their destination positions within the Time value.

when updating at a constant rate, you must use the Time (T) command.
doing that way, all servos are ready to go to the next positions, each cycle.
if a servo position can’t be reach, due to servo speed limitation (too much travel to perform in 0.02ms) this position will be overwritten by the new one (the next cycle)

Speed command can be used to limit speed, to preserve some hardware stuff
Time and Speed command can be mixed in a same command line…read the SSC-32 manual V2 to learn how

arh! i understand it good now, well the capabilities of the SSC-32 anyway. Thanks to all who replied. Whoever thought of the Timed command (T) is a genius! Makes smooth control possible with updates whenever you feel like it. I’ve tried running a sin wave movement on all of my 25 servos updating each at 5Hz, 10Hz, 16.67Hz, and 25Hz (ie. 200msec, 100msec, 60msec, and 40msec respectively), each producing a nice smooth output on all 25 servos! For those that run into the same problems as myself and come here for answers, i’ll explain a bit.

Say i want to update each servo at 25Hz. Then I send each servo the positions in a long string of ascii characters starting from:

#0P1500#1P1500#2P1500… …#24P1500T40

And i send this string to the SSC-32 with the updated positions every 40msec (25Hz). The correct value for the Timed move (T) is critical (40 for 40msec updates, 100 for 100msec updates, etc), and must be equivalent to the time between position updates to the SSC-32. So for a 5Hz position update, i would send the string every 200msec like so:

#0P1500#1P1500#2P1500… …#24P1500T200

This way the servo can be updated at less than 50Hz, and still produce a smooth output, since the SSC-32 firmware interpolates the servo positions inbetween, as long as it knows how long to interpolate for, which you tell it using the Timed (T) command, only needed once at the end of your string of servo positions, followed by a single carriage return . (as above).

Brilliant!!!

BUT… (and i say it still) a binary system over the ASCII commands would still be nice, (with the same position resolution and Time command of course) as i find that with 25Hz position updates, the computer really spends most of its resources dealing with the large amount of ascii characters it is sending to the serial port, and everything else the computer does with my software code is considerably slower… (and i’m running my C code in DOS on a Pentium2 500Mhz machine!) i will be praying to the firmware gods for this in the next version of the firmware…