Building a CAN API for Arduino DUE

Only example 4 in AdderD's code uses extended (29-bit) identifiers. All the other examples use the old standard identifiers. Make sure you're checking against the right variable? The family ID isn't the frame standard/extended id...

The difference is when setting up the mailbox, there's a "true" or "false" at the end of the parameter list - true is extended, false is standard.

AJK101:
Hey, I bought a due a week ago and tried using can with a device I have.
I checked the family id due was sending yesterday, and saw it to be huge. The docs of the device say it is expecting a 11bit cob id.

Googling it ,I found out about can v2 having 29 bit ids and can v1 having 11 bit ids. ... my current assumption is that the device is expecting can v1 while due is using v2
So, any idea how I can make due use v1?

Family ID is not what the Due sends. Family ID is a special field that allows you to track which sort of frames a receive mailbox is supposed to accept. When sending what matters is the ID you set. As Sherlock3112 said, the end parameter to several of the commands is either true or false. True means use extended addressing, false means don't (use standard addressing.)

For reference, family ID is there just to help you to do fast branching decisions on messages coming in on receive mailboxes. The docs for the processor go into the gritty details of how that works. But, you should be able to pretty much ignore it.

Thanks for the replies, AdderD, Sherlock.

I assumed family id to be three id being sent as it started with 1100, which I read somewhere is supposed to be for sdo, which is what I was trying out ...

Anyway, back to my issue, I directly used the example 1 from CAN0 to CAN2, and it worked (with 2 transceivers )

And as I already mentioned, with the device I'm using, it doesn't work

In the docs of the device, only the bits for the frame are, given, and this is the first time I'm using can ...
What I tried was to check all the values of the registers on the can and mailbox structures.

Could you help me out with this? Basically how do I find out exactly what it's sending, what mask is being used while receiving, what is the mall being applied on (full frame from id, or only data, etc) and finally what it's receiving ...

If you'll could help me out, it'd be awesome ... been trying to get the thing work for a week now ..

Hello AJK101,
Could you give us more details of your CAN device? Brand, model, firmware version/revision?

Thanks!

Maxon epos 2 controllers 70/10.

The product id according to the website is 375711

Thanks !

I made a brief review on Maxonmotor website and it looks like your device speaks Canopen. If that is the case, you can't communicate it with Due.
Canopen is a high-level protocol for CAN-bus. I would recommend you to contact them to confirm it.

Edit: Other devices like EPOS 2 P 24/5 (378308) have CAN bus functionality but not the one you mentioned (375711).

It does appear that the controller mentioned utilizes CANOpen only. I would not say that this makes it impossible to talk to with the Due. However, it would require someone to code up support for CANOpen on top of the existing canbus library. That someone has not yet materialized. I have been thinking about adding support for some higher level protocols but the thing is, well, I just don't have any need for them myself. Pretty much everything I'd interface with uses vanilla canbus. So, the options are, take the library and add on support for CANOpen, find some existing code to do that (though I don't know of anything that really fits the bill), or somehow motivate someone other than you to do it. The joy of open source is that you've got a head start. The downside is that people only work on stuff they want/need.

What exactly is the difference between can open and can ?

AJK101:
What exactly is the difference between can open and can ?

CanOpen is a protocol built on top of CAN (usually). It is a higher level protocol. This is much like how Zigbee is built upon 802.15.4 or WiFi is built upon 802.11 or how TCP/IP can be run over ethernet. Imagine CANOpen is TCP/IP and CAN is ethernet. You run CANOpen over CAN. You can easily get all the information you ever wanted on CANOpen by using Google.

CANOpen is a kind of large thing to implement. You don't want to have to reinvent the wheel on that one. So, it pays to start with something existing and make it work with what you have. Here's a promising link:

Any takers? :wink:

ah, this seems much more complicated than I had wagered on ...

I don't have much knowledge about this, so doubt I'd be able to make a whole library for it on my own ...

Could I make some haphazard venture to just "make it work" ?

I mean from the documentation from maxon, i got that it is expecting to receive :

1 bit Start of Frame
11 bit COB-ID (first 4 bits frame identifier, last 7 the ID of the receiving device)
1 bit RTR which should always be 1
6 bit control field (1 bit for identifier Extension which is to be dominant (1 ... i assume), 1 reserved bit which should also be dominant, 4 bits for Data Length Code which holds number of bytes being transfered)
The data bytes that need to be transferred
16 bit CRC. To generate the CRC, they have given a function
2 bit Acknowledge which should always be 11
7 bit End of Frame
3 bit with no data transfer (intermission)

Also, they've given an example for this also, with what the COB-ID should be like (0x600 + NODE_ID) and the data bytes should be...

... now As i had mentioned in my earlier post, if I knew exactly what Due sends via can, i.e. like which element of the structure is the ID, which element is data, etc ... I think i could achieve basic communication.

What I mean is like this : irrespective of the comm protocol, as long as i have a register somewhere that if i set it to : 1100000000111000111111111.. etc it will just put a start of frame, send the data, put end of frame and wait for the intermission, i can make it work

(this is something like UART, where i just put Serial.write('w'), it sends startframe + 'w' + endframe ... assuming no parity etc was enabled, now the 'w' may be according to some higher protocol, but for the transmitting_buffer, it doesn't really matter)

And also, for receiving, there would again be a receiving buffer (register) which i can just read in a continuous while loop ... like : i'll just put ...
if( CAN_RX_FLAG == true) {
my_msg = CAN_RX_BUF;
if(my_msg == 0x6d64f74e28.. )
Serial.print("comm was successful, motor is running ! ");
}

So ... any idea if some buffer like this are there ? or if I can use those structures in libsam for these ? Or maybe even instead of buffers, can I use mailboxes like this (as you said CanOpen is a higher protocol of Can, mailboxes would be there also ... i assume)

AJK101:
Could I make some haphazard venture to just "make it work" ?

I mean from the documentation from maxon, i got that it is expecting to receive :

1 bit Start of Frame
11 bit COB-ID (first 4 bits frame identifier, last 7 the ID of the receiving device)
1 bit RTR which should always be 1
6 bit control field (1 bit for identifier Extension which is to be dominant (1 ... i assume), 1 reserved bit which should also be dominant, 4 bits for Data Length Code which holds number of bytes being transfered)
The data bytes that need to be transferred
16 bit CRC. To generate the CRC, they have given a function
2 bit Acknowledge which should always be 11
7 bit End of Frame
3 bit with no data transfer (intermission)

The arrangement you listed above is just how CAN is sent over the wires. That's just vanilla CAN.

Also, they've given an example for this also, with what the COB-ID should be like (0x600 + NODE_ID) and the data bytes should be...

Yeah, now you're getting into CANOpen related stuff.

... now As i had mentioned in my earlier post, if I knew exactly what Due sends via can, i.e. like which element of the structure is the ID, which element is data, etc ... I think i could achieve basic communication.

What I mean is like this : irrespective of the comm protocol, as long as i have a register somewhere that if i set it to : 1100000000111000111111111.. etc it will just put a start of frame, send the data, put end of frame and wait for the intermission, i can make it work

(this is something like UART, where i just put Serial.write('w'), it sends startframe + 'w' + endframe ... assuming no parity etc was enabled, now the 'w' may be according to some higher protocol, but for the transmitting_buffer, it doesn't really matter)

And also, for receiving, there would again be a receiving buffer (register) which i can just read in a continuous while loop ... like : i'll just put ...
if( CAN_RX_FLAG == true) {
my_msg = CAN_RX_BUF;
if(my_msg == 0x6d64f74e28.. )
Serial.print("comm was successful, motor is running ! ");
}

So ... any idea if some buffer like this are there ? or if I can use those structures in libsam for these ? Or maybe even instead of buffers, can I use mailboxes like this (as you said CanOpen is a higher protocol of Can, mailboxes would be there also ... i assume)

Have you even downloaded my version of the library and looked at the four examples? The answers to your questions are pretty clear when you look at the examples.

Hi guys,
I tried to download
https://github.com/arduino-libraries/arduino-due-can
but it seems it is completely empty. I fiddled with the github command line tool but also I had no success. All empty.
What is wrong?

You're absolutely correct, it is empty. That's not where you get the can library from. You have two options:

Download the git version of the Arduino IDE and use the "can" branch.

Download my copy of the library and place it into your existing 1.5.2 directory where libraries for SAM go (hardware/arduino/sam/libraries).

The official Arduino IDE git repo is GitHub - arduino/Arduino: Arduino IDE 1.x
Mine is https://github.com/collin80/due_can

Pick your poison and download from one of those two places. It is probably easier to use my library both because the download will be a lot shorter and because it is the official version plus extra stuff I did thus it has more work done on it.

Thanks alot. I'll test it the next days.

Hello,

First, thank you all for your job, especially Palliser and AdderD !

I checked this topic from time to time and today I started to test the CAN on my Arduino DUE ! :slight_smile:

So I make here a first feedback of my first tests, in order to give some information and ask more questions...

First remark, I'm not a Github user, and I don't know how to download the CAN part of the official version, so I used the AdderD's version, which is available in a zip format (thanks).

So I just put the librairy in my directory and started to compile : OK.

About the hardware part, expecially the transceiver. I will also order the same SN65HVD234 as you, but at the right time I have one another kind of transceiver : MCP2551. It is a 5V transceiver, but I wanted to test it. its advantages : it is cheap and available in the "old fashion soldering", I don't know the word ("traversant" in french), I mean that you can easily solder it with you big figers and basic iron.

As it si 5V, of course it's better to put a Zener diode on the CanRx pin. And for the Tx, we hope that the 3.3v signal will be enough.

And the answer is.. yes, it seems to work fine.
With an oscilloscope I checked that 3.3v signal coming out of the Due is well transformed in differential tension.

Now, About first functionnal test.
My first test is the "Example1" delivered with AdderD librairy.
To understand a little bit more what I was sending I set CAN_MSG_DUMMY_DATA at 0.
So then I sent for example "250" from the serial port, and I got a communication with the result :
"CAN message received= 2500000000"

So display may be strange but it seems to work.

But I tried more values and I noticed that it works well only for value under 255... ?
Here is some examples of what I get :
250 => 2500000000
256 => 01000000
257 => 11000000
258 => 21000000
3000 = > 18411000000
65535 => 255255000000
65536=> 00100000

Do you have the same ? isn't it juste a problem of data interpretation or display?
I haven't yet looked insided the code, please give me your opinion about this.

Just a quick note to say I got my setup hooked up to the car today and it was working a treat. I've even got a nice interface in .NET at the other end to display the data. I'll try and get some pictures taken on Friday when I work on it again to share. :slight_smile:

Thanks for the hard work put in so far, and I look forward to seeing where this library goes in future!

Hello, new guy to the world of arduino and CAN. I apologize for the simple question, but using the example 1 from the zip file that Adder gave a link for a while back, I get "Type CAN message to send", but whatever I type nothing else happens. Apparently I never get into

if (Serial.read() == '\n') {
Serial.print("Sent value= ");
Serial.println(CAN_MSG_1);
}

Doesn't '\n' just indicate that the Return key was pressed? And actually with more testing, I realize the program gets to

while (!(CAN2.mailbox_get_status(0) & CAN_MSR_MRDY)) {
}

and then just waits forever. So I skip that if statement and go through everything till that while loop and just sit there. Could there be something wrong with the transceivers? I couldn't find a way to test that all initializing was actually taking place.

Thanks

Hello jspobuk,

I assume you are using Arduino IDE 1.5.2. and the wiring schematic shown in reply #33. If so,

  1. Make sure that the variant files (.c, .h) located in
    ...\arduino-1.5.2-windows\arduino-1.5.2\hardware\arduino\sam\variants\arduino_due_x\ contains the CAN0 and CAN1 pin definitions.
  2. Make sure you connected transceivers pins Rs to ground and EN pins to 3.3V.
  3. Make sure you connected CAN0_H with CAN1_H and CAN0_L with CAN1_L.

Please, keep us posted about it.

Wilfredo

Hello dammien,

I have not tried the CAN version you are using from AdderD.

I just tried the example 1 of my original library (published in github) with CAN_MSG_DUMMY_DATA equal to zero (as you did) and it runs OK, which means, if you send ABC you should receive ABC, or if you send 250 you should receive 250, or send 65536 should received 65536, etc...

It looks to me that what you are getting is the value you send but coded in HEX or so. Surely AdderD could explain better.

Anyway, I have attached for you my library below. If you can try it, let me know about how it goes.

-Wilfredo

CAN_API.zip (36.5 KB)

jspobuk: I don't want to sound like I'm stating the obvious, but since you say you're new to it then it may have been overlooked.... make sure the serial bitrate in your serial console is the same as the one in the serial.begin line. Without the code to hand I can't be certain, but I don't think there's any "halts" in the code before the first bit of code you post, and mismatched speeds could be a prime culprit there.