I'm working on a new product that will have a serial control option and I've been looking into what application protocol to use. I found references to a serial control protocol used by the OOPic. There used to be a site called
but that seems to be gone now.
How widely used is this protocol? Is anything besides the OOPic using it? Are there any other standard serial protocols I should be looking at?
I'd much rather use a known standard instead of inventing another one.
I have not seen many commercial products other than the OOPic use it, but that doesn't mean it isn't a good protocol. It's described a bit more in the OOPic manual, which you can get online at the oopic.com site.
What many people aim for today is multi-drop interfaces for addressing more than one device on the same line, and an ASCII control set (with some mechanism to provide values down to 0, and over 127), so it can be used with standard terminal software. Other than that, I think most anything is fair game.
Gordon, I agree that it looks like a good protocol. I was wondering if there was another serial protocol that is widely accepted that I may have missed in my searching. Doesn't look like there is though.
I think SCP will fit my needs so I plan to use it.
It looks like openscp.com is gone but I found that openscp.org wasn't taken. I am willing to build a site for SCP at openscp.org if anyone is interested collaborating on it. I'd like to promote the standard if I'm going to use it.
Not sure how widely used it is beyond the product line it was developed for, but you might look at the protocol used in the RoboBricks project:
Wayne often posts here and he can provide the pros and cons. Certainly one benefit would be compatibility with these little modules. For a while RobotStore was selling them (before Jameco bought them), but I don't know what their current status is.
One thing to keep in mind about both of these specs: they've been proven in real-life products, and I think that's important. I think Scott has used SCP in products other than OOPic (I'm pretty sure Speakjet, for one), and Wayne has demonstrated the efficacy of the Robobricks communications platform.
I'd like to through in my $0.02 and bring to light the MojoBus protocol. It is discussed in D. Jay Newman's Linux Robotics book. It was created by Brian Dean of BDMicro, Inc. It is ASCII based with a multidrop interface for addressing more than one device on a single line. Here is a description of MojoBus from an email that I got from Brian Dean:
Regarding MojoBus. For quite a while I have experimented with variousbus protocols for use on robots. The goals of MojoBus are simplicityof sending and receiving messages and consistancy of format betweenvarying devices. A single packet format is supported which is: [>]>t[,f]:cmd;[cmd;cmd;...] Items inside  are optional. A linefeed ends the message.Where: t = bus id of recipient (required) f = bus id of sender (optional) cmd = command to execute Command format: parameter | parameter=valueCommands can be read-only or read-write, depending on whether it makessense or not.I've defined a basic set of commands that all devices should support. These are:
RESET = ro, reset device VERSION = ro, display firmware revision ANNC = ro, display identity string, delayed by busid order WHO = ro, display identity string ID = rw, set controller bus ID BAUD = rw, set RS232/RS485 serial baud rate, units = bps The person who implements this can define whatever commands they want,of course, depending on what makes sense for they device they make.The idea is simply so that one can put an h-bridge on the bus, as well as other devices like sensors, etc, and be able to communicate with them all in a consistant way that is not too complicated yet not too constraining. For example, for MojoBridge which was the high level controller interface to the RX50, it supported the following additional commands: D = rw, set duty cycle -100 to 100, units = % ENCP = rw, set encoder sample period, units = ms TPOS = rw, set motor target position, units = encoder TVEL = rw, set motor target velocity, units = encoder APOS = ro, display actual motor position, units = encoder AVEL = ro, display actual motor velocity, units = encoder KP = rw, set PID P constant (float) KI = rw, set PID I constant (float) KD = rw, set PID D constant (float) PID = rw, set PID P, I, and D constants (float) REV = rw, set motor reverse 0 or 1 Thus, to set the duty cycle of this device to 50%, and its busid is7, one would send it the following message: >>7:d=50;In C, this could be done something like this: sprintf(buf, ">>%d:d=%d;\n", target, duty); puts(buf);Multiple commands to the same device can be strung together. I.e: >>7:d=50;rev=1;A linefeed ends the message to that device.The protocol is nice in that you can connect to a simple terminal emulator on a PC and type in commands directly and see results. This is great for testing and trying things out. Also, it is easilyparseable.A sender ID is supported also. If the sender sends its own sender ID,and if the command requires the recipient to produce any results,those results should themselves be in MojoBus protocol format. I.e.,like this: Sender: (request position from busid 7, sender is busid 3) >>7,3:APOS; Recipient (busid 7) should respond as follows: >>3,7:*APOS=359722The '*' indicates it is a result and not a command, just in case thesender might interpret that as a command instead in the case of amultimaster setup.I hope this gives you and idea of it. I hope to put up some morecomplete documentation on my web site soon.
Coming soon. I'm currently tied up polishing off my RX50 h-bridge and its associated companion board that runs the MojoBus protocol, so that's where my effort is going at the moment.
In D. Jay Newman's new book on Linux Robotics, he used a prototype RX50 which was named MojoBridge at that time which included not only the h-bridge but also a high level control interface which ran my MojoBus protocol. For the production board, though, I seperated out the h-bridge proper from the higher level control. The h-bridge is the RX50 (5 to 30V, up to 50 Amp, 100+ kHz PWM). The companion board which implements the high level interface including serial comms of various sorts, R/C servo pulse control, potentiometer feedback and control, quadrature feedback, and built-in PID algorithms is coming soon and will most likely carry the MojoBridge name.
Jay and I exchanged quite a bit of communication on this topic when he was writing his book. While the format of the protocol was pretty much done, Jay suggested several important refinements to the semantics based on his experience in developing Grouch. This includes refinements to the conditions when a device remains quiet or responds to queries which make more sense in bus oriented environment where this is targetted.
As you may or may not know, Jay used a pair of my "MojoBridge/RX50" h-bridges on the robot he developed in his book, as well as a MAVRIC-IIB as an "intermediate" controller. The h-bridge controller used MojoBus as I mentioned. I also provided the basis of the MAVRIC-IIB code which Jay then extended and refined for his specific application and added new functionality to make it do what he wanted. This code implements a MojoBus device and Jay used it to MojoBus-enable a variety of sensory input, including a dozen or so sonars connected to the MAVRIC-IIB. If I mis-speak here Jay, please correct me.
So currently as of this post, D. Jay Newman's book, "Linux Robotics, Programming Smarter Robots" is the best reference:
Talking to MojoBus devices is very easy - the code snippet I sent to Randall which he posted is really all there is to it.
Implementing a MojoBus device is not hard either, but does require a little parsing. Again, D. Jay Newman published the code used on his MAVRIC-IIB board on his web site that does this. We've made the source freely available in the spirit of sharing:
The core of the protocol implementation is here:
This includes an implementation of most of the "default" MojoBus commands as well as the state machine for parsing the command packet.
I do want to work in an optional checksum into the protocol. I have a few ideas on how to do that which I plan to explore shortly.
Sorry, about the late resp> Not sure how widely used it is beyond the product line it was developed
The first set of modules, called RoboBricks 1 (or RoboBRiX) used
5Volt signalling at 2400 baud. It was a binary protocol where a master module would send a 1 or more bytes and get 0, 1 or more bytes in return. It worked well with the bit banged serial protocol that the Parallax Basic Stamp, OOPic, Javalin, etc. could do. The RoboStore used to carry them, but Jameco did not pick up the contract when they purchased RoboStore. (Actually, there is quite a bit more to the RoboBrick 1 saga, but not on this forum.)
The next set of modules, called RoboBricks 2, (as you can see, I'm not very inventive with my project names) is based on a multi-drop bus. It evolved out of an extensive discussion we had on the Home Brew Robotics Club mailing list last September. It uses the CAN bus physical layer which is a differential signalling bus that was developed by the automotive industry. We only use the CAN bus physical layer and and UART's. We do *not* require microcontrollers that support the full CAN bus stack; we just need "addressable" UART's.
The first set of RB2 modules is up and running at 625,000 baud. CAN bus is capable of 1M bps, so the next set of modules is going to have all of the microcontroller crystals and resonators changed to shoot for 1M bps. By the way, the next set of modules is sitting on my dining room table waiting for a soldering party this coming Tuesday.
The jury is still out on how well the RB2 modules will work. Hopefully, in the next few weeks we'll get a chance to get a robot or two working with them to see how they do.
With regards to protocol selection, there are plenty of them out there. Either choose one that already exists or roll your own.
Wayne, thanks for the info. How did the soldering party go?
I'm leaning towards a human readable text protocol. A couple of protocols use bit/byte encoding which is more efficient but requires decoding for debugging. For my purposes, sending a few more bytes of data won't make a difference.