I have some experience with the MCP2515 with both the ISO and the J1939.
I built logger and gateways using the UNO and the 1284P.
I also have access to buss analysis tools and would be willing to help out as needed.
Thanks
Bruce
I have some experience with the MCP2515 with both the ISO and the J1939.
I built logger and gateways using the UNO and the 1284P.
I also have access to buss analysis tools and would be willing to help out as needed.
Thanks
Bruce
What bus analyzer do you use? I've been considering getting one of these, but mainly because I have their USB analyzer that works quite well.
Truth is, I have pretty much zero experience with CAN bus. But I do have 20+ years experience developing with microcontrollers and several years on Arduino libraries and code.
I could use a little advice about what to do on the CAN side of things.....
I use the Vector CANALYZER PRO with J1939 option.
These are pretty expensive and I have tried to replace this with some small micros. I have 4 gateways running with UNO's right now. $80 bucks ~$2000.
Any help is greatly appreciated, you guys are the greatest. I just want to send and receive one message in 11 bit and 29 bit. When I change the example DUMMY_DATA to 0x1234 and 0x5678, I get some kind of endian format with number pairs reversed. And the 29 bit message header is always 0. I can't get the message header for 29 bit. I have a seeeduino shield to monitor also. The seeeduino receives the right bit header, but not the Due. It also does not seem to send the 11 bit correctly. I tried to clear codes on my car but was not successful. The message never got interpreted by the ecu correctly.
Would someone be able to post simple code that I can analyse? I only want one mailbox to send, and then receive for 11 and 29 bit - all masks will do.
I too am watching this forum closely. I agree that the code should be simplified, like seeeduino with less concern for the Due internals.
I put in an order for the OSH Park Arduino Due CAN Test Board.
Does anyone have a parts list or link to a shopping cart (jamco, mouser, digikey) I can use for the can transceiver, resistor, caps, and DB9 header.
I am fairly new to surface mount components and am not sure what physical size components were used in the design.
I already have a DB9 to OBD adapter from the UNO can shield.
Yes pm me. Fwiw I finally have a production run of shields on order and I can share some of my prototyping stuff and parts list.
Arbies:
I put in an order for the OSH Park Arduino Due CAN Test Board.
Does anyone have a parts list or link to a shopping cart (jamco, mouser, digikey) I can use for the can transceiver, resistor, caps, and DB9 header.
Yes, here you go. I also updated the description at OSH Park.
Qty Digikey P/N Description
--- ----------- -----------
2 296-27991-1-ND CAN transceiver
2 445-7660-1-ND Capacitor, 10uF, 805
2 399-1170-1-ND Capacitor, 0.1uF, 805
2 609-4003-ND DB9M connector
2 CF14JT120RCT-ND Resistor, 120 ohm
2 3M9447-ND Header, 2 pin
2 3M9580-ND Jumper
Ok, it seems I had to send three times to the ecu before it responded.
id = 0x7DF
databyte[0]=0x2
databyte[1]=0x1
databyte[2]=0x0
databyte[3 to 7] = 99
global send three times in succession did the trick. I guess my jury-rigged shield needs help.
Well I finally got my shield to work reliably, bad soldering was the problem.
Now I am faced with a 29 bit extended frame problem.
I modified the Sample 4 to Serial print some data
#define TEST1_CAN_TRANSFER_ID 0x11AE756A //random 29 bits
CAN.get_rx_buff(&inFrame); //read the message
//display the message
Serial.print(" fid ");Serial.println(inFrame.fid);
Serial.print(" ide ");Serial.println(inFrame.ide);
Serial.print(" inFrame id = "); Serial.println(inFrame.id, HEX);
Serial.print(" id len = "); Serial.println(sizeof(inFrame.id), HEX);
What I don't see correctly is the inFrame.id.
This is what I get:
inFrame id = 2756A
id len = 4
fid 40000000
ide 1
The due_can.cpp file has the following:
ul_id = m_pCan->CAN_MB[uc_index].CAN_MID;
if ((ul_id & CAN_MID_MIDE) == CAN_MID_MIDE) { //extended id
rxframe->id = ul_id & 0x3ffffu;
//rxframe->id = (ul_id); // I wanted to look at the id - it always returns a 3 in the leftmost position
rxframe->ide = 1;
}
else { //standard ID
rxframe->id = (ul_id >> CAN_MID_MIDvA_Pos) & 0x7ffu;
rxframe->ide = 0;
}
inFrame id = 2756A //should be 11AE756A that was set as the id
id len = 4
fid 40000000
ide 1
Here is the modified cpp file result:
inFrame id = 31AE756A
I modified the file to look at the id and it returns 31AE756A (always a 3 in front)
I am hoping someone will show me just how dumb I am that I am overlooking an obvious parameter.
I'm fairly sure that extended frames are messed up in a variety of ways currently. I'm going back through this library once again and fixing it up so the problems should be corrected within a week or so. Also, I'm vastly simplifying the interface for most uses so it should be a lot easier to use too.
I have just pushed a commit to github. There are two examples now (as opposed to the previous four) but they show how to use the library now. Word of warning: If you update to this version of the library you will very likely need to update your sketch. Some things have changed. The function to get frames (get_rx_buff) now takes a reference parameter instead of a pointer. This should be easier for most people to use. There are now easy functions for sending frames, receiving frames, and setting filters. There is now less need to directly call low level functions or have to mess with the interrupts. A lot more things are handled within the library now. Additionally, all can frames now use CAN_FRAME instead of having different versions for RX and TX. CAN_FRAME now uses a union for the data bytes so you can directly set things 1 byte, two bytes, 4 bytes, or all 8 bytes all at once.
I have done various tests and this version of the library seems to properly send frames in both standard and extended mode. I have tested reception of standard frames but haven't tested reception of extended frames yet. Both included examples have been verified by connecting a Kvaser Leaf Light to a dual canbus board to scope the traffic.
More changes are coming soon. I'll also create a document that details how to use the new functions.
Hi all,
I recently started following this thread and I was trying to see if I could get it to work on my own. I cant, however , seem to get the examples to compile and I keep getting the following errors.
CAN_EchoTest.ino:7:21: error: variant.h: No such file or directory
In file included from C:\Users\jhsieh\Documents\Arduino\libraries\due_can/due_can.h:72,
from CAN_EchoTest.ino:8:
C:\Users\jhsieh\Documents\Arduino\libraries\due_can/sn65hvd234.h:34: error: 'uint32_t' does not name a type
C:\Users\jhsieh\Documents\Arduino\libraries\due_can/sn65hvd234.h:37: error: 'uint32_t' does not name a type
C:\Users\jhsieh\Documents\Arduino\libraries\due_can/sn65hvd234.h:39: error: 'uint32_t' does not name a type
etc...
I'm sure I have done something obviously wrong. Can anyone point it out?
noop:
Well I finally got my shield to work reliably, bad soldering was the problem.
Now I am faced with a 29 bit extended frame problem.The due_can.cpp file has the following:
ul_id = m_pCan->CAN_MB[uc_index].CAN_MID;
if ((ul_id & CAN_MID_MIDE) == CAN_MID_MIDE) { //extended id
rxframe->id = ul_id & 0x3ffffu;
//rxframe->id = (ul_id); // I wanted to look at the id - it always returns a 3 in the leftmost position
rxframe->ide = 1;
}
else { //standard ID
rxframe->id = (ul_id >> CAN_MID_MIDvA_Pos) & 0x7ffu;
rxframe->ide = 0;
}
Your problem with the extended ID was not your fault at all. You can see in the snippet you posted this line:
rxframe->id = ul_id & 0x3ffffu;
I'm not sure what sort of brain malfunction beset me or whoever wrote that but the proper mask for extended frames is 0x1FFFFFFF not 0x3FFFF. I just fixed that in the git repo. Extended IDs are stored in the bottom 29 bits of the register so all you have to do is mask off the extended bit which is what that line was supposed to do. Try your sketch again and I think you'll see it work better now. Sorry about that.
jwhsiehum:
Hi all,I recently started following this thread and I was trying to see if I could get it to work on my own. I cant, however , seem to get the examples to compile and I keep getting the following errors.
CAN_EchoTest.ino:7:21: error: variant.h: No such file or directory
In file included from C:\Users\jhsieh\Documents\Arduino\libraries\due_can/due_can.h:72,
from CAN_EchoTest.ino:8:
C:\Users\jhsieh\Documents\Arduino\libraries\due_can/sn65hvd234.h:34: error: 'uint32_t' does not name a type
C:\Users\jhsieh\Documents\Arduino\libraries\due_can/sn65hvd234.h:37: error: 'uint32_t' does not name a type
C:\Users\jhsieh\Documents\Arduino\libraries\due_can/sn65hvd234.h:39: error: 'uint32_t' does not name a type
etc...I'm sure I have done something obviously wrong. Can anyone point it out?
Hmm... variant.h does exist. My guess is maybe you aren't using the proper Arduino IDE (you need 1.5.2 or newer) or that you forgot to set the board to Arduino Due (programming or native port). Otherwise, you do have the library installed to the proper place so it should work.
I posted another example (a traffic snooper). But, does anyone have any other requests or suggestions? Maybe an example of how to do PID requests and parse responses for OBDII? I'd like at least some of the examples to be useful right off the bat for various things instead of being pointless demonstrations of features.
So originally I noticed I needed to update arduino and I did, but my stupid self forgot to switch the board back after updating. Thanks for the help!
Hello Collin,
Respect for doing this. I will read this topic in more detail ASAP, because I am now using a UNO with a CAN-bus shield. To use the DUE will be a big inprovement.
Thanks! I will give you feedback and I am willing to help further develop this. You can always PM me if you need help with something. I am not an expert, but maybe there is something I can do.
Pieter
Collin80:
I have just pushed a commit to github. There are two examples now (as opposed to the previous four) but they show how to use the library now. Word of warning: If you update to this version of the library you will very likely need to update your sketch. Some things have changed. The function to get frames (get_rx_buff) now takes a reference parameter instead of a pointer. This should be easier for most people to use. There are now easy functions for sending frames, receiving frames, and setting filters. There is now less need to directly call low level functions or have to mess with the interrupts. A lot more things are handled within the library now. Additionally, all can frames now use CAN_FRAME instead of having different versions for RX and TX. CAN_FRAME now uses a union for the data bytes so you can directly set things 1 byte, two bytes, 4 bytes, or all 8 bytes all at once.I have done various tests and this version of the library seems to properly send frames in both standard and extended mode. I have tested reception of standard frames but haven't tested reception of extended frames yet. Both included examples have been verified by connecting a Kvaser Leaf Light to a dual canbus board to scope the traffic.
More changes are coming soon. I'll also create a document that details how to use the new functions.
I've read most of this topic, then started skimming though it as troubleshooting questions took up most of the posts. I wanted to clarify some things and also add to the discussion about the MCP2515 CAN protocol controller that has been used on the ATmega328 among other legacy Arduinos as I have experience with it. At some point I, if someone else does not try to first, want to make it interoperable with the Due's CAN library so more than two transceivers could be used with the Due. I suspect after the modifications I recently made to the MCP2515 library that it might work now, but I do not have a Due, yet, to test with.
As for J1939 and other High-Level "CAN" protocols. Those should be ENTIRELY supported with the CAN controllers on the Due. I've used the ATmega328 with the MCP2515 to interface directly with J1939 systems. J1939 really is just a specification to make smart engine sensors and components work between manufactures. It transmits extended CAN IDs and 8 data bytes. The only catch is, you have to figure out the CAN ID from the PGN and source address which is not that hard. If you have access to a list of PGNs and SPNs, you can figure out a lot of what goes on in a J1939 bus. I used J1939 at my employer, and I have become very familiar with it.
I also want to say that support for higher-level protocols should be made in an additional library that takes use of the CAN library. There is no reason to add high-level bloat to the low-level library that not everyone will want or need, but that is my opinion.
As for what IC should be implemented on the Due CAN Shield, I would really like to see the 235 used because the ability for auto-baud selection without sending errors to the bus would be very useful to me. I would also suggest that the standard CAN pin-out be used if a DE9 is put on the shield.
FWIW - we have a production run of protoshields with CAN support now available. http://togglebit.net/product/arduino-due-can-shield/. Also found on Ebay. Thank you to everyone who helped and provided feedback!
Nice product! Thank you Dan for your contribution to make the Arduino DUE CAN interface easy to access using your protoshield. Please, keep us posted about the feedback from your curstomers. Regards, Palliser.