The Controller Area Network (CAN) is a reliable communication protocol ideal for environments with high noise and reliability requirements. Unlike UART and I2C, CAN is more robust and suitable for long-distance communication and harsh environments. This makes it vital in the automotive industry for linking sensors, actuators, and other components efficiently.
Considering CAN for your next project? The KIT_XMC14_2GO, the latest addition to the XMC1400 microcontroller family, simplifies the process. This board offers multiple interfaces, including a CAN bus, making it easier to incorporate reliable communication into your project.
CAN BasicsCAN Bus
In a CAN network, devices connect to a common bus made up of CAN High and CAN Low lines, carrying a differential signal. Each device can send data independently, and messages include an ID that specifies the intended recipient. Only the device with the matching ID processes the message, while all other devices receive the data but ignore it.
CAN is half-duplex, meaning only one device can transmit data at a time. Once the transmission is complete, another device can respond.
This setup enables multiple devices to communicate over a single network without a host or master device, unlike the traditional master-slave configuration.
Differential Signaling
CAN uses differential signaling to reduce electrical noise. Instead of reading absolute voltage levels, it reads the voltage difference between CANH and CANL.
For example:
- When CANH is 3 V and CANL is 1 V, the differential is 2 V, which represents a '0' bit.
- When CANH is 2 V and CANL is 2 V, the differential is 0V, which represents a '1' bit.
If noise affects both lines equally, the differential voltage remains unchanged, ensuring correct data interpretation.
CAN Messages
A CAN bus message is composed of several key parts:
- Start of Frame (SOF) bit.
- Arbitration Field containing a unique identifier and an RTR bit.
- Control Field includes the IDE bit, a reserved bit, and the Data Length Code (DLC).
- Data Field carries the payload (0 to 8 bytes).
- CRC Field for error detection.
- ACK Field for acknowledgment.
- End of Frame (EOF).
- Interframe Space (ITM) to maintain bus idleness between messages.
Asynchronous Communication
CAN is asynchronous, meaning devices do not share a common clock signal. They must agree on a baud rate to communicate effectively.
Cyclic Redundancy Check (CRC)
CAN incorporates CRC to ensure data integrity. The sender calculates and attaches a CRC to the data. The receiver recalculates the CRC using the received data and compares it to the received CRC. Any mismatch indicates data corruption during transmission.
Hardware SetupFor this example, we will use the CAN interface of the KIT_XMC14_2GO microcontroller. To connect two KIT_XMC14_2GO microcontrollers via CAN, you need to solder pins to the CAN high (H) and CAN low (L) pins of both microcontrollers and wire them accordingly. Here’s a step-by-step guide to set up your hardware:
- Soldering Pins: Begin by soldering pins to the CAN H and CAN L connectors on both KIT_XMC14_2GO boards.
- Wiring CAN Bus: Connect the CAN H pin of the first KIT_XMC14_2GO to the CAN H pin of the second board. Similarly, connect the CAN L pin of the first KIT_XMC14_2GO to CAN L pin of the second board.
- Powering the Microcontrollers: Connect each KIT_XMC14_2GO to your computer using USB cables. Ensure both microcontrollers are powered on and ready for programming.
1. Getstarted with Arduino IDE and XMC Boards
To start programming with XMC boards, you need to set up the Arduino IDE. Follow our step-by-step guide to get started with XMC for Arduino: documentation.
Get Started!
With everything prepared we’re ready to flash the first code example to the microcontroller. In order to do that you have to do the following steps in the Arduino IDE:
1.Select the right board
Once you have installed the XMC board family, you can select one of the supported boards from the menu: Tools > Board > Infineon’s XMC Microcontroller.In our case we have to choose the XMC1400 XMC2Go in order to select the correct board.
2.Open the first example
CANSenderWith the library installed in the Arduino IDE you can simply open one of the examples that are part of the library. To do that you have to go to the menu: File > Examples > CAN and then we can start by the CANSender example to setup the sender KIT_XMC14_2GO board.
Now, after choosing the CANSender code, we can flash it to our board and set it aside for later use to broadcast messages to our other board.
Let's go now through the code for sending the messages over CAN.
In the void setup function the code initializes the CAN communication at a baud rate of 500 kbps:
if (!CAN.begin(500E3)){
Serial.println("Starting CAN failed!");
while (1);
}
This code checks if the CAN bus starts correctly at 500 kbps. If it fails, it prints an error message and enters an infinite loop to halt the program.
Next, in the void loop, you need to structure the code to send your messages continuously.
CAN.beginPacket(0x12);
CAN.write('h'); ... CAN.write('o');
CAN.endPacket();
Serial.println("done");
delay(1000);
CAN.beginPacket(0x12): Begins a CAN packet with a standard identifier 0x12. The (0x12) is a standard 11-bit identifier for the CAN message.
CAN.write(' '): Writes the characters 'h', 'e', 'l', 'l', 'o' to the CAN data payload.
CAN.endPacket(): Ends the CAN packet, marking it ready to be sent on the CAN bus.
Sending an Extended CAN Message:
CAN.beginExtendedPacket(0xFFF);
CAN.write('w');
CAN.endPacket();
CAN.beginExtendedPacket(0xFFF): Begins a CAN packet with an extended identifier 0xFFF. 0xFFF: This is an extended 29-bit identifier for the CAN message.
CANReceiverNow that we have the CAN sender code set up, let's move on to setting up the second KIT_XMC14_2GO board to receive the message and print it on a tiny OLED display.
To do that, go to the menu: File > Examples > CAN, and then select the CANReceiver example. This example demonstrates how to set up your board to receive messages. We will start from this code and adjust it to print the message to the display using I2C communication.
Before we test the code with the OLED display, make sure that CAN communication is working using the original example. You should receive messages from the sender board, and the receiver board will print them on the serial monitor as shown in the photo below.
Now that we have our CAN communication working, we can now go through the code and further expand this example by setting up the code for the I2C display.
In the setup()
function, we initialize the serial communication at a baud rate of 9600 and wait for the serial connection to be established. We then print a message to indicate that the CAN receiver is starting up. Finally, we start the CAN bus at a baud rate of 500 kbps using CAN.begin(500000)
. If the CAN bus fails to start, we print an error message and enter an infinite loop.
In the loop()
function, we continuously check for incoming CAN packets using CAN.parsePacket()
. If a packet is received, we print information about the packet, including its ID, type (standard or extended), and length.
If the packet is not a remote transmission request (RTR) packet, we print the packet data as characters using CAN.read()
.Now, to display the received CAN messages on the display, we added the following code to the receiver code:
First, we have to install and import the Adafruit_SSD1306 library.
Now, In the setup()
function, we initialized the I2C display using the Adafruit_SSD1306 library:
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
In the loop()
function, we modified the code to print the received CAN messages to the I2C display.Here are the basic display-related commands used :
display.clearDisplay()
: Clears the display.display.setCursor(x, y)
: Sets the cursor position.display.print("string")
: Prints a string at the current cursor position.display.print(value)
: Prints a value at the current cursor position.display.print(value, format)
: Prints a value at the current cursor position with a specified format (e.g., HEX).display.display();
: Updates the display to show the new content.display.startscrollright(left, right)
: Starts a scrolling animation from left to right.display.stopscroll()
: Stops the scrolling animation.
if (packetSize) {
display.clearDisplay();
display.setCursor(0, 0);
display.print("Received CAN message:");
display.setCursor(0, 10);
display.print("ID: 0x");
display.print(CAN.packetId(), HEX);
if (CAN.packetExtended()) {
display.print(" (Extended)");
} else {
display.print(" (Standard)");
}
display.setCursor(0, 20);
display.print("Length: ");
display.print(packetSize);
if (!CAN.packetRtr()) {
display.setCursor(0, 30);
display.print("Data: ");
for (int i = 0; i < packetSize; i++) {
display.print((char)CAN.read());
}
}
display.display();
#Scroll the display to show the next message
for (int yOffset = 0; yOffset < SCREEN_HEIGHT; yOffset++) {
display.startscrollright(0x00, 0x07);
delay(100); }
#Stop scrolling after showing the message
display.stopscroll();
delay(1000);
}
Now that we have modified the receiver code to display on the OLED screen, we can test our CAN bus setup as shown in the GIF below.
We have connected one XMC board to a USB port to power it, and passed 5V and GND to the other board to power both. Make sure to refer to the schematics again for the correct connections.
After flashing the code to the receiver board and completing the schematics, you should see the CAN messages scrolling on the OLED screen.
We have now come to the finish line! In this article, we explored the basics of the Controller Area Network (CAN) protocol and its implementation using the KIT_XMC14_2GO microcontroller. We set up a CAN bus connection between two KIT_XMC14_2GO boards, sent and received CAN messages, and modified the receiver code to display the received messages on a small I2C OLED screen.
FarewellWith the understanding gained from this guide, you are now equipped to embark on your next innovative project using the KIT_XMC14_2GO and CAN bus. Don't forget to refer back to the guidance in this article for technical support.
Happy coding!
Comments
Please log in or sign up to comment.