-
-
Notifications
You must be signed in to change notification settings - Fork 101
Description
Summary
On Portenta C33 (RA6M5) using the Arduino_CAN library,
CAN.write() blocks indefinitely when the opposite CAN node cannot acknowledge the frame.
This causes the entire loop() to stop permanently.
The issue occurs on both CAN0 and CAN1.
In contrast, UNO R4 Minima and UNO R4 WiFi do not show this behavior.
Environment
- Board: Portenta C33 with Portenta Breakout (ASX00031)
- Library: Arduino_CAN.h
- Bitrate: 500 kbps
- Bus configuration: Only C33 connected (no active CAN node)
- CAN transceivers: M5Stack U085 (SN65HVD230) × 2
- Comparison boards: UNO R4 Minima, UNO R4 WiFi
- BOARDS MANAGER: Arduino Renesas Portenta Boards 1.5.1
Expected behavior
CAN.write() should:
- return even when no ACK is received, or
- provide a timeout, or
- return an error code, or
- expose an API to detect ACK/bus state.
This is the behavior on UNO R4 Minima and UNO R4 WiFi, where:
CAN.write(msg)does not block,- it returns an error code (e.g., rc = -60003),
- and the loop continues running normally.
Actual behavior (Portenta C33)
CAN.write() never returns when the opposite node cannot acknowledge the frame.
The following tested scenarios all result in a permanent block:
- Opposite node (UNO R4) powered OFF
- Opposite node reset via reset button
- Physical disconnection of CAN lines
- Opposite node with
CAN.begin()not executed (CAN disabled)
In all cases:
"Sent msg = ..."is printed- but
"rc = CAN.write(msg)"is never printed - because
CAN.write()never returns
Observed logs
Portenta C33 (blocks when ACK is unavailable)
Return msg = [031] (8) : CAFE0000F2000000
Sent msg = [021] (8) : CAFE0000F3000000
rc = CAN.write(msg) = 1
Return msg = [031] (8) : CAFE0000F3000000
Sent msg = [021] (8) : CAFE0000F4000000
rc = CAN.write(msg) = 1
After this point, no further logs appear because CAN.write() never returns.
UNO R4 Minima / UNO R4 WiFi (do NOT block)
Sent msg = [021] (8) : CAFE00005F010000
rc = CAN.write(msg) = -60003
Sent msg = [021] (8) : CAFE000060010000
rc = CAN.write(msg) = -60003
Sent msg = [021] (8) : CAFE000060010000
rc = CAN.write(msg) = -60003
Both boards behave identically and continue running normally.
Steps to reproduce
- Connect Portenta C33 to a CAN transceiver
- Do not connect any active CAN node
- Upload the sketch below
- Observe that
CAN.write()never returns
Minimal reproducible example (Portenta C33)
Note: The exact same sketch was also tested on UNO R4 Minima and UNO R4 WiFi.
On both boards, CAN.write(msg) returned -60003 instead of blocking.
#include <Arduino_CAN.h>
static uint32_t const CAN_ID = 0x21;
unsigned long previousMillis = 0;
const long interval = 1000;
void setup()
{
Serial.begin(115200);
if (!CAN.begin(CanBitRate::BR_500k))
{
Serial.println("CAN.begin(...) failed.");
for (;;) {}
}
delay(1000);
}
static uint32_t msg_cnt = 0;
void loop()
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
uint8_t const msg_data[] = {0xCA,0xFE,0,0,0,0,0,0};
memcpy((void *)(msg_data + 4), &msg_cnt, sizeof(msg_cnt));
CanMsg const msg(CanStandardId(CAN_ID), sizeof(msg_data), msg_data);
Serial.print("Sent msg = ");
Serial.println(msg);
int rc = CAN.write(msg);
Serial.print("rc = CAN.write(msg) = ");
Serial.println(rc);
Serial.println("");
msg_cnt++;
}
if (CAN.available())
{
CanMsg msg = CAN.read();
Serial.print("Return msg = ");
Serial.println(msg);
Serial.println("");
}
}Receiver-side code used during testing (UNO R4 Minima / UNO R4 WiFi)
#include <Arduino_CAN.h>
void setup()
{
Serial.begin(115200);
if (!CAN.begin(CanBitRate::BR_500k))
{
Serial.println("CAN.begin(...) failed.");
for (;;) {}
}
}
void loop()
{
if (CAN.available())
{
CanMsg const rx = CAN.read();
CanMsg tx(CanStandardId(0x31), rx.data_length, rx.data);
delayMicroseconds(500);
int const rc = CAN.write(tx);
}
delay(1);
}Additional notes
- Issue occurs on both CAN0 and CAN1
- Occurs regardless of termination resistors
- No API exists to detect ACK absence or bus state
- UNO R4 Minima / UNO R4 WiFi do NOT block
- both return rc = -60003 when no ACK is available
- both continue running normally