CANBed Dual problems -- multiple problems!

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):

  1. 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).

  2. 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)
  1. 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

  2. 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);
  }
}

Hi,

I received a CANBedDual a few days ago, and I’ve been able to run a simple example script (from the same longan git repo) looping one CAN bus to the other (but it really need the 120ohms termination resistors).

I have not yet tested other cases for now, but I may try to implement a slcan firmware (not sure if there is support for dual can bus in the slcan protocol).

But I agree that if the hardware seems nice, the software and documentation are not great (there is actually no real doc on seeedstudio product page, the schematic linked there is not the correct one, etc).

I’d also like to find the source code for the CAN controller (GD32E103CBT6), I’ve created an issue for this. It seems it’s not upgradable via the RP2040, but there are SWD pins available.

(BTW I also wonder what are the relations between seeedstudio and longan labs…)

David

Cool – glad to hear someone else is trying to use this thing! I still haven’t had any response from Longan labs support (though they say they’ll get back to you in 24 hours). Not a good sign.

I was also able to get the loopback code working… My problems started when I started trying to read real CAN messages! Very curious to hear whether that works for you.