CAN BUS Tutorial
This article is under construction
CAN BUS (Controller Area Network) is a very deterministic BUS heavily used in the automotive industry. It is a half-duplex BUS, that operates using a pair of differential signals. Typically, the speed standards are 100K, 250K, 500K or 1Mbit.
CAN BUS may have several tens of controllers on the same BUS and you can typically go relatively long distances such as 10 meters without compromising the speed or reliability. The message id of each message can address other nodes on a CAN BUS (more on this later).
CAN BUS Frame
A CAN frame may contain 50-114 bits which includes data bits like message id, the real payload (0-8 bytes), and some CRC bytes. After the hardware captures the CAN frame, it stores it into a simpler frame that contains frame information, message id, and the data bytes.
A CAN frame may contain one of two message id types :
| Frame Information | Message ID | 0-8 bytes | | RTR, Msg ID Type, Byte Count | 11 or 29-bit | 0-8 bytes |
- RTR : Remote transmission frame
- This bit indicates to the destination that an empty message is being sent.
- You can consider this "PING" or a signal to send something back to the source
- Message ID Type
- This bit (when 1) indicates it is a 29-bit ID or else an 11-bit ID
- Data bytes
- The payload can be zero bytes, or up to full 8 bytes in a CAN frame.
A message ID of a CAN frame is very unique in the sense that it is used as a priority on the physical BUS. A lower message ID has higher priority since logical 0s are recessive and they override logical 1s on the BUS. This is a key feature of the CAN BUS because you can guarantee that your message will get across above everyone else if it has the highest priority.
Another property of the message id is that each node on a CAN bus MUST acknowledge a chosen message id for a message to be successful. If a message is not acknowledged, retransmissions will take place by the hardware, which can eventually lead to "BUS-OFF" state as given by the CAN specifications.
Unlike other BUSes that can be up and running without any external hardware, CAN BUS REQUIRES a voltage transceiver that converts logical Rx/Tx pins into a single differential pair wire that is hooked up on the CAN BUS.
Multi-node CAN BUS
Before the CAN BUS is used in an application, it helps to know some basic characteristics of the BUS :
- No two nodes shall send the same message ID
- Doing so will cause two nodes to cause collisions on the BUS, since arbitration will not take place.
- No two nodes shall acknowledge the same message ID
- Doing so will cause two nodes to acknowledge the same packet.
So knowing the above requirements, there is a dilemma for us:
- How can two nodes send a message to another node using the same message id ?
Message ID Design
What we can do is split the message id into separate fields so each node on a CAN bus can address any other node:
| 4-bit destination id | 4-bit source id | 3-bit message id |
What we have done now is added the capability that multiple nodes can speak to each other, and whoever has the lowest source id has the highest priority on the CAN BUS. So suppose that we are a "lights controller" on a vehicle's CAN BUS, then we can specify the following standard :
- Lights Controller ID: 5
- Message ID : 1 = Lights command
- Message ID : 2 = Clear Faults
With this in mind, we would tell our CAN controller to accept the following range of all message ids:
| 0101 | xxxx | xxx |
Therefore, our CAN acceptance filter is 0x280 - 0x2FF. If we do this, anyone can send us a message, and no two nodes will send the same message id. Likewise, we can send a response message back to anyone using a unique message id.
OBDII standard uses CAN BUS to communicate to the ECU. You can connect a CAN controller to an OBDII port easily by using an OBDII to Serial cable. Since this kind of cable doesn't convert the CAN voltage signals to logical signals that a microcontroller can understand, you would also need an MCP2561 based transceiver which would allow your controller to be interfaced to an OBDII port.
The block diagram would be as follows :
| Car's computer --> CAN BUS --> (OBDII Port) --> MCP2561 --> Your CAN controller |
CAN on LPC17xx
LPC17xx or the SJ-One Board has two CAN controllers and the Sourceforge development package' projects contain the CAN driver. Therefore, you can connect to two separate CAN BUSes, however, some of the internal hardware is shared between the two CAN controllers. Note that a CAN controller needs to setup its filters such that it can generate ACKs and accept the chosen messages when another controller sends the specific CAN messages. The LPC17xx CAN allows you to setup your CAN acceptance filters in one of several ways :
- FullCAN message reception
- Standard (11-bit) ID list
- Standard ID range (low to high)
- Extended (29-bit) ID list
- Extended ID range (low to high)
Also note that the space for these filters are limited to 2Kb internal RAM, however, this is enough to setup 512 individual 29-bit addresses or 1024 standard message IDs. Generally, if you exhaust this space, you are doing something wrong or your CAN BUS protocol is badly designed.
Using FullCAN is one of the ways to setup a CAN message acceptance filter, and you have to know the exact id of each message. The LPC FullCAN is a way for us to specify specific message IDs and these messages are stored straight to RAM without our software getting interrupted! This is a neat away to automatically accept and store messages without using CPU cycles. There exist a means to test if the HW has updated a specific message and you can even get interrupt notifications for up to first 64 FullCAN messages.
The hardware filters (apart from FullCAN) provide second means of accepting specific message ids. Furthermore, you can also specify a range, for example, you can program it to accept all messages from standard 11-bit id range 0x100 to 0x200. The CPU can or will get interrupted upon accepting a message, and then your software can queue or process the incoming message. The hardware filter also provide a way to setup 29-bit message id acceptance filter.