I am writing a very simple CAN bridge (or relay) on the new CANBed Dual, which has an RP2040 and GD32E103CBT6 as the CAN controller, using the Arduino development environment. (See example code below).
Problems (in order of importance):
-
CAN messages appear to be garbled. I am just doing a basic CAN.read() (see below), and I know that all the messages on the vehicle bus have a length <= 8. But I read crazy CAN IDs (like 369100705) and length values (like 66).
-
Somewhat randomly, the main loop() completely bogs down because the CAN.reads() can sometimes take approximately 11-13 seconds. Sometimes it returns quickly (which is what I expect), but I canāt figure out why it sometimes has good behavior, or what makes it have the slow behavior!
- This even happens where there is no CAN traffic at all.
- This even happens when I have wired the board in loopback configuration (CAN0L to CAN1L and CAN0H to CAN1H)
-
About 50% of the time, the board fails to flash. I think this may be related to the mounting/unmounting of the RP filesystem. I then have to mess with the reset button, unplug/replug USB cables
-
Sometimes the board will not reset when I press the reset button. This is related to (3), since one of the things I try to get the board to recover is to reset it manually. The only thing that seems to work is to unplug the board for ~10 seconds, and then it will let me flash (and reset with the button properly)ā¦ at least for a while until the problem happens again.
Generally, the CAN library at GitHub - Longan-Labs/CANBedDual_Arduino_Lib: Arduino Library for CANBed Dual seems to be very poorly written, and Iām not sure it actually works.
Questions:
- Anything obviously busted with my code?
- Has anyone gotten this board to read legitimate CAN messages?
- Does anyone know what code is running on the GD32E103CBT6? Then at least I could figure out to fix the busted CANBedDual_Arduino_Lib code. Or maybe I should just program it and skip the RP2040ā¦
Thanks!!
Example code:
/* Relay messages between CAN and Serial.
Uses two CANBed V1.2d's connected by Serial to form a CAN bridge.
CANBedDual: https://www.longan-labs.cc/1030019.html
- Docs: https://docs.longan-labs.cc/1030019/
- Arduino library: https://github.com/Longan-Labs/CANBedDual_Arduino_Lib
TODO:
- Consider down-clocking (eg to 50 MHz) to reduce power usage
*/
#include <Wire.h>
#include <stdio.h>
#include "canbed_dual.h"
#define RELAY_DEBUG 1
CANBedDual CAN0(0);
CANBedDual CAN1(1);
unsigned long startMillis = 0;
unsigned long byteCount = 0;
void setup() {
if (RELAY_DEBUG) {
Serial.begin(115200); // USB serial port for debug
while(!Serial); // Block on the debug port
Serial.println("Debug serial OK!");
}
// Setup: pin 18 is the little blue LED (not the green power LED)
pinMode(18, OUTPUT);
// ??? Setup: Wire1/I2C is the underlying interface to the CAN controllers
Wire1.setSDA(6);
Wire1.setSCL(7);
Wire1.begin();
CAN0.init(500000); // CAN0 baudrate: 500kb/s
CAN1.init(500000); // CAN1 baudrate: 500kb/s
if (RELAY_DEBUG) Serial.println("Initialized CAN");
}
bool ledToggle = false;
void loop() {
// CAN message fields
unsigned long id = 0;
int ext = 0;
int rtr = 0;
int fd = 0;
int len = 0;
unsigned char data[64];
unsigned long nowMillis = millis();
if (nowMillis - startMillis >= 1000) {
Serial.print("bytes per second: "); Serial.println(byteCount);
startMillis += 1000;
byteCount = 0;
ledToggle = !ledToggle;
if (ledToggle) digitalWrite(18, HIGH);
else digitalWrite(18, LOW);
}
if (CAN1.read(&id, &ext, &rtr, &fd, &len, data)) {
if (RELAY_DEBUG) {
Serial.print("CAN1 ");
Serial.print(id); Serial.print(" ");
Serial.print(ext); Serial.print(" ");
Serial.print(rtr); Serial.print(" ");
Serial.print(fd); Serial.print(" ");
Serial.println(len);
}
byteCount += len;
CAN0.send(id, ext, rtr, fd, len, data);
}
if (CAN0.read(&id, &ext, &rtr, &fd, &len, data)) {
if (RELAY_DEBUG) {
Serial.print("CAN0 ");
Serial.println(id);
}
byteCount += len;
CAN1.send(id, ext, rtr, fd, len, data);
}
}