I'm trying to decide the architecture for my mobile robot, and I'm open for suggestions. Here's what I need to do:
Fact: Brain of the robot will reside on a PC. This PC has standard ports (serial, parallel, USB, etc). My original thought: Have the PC interface via RS-232 with what I call "the main message manager", which is a PIC mcu that is responsible to inquiry several "sensor slave modules" (as described below) if a message is ready to send. If yes, then the message manager reads that data, packages into a given software protocol and transmits to the host computer (the brain).
The sensor slave module is another PIC that interfaces with one or many sensors. The PIC "knows" the language of the sensor. It may be configured to sample sensors at a given time interval, and then once the sensor was read, it stores the data in memory and flags "I'm ready" to the message manager.
Now, until today I was set on implementing the messaging system using I2C, but someone also suggested RS-485 (CAN would be more difficult to implement as there are no direct libraries in my development platform and I'd have to do it in assembler).
IMO I2C is a bit overrated as a general purpose communications bus, especially as the needs of the system scale upward. Serial tends to be one of the easiest architectures to implement. You're more likely to be able to access serial ports than parallel ports, given different versions of Windows. (You didn't mention if your PC is running Windows, Linux, DOS, or something else.) Helpful for down the road...
With serial you are free to create whatever communications protocol you wish, though there are some "standards" already out there. You can see how other people have done these, but -- as an example -- you might start with a unit ID number (1 to 254), then send one or more bytes for the actual data. Data length can be arbitrary.
For examples of how some people have implemented good ol' serial as a two-way communications bus for robot components you might try here:
Wayne Gramlich, one of the creators of this system, is a regular contributor here. The site makes the specs, board designs, and software for many core modules freely available. The concept has been written up recently in SERVO magazine, if you have a subscription to that.
I use I2C in general, since there tends to be good hardware support for it in many micros (especially PICS and ATMEL devices) as well as a number of commercially available robotic peripherals or generally useful components. In particular, the hardware support is nice for slave and multi-master mode, since a given node will only be interrupted when it is addressed. It's generally fast enough for most mobile robotic use -- with the right termination it can be run at speeds up to 3.4mbs. I generally just use resistors for termination and fairly sloppy wiring and run the clock around 810khz to 1.2mhz -- which is more than adequate for my needs. I've never felt the urge to go to active termination.
If the PC motherboard doesn't support i2c (smbus -- see below), you can just use the RS-232 port to talk to the PIC directly at speeds as high as the PIC can support (which can be pretty high). The PIC simply acts as a dispatcher (as you describe) in addition to its other duties -- I've had great success with this approach. One of my robots has 4 PIC boards managing various sensors and other devices, as well as a number of devantech devices, all using I2C -- works like a charm. My robot "bus" is basically just Vcc, GND, SCL and SDA.
Note that smbus isn't identical to i2c -- the former is officially limited to 100khz, and has a much lower maximum current sink spec (around 350 ua), which means you have to use higher resistances for termination. There are other differences, but these are minor for most applications. I don't know if smbus supports some kind of active termination to raise the max clock rate -- it may.
You can also bit-bang i2c off of the parallel port -- but I haven't tried it personally.
Basically just a simple packet protocol to use on RS485. I've implemented this on several systems and it works very well.
Alternatively, I'm currently working on a purely ASCII protocol that works well also. I'm not quite ready to publish that but it's slightly easier to implement that ROBIN, not that ROBIN is too difficult. I'm currently experimenting with this ASCII version on a smart h-bridge that I'm working on.
But your idea is sound. RS485 is reliable, has good noise immunity, is easy to use, and bus lengths are not really an issue since RS485 is good for something like a kilometer or so. Also, you can turn any RS232 serial port into an RS485 port using a converter like found here:
I like RS485 so much that I include an RS485 transceiver on my MAVRIC-IIB board:
If you are using a PC for your main brain, it is prudent to architect your system so that you can advantage of the newer and newer processors that come out on a regular basis. USB and 10/100/1000 Ethernet look like they are going to be on the motherboard for quite a while. The serial port, parallel port, game port, ps/2 port, etc. are already starting to disappear from motherboards. Even the PCI bus, which has been around for a long time looks like it is going to fragment in the not too distant future (PCI Express, etc.) Unfortunately, neither USB nor Ethernet are particularly easy to interface a microcontroller to. My recommendation is to use some flavor USB to serial converter. The output of the serial converter can be either RS-232 or TTL compatable voltage levels. If the output is RS-232, a simple MAX232 chip can convert to the TTL compatible levels or you can use the same circuit that the Parallax Basic Stamp people use to level convert (a few transistors and a few resistors.) There is no reason not to crank the frequency up on your CPU to root microcontroller link. For some reason 115.2kbps is the typical baud rate used on PC CPU's although the UART on the root microcontrollers can go faster. Finally, when you get around to doing a vision system, give it it a private bus to pump the bits over (115.2kbps is not enough.)
Once you have serial data from the main CPU sitting in your root microcontroller you have lots of options. There is no reason to confine yourself to just one bus. There is no reason why the root microcontroller can not talk to more than one bus -- I2C, SPI, CAN, USB, or whatever. An example root processor that you can look at is:
This board has the Parallax RS-232 level converter, and the ability to talk to I2C (and SPI) buses, and bit-bang out serial protocol to multiple serial pins to a star topology.
When it comes to inter-module communication, differential signalling has a higher noise immunity than non-differential signalling. Examples of differential signalling are RS-422, RS-485, Ethernet, CAN bus, USB and probably a few more that I can't think of. Non-differential signalling is represented by RS-232, I2C, SPI, and plain old TTL level signalling. The longer the run and the higher the frequency, the more likely you want to pick up the noise immunity feature of a differential bus. Unfortunately, the motors we stuff into our robots typically kick out a lot of noise. If you carefully read the I2C specification you will find that Philips recommends using shielded cables for longer I2C runs. I don't know whether Philips is just playing it safe or whether the bus really starts to loose it as it gets longer. I suspect the bus looses it, since it does not take a very long piece of wire sitting next your next door neighbor's HAM tower to kick up a lot of noise. (I have very little experience with I2C, so other people who have used I2C may offer additional insight based on their experiences.) RS-422/485 is quite cheap to interface to and only requires three pins (RX, TX, and a direction control pin); the remaining microcontroller pins are yours.
If you want to try a star topology with a UART, a couple of inexpensive 74*151 and 74*138 chip allow for the easy stearing of the signal. The advantage a star topology has is that you don't have to figure out how to address your modules. If your module receives a message, it is knows the message is for itself. Whereas, on a multi-drop RS-485 bus, you have to somehow provide an address for each module and each module has to receive every message and ignore the messages that not addressed to it. An example design for such a star topology circuit is at:
This particular module is sitting on my shelf waiting for some spare time to dust it off and get it working. Sigh.
It is tempting to try to turn a multi-drop RS-485 bus into a mini-ethernet with full peer to peer communication. It can be done, but it makes things more compilicated since you have to provide code for detecting collisions, backing off, trying again etc. It has been done, but it now adds some uncertainty into whether or not a message you send actually got through or not. I do not recommend doing a peer to peer network; stick with a strict master/slave network instead.
The RoboBricks architecture uses asynchronous serial communication with TTL voltage level signalling in a star topology. Our inter module cables are 6 inches long to keep try and keep noise issues under control. At the time I started the project, PIC microcontrollers with UART's on them tended to be both expensive and had way too many pins on them. To reduce costs, I wound up using microcontrollers without UART's and bit-banged the serial protocol. I am currently in the process of upgrading the modules to use the PIC16F688 which has both an on-board UART, 8 channels of A/D, and reasonable number of pins (not too many and not too few.) I'm hoping to crank the baud rate of each module up to 115.2kpbs, but the jury is still out as two whether I can pull it off for every module.
Hopefully the text above is informative without being too technical. Please let us know what you decide upon.
P.S. I'll be off line for about a week starting tomorrow morning.
P.P.S. If you wish to contact me directly via E-mail, my E-mail address is Wayne .at. Gramlich @dot@ Net.
I hadn't think about that, the idea of using a usb2serial is a very good one and I think I'm gonna use it, thanks. I'll even take a look at the newest PICs that support USB.... I've heard that they made it very easy to interface with.
Here's what I'm very inclined to do:
Have the PC (running windows XP) communicate with the "microcontroller's box" via USB, either a direct USB path or a usb2rs232 cable. Supposing I decide for the later, when the signal gets to the "box", a MAX232 converts it to TTL levels and send the signal to an LTC485 for example, that is connected to the RS485 bus. In this case, the master will be the PC. Each sensor will have a dedicated microcontroller responsible for sensor data acquisition and packaging that data into a protocol known both by the slave and the master. This way, the master must only know the address of that sensor, since the "language" is standard for all sensors. I believe this architecture still promotes decoupling between the cpu and sensors, but eliminating the box's root processor eliminates one layer of communication.
One advantage that I can think of: for example, if at some point the "brain" decides that it doesn't need information from a particular sensor, instead of sending a message to the root processor of the type "hey root, I don't need info on sensor X for now, stop sending it to me until I request it back", it only doesn't request data from that sensor anymore.
For example, one of the sensors my robot has is a battery meter. The discharge rate of the batteries I'm using is known, so I could implement a variable sampling rate. When the batteries are full charged, I don't need to know their voltage every second.
The way I was thinking with I2C was very similar to this, except I'd have a root microcontroller in the "box" responsible for packaging information and communicating with the PC through serial port. Somehow, the idea of not having a root microcontroller in the box is growing in my mind.
What I like about the USART is how easy it is to work with. I constantly use it do debug my applications (I send breakpoint info through USART instead of showing it on an LCD for example). But one thing I liked about the RS485 is that because it uses differential signaling, the devices can be implemented with uncommon grounds. Somehow this gives me the idea that more modularity and isolation between modules is provided. Another benefit is that I'll have two 14V DC motors running my car (the platform is an RC car... or better, an RC monster truck) at more or less 18A with spikes up to 50A, so noise may be a problem.
Very. Thank you for such detailed explanation.
As far as what I'll decide on using, I'm very biased on RS485. This is my Master's thesis, and although I wish I had more time to play around with the electronic side of it, I don't. RS485 libraries are provided with the development platform I'm utilizing (mikropascal), therefore reducing time spent on this part of the project.
I would say that RS-232 will be around for a while, don't panic. If and when the time comes that it is no longer available, the modules to convert USB to serial will probably work with the future version of USB that will be the standard.
In short, don't plan too far ahead with computers. There seems to be no risk as that what you want to do currently works, and the technology that will eventually replace what you have probably isn't out yet.
Windows? That's so sad. A potentially great robot incapacitated with a BSOD.
You're probably right, but I'll investigate the USB way either way. If it's proven to be as easy or just a little bit more complex to implement than RS232, then I'll go for it. I don't know.
Hehe, I knew you'd say something like that. I have nothing against linux, and it would be probably more efficient than windows. I don't need the graphic environment in the robot, but I think it won't hurt it too bad. The thing is that I'm not familiar with linux, and although this could be an excellent opportunity to learn a new OS, I have a very limited time to learn lots of other things. I have to focus on my research which is coming up with a robust navigation system for my rover, instead of dealing with OS problems. I know that if I go with linux I'll surely have problems with something related to the OS, either by OS inadequacy or my lack of experience with linux. I'm a seasoned windows developer, that's what I've been doing for the past
13 years, and if I go with Windows, I'm sure I won't have to deal with OS problems, and if I do, I'm pretty confident that I can "patch" it much faster than I'd do in linux.
Furthermore, by implementing the cpu completely decoupled from the sensor system, replacing the CPU and the OS is a much easier task.
I have a liberal policy about learning and obtaining new tools. It has been my experience that learning to use something inherently more aligned to your task is often faster in the long run.
How will you get the "robust" in Windows?
I'm a seasoned Windows *and* Linux developer and I am dubious that this is true.
I have a number of problems with Windows, 1st, it is unpredictable, no matter how good you are at your craft, you can not make a reliable solution. 2nd, unless you are using an old version, say 2K or 98, every time you materially change your system you'll have to call Microsoft and ask permission to use your computer again. Lastly, the granularity of control over the system is discouraging.
Because this project is potentially attractive to the military, I'm investigating the possibility of implementing this type of "soft" messaging protocol:
In the future, all (automomous vehicle) robotic projects that pledge government funds must comply with their framework. Their goal is to make a software control unit of vendor A to be able to control the robotic vendor of supplied by vendor B that is carrying payloads (sensors, guns, actuators, manipulators) of vendor C. They have recently field tested this concept and the framework specification is very detailed.
This doesn't invalidate at all the discussion RS485 x I2C, as they decouple the framework from the physical communication layer, hardware and OS.
I think that the exact method of serial "playout" from the PC is of less overall concern than the fact that you're using byte-oriented serial communications. Your current serial port can work now; RS-232 and RS-485 level-shifting is fairly easy with off-the-shelf parts; and serial USB-RS232 adapters can always be added.
Do consider a "middleware" controller that can be used as a master for slave controllers. Yes, at first it might appear that it's simpler to communicate directly with each subcontroller, but in the long run, I think a master controller is the easier and more flexible approach. You still have the ability to turn sensors on and off, but an advantage of a master controller is that the subcontrollers can be of any type, on any bus. You might use I2C for some, serial for others, SPI for yet some more, or simple pin signalling for still others.
Changes you make from the host can be more readily adapted by updating code in just one master, rather than updating all the subcontrollers. It also allows you to use some ready-made sensors that come with own bus, like I2C. You don't have to make anything special to use the sensor.
One other potential benefit of a master controller is that you can design a kind of message queue in it, similar to the one you have in Windows. The controller dispatches messages bidirectionally. This allows you to send and receive messages to/from sensors without regard to timing restrictions. You don't have to set the message speed to the slowest sensor.
1) Linux may be "scary" because it's new. The concepts and organization, however, are much more forward than M$. The only reason Windows seems simpler to use to most people is that it's what they know, and what you know is simple. In 30 days or less of working with linux, you WILL know the ins and outs of how it works. You wont be a guru, but once you grasp the basic concepts, it's very simplistic in nature and beautiful in form.
As far as patching goes...there are hundreds if not thousands of patches written daily for everything from the linux kernel to the calculator. Does this mean you NEED these patches? No...but history dictates that if a vulnerability is found that could actually be exploited, it's amatter of minutes to hours before a patch is available, as compared to windows where it has to make it's way around the internet, then the magazines, then the rpess releases, THEN microsoft will act.
2) A number of years ago there was an Aegis Cruiser (US Navy top of the line missile cruiser), and this ship had been running windows flawlessly for quite a while. Everything ran on microsoft products, even though
99.9% of the software was custom written by Naval programmers...but a seemingly innocuous system BSOD'd. This cause a catastrophic cascade of BSOD's to the point where they couldn't even reboot the ship. Literally. It had to be towed from it's Sea Trial several hundred miles back to port. As of my last update, they were running unix on those ships now. Something to think about. No matter how many times you patch, no matter how stable you THINK it is, it's unix that keeps the world running, and windows that lets the masses of farm animals in the workplace access those unix boxes.
I think you've missed a very important point with RS-485. Each RS-485 chip (like the LTC486) has send, receive, *and* direction pins. When the PC is transmitting, it needs to be able to assert the send direction pin *before* it starts transmitting. After transmission, it needs to deassert the transmit direrection pin.
It is tempting to just grab and extra RS-232 pin, like DTR, and use it to control direction. Unfortunately, the protocols for each USB to RS-232 convertes tend not to be published. It may not be possible for the operating system to guarantee that the USB message that changes the DTR pin value occurs within the minimum amount of time required for your sensors to send a response message.
I recommend that you use a root microcontroller to do the RS-232 to RS-485 conversion. It lets you carefully control the timing of the direction line.
Yup. Dedicating a mircocontroller to each sensor is a reasonable architecture.
It can be done, but you need to think through *all* of the timing issues.
RS-485 requires *some* level of electrical connectivity between the modules. Be sure to read up on several of excellent application notes on RS-422/485 that have been published (National has a bunch.)
You can "spoof" the direction line by putting a retriggerable one-shot on the line that responds to the transmit data. I've seen reference designs that do this. I think a more reliable means is to put a micro out there that relays the serial data after it properly sets up the data direction line for the RS485 driver, but that's just my opinion.
: > Here's what I'm very inclined to do: : > : > Have the PC (running windows XP) communicate with the "microcontroller's : > box" via USB, either a direct USB path or a usb2rs232 cable. Supposing I : > decide for the later, when the signal gets to the "box", a MAX232 converts : > it to TTL levels and send the signal to an LTC485 for example, that is : > connected to the RS485 bus.
: I think you've missed a very important point with RS-485. Each RS-485 : chip (like the LTC486) has send, receive, *and* direction pins. When : the PC is transmitting, it needs to be able to assert the send direction : pin *before* it starts transmitting. After transmission, it needs to : deassert the transmit direrection pin.
: It is tempting to just grab and extra RS-232 pin, like DTR, and use it : to control direction. Unfortunately, the protocols for each USB to RS-232 : convertes tend not to be published. It may not be possible for the : operating system to guarantee that the USB message that changes the DTR : pin value occurs within the minimum amount of time required for your : sensors to send a response message.
: I recommend that you use a root microcontroller to do the RS-232 : to RS-485 conversion. It lets you carefully control the timing of : the direction line.
: > In this case, the master will be the PC. Each sensor will have a dedicated : > microcontroller responsible for sensor data acquisition and packaging that : > data into a protocol known both by the slave and the master. This way, the : > master must only know the address of that sensor, since the "language" is : > standard for all sensors. I believe this architecture still promotes : > decoupling between the cpu and sensors, but eliminating the box's root : > processor eliminates one layer of communication.
: Yup. Dedicating a mircocontroller to each sensor is a reasonable architecture.
: > One advantage that I can think of: for example, if at some point the "brain" : > decides that it doesn't need information from a particular sensor, instead : > of sending a message to the root processor of the type "hey root, I don't : > need info on sensor X for now, stop sending it to me until I request it : > back", it only doesn't request data from that sensor anymore. : > : > For example, one of the sensors my robot has is a battery meter. The : > discharge rate of the batteries I'm using is known, so I could implement a : > variable sampling rate. When the batteries are full charged, I don't need to : > know their voltage every second. : > : > The way I was thinking with I2C was very similar to this, except I'd have a : > root microcontroller in the "box" responsible for packaging information and : > communicating with the PC through serial port. Somehow, the idea of not : > having a root microcontroller in the box is growing in my mind.
: It can be done, but you need to think through *all* of the timing issues.
: > What I like about the USART is how easy it is to work with. I constantly use : > it do debug my applications (I send breakpoint info through USART instead of : > showing it on an LCD for example). But one thing I liked about the RS485 is : > that because it uses differential signaling, the devices can be implemented : > with uncommon grounds.
: RS-485 requires *some* level of electrical connectivity between the : modules. Be sure to read up on several of excellent application : notes on RS-422/485 that have been published (National has a bunch.)
I see, from these feedbacks it sounds like it's easier to just put a PIC there to make the bridge between the max232 and the rs485 transceiver right? If this is easier, then I'll just to this way (lazyness is the mother of all [efficient] inventions).
Now, if the PC sends messages packed in a software protocol, does the root mcu need to have any intelligence? Does it need to bufferize that message prior to sending it down the rs485 bus?
Here's what I envision: PC needs to send a message to the steering servo to turn +20 degrees. It first packs that command into a packet (I will decide later which messaging framework I'm gonna use, but it will probably be JAUS), for example:
where @0001 is the address of the mcu that controls the steering servo, TURN is the command and +20 is 20 degrees to the right and # marks the end of the message. I just came up with this "protocol" as an example, don't pay attention to it.
Then the CPU streams this message to the serial port, connected to the root mcu. I guess there's no other way right? The mcu must parse that message, at least to get the device address. Once it has the device address, then it starts a message on the RS485 bus by activating device "0001", once it gets the ACK from it, it sends the message "TURN+20". I don't know if I really need to wait for a final ACK from the device, but let's suppose that yes. When the root mcu receives the final ACK, then it sends a message to the host cpu, something like "@0001-ACK"
Does it seem reasonable?
I'm going to order Jan Axelson's Serial Port Complete just to grab a few more concepts on RS-485, as I'll be spending a lot of time creating this bus in the next upcoming weeks. Any other good pointers on RS-485?
While I've never used a one-shot, I suspect that using a one will work. The issue is how fast the RS-485 chip can go from receive mode to transmit mode. At 115.2kpbs, a single bit is 8.68uS long. If the one-shot can trigger and get the transceiver turned around in .1uS (worst case), only
1.15% of the start bit is lost in turn-around time. That should not introduce too much additional error into the USART receivers that are sitting on the receiving end of the RS-485 bus.
Both the transmitting USART in the CPU and the receiving USART on the RS-485 bus, are probablly running a little off frequency and have some additional timing error. For example, a PIC16F688 running off its internal 8MHz oscillator, has ~1% oscillator error and 2.12% frequency counter error at 115.2kbps. USART frequency error on a PC is rarely documented. All of these errors can add up and eventually cause an increase intransmission errors.
I concur with your opinion. If you want to change bus speeds with the one-shot, you need to change the RC constant of the one-shot. If you use a microcontroller, not only can the speed be changed via software. it can do all sorts of other useful things like poll sensors, error checking, etc.
There are many ways to accomplish this. The three broad ways of doing this are:
Unbuffered: The microcontrolelr listens to the message traffic and figures out when to change the RS-485 direction line.
Buffered: 2 USARTS available: Hook one USART to the RS-232 line and the other RS-485 bus. 1 USART available: Add some steering circutry to allow the PIC to select whether it is listening to the RS-232 line or the RS-232 bus and another line to steer USART output to either the RS-232 line or the RS-485 bus.
I think the 2 USART method is best if your microcontroller has 2 USARTS. Since most Microchip PIC's only have 1 USART, a PIC based solution usually involves adding a little steering circuitry. The Unbuffered solution tends to be fragile in the sense that an error can cause loss and message synchronization and result in complete chaos. Adding one or two simple gates for steering is really a cost effective way of improving overall reliability.
Actually, the root processor is more concerned with the length of the send message. Since all devices are hanging off of the RS-485 bus, the device address is not really very interesting to it.
Jan's book is pretty reasonable; she spends approximately 100 pages talking about an RS-485 bus.
You should also avail yourself of some the excellent application notes that are available for RS-422/RS-485. Heres a list of application notes from my National Semiconductor directory: