Am I on the Right Track – CAN Protocol ?

Thread Starter

Embededd

Joined Jun 4, 2025
178
I ran some CAN example code on my Arduino setup, and it worked as expected. Now I'm trying to understand the CAN protocol in depth instead of just using the example code.

I've written down my understanding of how I think it works. I'm fairly confident in my reasoning, but I'd really appreciate a second opinion from someone with more experience working with CAN. Even if my understanding is mostly correct, an experienced person @Papabravo might catch something I've overlooked.

CAN is a communication protocol mainly used in the automotive industry and industrial automation. It uses two communication lines, CAN High (CAN_H) and CAN Low (CAN_L). It works using a differential signalling mechanism, which makes communication more reliable in noisy environments.

On the CAN bus, we have two logic states:

  • Dominant bit (0)
  • Recessive bit (1)

When a sender node wants to transmit a dominant bit (0), it drives CAN High to about 3.5 V and CAN Low to about 1.5 V. The receiver measures the voltage difference between the two lines (about 2 V) and recognizes it as a dominant bit.

When the sender wants to transmit a recessive bit (1), both CAN High and CAN Low remain at approximately 2.5 V, so the differential voltage is almost 0 V. The receiver recognizes this as a recessive bit.

One important property of the CAN bus is that any node can force a dominant bit onto the bus, but no node can force a recessive bit if another node is transmitting a dominant bit.

CAN is a message-based protocol, which means messages are identified by their identifier (Message ID) instead of the destination node address. Any node can transmit a message, and every node receives it. Each receiver decides whether to accept or ignore the message using its acceptance filters and masks.

Whenever a node wants to transmit a message, it must follow the CAN frame format.

A CAN data frame contains the following fields:

  • Start of Frame (SOF)
  • Arbitration Field
  • Control Field
  • Data Field
  • CRC Field
  • ACK Field
  • End of Frame (EOF)

Normally, when no node is transmitting, the CAN bus remains in the recessive state, with both CAN High and CAN Low at approximately 2.5 V.

To begin communication, the transmitting node sends the Start of Frame, which is one dominant bit. Therefore, the bus changes from recessive to dominant, indicating that a new message is starting.

The next field is the Arbitration Field, which contains the Message Identifier and the RTR (Remote Transmission Request) bit. This field is used for bus arbitration.

If more than one node starts transmitting at the same time, they all transmit their identifier while simultaneously monitoring the bus. Since dominant (0) always overrides recessive (1), the message with the lowest numerical identifier (highest priority) wins arbitration.

For example, suppose two nodes transmit the following identifier bits

Node A : 10011...

Node B : 10010...

Both nodes transmit the same bits until the last bit shown. At that point, Node A transmits 1 (recessive) while Node B transmits 0 (dominant). Since the bus becomes dominant, Node A realizes that the bus does not match what it transmitted, so it immediately stops transmitting and becomes a receiver. Node B continues sending the rest of the message without interruption.

This arbitration process only occurs during the Arbitration Field.

The next field is the Control Field. One important bit is the IDE (Identifier Extension) bit, which indicates whether the frame uses the Standard 11-bit identifier or the Extended 29-bit identifier. The Control Field also contains the DLC (Data Length Code), which specifies how many data bytes are present in the Data Field. In Classical CAN, the DLC can indicate 0 to 8 data bytes. For example, if the DLC is 2, then the message contains two bytes of data.

Next comes the Data Field, which contains the actual information being transmitted.

After that is the CRC Field. The sender calculates a 15-bit CRC from the transmitted message and appends it to the frame. The receiver performs the same CRC calculation on the received bits and compares the result with the received CRC value. If they do not match, the receiver detects a CRC error, indicating that the message was corrupted during transmission. After the 15 CRC bits, there is a CRC Delimiter, which is one recessive bit. It simply marks the end of the CRC Field

The next field is the ACK (Acknowledgement) Field, which is used to indicate that the message was received correctly. The transmitter sends a recessive bit in the ACK Slot. If at least one receiver successfully receives the frame without detecting any errors, it overwrites that bit with a dominant bit. The transmitter monitors the ACK Slot, and if it reads a dominant bit, it knows that at least one node received the message correctly. It does not know which node acknowledged it. The next bit is the ACK Delimiter and It simply marks the end of the ACK Field and separates it

Finally, the transmitter sends the End of Frame (EOF), which consists of 7 recessive bits, indicating that the frame has finished and the bus returns to the idle (recessive) state.

Sorry for the too long post. I have a few doubts about some parts of the CAN protocol, but before moving on to those, I wanted to make sure my understanding of the frame format is correct
 

Ian0

Joined Aug 7, 2020
13,177
Your summary is correct, although it is not as good as RS485 for noise immunity because the bus relies on termination resistors to return it to the recessive state. The dominant/recessive is, however, essential to the operation of CAN as it allows it to deal with data collisions in hardware. If one node tries to send recessive at the same point another sends dominant, each node reads back what the bus is doing, and if there is a disagreement, the node trying to send recessive abandons its attempt, but automatically retires as soon as the bus is idle.
Unlike various RS485 protocols, where the software has to keep track of who is sending and who is receiving, CAN has the hardware deal with it, so there is no processor overhead. Just set up the message, tigger it to send, and the hardware ensures it is delivered. Thus, if you can set up the peripherals, you don’t actually need to know precisely what is going on.
 

Thread Starter

Embededd

Joined Jun 4, 2025
178
Your summary is correct,
One thing I'm still confused about is where arbitration effectively ends.

I'm thinking about a very rare scenario where two nodes start transmitting at exactly the same time and have the same message ID. If they also happen to have the same control field and identical data bytes, then they would generate the same 15-bit CRC sequence as well (excluding the CRC delimiter).

I know this is an extremely unlikely situation in a real system, but theoretically, could both nodes continue transmitting together all the way through the CRC sequence without either one losing arbitration? Or does arbitration actually end of data filed?

I'm asking because I'm trying to understand how the protocol behaves in this cases, not because I expect this to happen in practice.
 

Thread Starter

Embededd

Joined Jun 4, 2025
178
My understanding of bit stuffing is this

When the transmitter detects five consecutive bits of the same polarity (for example, 11111 or 00000), it automatically inserts a stuff bit of the opposite polarity. So after 11111, it transmits a 0, and after 00000, it transmits a 1.

The receiver performs the same check while receiving the frame. If it sees five identical bits followed by the expected opposite-polarity stuff bit (for example, 111110), it removes the stuff bit and continues processing the frame normally.

However, if the receiver sees six consecutive identical bits instead (for example, 111111), it knows that the required stuff bit was missing or corrupted, so it detects a bit stuffing error and treats the frame as invalid.
 

Ian0

Joined Aug 7, 2020
13,177
One thing I'm still confused about is where arbitration effectively ends.

I'm thinking about a very rare scenario where two nodes start transmitting at exactly the same time and have the same message ID. If they also happen to have the same control field and identical data bytes, then they would generate the same 15-bit CRC sequence as well (excluding the CRC delimiter).

I know this is an extremely unlikely situation in a real system, but theoretically, could both nodes continue transmitting together all the way through the CRC sequence without either one losing arbitration? Or does arbitration actually end of data filed?

I'm asking because I'm trying to understand how the protocol behaves in this cases, not because I expect this to happen in practice.
They really shouldn’t have the same message ID. They will continue to transmit in parallel until the messages differ. At that point the one trying to send recessive loses and gives up, and the dominant wins. If the entire ID and number of bytes were all identicAl, the one sending the numerically lowest data wins.
 

Papabravo

Joined Feb 24, 2006
22,086
You wrote:
CAN is a message-based protocol, which means messages are identified by their identifier (Message ID) instead of the destination node address. Any node can transmit a message, and every node receives it. Each receiver decides whether to accept or ignore the message using its acceptance filters and masks.

It is true that any node can transmit a message, but multiple nodes should NOT transmit messages with identical arbitration fields since that would defeat the whole purpose of arbitration. Arbitration continues for the entire length of the arbitration field, which may include the Data Length Code, and if the network rule is that two nodes may NOT have the same identifier is enforced by design, then arbitration will end at the end of the identifier field.

At, Allen-Bradley in the Device-Net implementation we had a MAC address embedded in the 11-bit identifier field and a power on node protocol to detect duplicate MAC addresses on an active network. Having this higher-level protocol on top of CAN. made network commissioning and debugging ever so much easier. It was often the case that nodes which went Bus-Off were victims rather than perpetrators.
 
Top