Marcio Cunha

Implementing CAN Bus Control Systems for Reliable Microcontroller Communication

Learn how to design robust communication systems using the CAN bus to interconnect microcontrollers in noisy industrial environments, ensuring high reliability and temporal determinism.

Marcio Cunha•4 min
Also available in:EspañolPortuguês
Summary
  • The CAN protocol uses differential voltage signaling to guarantee superior immunity against severe electromagnetic noise common in factories.
  • Bitwise arbitration by priority prevents destructive bus collisions without requiring complex node addressing schemes.
  • Integrated controllers and external transceivers form the essential physical layer to protect microcontrollers from voltage surges.
  • Correct one-hundred-twenty-ohm termination resistors at both ends of the bus prevent signal reflections that corrupt data packets.
  • Robust error handling and automatic retransmission ensure that transient faults do not take down the automation network.

The Challenge of Reliable Industrial Communication

Factories and industrial environments are unforgiving settings for modern electronics. High-power electric motors, frequency inverters, and relays generate intense electromagnetic fields that induce parasitic noise into standard signal cables. When microcontrollers communicate using conventional protocols like UART or I2C, this noise easily corrupts data packets, causing catastrophic failures on production lines. In practice, this means a machine might lose its emergency stop command simply due to interference generated when a neighboring conveyor belt starts up.

To solve this problem, industry widely adopted the CAN bus, originally developed for the automotive sector. The acronym stands for Controller Area Network. It is a serial communication system focused on connecting industrial or automotive devices with extremely high immunity to interference and without requiring a central computer to coordinate all traffic. In this article, we will explore how to implement this technology in practice using modern microcontrollers.

How the CAN Bus Physical Layer Works

The secret to CAN bus robustness lies in its differential physical layer. Instead of sending signals using a single wire referenced to ground, the CAN network uses two twisted wires called CAN_H and CAN_L. The receiver measures the voltage difference between these two conductors to interpret the bits. In practice, if an external electromagnetic field hits the cable, it affects both wires equally. Because the receiver looks only at the difference between them, common-mode noise is cancelled almost entirely.

To connect the microcontroller to these two wires, a component called a CAN transceiver is used, such as the classic MCP2551 or the modern TJA1050. The microcontroller generates standard digital logic signals on its internal transmit and receive pins, known as TX and RX. The transceiver translates these digital signals into the differential voltage levels of the bus and protects the microcontroller from transient voltage surges and electrostatic discharges common on the factory floor.

Priority Arbitration and the End of Collisions

In traditional networks like basic Ethernet, when two devices attempt to transmit data at the same time, a collision occurs, corrupting messages and requiring retransmission after a random delay. The CAN bus solves this elegantly through a mechanism called bitwise arbitration based on identifiers. Each transmitted message has a numeric identifier that defines its priority. The lower the number, the higher the priority of the message on the network.

In practice, when multiple microcontrollers start transmitting simultaneously, all of them send their bits to the bus. Nodes transmitting recessive bits (logic high) notice that the bus is in a dominant state (logic low) due to another node with a more urgent message and immediately back off, yielding space without losing data. This ensures that critical messages, such as an urgent stop command, pass instantly, while less urgent temperature readings wait their turn in a fully deterministic manner.

Error Handling and Extreme Reliability

The reliability of an industrial system depends on its ability to detect and isolate faults before they halt the entire plant. The protocol features highly sophisticated error detection mechanisms built directly into the controller hardware. It uses cyclic redundancy checks, known as CRC, alongside constant monitoring of transmitted bits, frame format checking, and message acknowledgment.

If a microcontroller detects that a packet has been corrupted, it immediately generates an error flag on the bus, destroying the frame so all other nodes know the information is invalid. Each device internally maintains transmit and receive error counters. If a node experiences consecutive failures due to a broken cable or hardware issue, it automatically disconnects itself from the network to prevent dragging down the communication of other productive equipment.

Practical Implementation Guide with Microcontrollers

To put this architecture into operation, we need to correctly configure the microcontroller hardware and software. Most modern microcontrollers, including popular ARM Cortex-M lines and various 8-bit or AVR models, already feature integrated CAN controllers. If the chosen chip lacks an internal controller, a dedicated external controller connected via an SPI bus can be used.

The first practical step consists of setting the transmission speed, known as baud rate, based on the physical length of the bus. CAN networks support up to one megabit per second for short distances of forty meters, but can reach one kilometer if the speed is reduced to fifty kilobits per second. The second step involves installing one-hundred-twenty-ohm termination resistors at both physical ends of the cable to prevent signal reflections. The third step requires properly initializing timing registers and message acceptance filters in the microcontroller firmware.

#include <stdio.h>
#include "can_driver.h"

void setup_can_network(void) {
CAN_Config config;
config.baud_rate = CAN_BAUD_500K;
config.mode = CAN_MODE_NORMAL;

if (CAN_Init(&config) != CAN_SUCCESS) {
printf("Error initializing CAN controller.\n");
while(1);
}

CAN_Filter filter;
filter.id = 0x100;
filter.mask = 0x7FF;
CAN_SetFilter(0, &filter);
}

void send_sensor_data(uint16_t temperature) {
CAN_Message msg;
msg.id = 0x101;
msg.len = 2;
msg.data[0] = (temperature >> 8) & 0xFF;
msg.data[1] = temperature & 0xFF;

if (CAN_Transmit(&msg) != CAN_SUCCESS) {
printf("Failed to transmit CAN message.\n");
}
}

Final Considerations

Successful implementation of CAN networks in industrial environments transforms vulnerable electronic systems into highly resilient distributed architectures. Understanding the physics of differential signals, priority arbitration logic, and the importance of correct bus termination empowers engineers and designers to build durable products capable of operating for years without human intervention. With proper hardware and software planning, microcontroller communication ceases to be the weakest link in automation and becomes the solid foundation of modern, efficient industrial plants.