Controller Area Network (CAN) is a communication protocol that utilizes differential pair communication for reliability and noise reduction, and has a fixed bit arrangement so that each packet can contain the maximum of 8 bytes. The physical protocol of the CAN bus is designed so that if there are non-conflicting IDs, one is guaranteed to win if two nodes attempt to communicate at the same time. If two of the nodes attempt to communicate on the CAN bus with identical IDs at the same time, it will quickly lead to a condition known as bus-off, where one or both of the nodes essentially stop responding to packets until a fixed correct number of packets is received.
For this example I am using an LPC1788 NXP microcontroller with several LPC11C24‘s all communicating on the same CAN. The LPC1788 is the center of a star topology of LPC11C24’s, which behave in a master-slave relationship. The LPC11C24 has a built-in CAN transceiver, but the LPC1788 needs an external transceiver to communicate (in this case we are using an NXP TJF1051T). For this particular application, all CAN packets are using the extended data frame to maximize the amount of data transmitted per transaction. A clear breakdown of the fields used in this extended CAN frame can be seen below (As shown in this Application Note AN-1123, page 6).
I decided during my implementation of the master-slave system to use the 11-bit Standard Identifier for commands, and the 18-bit Extended Identifier for unique IDs used for addressing a node. Data bytes vary for each command.
Striving for Uniqueness
To avoid the condition of bus-off, I have implemented a few different techniques to ensure that each node on the bus has a unique ID when communicating on the CAN bus. The first technique is to use a simple pull-up resistor on a few GPIO lines (configured internally in pull-down mode) so that each node will have a physical jumper which should be unique for the entire system. The second technique is to retrieve the Unique ID that each LPC11C24 has built into it from the factory.
Makeup of the Extended ID
When each node powers on, it first retrieves the Unique ID using the method described above. The hardware jumper positions form the highest order bits in the Extended ID. A summation of the 128 bit Unique ID, in 4 byte groups, form the lower 14 bits of the Extended ID. For this application, even if the hardware jumpers are missing, there should be sufficient uniqueness in each node’s packet to virtually guarantee that the bus-off condition won’t occur.
Negotiation with the Master
On a fairly regular interval, the Master sends a CAN packet to all nodes instructing them to reply immediately with their Unique ID. Since multiple nodes are receiving this multicast packet, all of them respond at once. Since each node’s Unique ID is unique, after enough bits are sent, there is a winner for the arbitration that occurs in all connected CAN transceivers. After a fixed length of time, all nodes that failed arbitration the first time try again.
Detection of power off or reset events using the Unique ID
Eventually the Master receives a reply from each node, and at this point, I reassign the ID for each node using another CAN packet. When each node receives this customized packet, it re-configures the CAN interface so that it only responds to commands directed specifically at it (in the form of “Command | my_id” ). On all subsequent heartbeat packets, each node replies with the ID assigned to it from the Master. In this way, we can not only guarantee that the bus-off situation doesn’t occur, but we have added the ability to detect when a node resets.