Revised: January 15th, 2014
I’ve recently revised a schematic of the MCP2515 (CAN) Shield.
My updates to it are:
3v3 or 5v I/O voltages for the MCP2515. I have sourced a transceiver chip that has a Vio pin to set the TX and RX IO voltage level (CAN specifies a 5 volt level for the bus, so VCC on the transceiver has to be 5VDC, there is no way around this.)
SPI via the ISP header with solder jumpers to change to the Digital IO SPI
Split termination of the CAN bus via two solder jumper or switch. (Split termination improves CMRR)
Option to choose pinout of the DE9 via three solder jumpers with no default option (I hate cutting traces)
Four position terminal block for custom power and CAN bus connection
R3 compatibility
Additional Suggestions:
Physical jumper or switch to move MCP2515 CS and INT lines to another pin.
Space for DC-DC converter (10-30VDC to ~7.5VDC connected to VIN)
Can anyone think of anything else I may have missed that doesn’t make the board application specific?
Things I plan on adding to the MCP2515_lib library:
Support for multiple MCP2515 transceivers
Support for other Arduino boards
Support to handle interrupts correctly
Support for error handling
Support for different board crystals (The library supports 16MHz, but you have to edit the header files to get 20MHz which is easier said than done. I made an Excel spreadsheet to calculate the constants. I’ll add that speadsheet to my MCP2515_lib repository on my Github soon.
Right now, a lot of the functionality of the MCP2515 is hard-coded using compiler define parameters in the header files. Most of the hard coded stuff doesn’t need to change, but there is room to grow.
I am also interested in writing a CAN library that supports other transceiver ICs but thats still a ways off. The Arduino Due has a CAN MAC but no PHY. If someone wants to send me a Due, I can make a start on implementing it and the MCP2515 into a combined library or something.
Yeah I have something,… making it possible to change the SPI SS/CS pin to another pin so it becomes possible to stack a shield on top of it which is also using pin 10 for SS/CS.
I am trying this right now, but I wired my CAN-shield from pin 10 on the shield to another pin as SS/CS on the UNO. I am trying it for days now, but cant get it to work, not sure what I am doing wrong, changed the “#define SPICS 10” in the file “mcp_can_dfs.h” into another port number but it is not working. When I change it back to 10 it works. Bit confused here. Got any experience with this?
I do have the intention of adding support for that to the library.
Right now, it is possible but you will need to set the new SS pin mode and state before initiating the CAN or SPI libraries in the code as well as changing the compiler define parameter in the header file.
eg.
pinMode(9, OUTPUT);
digitalWrite(9, HIGH); // Define IO state to a known level to make sure the MCP2515 is unselected before initiating both SPI and CAN.
CAN.begin(SOME_BAUD_RATE);
What about place for optional 2 x RJ45 connectors? For Model Railroading, NMRA (the powerful US Model Railroading Association) is setting NMRAnet features for a standardized bus based on a CAN-bus with OpenLCB protocols and specs, including 2 RJ45 connectors in each board.
But main feature to be incorporated, as you pointed before, should be the possibility to piggiback on an Arduino two or more Shields using SPI transmission (that is, your CAN Shield plus another other shield), thus allowing Arduino to have two different SS pins to able / dissable one or the other shield according to which one should communicate with Arduino at a due moment.
I will keep this in mind. I have a few railfans friends.
You can do that with the library on my github as well as use more than one CAN shield on the same Arduino. I had a CAN-Shield setup with an Ethernet shield a few days ago. Was taking received CAN data, encapsulating it inside a UDP packet, and sent it to of my Linux boxes. I made a Perl script to listen to the UDP port and display it on the console. I also have a breadboard with two MCP2515s connected to an ATmega328 that has been transferring data on one CAN bus to the other. Its been running for a good week or more now.
Can you please explain how you do this with a Perl Script // Console? It would be amazing for me to have a sort of a GUI on my laptop that can read in UDP packages coming over WiFi or Ethernet, and show them in Real-Time. The only thing I can do now is showing the whole UDP package in a terminal that keeps on running (for this I use the freeware tool UDP_TestTool). But it would be great to have a GUI in which you can dismantle your UDP packages and display different signals in the packages in a small window which constantly updates to the last incoming value.