I'm working on some devices that will talk to each other over CAN. The simple idea is to daisy chain essential signals between each device: power (+12V and ground), enable and CAN high / low.

Now, there main two problems I have with introducing this daisy-chaining set up are node addressing and bus termination. My current solution to these two problems are:

Current Solutions

Node Addressing

I'd have some sort of switch (analog switch, MOSFETs, something) break the CAN bus between the input connector and output connector of every device. They would be, at start up, configured to essentially only be "attached" to the input connector portion of the bus wiring. Thus, when all devices power up, node #1 (connected directly to the master node) will be the only node connected, and will be able to pull an address. Once a node pulls an address, it closes its bus wiring switches and lets the next node connect. The master keeps assigning IDs until it determines no other nodes are out there waiting.

Bus Termination

I have worked up a way to use extra pins in the connectors as a "sense" signal... driving a voltage to the output connector and seeing it if comes back (each device shorts the pins on their input connectors) to tell us if we are the end of the bus or not.. and whether we should apply termination.

What I'm Not Sure On / Want To Make Better

Using Analog Switches

The analog switch thing works conceptually, but the electrical aspect confuses me. For example, a lot of the bit rate charts you see for CAN are referenced by how long the network is... this makes total sense. Harder to drive a signal farther without repeating, etc. Now, my confusion is... would an analog switch, with it's inherently high (compared to raw wire) resistance be killing my maximum bit rate on the bus?

From calculating it out, if my bus was entirely 20AWG wire... adding in an analog switch with a really low Ron (lowest I've found is 0.3 ohms so far) to each node to provide the circuitry to do node addressing would be the equivalent of adding an extra ~30 feet of wiring for every node. Am I overestimating the impact these switches would have? The bus is already terminated at each end by 120 ohm termination resistors so it's not adding a ton in terms of the passive bus resistance... but calculating it in terms of how much extra wiring it appears as makes it seem bad.

Remote Node Sensing

Also, as far as sensing remote nodes.... I'd like to avoid an approach that relies on using dedicated pins in the connectors. Long story short, being able to ditch the sense pins lets me save money on a lower pin count connector AND it lets me switch to thicker wiring which means I can carry more power and support more end nodes. I'd also like to be able to slightly reduce the component count of the driving/receiving circuitry of the sense functionality which involves a lot of passives, zeners for clamping, discrete logic ICs, etc.

So... thoughts? :)

  • \$\begingroup\$ Capacitance between the CAN lines is a significant factor determing maximum length so watch out that your analogue switches don't add too much. \$\endgroup\$
    – Martin
    Dec 31, 2012 at 15:07
  • \$\begingroup\$ @Martin good point. Again, running the numbers, assuming a typical separation of about a millimeter or so, using 20AWG wiring.... these switches add around 250 - 350pF which translates to about 25 - 30 feet worth of "wire capacitance." Seems like resistance-wise and capacitance-wise... the switches are as good as adding in 25 - 30 extra feet of wiring in between nodes. \$\endgroup\$ Dec 31, 2012 at 15:17

4 Answers 4


Background Information

I have used CAN a few times now for multiple devices distributed over a physically small area, like within a few 10s of meters. In each case, the CAN bus was internal to the system and we could specify exactly what the protocol over CAN would be. None of these systems had to, for example, interface with OBDII, NMEA2000, etc, where a specific protocol was already defined. One case was a large industrial machine that required lots of distributed sensors and actuators. The outside world interface just dealt with the overall operation of the machine. How the controller got the sensor information and caused the actuators to do stuff was a internal implementation choice that we happened to use CAN for. In another case, a company needed a good way for their customers to control multiple (up to a few dozen) of the gizmos they make within a single larger system. In this case we specified CAN as one communication means and documented the protocol. This protocol would be implemented by the controller of this system, but not surfaced to the end customer which bought this system as a whole and communicated with it thru different means at a higher level.

The EmCan solution

I have converged on a way of dealing with this over several implementations. I am now in the middle of two more such implementations, and this time I decided to use the previous experience to create a formal spec for a infrastructure layer immediately above CAN. CAN is a well designed protocol as far as it goes, and is directly implemented in a number of microcontrollers nowadays. It seems a natural way to connect multiple little devices over a limited physical distance as long as the data rate isn't too high. Basically, it can do everything you probably would have used RS-485 for 20 years ago, except that more protocol layers are specified, the specification makes sense, and hardware implementations are available built into low cost microcontrollers.

The result of this is what I call EmCan (EMbed CAN). I am slowly filling out the formal protocol specification as I migrate code from the previous implementations, generalize the concepts a bit, and make re-usable firmware modules where the EmCan protocol code can be used without change accross a variety of projects. I'm not really ready to officially publish the spec yet and provide the reference implementations, but you can look at what is there to see where things are heading. The current document is a work in progress, as it itself says.

So far I have PIC 18 and dsPIC 33 implementations of the EmCan device side, a stripped down host implementation for PIC 18, and a more full (more things handled locally) implementation for the dsPIC 33. Everything documented in the current version is implemented and seems to be working. I am working on the byte stream interface right now. I did this before in one of the previous systems, but it was more tied into the application and not a nice separable layer like EmCan.

The issue with a switched load

I think trying to switch the CAN bus with FETs or analog switches is a really bad idea. The main reason for the bit rate versus length tradeoff is not the total resistance of the cable, but the round trip propagation. Look at how CAN detects collisions, and you will see this mechanism assumes signal propagation from one end to the other within a fraction of a bit time. The CAN bus needs to be kept a transmission line. For most implementations, such as when using the common MCP2551 bus driver, the characteristic impedance should be close to 120 Ω. That means a 120 Ω resistor at each end of the bus, so any point on the bus looks like a 60 Ω load.

How EmCan fixes this

EmCan solves the node address problem without requiring special hardware. For details, see the EmCan spec, but basically, each node has a globally unique 7 byte ID. Each node periodically requests a bus address and sends this ID. The collision detection mechanism will guarantee that the bus master sees only one of these requests even if multiple nodes send a address request at the same time. The bus master sends a address assignment message that includes the 7 byte ID and the assigned address, so at most one single node is assigned a new address at a time.

If you are interested in this concept and are willing to discuss details of your system, talk to me. My biggest fear right now is specifying something that will be awkward later or prohibit certain usage that I hadn't considered. Having another implementation in progress as the spec is being finalized would be good for spec development and to test out the reference implemenation if you plan to implement it on Microchip PICs.

  • 1
    \$\begingroup\$ Nice advertisement. ;) All jokes aside, the device family is already locked down (NXP LPC17xx and NXP LPC11Cxx) so I'm not able to use any of your code but I do like the idea behind node address assignment... as it transposes the solution from hardware to software entirely.. which has a faster iteration cycle should I screw something up. I'm not sure how I feel about your protocol... I don't think it's based, but there's also native CANopen drivers for my MCU family so it's a tough trade-off. \$\endgroup\$ Dec 31, 2012 at 18:11
  • 2
    \$\begingroup\$ I'm not trying to come off like a dick here, but the first two paragraphs just seem very extraneous to me. Talking about your experiences.. that's all fine and good, but it has little to do with my actual question. You explaining that you have been working on a lightweight protocol designed to run over CAN and how it could potentially solve one of my problems would be far more succinct, specific and applicable to my question. Also, if you're serious about getting feedback on EmCan, you should stop by the chat sometime. \$\endgroup\$ Dec 31, 2012 at 20:15
  • 1
    \$\begingroup\$ I mean, if you want to sit at home in front of a wooden table with a plain desk light and some pencil and paper and work out that specification... by all means, go for it. If you want fast feedback with a more free exchanges of ideas... chat is a good place to be. :) \$\endgroup\$ Dec 31, 2012 at 21:48
  • 2
    \$\begingroup\$ Looking at your protocol spec I dont see much difference to the CANopen specs which have been around for 20 years, Im interested as to the motivation behind this./ \$\endgroup\$ Jan 2, 2013 at 13:06
  • 1
    \$\begingroup\$ I have performed an edit to clarify, titles like above allow users to jump to what they are interested in. The titles are are quick suggestions. If someone does not want that info they can just skip to the section they are interested in, let me know what you think. Also, we do often goof off in chat, that is what it is there for, whatever we want to discuss but we often also have technical exchanges, more often then you might think, and if you want a business only chat it can be made. I would enjoy it if you dropped by some, but it is my attempt at helping grow a community. \$\endgroup\$
    – Kortuk
    Jan 2, 2013 at 21:52

Rather than switching the CAN bus in order to achieve sequential addressing, consider switching the power bus in the same way? Each node has Vin and Vout. Once a node is powered, it receives an address, then enables Vout such that the next device in line will be powered. This might add a FET per board, but eliminates the analog switches and keeps the risk of strangeness on your CAN bus low.

You don't mention what the enable pin in the daisy chain is for, and whether it is logic level, but this could be used instead of power in a similar way - use it to sequence address assignment at powerup, then have each node just repeat the logic level seen on its input to replicate a solid wire after everyone has an address.

I haven't seen any good automated ways to manage bus termination; it generally requires prior knowledge of the bus topology. If your harness were fixed length, the best place to do termination is in the harness itself. If the number of nodes is unknown, you'll likely want to make a special termination connector that goes on the daisy_chain_out of the last board in the chain. It then becomes a requirement that there is always something connected to the daisy_chain_out port -- either another node or the special termination resistor.

Hope any of the above was helpful.

  • \$\begingroup\$ I like your approach but I think switching the enable signal, rather than the power itself, should keep things a lot lighter, cooler and simpler. I wouldn't have to worry about actually pushing all the current for the whole chain through a single FET that way. The auto-termination is still a few issue but I'm thinking that I could load the enable line in such a way that if a downstream device is connected, it always pulls at least 10mA, let's say. I could then fashion a simple current sense circuit to determine if there is a device connected. \$\endgroup\$ Dec 31, 2012 at 17:05
  • \$\begingroup\$ Agreed, the enable approach has benefits--it wasn't clear from your description if it was "up for grabs" or not. The problem with auto-termination in general is that you're back to actively switching things onto the bus. Possible, yes. Recommended, not really. \$\endgroup\$
    – HikeOnPast
    Dec 31, 2012 at 17:45
  • \$\begingroup\$ Well the termination should conceivably settle very quickly... the way I have it now, power is supplied to the auto-termination circuitry even if the device isn't enabled. It should settle as you add or remove devices while the car isn't on... so that when it does turn on, everything is ready to go. \$\endgroup\$ Dec 31, 2012 at 17:53

Tricky question to answer without knowing how many nodes, cable lengths, baud rate, bus loading etc. but in general, CAN does not really lend itself to having a 'variable' cable length and variable number of nodes as (I think) you require.

I would advise against adding any form of 'switch' in the CANH and CANL signals as any type of failure here would destroy comms from everything downstream of this.

Have you considered fault-tolerant CAN? It uses a slightly different physical layer chip (NXP TJA1054 as an example) but the network termination is placed at each node, not at the extremities of the bus. The drawback is a maximum baud rate of 125k and about 100m of cable length, as it was designed for automotive use.

Your other problem of assigning node IDs dynamically - a solution already exists called 'Layer Setting Services' and is defined in the CANopen spec DS-306. Of course both master and slave have to support this feature.

  • \$\begingroup\$ Well the variable node count is a required feature. Fault-tolerant CAN seems to be, by way of reading datasheets for fault-tolerant CAN transceivers, designed for a fixed number of nodes... which kind of throws it out the window. The fault-tolerant CAN transceivers also seem to have a way bigger footprint than regular transceivers which wouldn't fit on the master node board. As far as the "switch" idea, I've foregone that. I'm concentrating on making sure termination is settled/in place before any device on the bus tries to talk. \$\endgroup\$ Jan 2, 2013 at 13:32
  • \$\begingroup\$ If you absolutely need a varying number of nodes and a cable of unknown length then my feeling is that CAN is not the solution. However, good luck to you :-) \$\endgroup\$ Jan 2, 2013 at 16:39
  • \$\begingroup\$ I feel like you'd be hard-pressed to suggest an alternative bus technology that operates as reliably, and simply, as CAN does for multiple off-board nodes. I'm certainly not an expert, but with CAN being used over distances of hundreds of meters, with hundreds of devices, in industrial and automotive settings, etc etc... it seems like it's more than capable of having a little variance. \$\endgroup\$ Jan 2, 2013 at 16:42

Auto Discovery

CANOpen is an example of a protocol that implements device discovery.

The basic approach is this: Every node gets assigned globaly unique identifier at production time. call it GUID. this can be derived from some unique serial number you get from the silicon, or a unique number assigned during some post production configuration step.

Once all devices are connected to the bus, the bus master performs a discovery step. This step can be triggered when a new device is added because the new device sends a specific "hey I'm new here" message, or it can be triggered by the user.

The master then sends messages on specific CAN IDs reserved for the discovery operation.

It divides the address space into two sections A and B and asks "are there any devices with a GUID in range A" and the devices in that range will then reply with an RTR message indicating that yes, there exists at least one. The CAN collision protocol will guarantee that the messages do not interfere with one another when there are multiple devices that respond simultaneously.

If the master gets a hit for a section of the address space it then divides that section by two again and repeats the process. eventually the section size will be 1 meaning that there exists a device with exactly that GUID.

The master can then assign an ID to the device with that specific GUID.

If section A gets no response, the master knows there are no devices with a GUID in that range, and it moves on to ask for section B.

Once the entire address space has been covered the master steps back and the normal bus operation proceeds.

NOW... since can frames contain at most 8 bytes it is difficult to fit a complete GUID range in those bytes so you have to use multiple messages. It CANOpen I believe it is done with one message that sets the low address and another message that sets the high address and solicits the response. you could also use a GUID and a mask. if your GUIDs are 7 bytes you could use the 8th byte as a mask indicating how many of the most significant bits should match to solicit a response.

Auto Termination

This one is a little more complicated. if you need to preserve the signal quality of your bus, the best solution is simply to provide termination resistors in external housings that the user can plug into the first and last device to terminate it.

If this process needs to be automatic you can use special plugs that have an extra contact to detect when the plug is left open so you can do termination yourself. With one contact like this that closes when the plug is unplugged and is open when it is plugged, you can add a 120 ohm resistor between can High and can Low.

If you don't have the a plug with those kind of contacts you would need some other way to determine if you are the last device in a series of devices. You can use extra contacts in the plug to code that information like you already suggested and then switch a relay or something to add termination.

If I am not mistaken there was a can driver that did automatic termination but i don't remember the part number.

Again, It's not uncommon simply to ship two termination plugs with your product.


Not the answer you're looking for? Browse other questions tagged or ask your own question.