Go Down

Topic: Building a CAN API for Arduino DUE (Read 367906 times) previous topic - next topic


Jul 04, 2013, 10:20 am Last Edit: Jul 04, 2013, 11:29 am by Transistorfips Reason: 1
No, I haven't. I'm (as a hobbyist) using PIC 18F for several years now and I haven't bricked not even only one. But if the CAN expanders base on the same rationale I do not know. At least for CAN it seems they have the same buffers, protocol engine and control as the 18F458. I actually have two of them on my perf board http://imageshack.us/photo/my-images/24/6urm.jpg/. True, the PICs sometimes are the worst imps of satan in the business. For example the CAN timing on my PICs are 7.7us instead of 8.0us at 125kbaud. I tried several hour to fix but without success. But they do their job with zero in the error counter.


Hi guys, i've been following this project since its inception and i want to thank everybody for such a great work.
I just got my DUE so i started to experiment, My goal is to use the DUE in a GMlan network which is a single wire CAN bus i got the transceivers so thats fine, my only problem is that the GMlan low speed is just 33.333Kbps, is there any way to incorporate that or any other custom baud rate in  the duo_can.h? i tried adding #define CAN_BPS_33k    33.333 but something is missing.


There are/were a couple of problems with trying to get 33.333K baud.

1. There are no fractions. The math is all done on integers so 33.333 is just 33
2. This is partly because baud is defined in thousands. If it were defined as the total baud then you could put in 33333 as the baud.

For proper results you need to be able to divide your system clock by some value to get the canbus baud rate. You will notice that the normal baud rates evenly divide millions of hertz because they are multiples of 5 (25,50,100,250,500,1000) 84MHz / 33333 = 2520.0252. The fractional part will go away leaving you with a divisor of 2520. 84MHz / 2520 = 33,333.333 baud. This is probably close even and maybe even what gmlan has in mind. Additionally, 84MHz / 126 (which is a valid divisor value) = 20 (and a very small fractional portion). 20 is a valid # of TQ. So, the library should be able to set the baud fairly accurately.

However, the only way you're going to get that baud rate is for you, me, or someone to modify the library to input the actual baud to the set_baudrate function. It's not hard to do. Just take out all of the "* 1000" spots and switch up the defines to be 1000 times what they are now. Then you can set any baud you want. I can't promise it will work but that's the way to try. I have attached a test copy of the due_can source code where I made the changes. I have not tested them. Try it out and let me know if it works. If it does I'll commit the changes to git and we won't have this problem any more.


Hi guys,
without reading the 16 pages of this thread before, does anyone has already made a real-world-application for the CAN?

I found CODE BY DEBRAJ DEB FOR OBD READER, https://sites.google.com/site/hobbydebraj/home/can-bus-based-obd-reader made for a Microchip PIC24 CAN device. This code is quite simple to port since all of the data handling is very similar to the data structures used by the Atmel/Arduino example. I fly to Spain for holiday on tomorrow but as a real nerd I of course have my Due with me. Hopefully while with my big toe drilling holes in the sand I have enough time to port the code under the parasol.


Jul 10, 2013, 09:23 pm Last Edit: Jul 10, 2013, 09:25 pm by Collin80 Reason: 1
Yeah, I eat my own dog food (common US expression... I use my own products). I'm using the library in an open source vehicle control unit: https://github.com/collin80/GEVCU

So, I do know that it works well enough, at least with standard frames. I've been occupied with hardware design recently so neither this library nor GEVCU have gotten much love recently but all of it does work.


Hello, so i found time to go back to my arduino due.  Still same problem as before.  I did hook up an oscilloscope as you suggested Collin80 in a previous post:

It can be hard to say. If you have an oscilloscope or logic analyzer you could try scoping the H and L pins at the output of the transceivers or scope the CANTX and CANRX pins at the Due to see if any form of signal is getting out. What you'd expect to see is a momentary signal as the frame is transmitted from one canbus device to the other. If there is as problem but it is trying to send you should see the frame very rapidly resending forever. This is pretty easy to see on a scope. If you are getting constant resends then either you aren't looped back, the signal is corrupt, or the receiver is not responding.

I hooked up just the due CANTX and GND. When i start the serial monitor I get a solid 3.2 V.  When i press "Send", I see the following screen.  Is that the resending forever you were mentioning?



It sort of seems that way. The default sending rate of the canbus examples is 1M baud so you really need to be closer to 1-10uS divs to see the actual signal itself but your larger div screen shows it trying to resend around 1.5ms between attempts. This makes it appear as if your Due is working perfectly fine. If things are still not working then perhaps the transceiver is not operating properly. You do have to enable the transceiver to make it work. You should probably try scoping the CANH and CANL lines to see if they're responding to the signal coming out of the Due.


Jul 22, 2013, 11:00 pm Last Edit: Jul 23, 2013, 12:16 am by jspobuk Reason: 1
So I got the signal to go all the way to the CANRX in to DAC0.  But the serial monitor still does nothing when I press send.  I can't get past the line:

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

Any help is greatly appreciated.


Hello jspobuk,
I don't remember if you followed the directions I gave you in my (reply #181). Remember, if you have the wrong variant files, the communication can't be established.


Please, keep us posted. Regards,


Yes, actually I was just re reading that.  this is what i have in my variant.h

* Complementary CAN pins
static const uint8_t CAN1RX = 88;
static const uint8_t CAN1TX = 89;

// CAN0
#define PINS_CAN0            (90u)
// CAN1
#define PINS_CAN1            (91u)

I believe that is correct, and my variant.cpp

// 88/89 - CANRX1/CANTX1 (same physical pin for 66/53)

  // 90 .. 91 - "All CAN pins" masks
  // 90 - CAN0 all pins
  // 91 - CAN1 all pins

which i also believe is correct.  I tried all the examples, but to no avail.  If i comment out the while loop in the example one that i alluded to above, it prints out 00000000.


Jul 23, 2013, 04:16 am Last Edit: Jul 23, 2013, 04:23 am by Palliser Reason: 1
I was double checking that. I also believe you forgot to mention the following remaining lines:

In variant.h:
Code: [Select]
static const uint8_t CANRX = 68;
static const uint8_t CANTX = 69;

In variant.cpp
Code: [Select]
// 68/69 - CANRX0/CANTX0

I have a check-out list somewhere. I will try to find it but in the meantime remember:

1. CANH0<->CANH1    /    CANL0<->CANL1
2. 'direct mode' in the transceivers connecting pins 5(EN) to 3V3 and pins 8(Rs) to GND.
3. Serial monitor of the Arduino IDE 1.5.2 with autoscroll and newline modes activated.

EDIT: Terminal resistors (120 ohm) between CANL and CANH lines.


I know that it's totally wrong place but I don't know where I can get it, maybe someone from forum can help me.
I've bought these interface:

Looks fine but unfortunately CD with software was broken. I'm looking for any of these programs:

  • CANPro protocol analysis platform for the latest version (V1.46)

  • ZLG USBCAN equipment CAN-bus Universal Test Software CANTest latest version (V2.17)

  • CANTools latest software tools version (V6.12)


Thanks Palliser,

I didn't have newline mode on, which caused the "Sent Value" to not show up.  And I have at least one bad connection which is what kept the while loop going. (i am starting to dislike surface mount chips).  After I finish with these simple connection issues I want to be able to communicate J1939.  Anyone else know about J1939?  I want to be able to read and maybe write to diesel engines that are J1939 compatible. However, its pretty murky waters to me right now.  If anyone else is also doing stuff, any help is greatly appreciated.



Hello jspobuk,

As I mentioned in my reply #125, I am not sure if the CAN library support J1939. Definitively the one that have gasped more with it is Collin80. Please, read his reply 126 about the masking. Anyway, if you have the specific brand and model of your J1939 device, please, let us know. May someone else is working with it or we could make time to read about it and try to help you more.



Go Up