Building a CAN API for Arduino DUE

Hi there,

I did some research for CANopen OpenSource libraries and found the canfestival.org. That seams to have a very active community. canfestival also supports already AVR chips as noted on their "supported devices" page under CanFestival documentation.

I saw all the work you have already done for supporting CAN on the due. Great work, amazing.

Do you think it is feasible to integrate the canfestival into the Arduino IDE for Arduino Due and possibly also in Arduino Uno with the seeedstudio or sparkfun can shield?

Thx

Zabaat - is that a deutsch dtm series pcb mount connectors for use with the oem sealed enclosure they offer?

maxwest:
Do you think it is feasible to integrate the canfestival into the Arduino IDE for Arduino Due and possibly also in Arduino Uno with the seeedstudio or sparkfun can shield?

Hello maxwest,

As an integrator I could say Yes. Integrate canfestival (or any other third-party CANopen protocol like CanOpenNode, etc.) to Due or UNO should be feasible. The problem lies that between CAN bus and CANopen there is an in-construction bridge of missing layers to be built. So far, I'm not aware of any software (code) implementation that fills the gap. Again, it can be done and collin (reply #152) and me have made comments about this matter but let me explain in a dossier this thing.

CAN bus and CANopen (an other CANs) are OSI bus standards to communicate embedded control systems like MCUs between them without an intermediate host.

CAN bus is the lowest level link in the chain and it comprehends basically three layers or profiles.

  1. Physical layer. Implemented with a transceiver (SN65HVD234 in my design)
  2. Data Link layer. Implemented with a controller (inside SAM3X8E)
  3. Application Layer. Implemented with software (our CAN library)

Layers 1 and 2 are known as CAN itself.

CAN open is a higher level protocol. It comprehends the first two layers of CAN bus plus other layers above, as follows:

  1. Application Layer (non existent for DUE) - communication - I/O - drives -motion control - programmable devices
  2. Transport Layer (software-reliability, segmentation/desegmentation, error control).

Thus, it all about to generate the layers 3 and 4.

Having said this, now you know, broadly speaking, what it is required to complete the bridge and let the train goes.

There is another thing: Time. How much time can you afford to reconcile canfestival and Due? Right now I am trying to make our new Arduino CAN and EMAC libraries to run in a third-party board based on a SAM3X8C. This MCU has only 100 pins unlike the MCU of the Due SAM3X8E with 144 pins and even though they belong to the same family "X", I have to so some tweak on the current variant files (.cpp and .h) and pin_arduino.h. See that my case is your opposite case, I am integrating a third-party board with CAN library (you want integrate a third-party library with DUE or UNO). My integration is not a big deal given that the differences between both MCUs is minimal. In your case, I would recommend to visit the canfestival community and ask questions. I would recommend also that you start with UNO (AVR) and a CAN shield. I hope this helps you. Good luck!

hi,

I have on hands the tja1042t(High-speed CAN transceiver with Standby mode) http://www.nxp.com/documents/data_sheet/TJA1042.pdf

I like know if can I use this library to work with this uC, I see both datasheet (SN65HVD234 and TJA1042T -T/3) and both are the transceiver uC to CAN BUS.. the TJA1042T is only 5v and it can burn I/O on Due, for this I will use one circuit to make division, maybe 10k-10k get me 2.5v and this is OK to work.

I see on github the library name is SN56HVD234.c and .h is because this my question about use library on TJA1042.

tks all

You can try it. The transceiver is really fairly invisible to the way the library works. There is just a small amount of code to support an SN65HVD234. What happens is that the enable pin is set to enabled and the RS pin is controlled to manipulate the slope rate. But, you can easily make a board that does its own enabling and slope control and just not hook that stuff up to the Due at all. So, that brings me to whether you can use your transceiver. I suppose you could. It would probably accept the CANTX signal from the Due just fine. Then, as you said, you have to use a voltage divider or buffer chip to turn the 5V CANRX signal from the transceiver into a 3.3V signal to the Due. Chances are it would accept 2.5v. It isn't ideal but if you're just making something for yourself it makes sense to use whatever you happen to have on the bench.

Hi All,

Just for information, I made 2 shields : one is based on SN56HVD234, the other uses MCP2551.
I have run some basic tests and it seems to work fine for both.
Concerning the 5V aspect, I use Zener diode (3.3 or 3.6v) on the Rx pin, and it seems to work fine.

Hi guys,
I'm a bit in trouble.

First I started the CAN project with the original ASF example and did very minor changings. Unfortunately the CAN1 rcv interrupt routine doesn't get touched at all. I checked all my hardware with a oscilloscope and it seems it works fine. But no message reveiving, not even a error. Hrrmpfh.

Now I tried to attack with the functional Arduino example. I downloaded https://github.com/collin80/due_can, unzipped it, and copied it to C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\arduino-1.5.2\hardware\arduino\sam\libraries
Since the IDE did not accept the original name "due-can-master" while starting I named it DueCanMaster instead. When I try to compile I get a shipload of errors. Here are a few:

C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2/hardware/tools/g++arm_none_eabi/bin/arm-none-eabi-g++ -c -g -Os -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -Dprintf=iprintf -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=152 -D__SAM3X8E_ -mthumb -DUSB_PID=0x003e -DUSB_VID=0x2341 -DUSBCON -IC:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/libsam -IC:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/CMSIS/Include/ -IC:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/Device/ATMEL/ -IC:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\cores\arduino -IC:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\variants\arduino_due_x -IC:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\libraries\DueCanMaster C:\Users\Joachim\AppData\Local\Temp\build386121661864746555.tmp\Arduino_Due_CAN_Sample_1.cpp -o C:\Users\Joachim\AppData\Local\Temp\build386121661864746555.tmp\Arduino_Due_CAN_Sample_1.cpp.o
In file included from C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/Device/ATMEL/sam3xa/include/sam3x8e.h:260,
from C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/Device/ATMEL/sam3xa/include/sam3xa.h:44,
from C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/Device/ATMEL/sam3.h:59,
from C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/Device/ATMEL/sam.h:189,
from C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/libsam/chip.h:25,
from C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\cores\arduino/Arduino.h:34,
from C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\variants\arduino_due_x/variant.h:26,
from Arduino_Due_CAN_Sample_1.ino:7:
C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/CMSIS/Include/core_cm3.h:355: error: #elif without #if
C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/CMSIS/Include/core_cm3.h:655: error: #elif without #if
C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/CMSIS/Include/core_cm3.h:955: error: #elif without #if
C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/CMSIS/Include/core_cm3.h:1066: error: #endif without #if
C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/CMSIS/Include/core_cm3.h:1070: error: #endif without #if
C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/CMSIS/Include/core_cm3.h:1071: error: stray '\265' in program
C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/CMSIS/Include/core_cm3.h:1071: error: stray '\265' in program
C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/CMSIS/Include/core_cm3.h:1073: error: stray '\2' in program
C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/CMSIS/Include/core_cm3.h:1073: error: stray '\270' in program
C:\ARM_ARDUINO\1_5_2\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\system/CMSIS/CMSIS/Include/core_cm3.h:1073: error: stray '\210' in program

Why is that? Do I have to change some settings? I have no clue about github so I downloaded the zip file and unzipped it. Something wrong with this way?

Name the directory "due_can" just like the project name.

Hi Collin, renaming got me in the ballpark (is this yankee phrase suitable here? :slight_smile: and after additionally cleaning up the directories it compiles fine. I simply have to little experience with the IDE since all stuff I do with Atmel Studio. Thanks!

Here's a photo of my test hardware. DUE + 2x PIC 18F458.

I'm still researching the deeper sense of some registers since especially the PICs have a behaviour I don't always understand :wink:

hello, today came the SN65, TJA and the MCP CAN TRANSCEIVERS,

Before I make one board to use with this uC because I still having problens with breadboard assembly,
the picture foto(1) and Image(17) show this board... the top of image(17) show the SN65, I use Schematic of this post (page 3)

I try on with SN65 chip and work fine with DUE_CAN API, Thank You very much for this API

but I'm a very newbie on CAN Interface, I want talk with the board of the foto(2) but I don't know how,

I still reading forum and informations about CAN, and I conect the board direct on the can wire, the bard baud rate is 125KHZ (i change it on start ports) but no answare,

can anybody show one documentation to help me make this comunication.

thank you so much.

and thank you again for the CAN API,

foto (2).JPG

Don't you have a schematic of the board you want to connect to?
Usually to connect to the CAN Transceivers is pretty straightforward. Maybe even they are Pin compatible to others too, so simply watch the footprints and follow the lines. Some are high-speed, some aren't. The best expierince I made was with TI's SN65 series which are avavilable for 5V, too. They can be used for both speed ranges. The High-Speed TJA1050 have a strange behaviour when testing with a multimeter, mine lost the signals after some usec and reacted like a monoflop.

Hello, sorry to ask a simple question, but I am trying to re-download the files again after reinstalling windows. I don't see anywhere on this page that I can download the header and .cpp files and examples and such.
https://github.com/arduino/Arduino/tree/can/hardware/arduino/sam/libraries/CAN#due_can
thanks!

Well, I can't seem to find a way to do that either. But, you can do it at my repo: https://github.com/collin80/due_can

Thanks! that's what I was looking for. Boy that was getting frustrating. :slight_smile:

Why am I getting these errors?

In file included from C:\Users\johnp.PEM\Documents\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\libraries\CAN\sn65hvd234.c:26:
C:\Users\johnp.PEM\Documents\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\libraries\CAN/sn65hvd234.h:30: error: expected '=', ',', ';', 'asm' or 'attribute' before 'SSN65HVD234'
C:\Users\johnp.PEM\Documents\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\libraries\CAN\sn65hvd234.c:37: error: expected ')' before '' token
C:\Users\johnp.PEM\Documents\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\libraries\CAN\sn65hvd234.c:54: error: expected ')' before '
' token
C:\Users\johnp.PEM\Documents\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\libraries\CAN\sn65hvd234.c:72: error: expected ')' before '' token
C:\Users\johnp.PEM\Documents\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\libraries\CAN\sn65hvd234.c:88: error: expected ')' before '
' token
C:\Users\johnp.PEM\Documents\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\libraries\CAN\sn65hvd234.c:103: error: expected ')' before '' token
C:\Users\johnp.PEM\Documents\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\libraries\CAN\sn65hvd234.c:118: error: expected ')' before '
' token
C:\Users\johnp.PEM\Documents\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\libraries\CAN\sn65hvd234.c:135: error: expected ')' before '*' token

Maybe sn65hvd234.c should have a CPP extension to invoke the C++ parser/compiler/whatever


Rob

Oh duh, I see, there was a random sn65hvd234.c file.... so i just deleted it and it works fine. There already was a sn65hvd234.cpp file.

Thanks!

When I press "Send" in the following screen, I get nothing. The input box goes blank and the message is the same. Just a TX blinking, but that's it. Any ideas as to what is wrong? Here is my code

// Arduino Due - CAN Sample 1
// Brief CAN example for Arduino Due
// Test the transmission from CAN0 Mailbox 0 to CAN1 Mailbox 0
// By Thibaut Viard/Wilfredo Molina/Collin Kidder 2013

// Required libraries
#include "variant.h"
#include <due_can.h>

#define TEST1_CAN_COMM_MB_IDX 0
#define TEST1_CAN_TRANSFER_ID 0x07
#define TEST1_CAN0_TX_PRIO 15
#define CAN_MSG_DUMMY_DATA 0x55AAAA55

// CAN frame max data length
#define MAX_CAN_FRAME_DATA_LEN 8

// Message variable to be send
uint32_t CAN_MSG_1 = 0;

void setup()
{
// start serial port at 9600 bps:
Serial.begin(9600);
Serial.println("Type CAN message to send");
while (Serial.available() == 0);
}
void loop(){

while (Serial.available() > 0) {
CAN_MSG_1 = Serial.parseInt();
if (Serial.read() == '\n') {
Serial.print("Sent value= ");
Serial.println(CAN_MSG_1);
}
}

// Initialize CAN0 and CAN1, baudrate is 1Mb/s
CAN.init(SystemCoreClock, CAN_BPS_1000K);
CAN2.init(SystemCoreClock, CAN_BPS_1000K);

// Initialize CAN1 mailbox 0 as receiver, frame ID is 0x07
CAN2.mailbox_init(0);
CAN2.mailbox_set_mode(0, CAN_MB_RX_MODE);
CAN2.mailbox_set_accept_mask(0, 0x7FF, false);
CAN2.mailbox_set_id(0, TEST1_CAN_TRANSFER_ID, false);

// Initialize CAN0 mailbox 0 as transmitter, transmit priority is 15
CAN.mailbox_init(0);
CAN.mailbox_set_mode(0, CAN_MB_TX_MODE);
CAN.mailbox_set_priority(0, TEST1_CAN0_TX_PRIO);
CAN.mailbox_set_accept_mask(0, 0, false);
// Prepare transmit ID, data and data length in CAN0 mailbox 0
CAN.mailbox_set_id(0, TEST1_CAN_TRANSFER_ID, false);
CAN.mailbox_set_datal(0, CAN_MSG_1);
CAN.mailbox_set_datah(0, CAN_MSG_DUMMY_DATA);
CAN.mailbox_set_datalen(0, MAX_CAN_FRAME_DATA_LEN);

// Send out the information in the mailbox
CAN.global_send_transfer_cmd(CAN_TCR_MB0);

// Wait for CAN1 mailbox 0 to receive the data
while (!(CAN2.mailbox_get_status(0) & CAN_MSR_MRDY)) {
}

RX_CAN_FRAME incoming;
// Read the received data from CAN1 mailbox 0
CAN2.mailbox_read(0, &incoming);
Serial.print("CAN message received= ");
Serial.print(incoming.data[0]);
Serial.print(incoming.data[1]);
Serial.print(incoming.data[2]);
Serial.print(incoming.data[3]);
Serial.print(incoming.data[4]);
Serial.print(incoming.data[5]);
Serial.print(incoming.data[6]);
Serial.println(incoming.data[7]);

// Disable CAN0 Controller
CAN.disable();

// Disable CAN1 Controller
CAN2.disable();

Serial.print("End of test");

while (1) {
}
}

Thanks!

arduino.png

To test I would forget about the UI stuff and just send a hard-coded value. Then test the UI by itself and finally put them together.

Where are CAN and CAN2 defined? Are they created in the library?


Rob