I've been playing around with CAN BUS, with a view to using it for home automation, mainly because it seems a really cheap way of off-loading communications to another device, freeing up the Arduino to do whatever in the meantime. The main problem I've had is the shortage of documentation and simple beginners sketches to start off with. I built two breadboard copies of the Seeeduino CAN-BUS Shield (http://www.seeedstudio.com/wiki/CAN-BUS_Shield) using two Nano Arduinos. CS is shown as selectable, but I used D10 and it works fine, 16MHz crystal with 2x22pf capacitors and 2x 0.1uF capacitors, one across each chip's supply as decoupling, and a random 330 Ohm resistor I had laying around as CAN-BUS terminator!
The Seeduino CAN-BUS Shield library does not work properly, and neither do the examples! Or at least I couldn't get them working initially in Arduino IDE 1.0.1. Fortunately the debugging in the compile window at the bottom of the Arduino IDE is pretty good, and I found that this was enough to help me correct the odd mistakes made there. I had to re-write the Receive example, as the contents of the original seem intended to do something completely different!
I hope this helps someone; it's far from being a complete network, but from reading the MCP2515 datasheet it looks relatively straightforward to implement Masks and Filters. If you can't be bothered to do that you could use the Arduino to do the filtering instead and just use the cheap hardware to do the receiving, buffering and CRC etc.
Seeduino CAN-BUS Shield clone Send.ino
#include "mcp_can.h"
#include <SPI.h>
unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
void setup()
{
delay(5000); // delay to allow me time to open the serial monitor window to check all is well
Serial.begin(9600);
if(CAN.begin(CAN_500KBPS) ==CAN_OK) //check the Seeeduino CAN-BUS wiki for more details on code
{
Serial.print("can init ok!!\r\n");
for (int i = 0; i < 9; i = i + 1)
{
Serial.print(stmp[i], DEC);
}
}
else Serial.print("Can init fail!!\r\n");
}
void loop()
{
CAN.sendMsgBuf(0x00, 0, 8, stmp);
delay(1000); //
}
Seeduino CAN-BUS Shield clone Receive.ino
#include "mcp_can.h"
#include <SPI.h>
#include <stdio.h>
#define INT8U unsigned char
unsigned char Flag_Recv = 0;
unsigned char len = 0;
unsigned char buf[8];
char str[20];
void setup()
{
delay(5000);
Serial.begin(9600);
if(CAN.begin(CAN_500KBPS) ==CAN_OK) Serial.print("can init ok!!\r\n");
else Serial.print("Can init fail!!\r\n");
attachInterrupt(0, MCP2515_ISR, FALLING); // interrupt indicates when message is available
}
void MCP2515_ISR()
{
Flag_Recv = 1;
}
void loop()
{
if(Flag_Recv)
{
Flag_Recv = 0;
CAN.readMsgBuf(&len, buf);
Serial.print("CAN message length = ");
Serial.print(len, DEC);
Serial.print(" CAN message = ");
for (int i = 0; i < 8; i = i + 1)
{
Serial.print(buf[i], DEC);
}
Serial.println();
}
}
If anyone else wants to try this and has problems with Seeduino CAN-BUS library, I post those as well; I just can't remember exactly what I had to change!
Cheers, JJ