I am seeing many people who want to establish CAN communication between Raspberry Pi and Arduino and that made me post the solution here .
VERY IMPORTANT NOTE:
1.Most of my steps are from viewtopic.php?t=141052 , Please check that out before coming here
2. You should not give 5V to MCP2515 at it may damage your Raspberry pi GPIOs , So there is a step for giving 3.3V to MCP2515(CAN controller) and 5V for TJA1050(CAN transceiver) , That soldering step is available in viewtopic.php?t=141052 , Please do that first and come here or else your raspberry pi will be damaged.
[OR]
You can use a logic level shifter similar to this https://learn.sparkfun.com/tutorials/bi ... -guide/all , Please share if you do so!!
Connections:
Code: Select all
RPi to CAN module
3.3V (Physical Pin 1) <==> Vcc CAN module
5V (Physical Pin 2) <==> soldered capacitor behind CAN module
GND (Physical Pin 6) <==> GND CAN module
CE0 (Physical Pin 24) <==> CS CAN module
MISO (Physical Pin 21) <==> SO CAN module
MOSI (Physical Pin 19) <==> SI CAN module
SCLK (Physical Pin 23) <==> SCK CAN module
GPIO-BCM-12 (Physical Pin 32) <==> INT CAN module
Code: Select all
UNO to CAN module
5V <==> Vcc
GND <==> GND
Pin 13 <==> SCK
Pin 12 <==> SO
Pin 11 <==> SI
Pin 10 <==> CS
Do the following :
1.Open the configurations file
Code: Select all
sudo nano /boot/config.txt
Code: Select all
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=12
dtoverlay=spi-bcm2835-overlay
3.
Code: Select all
sudo apt-get install can-utils
Code: Select all
sudo reboot
Code: Select all
ls /sys/bus/spi/devices/spi0.0
driver modalias net of_node power statistics subsystem uevent
ls /sys/bus/spi/devices/spi0.0/net
can0
ls /sys/bus/spi/devices/spi0.0/net/can0/
addr_assign_type dev_id link_mode proto_down
address dev_port mtu queues
addr_len dormant name_assign_type speed
broadcast duplex netdev_group statistics
carrier flags operstate subsystem
carrier_changes gro_flush_timeout phys_port_id tx_queue_len
carrier_down_count ifalias phys_port_name type
carrier_up_count ifindex phys_switch_id uevent
device iflink power
Code: Select all
sudo ip link set can0 up type can bitrate 500000
sudo ip link set can0 down )
7.
Code: Select all
sudo ifconfig
Code: Select all
can0: flags=193<UP,RUNNING,NOARP> mtu 16
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC)
RX packets 1651057 bytes 717672 (700.8 KiB)
RX errors 1707 dropped 39 overruns 0 frame 1707
TX packets 23 bytes 141 (141.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
LIBRARIES:
Arduino C CAN : https://github.com/Seeed-Studio/Seeed_A ... N/tree/old
Code: Select all
Install the above library in your arduino IDE
Code: Select all
pip3 install python-can
2.Run python3 can_basic_recv.py in RPi and CAN_TX.ino in Uno
VERY IMPORTANT NOTE:
Bitrate of RPI & UNO is 500000(set in program)
Clock frequency of RPI & UNO is 8Mhz(set in config file and program)
Remove unwanted LED stuff from arduino code if you want!!
can_basic_recv.py OUTPUT:
Code: Select all
Timestamp: 1607220936.314801 ID: 0043 S DLC: 8 01 02 03 04 05 06 07 08 Channel: can0
Timestamp: 1607220937.314749 ID: 0043 S DLC: 8 01 02 03 04 05 06 07 08 Channel: can0
Timestamp: 1607220937.315004 ID: 0043 S DLC: 8 01 02 03 04 05 06 07 08 Channel: can0
Timestamp: 1607220937.315288 ID: 0043 S DLC: 8 01 02 03 04 05 06 07 08 Channel: can0
Timestamp: 1607220938.315610 ID: 0043 S DLC: 8 01 02 03 04 05 06 07 08 Channel: can0
Code: Select all
Data from ID: 0x7EE
0 1 3 1 4 1
-----------------------------
Data from ID: 0x7EE
0 1 3 1 4 1
-----------------------------
Data from ID: 0x7EE
0 1 3 1 4 1
-----------------------------
Data from ID: 0x7EE
0 1 3 1 4 1
-----------------------------
Data from ID: 0x7EE
0 1 3 1 4 1
CAN_RX.ino
Code: Select all
#include <SPI.h>
#include "mcp_can.h"
const int spiCSPin = 10;
const int ledPin = 2;
boolean ledON = 1;
MCP_CAN CAN(spiCSPin);
void setup()
{
Serial.begin(115200);
pinMode(ledPin,OUTPUT);
while (CAN_OK != CAN.begin(CAN_500KBPS,MCP_8MHz))
{
Serial.println("CAN BUS Init Failed");
delay(100);
}
Serial.println("CAN BUS Init OK!");
}
void loop()
{
unsigned char len = 0;
unsigned char buf[8];
if(CAN_MSGAVAIL == CAN.checkReceive())
{
CAN.readMsgBuf(&len, buf);
unsigned long canId = CAN.getCanId();
Serial.println("-----------------------------");
Serial.print("Data from ID: 0x");
Serial.println(canId, HEX);
for(int i = 0; i<len; i++)
{
Serial.print(buf[i]);
Serial.print("\t");
if(ledON && i==0)
{
digitalWrite(ledPin, buf[i]);
ledON = 0;
delay(500);
}
else if((!(ledON)) && i==4)
{
digitalWrite(ledPin, buf[i]);
ledON = 1;
}
}
Serial.println();
}
}
can-basic-send.py
Code: Select all
import time
import can
bustype = 'socketcan'
channel = 'can0'
bus = can.interface.Bus(channel=channel, bustype=bustype,bitrate=500000)
msg = can.Message(arbitration_id=0xc0ffee, data=[0, 1, 3, 1, 4, 1], is_extended_id=False)
while True:
bus.send(msg)
time.sleep(1)
CAN_TX.ino
Code: Select all
#include <SPI.h>
#include <mcp_can.h>
const int spiCSPin = 10;
int ledHIGH = 1;
int ledLOW = 0;
MCP_CAN CAN(spiCSPin);
void setup()
{
Serial.begin(115200);
while (CAN_OK != CAN.begin(CAN_500KBPS,MCP_8MHz))
{
Serial.println("CAN BUS init Failed");
delay(100);
}
Serial.println("CAN BUS Shield Init OK!");
}
unsigned char stmp[8] = {1, 2, 3, 4, 5, 6, 7, 8};
void loop()
{
Serial.println("In loop");
CAN.sendMsgBuf(0x43, 0, 8, stmp);
delay(1000);
}
can-basic-recv.py
Code: Select all
import can
import time
can_interface = 'can0'
bus = can.interface.Bus(can_interface, bustype='socketcan',bitrate=500000)
while True:
message = bus.recv()
print(message)
#for msg in bus:
#print(msg.data)