mbeals 74 Posted April 20, 2014 Share Posted April 20, 2014 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? Quote Link to post Share on other sites
bluehash 1,581 Posted April 20, 2014 Share Posted April 20, 2014 @@spirilis can totally help you out with this. mbeals 1 Quote Link to post Share on other sites
spirilis 1,265 Posted April 20, 2014 Share Posted April 20, 2014 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. bluehash 1 Quote Link to post Share on other sites
SixSixSevenSeven 23 Posted April 20, 2014 Share Posted April 20, 2014 @@spirilis so there is no master/slave in CAN? Just a bunch of controllers filtering specific ID's? Quote Link to post Share on other sites
spirilis 1,265 Posted April 20, 2014 Share Posted April 20, 2014 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. Quote Link to post Share on other sites
spirilis 1,265 Posted April 20, 2014 Share Posted April 20, 2014 @@spirilis so there is no master/slave in CAN? Just a bunch of controllers filtering specific ID's? That is correct. Quote Link to post Share on other sites
SixSixSevenSeven 23 Posted April 20, 2014 Share Posted April 20, 2014 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 Quote Link to post Share on other sites
mbeals 74 Posted April 21, 2014 Author Share Posted April 21, 2014 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. Quote Link to post Share on other sites
spirilis 1,265 Posted April 21, 2014 Share Posted April 21, 2014 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. Quote Link to post Share on other sites
drkm 7 Posted April 23, 2014 Share Posted April 23, 2014 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... Quote Link to post Share on other sites
spirilis 1,265 Posted April 23, 2014 Share Posted April 23, 2014 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). Quote Link to post Share on other sites
dpharris 13 Posted April 24, 2014 Share Posted April 24, 2014 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. spirilis 1 Quote Link to post Share on other sites
mbeals 74 Posted April 24, 2014 Author Share Posted April 24, 2014 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. Quote Link to post Share on other sites
dpharris 13 Posted April 25, 2014 Share Posted April 25, 2014 Should be no problem over that short distance. We used ribbon cable for our prototypes. We use CAT5 now. Quote Link to post Share on other sites
JonnyBoats 40 Posted April 26, 2014 Share Posted April 26, 2014 @spirilis have you worked with NMEA 2000 which is basically CANBus for boats? Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.