Filter results by

Serial CAN Bus Solution

Trying to find the ideal IoT serial bus for wired local communications with other microcontrollers? Or just a way to monitor the diagnostic system of your car?

A Controller Area Network (CAN) Bus solution may be what you're looking for. It provides a way to send data in 8-byte blocks among multiple microcontrollers sharing the two-wire serial bus. Arbitration is automatic.

This article provides instructions for using the serial CAN bus module available through Seeed.


CAN is designed to run over a twisted wire pair with 120Ω characteristic impedance. The serial CAN bus module attaches to the wire pair with screw terminals, and comes terminated with a 120Ω resistor. Its microcontroller interface plugs into the UART connector on the Grove base shield. Features include:

  • Based on the Microchip MCP2515
  • CAN bus rates up to 1Mb/s
  • Easy setup through sysfs commands; setup is retained in Flash memory
  • Programmable addresses
  • Arduino IDE support – uses software serial on GPIO pins to free up the UART.

  1. Connector to Grove base shield
  2. Power and status LED indicators
  3. Send and Recv LED indicators
  4. Terminal to connect to CAN Bus (CAN_H & CAN_L)
  5. 120Ω termination pad (cut pad to disconnect termination, if needed)

The module requires a 5V supply. You must set the switch on the Grove base shield to the 5V position.


You'll need at least two CAN devices on the bus. They can be two Serial CAN Bus modules attached to different ARTIK boards, or you can just set up one ARTIK board + CAN bus module and connect to an existing bus (such as the diagnostics connector of your car).

ARTIK 530/710 boards additionally require an Arduino-friendly adapter board.

For each ARTIK board:

  1. Attach the Grove base shield to your ARTIK Arduino interface.

  2. Connect the CAN bus module to the base shield UART connector using the cable provided.

  3. Set the base shield to 5V operation.

Refer to the Longan Labs serial CAN bus article for additional information.


Configuring each serial CAN bus module is only required once for initialization. The information is retained until you overwrite it with a new configuration.

Refer below or to the UART Interface article for UART port assignments.

ARTIK TYPE Linux device name
520 /dev/ttySAC3
530 /dev/ttyAMA4
710 /dev/ttySAC4
1020 /dev/ttySAC1

We're assuming you are using two CAN bus modules mounted on separate ARTIK development kits. Perform these steps on each board. The sample commands we provide set the bus to its slowest rate (5kb/s) and clear all filters and masks to accept all message IDs.

  1. Create a script file (or a name of your choice) with desired contents.

  2. Replace all instances of XXXX with the correct port name for your ARTIK module.

  3. Save the file, then use chmod 777 to make the script executable.

echo -e "+++AT+C=01\nAT+Q\n" > /dev/ttyXXXX
sleep 0.5
echo -e "+++AT+M=[0][0][00000000]\nAT+Q\n" > /dev/ttyXXXX
sleep 0.5
echo -e "+++AT+M=[1][0][00000000]\nAT+Q\n" > /dev/ttyXXXX
sleep 0.5
echo -e "+++AT+F=[0][0][00000000]\nAT+Q\n" > /dev/ttyXXXX
sleep 0.5
echo -e "+++AT+F=[1][0][00000000]\nAT+Q\n" > /dev/ttyXXXX
sleep 0.5
echo -e "+++AT+F=[2][0][00000000]\nAT+Q\n" > /dev/ttyXXXX
sleep 0.5
echo -e "+++AT+F=[3][0][00000000]\nAT+Q\n" > /dev/ttyXXXX
sleep 0.5
echo -e "+++AT+F=[4][0][00000000]\nAT+Q\n" > /dev/ttyXXXX
sleep 0.5
echo -e "+++AT+F=[5][0][00000000]\nAT+Q\n" > /dev/ttyXXXX

The -e parameter is required to recognize backslash shorthand like \n.

You can edit the configuration script at any time to set up your own filters, masks, baud rates, etc. Once you are ready to make the configuration change:

  • Run ./ to configure the chip registers on the serial CAN bus module.

When you unplug and then reconnect the module to the Grove base shield, you should see your settings reflected in the initialization printout. For example:

	Rate: 5 Mb/s
	Mask0: 0x0
	Mask1: 0x0
	Filt0: 0x0
	. . .
	Filt5: 0x0

Note that there is a mistake in Rate: It should show kb/s, not Mb/s.

Test Operation

Run these commands on each board, once again replacing XXXX with the correct port name for your ARTIK module.

  1. Run this background command to read incoming UART messages.

    cat /dev/ttyXXXX &

  2. Disable echo on the port to prevent conflicts on returned data (screen display will be messy and you will lose characters if you skip this step).

    stty -F /dev/ttyXXXX -echo

  3. Unplug and reattach each board to verify that you see the configuration printout and INIT OK message.

  4. Send a header and message to a device programmed to accept an ID of 0x0DC.

    echo -e "\x00\x00\x00\xDC\x00\x00"'testing' > /dev/ttyXXXX

    where the header format

    00 00 00 ID EXT RTR message

    - bytes 0, 1: set to 00 in standard addressing mode
    - byte 2: normally 00, set to 04 to force intermediate buffer output
    - byte 3: CAN ID
    - byte 4: EXT – normally 0; if =1, extended frame addressing is used
    - byte 5: RTR – normally 0; if =1, data is to be provided by the remote (target) device.

At the receiver, you should see the message
preceded by the CAN ID, which may or may not be a displayable character.

Data is buffered as long as full (8-byte) lines are received. When you sent a short line, all buffered messages are printed out.

Full buffering. Here we'll try a full sentence, where we have chosen an ID of 0x3B because it shows up as a semicolon. Our example uses ttyAMA4; don't forget to replace it with your correct port.

echo -e "\x00\x00\x00\x3B\x00\x00"'The quic' > /dev/ttyAMA4     
echo -e "\x00\x00\x00\x3B\x00\x00"'k brown ' > /dev/ttyAMA4     
echo -e "\x00\x00\x00\x3B\x00\x00"'fox jump' > /dev/ttyAMA4     
echo -e "\x00\x00\x00\x3B\x00\x00"'ed over ' > /dev/ttyAMA4     
echo -e "\x00\x00\x00\x3B\x00\x00"'the lazy' > /dev/ttyAMA4     
echo -e "\x00\x00\x00\x3B\x00\x00"'sleeping' > /dev/ttyAMA4     
echo -e "\x00\x00\x00\x3B\x00\x00"' dog!  '"\n" > /dev/ttyAMA4

Nothing prints on the receiving side until the last line is sent. Output should look like this:

;The quic;k brown ;fox jump;ed over ;the lazy;sleeping;dog!

Buffer flush. Repeat the last test, this time setting buffer flush (third byte = 04). Now you'll see that each new message received forces the previous one to be printed out.

echo -e "\x00\x00\x04\x3B\x00\x00"'The quic' > /dev/ttyAMA4     
echo -e "\x00\x00\x04\x3B\x00\x00"'k brown ' > /dev/ttyAMA4     
echo -e "\x00\x00\x04\x3B\x00\x00"'fox jump' > /dev/ttyAMA4     
echo -e "\x00\x00\x04\x3B\x00\x00"'ed over ' > /dev/ttyAMA4     
echo -e "\x00\x00\x04\x3B\x00\x00"'the lazy' > /dev/ttyAMA4     
echo -e "\x00\x00\x04\x3B\x00\x00"'sleeping' > /dev/ttyAMA4     
echo -e "\x00\x00\x04\x3B\x00\x00"' dog!  '"\n" > /dev/ttyAMA4
Last updated on: