Cheap & simple MCP2551/MCP2515 CAN BUS set up

Try the library here: GitHub - coryjfowler/MCP_CAN_lib: MCP_CAN Library

I have fixed a lot of the issues I encountered with the Seeedstudio library and the examples. It has been working pretty well at this point even hooked up to highly utilized CAN Buses. I also have the intention to add support for multiple MCP2515 ICs, error support, and a better interrupt handling method.

Also, using the MCP2515 in "listen" mode causes it to NOT acknowledge any messages it receives. It is in a purely ears-only mode. If you use this mode on a CAN bus with only one other active CAN transceiver, you will find messages are sent infinitely till its controller errors out and shuts down.

Guys,

I've been doing a bit of tinkering with bus networking for a particular project I'm working on. Initially I attempted to implement ModBus protocol running on an RS-485 physical layer using 3 arduino slaves and one Mega master. My over-all intention/objective is to prototype for a large 100+ node-support each performing simple tasks. Each slave/node has ONE output and TWO inputs which they need to monitor and report to a master controller. A GUI app will be tied to the master node making use of the data for an operator.

This was successfully done using ModBus, however, the major draw-back is that for my project I will NOT have the ablity to individually preset the slave IDs. On the flip-side, I will be embedding a UNIQUE serial IC that will guarantee each node to have a non-repeating addressable value.
My issue with ModBus is that I cannot detect a new slave added to the network without knowing it's address to ask it it's address....if that makes sense. Furthermore, as per the requirements of the task at hand, I am to assume that ALL 100+ nodes are identically flashed and are ALREADY connected to a bus. Oh AND I have no physical access to each node (they're mounted behind cabinets and installed by NON-technical people....they just connect them...that's IT!).

That's where I stumbled upon switching to a CAN bus. Being that I can load identical firmware on each node and (in theory) I can have a multi-master situation where each node can broadcast onto the bus, this seemed pretty promising. First of all, am I understanding correctly? Can I in fact upon connecting to the network send out a message that has a destination address of the MASTER node to say 'hey, I'm new, give me a node address?.' Or even have the MASTER node send out a broadcast message periodically asking 'hey, is there anyone new?.'

If so, does the library linked above (GitHub - coryjfowler/MCP_CAN_lib: MCP_CAN Library) have commands to support this?
I want to make sure before I buy a few shields to support CAN bus. Maybe CAN isn't the best answer....any ideas guys?

Thanks in advance.

bsahilu,

Did you get answers to your questions? I am a noob at CAN - very simply trying to establish some triggering / simple monitoring of some equipment using the Sparkfun CAN-BUS shield - and can't seem to figure it out... Would be interested if you got anywhere with your questions!

bsahilu:
Guys,

I've been doing a bit of tinkering with bus networking for a particular project I'm working on. Initially I attempted to implement ModBus protocol running on an RS-485 physical layer using 3 arduino slaves and one Mega master. My over-all intention/objective is to prototype for a large 100+ node-support each performing simple tasks. Each slave/node has ONE output and TWO inputs which they need to monitor and report to a master controller. A GUI app will be tied to the master node making use of the data for an operator.

This was successfully done using ModBus, however, the major draw-back is that for my project I will NOT have the ablity to individually preset the slave IDs. On the flip-side, I will be embedding a UNIQUE serial IC that will guarantee each node to have a non-repeating addressable value.

The CANopen NMT protocol will solve this for you. It has a Master node that keeps track of what nodes are on the bus, sends out periodic requests for new nodes to announce themselves, allocates them an unused address and implicitly gives them permission to participate in the bus with that new address.

bsahilu:
That's where I stumbled upon switching to a CAN bus. Being that I can load identical firmware on each node and (in theory) I can have a multi-master situation where each node can broadcast onto the bus, this seemed pretty promising. First of all, am I understanding correctly? Can I in fact upon connecting to the network send out a message that has a destination address of the MASTER node to say 'hey, I'm new, give me a node address?.' Or even have the MASTER node send out a broadcast message periodically asking 'hey, is there anyone new?.'

Yes, CAN is multi-master. But you generally want to design your network so that only one special head node runs particular master services like address-space management. The CANopen NMT is similar to what you suggest, with a dedicated NMT Master service running on a central node and managing who has access to the bus with what address. The specification provides for several levels of intelligence from both the NMT master and each of the slaves, from fully-dynamic and capable of error-reporting, down to basically brain-dead operation from jumpered addresses.

If you go with a recognised presentation protocol like CANopen, it also gives you formalisms for communicating the input and output values of each node that will possibly be compatible with other commercial (factory automation) systems. Plus other useful things like the ability to download configuration data/code to your slaves and whole lot more.

coryjfowler:
Try the library here: https://github.com/coryjfowler/MCP2515_lib

I have fixed a lot of the issues I encountered with the Seeedstudio library and the examples. It has been working pretty well at this point even hooked up to highly utilized CAN Buses. I also have the intention to add support for multiple MCP2515 ICs, error support, and a better interrupt handling method.

Also, using the MCP2515 in "listen" mode causes it to NOT acknowledge any messages it receives. It is in a purely ears-only mode. If you use this mode on a CAN bus with only one other active CAN transceiver, you will find messages are sent infinitely till its controller errors out and shuts down.

Hi cory,
Your library for MCP2515 is the best one I've tried so far. Thank you very much. I also found a bug in sendMsg() function, which I guess you might want to be informed of.

I think the code: res1 = mcp2515_readRegister(txbuf_n) should be changed to: res1 = mcp2515_readRegister(txbuf_n - 1) to get TXBnCTRL correctly. I check the library, txbuf_n is the address of SIDH returned by mcp2515_getNextFreeTXBuf(&txbuf_n). If bit3 in SIDH happen to be 1, the bit will never be cleared even the CAN message has been sent successful, and sendMsg() will be stuck in the while loop until the set TIMEOUTVALUE is reached.

The library I linked to has no high-level functions. It is purely a library to control the MCP2515 for generic CAN use. Higher level functionality would need to be coded for your specific needs in your sketch. I have used the library to mock other protocols like J1939 and NMEA2000 but my sketch is what contained that higher functionality. It would be possible to create additional libraries that take advantage of the MCP2515 library to allow a more streamlined approach to these other protocols but that is outside the scope of the library I have been debugging and improving. I hope that clarifies things a bit.

lian999111:
Hi cory,
Your library for MCP2515 is the best one I've tried so far. Thank you very much. I also found a bug in sendMsg() function, which I guess you might want to be informed of.

I think the code: res1 = mcp2515_readRegister(txbuf_n) should be changed to: res1 = mcp2515_readRegister(txbuf_n - 1) to get TXBnCTRL correctly. I check the library, txbuf_n is the address of SIDH returned by mcp2515_getNextFreeTXBuf(&txbuf_n). If bit3 in SIDH happen to be 1, the bit will never be cleared even the CAN message has been sent successful, and sendMsg() will be stuck in the while loop until the set TIMEOUTVALUE is reached.

I will look into that, thanks for pointing it out!

Hi Guys!

I've been looking at this library and the code for some time now. The CAN.sendMsgBuf() function uses the ID of the receiving end but is this limited to 0xFF? Normaly CAN can handle more nodes so is this a restriction of the library?

coryjfowler:
Try the library here: GitHub - coryjfowler/MCP_CAN_lib: MCP_CAN Library

I have fixed a lot of the issues I encountered with the Seeedstudio library and the examples. It has been working pretty well at this point even hooked up to highly utilized CAN Buses. I also have the intention to add support for multiple MCP2515 ICs, error support, and a better interrupt handling method.

Also, using the MCP2515 in "listen" mode causes it to NOT acknowledge any messages it receives. It is in a purely ears-only mode. If you use this mode on a CAN bus with only one other active CAN transceiver, you will find messages are sent infinitely till its controller errors out and shuts down.

Did you ever build a library for multiple mcp2515 ?

I'm interested in having 2 can bus shields controlled by one controller.

goodguy:
Did you ever build a library for multiple mcp2515 ?

I'm interested in having 2 can bus shields controlled by one controller.

The library has been capable since 2014, if I recall correctly.

Before the setup() function, does the following exist?

MCP_CAN CAN0(10);

If so, make

MCP_CAN CAN1(the unique digital pin the second CAN chip select is on);

MCP_CAN CAN2(the unique digital pin the third CAN chip select is on);

and so on.

coryjfowler:
The library has been capable since 2014, if I recall correctly.

Before the setup() function, does the following exist?

MCP_CAN CAN0(10);

If so, make

MCP_CAN CAN1(the unique digital pin the second CAN chip select is on);

MCP_CAN CAN2(the unique digital pin the third CAN chip select is on);



and so on.

I must have looked at the wrong library.

The one I played with has;

const int SPI_CS_PIN = 10;

MCP_CAN CAN (SPI_CS_PIN);

Do you have a link to the gethub page with the correct library? Thanks so much.

Had time today to try this library.

Thanks Cory for the link and library.

Having a problem with it.

Have any idea why?

Thanks

See attached image.

2016-07-14 13.36.40.jpg

DO NOT use MCP_STD or MCP_EXT in the can0.begin(...) function. There is a bug in the silicon of the MCP2515 and the feature does NOT operate as specified in the datasheet. The only two solid modes are MCP_ANY or MCP_STDEXT. I have confirmation from Microchip on the bug.

**** AUTOMATED MESSAGE - SEE RESPONSE METHODS BELOW ****

Below is a proposed resolution from Microchip Engineering Support Team for your Ticket 278363

Area : Analog/Interface Products
Product Group: SMPINT
Product : MCP2515

Problem Description:
I have been developing a library for the MCP2515 protocol controller for the Arduino community. I am at the point where I believe that the issue lies in the IC and not the library. My issue is with the mask and filtering functions with-in the IC. I have found that what I am seeing contradicts what the datasheet reads. DS21801G page 27 and 28 inform me that setting RXM1 and RXM0 on the RXBnCTRL register will change how received frames are handled. Setting those bits to '11' receives everything and ignores the mask and filter functions, setting those bits to '10' will receive only valid extended IDs that meet filter criteria and so on.. I have set those bits to '10' in both registers and I still get standard IDs entering the receive buffer. I have set up the library to read the register after it has written to the IC and shows the correct values were written. The same goes if I set those bits to '01' I will still get extended IDs appearing, but, as the data sheet declares, the registers RXFnEID8:RXFnEID0 are ignored. Basically, it was filtering the first 11 bits of the extended IDs that came in. This was across more than one IC, though, they were probably from the same lot as they were purchased together from Mouser. Assistance would be greatly appreciated.

This is identical to Ticket 273853.

My test bus has standard identifier and extended identifier messages being transmitted on it. With both masks empty both extended identifiers and standard identifiers entering the receive buffer of the MCP2515 I am using regardless of how the above bits are set which does not correspond to the datasheet as I understand it.

Problem Resolution:
Hi Cory,

I have received feedback from the MCP2515 applications engineer.

In short, he was able to reproduce the observations related to RXM 01 and 10 are not working as described. I am expressed interest in exercising similar tests on the MCP25625, a new CAN module, and exercising a design review of cause if there is a similar result. However, the given the age of the MCP2515 design, it is unlikely the MCP2515 will be reviewed by design and updated.

Observation Summary:
RXM 00 can be used to setup filters.
RXM 11 can be used to receive all messages.
RXM 01 and 10 are not working as described.

Thanks for your persistence,

Michael

Hello,
I am trying to set up an CAN network using a can shield from aliexpress with the MCP2515 and a TJA1050 tranceiver.
For the test I am using a arduino nano and your libray Cory.

When I try the Send example the initializing works fine, but then I always get the "error sending message"

Is there a way, to get more debug information? Do I have the send an ack message or something else? I am just reading the can signals from the Arduino with a CAN USB interface which I use at work.

BR Alex

"Do you have to send the acknowledge" - No, the acknowledge is a single dominant bit that is sent by any active receiving node on the CAN bus and should be an automatic thing handled by the protocol controller in your USB dongle assuming it is not in a listen-only mode.

What kind of USB dongle is this and are you receiving anything?

If you are receiving a message, I would check to ensure that the USB dongle you are using is in an active mode on the CAN bus (Not listen-only).

If you are not receiving any messages, I would check to confirm the crystal frequency set in the program matches the actual crystal frequency on the shield and then confirm baud-rates are the same between the program and your USB dongle. (I have see a lot of cheap Chinese boards using 8MHz crystals instead of 16MHz that Seeedstudio and SKPang have used.)

I am using a Vector VN1630 and for viewing the messages I use the trace function in CANape.
No I am not receiving anything. My shield has a 8Mhz crystal so I changed the initialize line to "CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK)"

For wiring the shield I used Pin10 (CS), Pin11 (MOSI), Pin12 (MISO), 13 (SCK).
This should be correct and also I got the "MCP2515 Initialized Successfully!" message so it seems that the spi connection works.

Edit: I found the error in the Shield. It has a pin header as well as a screw terminal for the CAN connection. The screw terminal somehow seems not be connected properly on the PCB because as I tried the pin header it works just fine!

Sorry about the delay, I just returned from a trip and I didn't have an Arduino with a CAN shield with
me.

I have a clone UNO setup with an old Seeed Studio CAN shield and without any changes to the send example, I am able to see the example message come across CANalyzer at 500k.

Unfortunately the shield I have uses a 16MHz crystal, but I have a MCP2515_CAN break out that uses an 8Mhz crystal and with the frequency modification to the begin function, I see the message come across CANalyzer.

At this point I suspect the shield you sourced may have a bad connection between the protocol controller IC and the transceiver IC, or there is a wiring error between the shield and the CAN dongle. I assume you also have the bus terminated; at least one termination resistance must be present for reliable communication to occur.

for the CAN-BUS Home Automation i made PCBs for use behinde a light switch or power outlet, the pcbs are already in production. This little PCB will have an atmega8 and a MCP2515/TJA1050 Can Bus Transceiver, a Relays for switching / a MOSFET for powering LEDs with pwm.
There are also 7 analog inputs for reading back some things like NTC, LDR or for other useage.
The 8th analog Input replys the state of the relays/mosfet.
There are 8 solder-jumpers for setting the CAN ID (lower 8 Bits of 11)
Here a preview of the pcb:


I use a standart 4 wire telephone cable for CAN-L, CAN-H, GND and 24V.
Every Slave has a little step-down converter to make the 5V.
Somewhere there will be 24V/7Ah PB-Batteries for Backup-Power, so the system runs even mains fail.
The sketch for the master you can see here: CAN MASTER
The sketch for the slave you can see here: CAN SLAVE
These 2 Units are running very stable since about 2 weeks!
I am using standart IDs 000-7FF.
The Master is a UNO+ElecFreaks CAN Shield
,
the Slave is a Nano with this small MCP2515 PCB,8Mhz.

more updates will be published...

the pcbs has arrived and i assembled two of them, everything works fine!
on my test-setup there are one Nano+2515 pcb, one uno+can-shield, 2 round pcb with atmega8.
one atmega8 runs at 12Mhz, the other one with 8 Mhz, both are more than fast enouhg.
The one round pcb is lighting a LED with PWM, the other one turns on/off a relays.
The Voltage is at the moment 12V, later 24-28V.
On AnalogInput7 there is a VoltageDivider to measure the output, there will be a second voltage divider on A6 for measuring the 24V, so i can read and monitor this.
The next step will be making a website for home automation.

Very nice! Like to see projects using Can Bus, it's very simple, reliable and incredibly cheap.

For your Website, have a look on using Grafana + Influxdb for graphing if you plan to collect sensor and status data. It's very simple to insert data and the create nice dashboards. I have created a little blog showing some basics: https://talk2.wisen.com.au/2016/05/24/influxdb-grafana/

I normally run it on a RPI with a Can Bus (don't forget RPi is 3.3v only) or connected via Serial with another Arduino working as Gateway, but I also have some setups using a Google Cloud VM, sending the data over the I internet.