I have tried to exactly reproduce the R4 CANBus example at https://docs.arduino.cc/tutorials/uno-r4-minima/can to no avail.
I purchased three of the SN65HVD230 CAN Board Accessory Network Transceiver modules recommended in the article. https://www.amazon.com/dp/B0B2W9PGKQ?psc=1&ref=ppx_yo2ov_dt_b_product_details. Wiring is simple: 3.3v, gnd, TX on D4, RX on D5. I have two R4 Minimas and connected CANH and CANL to two rails on a protoboard with 120 ohm resistors between the two rails on each end.
As an aside, I am familiar w/ CANBus and well versed in using can-utils such as candump, cansend, and cangen on a RaspPi.
I have copied the exact code from the send and receive portions of the article and sent each to the two R4s. Both appear to initialize (begin) the CAN OK but the send gets a -60003 rc "CAN.write(...) failed with error code -60003" and the receive doesn't do anything, even if I connect a pi w/ a PICAN2 shield to the rail's CANH and CANL and cangen can0 -v
a bunch of traffic.
Interestingly, the successful begin could be a lie because I can remove all 4 jumper wires to the SN65HVD230 and begin still "appears" to succeed (i.e., CAN.begin(CanBitRate::BR_250k returns true). Also, I normally run my CANBus at 500k but left the sample untouched at 250k just to eliminate any confusion. I've tried both speeds to same result.
I do not own an oscilloscope but am happy to perform any other suggested diagnostics.
Does anyone have any insight?
Send from article:
/**************************************************************************************
* INCLUDE
**************************************************************************************/
#include <Arduino_CAN.h>
/**************************************************************************************
* CONSTANTS
**************************************************************************************/
static uint32_t const CAN_ID = 0x20;
/**************************************************************************************
* SETUP/LOOP
**************************************************************************************/
void setup()
{
Serial.begin(115200);
while (!Serial) { }
if (!CAN.begin(CanBitRate::BR_250k))
{
Serial.println("CAN.begin(...) failed.");
for (;;) {}
}
}
static uint32_t msg_cnt = 0;
void loop()
{
/* Assemble a CAN message with the format of
* 0xCA 0xFE 0x00 0x00 [4 byte message counter]
*/
uint8_t const msg_data[] = {0xCA,0xFE,0,0,0,0,0,0};
memcpy((void *)(msg_data + 4), &msg_cnt, sizeof(msg_cnt));
CanMsg msg(CAN_ID, sizeof(msg_data), msg_data);
/* Transmit the CAN message, capture and display an
* error core in case of failure.
*/
if (int const rc = CAN.write(msg); rc < 0)
{
Serial.print ("CAN.write(...) failed with error code ");
Serial.println(rc);
for (;;) { }
}
/* Increase the message counter. */
msg_cnt++;
/* Only send one message per second. */
delay(1000);
}
Receive from article:
/**************************************************************************************
* INCLUDE
**************************************************************************************/
#include <Arduino_CAN.h>
/**************************************************************************************
* SETUP/LOOP
**************************************************************************************/
void setup()
{
Serial.begin(115200);
while (!Serial) { }
if (!CAN.begin(CanBitRate::BR_250k))
{
Serial.println("CAN.begin(...) failed.");
for (;;) {}
}
}
void loop()
{
if (CAN.available())
{
CanMsg const msg = CAN.read();
Serial.println(msg);
}
}
There are so many CAN libraries out there. The example uses Arduino_CAN. There is also CAN from the samples but it fails in begin()...
CAN.h send example (result:
16:56:30.203 -> CAN Sender
16:56:30.203 -> Starting CAN failed!)
// Copyright (c) Sandeep Mistry. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include <CAN.h>
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("CAN Sender");
// start the CAN bus at 500 kbps
if (!CAN.begin(500E3)) {
Serial.println("Starting CAN failed!");
while (1);
}
}
void loop() {
// send packet: id is 11 bits, packet can contain up to 8 bytes of data
Serial.print("Sending packet ... ");
CAN.beginPacket(0x12);
CAN.write('h');
CAN.write('e');
CAN.write('l');
CAN.write('l');
CAN.write('o');
CAN.endPacket();
Serial.println("done");
delay(1000);
// send extended packet: id is 29 bits, packet can contain up to 8 bytes of data
Serial.print("Sending extended packet ... ");
CAN.beginExtendedPacket(0xabcdef);
CAN.write('w');
CAN.write('o');
CAN.write('r');
CAN.write('l');
CAN.write('d');
CAN.endPacket();
Serial.println("done");
delay(1000);
}
I've used mcp_can in the past (with a MKR 1010 and CAN shield) and would be happy to use it again with the R4 but haven't been able to get it to work either. Probably because I'm not really sure what the CS and INT pin values should be for that library. I think CS is pin 10 so this is what I tried (with result
17:01:03.363 -> Error Initializing MCP2515...
17:01:03.505 -> Error Sending Message...6)...
// CAN Send Example
//
#include <mcp_can.h>
#include <SPI.h>
MCP_CAN CAN0(10); // Set CS to pin 10
void setup()
{
Serial.begin(9600);
while(!Serial);
// Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!");
else Serial.println("Error Initializing MCP2515...");
CAN0.setMode(MCP_NORMAL); // Change to normal mode to allow messages to be transmitted
}
byte data[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
void loop()
{
// send data: ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
byte sndStat = CAN0.sendMsgBuf(0x100, 0, 8, data);
if(sndStat == CAN_OK){
Serial.println("Message Sent Successfully!");
} else {
Serial.print("Error Sending Message...");
Serial.println(sndStat);
}
delay(1000); // send data per 1000ms
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/