Jump to content
43oh

Recommended Posts

I'm starting to work on the motor controller for my robot project again and am thinking about switching to can bus for inter-module communications.

 

Does anyone have experience working with can bus and the msp430? Is it a major PITA?

I built a boosterpack to enable this -- http://store.43oh.com/index.php?route=product/product&path=64&product_id=127 -- only 1 left but I have a stock of 10 PCBs waiting to be soldered up if you need more.

 

The long and short of it is, CAN has two components, a lot like Ethernet -- a "controller" (think Ethernet MAC, where all the logic is) and "transceiver" (think Ethernet PHY, doing the differential signalling over the actual bus).  Many higher-end MCUs and CPUs have the CAN controller but not the transceiver; the MSP430 has neither.

 

So the Controller is the part you care about most since it's what you'll be coding against.  Microchip makes the MCP2515, an SPI CAN controller featured on my boosterpack board.  I wrote a C library to enable I/O with this -- https://github.com/spirilis/mcp2515

To make it work on a bus you need a transceiver; my board features the NXP TJA1051T/3, a transceiver that takes both 5V and 3.3V voltage rails (5V for driving the CAN bus, 3.3V for the CMOS I/O levels for the CAN controller-to-transceiver link and the one input an MCU can drive manually to disconnect the transceiver from the bus internally).  TI makes a lot of CAN transceivers, some of which work at 3.3V, and probably other vendors do too.  You often find 3.3V controllers hooked to a 5V transceiver with a level shifter at least on the CAN_RX line, but this TJA1051T/3's V_IO rail means the level shifter's built into the transceiver.

 

Like how Ethernet has a standard "MII" or "RMII" as a link between its MAC and PHY, CAN has a pair of unidirectional lines; CAN_TX and CAN_RX for the controller to communicate with the transceiver.

 

CAN bus is probably the best tool for what you're thinking IMO, although that's something you'd have to decide; if it's all on one PCB or across relatively short distances I2C may work too, but CAN is designed for robust controller-to-controller communication with guaranteed latency during error conditions.  Used for automotive signalling (the original application it was designed for) and other industrial control stuff.

 

The MCP2515 datasheet has a lot of details that will give you a tour of CAN's nitty gritty configuration stuff - http://ww1.microchip.com/downloads/en/devicedoc/21801d.pdf

 

I read this book before embarking on my boosterpack project, and frankly I wasn't too impressed with the cost of the book w/ respect to content (it's mostly a Microchip PIC advertisement)- http://www.amazon.com/Controller-Network-Projects-Dogan-Ibrahim/dp/1907920048/ref=sr_1_1?ie=UTF8&qid=1398021005&sr=8-1&keywords=controller+area+network

Might find some more out there.

 

The gist of it is:

 

CAN is a differentially-signalled bus (referenced around 5V, but the actual signal levels just need to be some +/- level away from each other) with multi-master, multi-slave operation and arbitration that works somewhat similarly to I2C.  It operates up to 1Mbps (<40m total bus length) and can scale accordingly by lowering the bitrate.  Its line should be laid out in a Bus topology, with a well defined termination at both ends (using 120ohm terminator between the CAN_H and CAN_L lines at both ends) and nodes should "tap" into it along the bus without any significant branch length between the bus and the device.

 

Messages on a CAN bus have no origin or source address, just a destination address (again, a lot like I2C) -- they're either 11-bit Standard IDs or 29-bit Standard+Extended IDs.  The payload of the message can be 0-8 bytes long.  The typical paradigm is a controller enables a "filter" defining what IDs they're interested in hearing about (typically an ID + bitmask, like a subnetmask in IPv4 lingo).  The controller will receive all messages but only notify the MCU about those matching its filters.

 

Each message has an ACK/NACK time slot at the end for determining if the message was successfully heard by any other CAN controllers.  That actually means that if you have just 1 node on the CAN bus, and it sends a message, it will register an error because there was no other device out there to acknowledge successful receipt & CRC of the message.  If any controllers detect a signal sequence that seems in error, there is an "error packet" procedure that is initiated where all controllers participate; the length of this error packet is such that it will drown out any other traffic on the network, resulting in its sender noticing an error condition on the bus and internally incrementing a TX error counter (when that counter exceeds 255 usually, the standard says the transmitter needs to disconnect itself and watch the bus for signs of stability before reconnecting).  The length of this error packet is also limited such that once it's overwith, the bus is in a stable state; that's how the "maximum latency on error" is implemented.

 

Sounds like a lot but it's a robust protocol.  Power consumption wise, I wouldn't call it a "ULP" protocol but the MCP2515+TJA1051T/3 standby power consumption at idle is probably in the ~5-10mA range; this is with the MCP2515 driving a 16MHz XTAL.  Its power consumption will surge during transmit due to the current passing through the termination resistors on either end; think upwards of 75mA for each pulse.  I doubt it'll contribute a huge amount to the power drain in any motor-hungry applications.

 

I think the general paradigm is that individual controllers will have a set of message IDs corresponding to their functions; e.g. a controller might listen for a specific ID addressing it to change speed or torque, but likewise it may transmit its own messages on a different ID broadcasting its power consumption, voltage, etc.  So you can have other nodes listening and relaying information for reporting/UI/RF communication purposes.

Link to post
Share on other sites

Also another protocol used more for lower-power and lower-speed applications is LIN (Local Interconnect Network - http://en.wikipedia.org/wiki/Local_Interconnect_Network ); this can be implemented with a standard USCI_A UART port I believe, but still requires a sort of transceiver chip or some sort of transceiver hardware to adapt it.  It's a single line (referenced to GND), not differential, and I think in automotive applications you basically have a few LIN busses "branched off" of the main CAN bus with MCUs that talk both protocols.  Then low-cost stuff like steering wheel buttons, lighting controls, lighting relays, etc. are implemented with cheaper non-CAN-compatible MCUs.

 

I don't have any personal experience with it but I might play around sometime and make a boosterpack for it.  Sounds like something better suited for the MSP430's.  CAN would be a better choice for longer-distance links where noise & speed is a concern though.  Sounds like LIN is single-master, <=16 slaves.

Link to post
Share on other sites

That is correct.

I so going to have to take a look at this for the future.

 

LIN I was already slightly interested in myself after seeing it featured on hackaday yesterday. Someone built a LIN bus signal injector, you can see near each wiring triplet there does appear to be an additional chip present which I would presume is the transceiver: http://hackaday.com/2014/04/19/a-lin-bus-signal-injector

Link to post
Share on other sites

wow thanks @@spirilis.  Lots to digest there.

 

The more I look into it, the more I think CAN is the way to go.  

 

My goal is to make this modular.  I want to be able to design a battery pack or sensor node that I can swap in without having to rewrite the firmware on the main controller.  I also want the modules to be able to work independently from the master controller.  For instance, if the motor control board wants to know how much juice is left in the batteries, it can ask that module directly instead of relaying it through the master... or a sensor node can broadcast a "stop the motors NOW" message and have the motors react without the sensor node having to know the actual address of the motor controller.

Link to post
Share on other sites

wow thanks @@spirilis.  Lots to digest there.

 

The more I look into it, the more I think CAN is the way to go.  

 

My goal is to make this modular.  I want to be able to design a battery pack or sensor node that I can swap in without having to rewrite the firmware on the main controller.  I also want the modules to be able to work independently from the master controller.  For instance, if the motor control board wants to know how much juice is left in the batteries, it can ask that module directly instead of relaying it through the master... or a sensor node can broadcast a "stop the motors NOW" message and have the motors react without the sensor node having to know the actual address of the motor controller.

Yup, I think CAN gets you that.  FWIW there is a packet type called "remote request" where the sender sends it to a certain ID, and if a node is listening for that, it will acknowledge the request by turning around and sending a data packet to that same message ID with a payload.  Somewhere I read the use of that feature is "deprecated" but I don't know, I see it implemented at least in the MCP2515 as well as the Tiva-C built-in CAN (controller) peripheral.  It's a standard feature whether auto mfr's use it or not.

Link to post
Share on other sites

While again not low power, you could use RS-485 to accomplish what you want. But you would need to set up the protocol handling yourself. 

 

A reasonably low power (and low speed) option is to invert the output of a regular UART and run it on a single wire using a tri-state driver. This will consume very little power and allow you to do multiple drops (since you would use the gate of a fet to trigger the reciever). But again you would need to impliment a master-slave protocol if you want to be passing information both ways. 

 

I don't have much experience with CAN, from what I understand its a pretty powerful protocol. Is the barrier to entry high spirillis? I may have a work related project involving CAN in the not so distant future... 

Link to post
Share on other sites

While again not low power, you could use RS-485 to accomplish what you want. But you would need to set up the protocol handling yourself.

 

A reasonably low power (and low speed) option is to invert the output of a regular UART and run it on a single wire using a tri-state driver. This will consume very little power and allow you to do multiple drops (since you would use the gate of a fet to trigger the reciever). But again you would need to impliment a master-slave protocol if you want to be passing information both ways.

 

I don't have much experience with CAN, from what I understand its a pretty powerful protocol. Is the barrier to entry high spirillis? I may have a work related project involving CAN in the not so distant future...

I kinda think the biggest barrier-to-entry is understanding the timing mechanism. But if you have a reasonable library or codebase that does it for you (my mcp2515 C lib basically does this), the rest is .... really not that complicated. Just choose message IDs for all your functions and fire away the packets.

 

I suppose when going hardcore trying to tease higher speeds out of long distances it would pay to have a 'scope to analyze the CAN signals and maybe tune the propagation segment length/etc. but you can always dial back the speed.

 

Overall though still more hardware than your UART solution and probably a multidrop RS485 (never used them, just read about it).

Link to post
Share on other sites

A word of caution:  the specifications for bus-speed/distance usually overstate the performance.  The actual performance will depend on a wide variety of issues such as line capacitance, drive loading, etc.  While one can push it to the maximums, this often needs sophisticated equipment.  

 

That being said, I am part of a project to use this for model railroading which is a noisy environment, and we think that CAN is close to perfect for this because of all its built-in hardware supported error detection and correction.   [We found the 8-byte data-part limiting, though.]   For our bus-speed of 125k baud, we have some rough guidelines for success*:

  • Maximum CAN segment cable length is 1000 ft / 300m
  • The max cable length is reduced by 20 ft / 6m for each physical node attached to the segment
  • The max cable length is further reduced by double the length of each stub cable attached to the segment
  • There may never be less than 1 ft / 30cm of cable between nodes, nor between a stub connection and a node.
  • This implies that there is a limit of about 48 nodes on a single segment. 

Hope that helps.  

David

*See: CanPhysicalS.pdf and CanPhysicalTN.pdf  for details and lots of references.  

 

Link to post
Share on other sites

While again not low power, you could use RS-485 to accomplish what you want. But you would need to set up the protocol handling yourself. 

 

 

I considered rs485....but you are right, I would still need to create my own protocol or use something like modbus.  Certainly do-able, but sort of a pain.  The thing I liked about the CAN setup is that the CAN controller can handle all the message buffering and filtering internally, and does so at a pretty high speed.  So I can run a high speed bus without having to devote a large number of MCU cycles to filtering out messages I don't care about.

 

This is only for a small, wheeled robot, and the total cable length will be well less than 16", so I'm not super worried about stretching the bus past it's limits.  I am thinking about running power and data over a single ribbon cable to simplify hookup and layout....and that might make it a touch noisier.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...