Skip to main content
Version: 1.0.2

CAN Bus

Hardware​

One CAN FD bus is integrated into AutomatePro with a max data rate of 8 Mbps.

Connector Pinout​

CAN Specifications​

ParameterValue
TransceiverTCAN3413DDFR
CAN FDYes
Max data rate8 Mbps
Integrated 120 Ω termination resistorYes
CAN H and L input protection< ±58V

Software​

automatepro-start-can0.service brings can0 up at boot at 500 kbps with a transmit queue of 1000 frames.

To use the network, configure the interface properties. For instance, to set the network interface with a bus bit rate of 500 kbps, use the following command:

sudo ip link set can0 up type can bitrate 500000 berr-reporting on

Install CAN utilities for testing:

sudo apt-get install can-utils

This command transfers a packet to can0 with CAN ID 123 and data 'abcdabcd':

cansend can0 123#abcdabcd

This command receives packets from any CAN node connected to the bus:

candump -x any

For more information about the use of cansend, enter this command:

cansend --help

You can use other tools, such as cangen, for different filtering options.

Example​

This example sends a frame with CAN ID 0x123 and a two-byte counter every second with can_sender and prints each frame can_receiver reads. The programs are in the misc folder of the AutomatePro tutorials repository, and its README explains how to build and run them. Each program takes the interface as its only argument: can0 on AutomatePro, or a virtual vcan0 interface to test without a bus. Run the receiver and the sender in separate terminals. The Python programs need python-can.

Sender: can_sender.py

import can
import sys
import time
import signal

running = True


def signal_handler(sig, frame):
global running
running = False
print("\n[Sender] Stopping...")


signal.signal(signal.SIGINT, signal_handler)


def main():
if len(sys.argv) < 2:
print("Usage: python3 can_sender.py <interface>\nExample: python3 can_sender.py vcan0")
sys.exit(1)

interface = sys.argv[1]
print(f"[Sender] Using interface: {interface}")

try:
bus = can.interface.Bus(channel=interface, interface='socketcan')
except OSError as e:
print(f"[Sender] Failed to connect to interface {interface}: {e}")
sys.exit(1)

counter = 0

while running:
data = [counter & 0xFF, (counter >> 8) & 0xFF]
msg = can.Message(arbitration_id=0x123, data=data, is_extended_id=False)

try:
bus.send(msg)
print(f"[Sender] Sent ID 0x{msg.arbitration_id:X} "
f"Data: {' '.join(str(b) for b in msg.data)}")
except can.CanError as e:
print(f"[Sender] Send failed: {e}")

counter += 1
time.sleep(1)

bus.shutdown()
print("[Sender] Closed.")


if __name__ == "__main__":
main()
python3 can_sender.py can0

Receiver: can_receiver.py

import can
import sys
import signal

running = True


def signal_handler(sig, frame):
global running
running = False
print("\n[Receiver] Stopping...")


signal.signal(signal.SIGINT, signal_handler)


def main():
if len(sys.argv) < 2:
print("Usage: python3 can_receiver.py <interface>\nExample: python3 can_receiver.py vcan0")
sys.exit(1)

interface = sys.argv[1]
print(f"[Receiver] Listening on interface: {interface}")

try:
bus = can.interface.Bus(channel=interface, interface='socketcan')
except OSError as e:
print(f"[Receiver] Failed to connect to interface {interface}: {e}")
sys.exit(1)

while running:
try:
msg = bus.recv(timeout=1.0)
if msg:
print(f"[Receiver] Received ID 0x{msg.arbitration_id:X} "
f"Data: {' '.join(str(b) for b in msg.data)}")
except can.CanError as e:
print(f"[Receiver] Receive failed: {e}")

bus.shutdown()
print("[Receiver] Closed.")


if __name__ == "__main__":
main()
python3 can_receiver.py can0

Troubleshooting​

Loopback test​

You can perform a loopback test to determine whether the controller is working.

Ensure the CAN drivers are loaded. To check whether the drivers are loaded, use the following command:

lsmod | grep mttcan

If the drivers are not loaded, enter this command:

sudo modprobe mttcan

To perform a loopback test, run the following commands:

sudo ip link set can0 type can bitrate 500000 loopback on
sudo ip link set can0 up
candump can0 &
cansend can0 123#abcdabcd

If the loopback test is successful, the last command displays this:

can0 123 [4] AB CD AB CD
can0 123 [4] AB CD AB CD

Other Methods​

Additional debugging techniques to consider:

  1. If a loopback test shows that the controller is working correctly and you still cannot send or receive packets, try reconnecting the transceiver and confirm that the connections are correct.

  2. Check if the mttcan driver is loaded.

  3. Connect an oscilloscope to analyze the bus signal integrity and verify proper operation.

  4. If the device logs a No buffer space available message during send, enter this command to use the polling mechanism:

    cangen -L 8 can0 -p 1000