Arduino DUE and Pi Pico communication over CAN

Hello,
I'm trying to read Value from potentiometer using Arduino DUE, send it via CAN to Raspberry Pi Pico and show it on LCD. But it doesn't work and I have problem with troubleshooting. I don't know if the problem is between DUE and Can module or second Can module and Pico.
It is connected in following order:

I am using Arduino IDE and there is my code for both devices (there are no errors):

//CAN Transmitter Code (Arduino DUE):

#include <SPI.h>          //Library for using SPI Communication 
#include <mcp2515.h>      //Library for using CAN Communication
//#include <DHT.h>          //Library for using DHT sensor 

#define DHTPIN A0       
#define DHTTYPE DHT11

struct can_frame canMsg;
MCP2515 mcp2515(52);

int potPin = 0; 
int val = 200; 
//DHT dht(DHTPIN, DHTTYPE);     //initilize object dht for class DHT with DHT pin with STM32 and DHT type as DHT11

void setup() 
{
  while (!Serial);
  Serial.begin(9600);
  
  SPI.begin();               //Begins SPI communication
//  dht.begin();               //Begins to read temperature & humidity sesnor value
  
  mcp2515.reset();
  mcp2515.setBitrate(CAN_250KBPS,MCP_8MHZ); //Sets CAN at speed 500KBPS and Clock 8MHz
  mcp2515.setNormalMode();
}

void loop() 
{
  val = analogRead(potPin);
  int h=7; //= dht.readHumidity();       //Gets Humidity value
  //int t; //= dht.readTemperature();    //Gets Temperature value

  canMsg.can_id  = 0x036;           //CAN id as 0x036
  canMsg.can_dlc = 8;               //CAN data length as 8
  canMsg.data[0] = h;               //Update humidity value in [0]
  canMsg.data[1] = val;               //Update potentiometer value in [1]
  canMsg.data[2] = 0x00;            //Rest all with 0
  canMsg.data[3] = 0x00;
  canMsg.data[4] = 0x00;
  canMsg.data[5] = 0x00;
  canMsg.data[6] = 0x00;
  canMsg.data[7] = 0x00;
  mcp2515.sendMessage(&canMsg);     //Sends the CAN message
  delay(100);
  
}


//CAN Receiver Code (Pico):

#include <SPI.h>  //Library for using SPI Communication 
#include <Wire.h>   // Include Wire Library for I2C
#include <mcp2515.h>          //Library for using CAN Communication
//#include <LiquidCrystal.h>    //Library for using LCD display
#include <LiquidCrystal_I2C.h> // Include NewLiquidCrystal Library for I2C
// Define LCD pinout
const int  en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;

// Define I2C Address - change if reqiuired
const int i2c_addr = 0x27;

LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE);

struct can_frame canMsg; 
MCP2515 mcp2515(5);                 // SPI CS Pin 10 
 
void setup() {
  lcd.begin(16,2);                   //Sets LCD as 16x2 type
  lcd.setCursor(0,0);                //Display Welcome Message
  lcd.print("CIRCUIT DIGEST");
  lcd.setCursor(0,1);
  lcd.print("CAN ARDUINO");
  delay(1000);
  lcd.clear();
  
  SPI.begin();                       //Begins SPI communication
  
  Serial.begin(9600);                //Begins Serial Communication at 9600 baudrate 
  
  mcp2515.reset();                          
  mcp2515.setBitrate(CAN_250KBPS,MCP_8MHZ); //Sets CAN at speed 500KBPS and Clock 8MHz 
  mcp2515.setNormalMode();                  //Sets CAN at normal mode
}

void loop() 
{
  if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) // To receive data (Poll Read)
  {
     int x = canMsg.data[0];         
     int y = canMsg.data[1];       
      
      lcd.setCursor(0,0);          //Display Temp & Humidity value received at 16x2 LCD
      lcd.print("Humidity : ");
      lcd.print(x);
      lcd.setCursor(0,1);
      lcd.print("Temp : ");
      lcd.print(y);
      delay(100);
      lcd.clear();
   }
}

Everything is based on this tutorial, and that is why you can see temperature and humidity in code, but i changed variables:

Reading value from potentiometer, and connection between Pico and LCD are ok.
I think i messed something up with SPI.

Welcome to the forum.

Can you provide a schematic of the system and a datasheet of the module?

The module I have seen are 5V and therefore you would need level shifter between the Arduino and the CAN module. The MCP2515 would work with lower voltages but that does not mean the CAN transceiver does. The CAN transceiver creates the voltages on the CAN bus.

Can you identify the CAN transceiver used on the module?

1 Like

What frequency crystal is on the MCP2515, I have both 8 and 16 MHz. If they are the same no problem. I had some problems with the MCP2515 not receiving data sometimes. It works without error now that I have everything on the same ground. Also there are termination jumper pins on the modules, you need to add the jumper. This places a 120 ohm across the buss. You need one at each physical end but none in between.

1 Like

Yes, there could be problem with 3.3/5V, but something else worries me more:

I couldn't find any example of connection between MCP2515 and DUE, or MCP2515 and Pico,
Other people use SN65HVD230 transceiver with DUE, and Pico with CAN is even more complicated topic. Do You know about any project, that uses MCP2515 and one of these boards?

Do You think, it might be impossible to use MCP2515 with my boards(even with level shifter)?
Maybe the problem is, that libraries for MCP2515 are not compatible with my boards.

With level shifters this should work. I can test this over the weekend. I expect no surprises. :slight_smile:

The libraries only need to send and receive bytes over SPI. There is no processor/device specific stuff needed.

Wow, I would be very grateful if You check it for me. If You do this, please make some photos. It's my first project with SPI connection.

I used the MCP_CAN_lib-master from GitHub, it worked first time. You need to have both send.ino and receive.ino operating or it will not work. The level shifter will work, unless it is defective. The SPI is straightforward. Here are the connections I used which is compatible with the library: You must connect the int to D2 or change the code accordingly.
MPC2515 -
VCC +5V
MPC2515 - GND GND
MPC2515 - CS 10 (SPI_SS)
MPC2515 - SO 12 (SPI_MISO)
MPC2515 - SI 11 (SPI_MOSI)
MPC2515 - SCK 13 (SPI_SCK)
MPC2515 - INT D2

1 Like

Thanks a lot, I'll order level shifters and hope it will work.

Good Luck, We will be here to help you. The MPC2515 states it is compatible with any micro that supports SPI however it does not supply the software. Get the two nodes operating first then slow it down a notch or two unless you need the speed.

No problem, I can confirm the MCP2515 works fine when using a level shifter.

I used a module with the Texas Instruments TXS0108E 8-Bit Bi-directional level shifter. Additional to the pins gilshultz mentioned, I connected the level shifter OE (output enable) pin to the Arduino plus a 10K pull-down resistor on that pin. This allows you to enable the output pins when the system is setup correctly. This seems to be the recommended option in the datasheet.
You can connect the pin to the low-voltage-side Vcc (3.3V) directly if you want to save a pin.

I build the board for an Arduino Nano 33 IoT so I can have a WiFi or BLE enabled CAN node. And I tested it with an Arduino Due via some wires.

Here are two photos of the board.
My board power module provides 3.3V to the left side and 5V to the right.

Nano33IoT_MCP2515_f

Nano33IoT_MCP2515_b