Main Content

Advanced CAN Communication with Arduino Using Vehicle Network Toolbox

This example shows you how to use the MATLAB® Support Package for Arduino® Hardware along with the Vehicle Network Toolbox™ to read and write CAN messages and signals using a CAN database.

Required Hardware

To run this example, you will need the following hardware:

  • VN1610 Vector CAN Interface device

  • Arduino Mega2560 board

  • Seeed Studio CAN-Bus Shield V2

Hardware Setup

Mount the Seeed Studio CAN-Bus Shield V2 on the Arduino Mega2560 board. Use a properly terminated custom cable to link the CANH and CANL pins of the Vector device to the Arduino CAN shield.

This example demonstrates the bi-directional communication between the Arduino Mega2560 board and the Vector VN1610 device.

Create CAN Channels

Create a CAN channel connected to the VN1610 device using the canChannel (Vehicle Network Toolbox) function from the Vehicle Network Toolbox.

ch1 = canChannel('Vector','VN1610 1',1);

Create a connection to the CAN channel linked to the Arduino Mega2560 board using canChannel (Vehicle Network Toolbox) from the MATLAB Support Package for Arduino Hardware.

arduinoObj = arduino('COM4', 'Mega2560','Libraries','CAN','F','true');
ch2 = canChannel(arduinoObj,'MCP2515','D9','D3');

The CAN database file, demoVNT_CANdbFiles.dbc, will be used to define and decode messages using the canDatabase (Vehicle Network Toolbox) function from the Vehicle Network Toolbox. Create handle to the CAN database file and attach it to the CAN channels.

db = canDatabase('demoVNT_CANdbFiles.dbc');
ch1.Database = db;
ch2.Database = db;

Create CAN Messages

Create CAN messages, with the definition from the CAN database file, using the canMessage (Vehicle Network Toolbox) function from the Vehicle Network Toolbox.

msg = canMessage(db,'EngineMsg');

Transmit CAN Messages from Vector Device and Read from Arduino Hardware

Transmit CAN messages from the Vector VN1610 device using the transmit (Vehicle Network Toolbox) function from the Vehicle Network Toolbox. You must start the channel using the start (Vehicle Network Toolbox) function from the Vehicle Network Toolbox before you transmit the messages.

start(ch1);
msg.Signals.EngineRPM = 2000;
transmit(ch1, msg);

Read the timetable which contains all the CAN frames from the channel linked to the Arduino Mega 2560 board using the read (Vehicle Network Toolbox) function.

arduinoRx = read(ch2)
arduinoRx=1×8 timetable
              Time              ID     Extended        Name            Data        Length      Signals       Error    Remote
    ________________________    ___    ________    _____________    ___________    ______    ____________    _____    ______

    14-Jul-2020 17:07:15.403    100     false      {'EngineMsg'}    {1×8 uint8}      8       {1×1 struct}    false    false 

arduinoRx.Signals{1}.EngineRPM
ans = 2000

You have now established successful communication between the nodes.

Write CAN Messages from Arduino Hardware and Receive from Vector Device

Now write new values into the CAN Message object and transmit it through the Arduino Hardware. Write the CAN message from the Arduino Mega 2560 board using the write function.

msg.Signals.EngineRPM = 500;
write(ch2, msg)

Receive the CAN frames from the VN1610 Vector hardware using the receive (Vehicle Network Toolbox) function from the Vehicle Network Toolbox. You must specify the value of ‘OutputFormat’ to 'timetable' when using the receive function for optimal performance and representation of CAN messages in MATLAB.

vectorRx = receive(ch1,2,'OutputFormat','timetable')
vectorRx=2×8 timetable
        Time        ID     Extended        Name            Data        Length      Signals       Error    Remote
    ____________    ___    ________    _____________    ___________    ______    ____________    _____    ______

    0.073982 sec    100     false      {'EngineMsg'}    {1×8 uint8}      8       {1×1 struct}    false    false 
    0.29798 sec     100     false      {'EngineMsg'}    {1×8 uint8}      8       {1×1 struct}    false    false 

vectorRx.Signals{1}.EngineRPM
ans = 2000
vectorRx.Signals{2}.EngineRPM
ans = 500

The message which is transmitted from the Vehicle Network Toolbox, is available in the receive buffer until it is received. Hence you see the first transmitted value in Signals{1}. You have received the CAN message transmitted by Arduino hardware in Signals{2}.

Using Vehicle Network Toolbox you can extract the signals from the received timetable.

canSignalTimetable(vectorRx)
ans=2×2 timetable
        Time        VehicleSpeed    EngineRPM
    ____________    ____________    _________

    0.073982 sec         0            2000   
    0.29798 sec          0             500   

There is a difference in Time output in the timetables from Vehicle Network Toolbox and MATLAB Support Package for Arduino Hardware. The Time output from the MATLAB Support Package for Arduino Hardware is the absolute time in datetime whereas the Time output from the Vehicle Network Toolbox is the relative time as most of the VNT hardware drivers are built around relative times. To fetch the absolute time, use the InitialTimestamp property of ch1.

ch1.InitialTimestamp
ans = datetime
   14-Jul-2020 17:07:15

To see the table with absolute time, add the InitialTimestamp to the Time column of the vectorRx timetable.

vectorRx.Time = vectorRx.Time + ch1.InitialTimestamp
vectorRx=2×8 timetable
            Time            ID     Extended        Name            Data        Length      Signals       Error    Remote
    ____________________    ___    ________    _____________    ___________    ______    ____________    _____    ______

    14-Jul-2020 17:07:15    100     false      {'EngineMsg'}    {1×8 uint8}      8       {1×1 struct}    false    false 
    14-Jul-2020 17:07:15    100     false      {'EngineMsg'}    {1×8 uint8}      8       {1×1 struct}    false    false 

Clean Up

When finished, clear the connections to the hardware.

clear db;
clear msg;
clear arduinoRx;
clear vectorRx;
clear ch1;
clear ch2;
clear arduinoObj;