Sending log messages over CAN (not CAN logging)

Introduction and miscellaneous that we haven't created categories for, yet
Post Reply
User avatar
chrskly
Posts: 190
Joined: Fri Feb 21, 2020 5:04 pm
Location: Dublin, Ireland
Has thanked: 73 times
Been thanked: 98 times
Contact:

Sending log messages over CAN (not CAN logging)

Post by chrskly »

Hi all,

Anyone know of a protocol or standard for sending log messages over CANbus? Turns out this exact thing is hard to search for and it seems like there should be already something for doing this.

What I'm trying to do might make more sense if I give you and example. I have lots of code that does a printf to a tty which is fine for debugging, but in the longer term, I want to be able to record all of that information in one central place. It's all well and good capturing all of the CAN traffic between all of the devices in the car, but that only really gives you the 'what', not the 'why'.

For example, I have functions like this:

Code: Select all

bms.enable_charge_inhibit("[S09] too cold to charge", R_TOO_COLD);
This is part of the BMS and disallows charging. Right now, the string "[S09] too cold to charge" gets printed to the serial port and the 'reason' (R_TOO_COLD) gets saved for later reference. But, there could be other reasons why charging was disallowed. E.g. battery too hot, battery full, etc. The BMS broadcasts it's state, so I can figure out the why (usually), but it would be much easier to debug if I had the sort of narrative that logging gives you.

I was thinking of implementing it the following way. First, assign each log message a unique id and have a global mapping, across all of the devices, of id to log message. E.g.

Code: Select all

enum canLogMessage {
    BMS_BOOT,
    BMS_BOOT_FROM_WATCHDOG,
    ...
    BMS_CHARGE_INHIBIT_TOO_COLD,
    BMS_CHARGE_INHIBIT_TOO_HOT,
    BMS_CHARGE_INHIBIT_BATTERY_FULL,
    ...
    AC_CHARGER_CHARGE_INITIATED,
    AC_CHARGER_CHARGE_TERMINATED,
    ...
}
Then pick some universal id that all devices send their log messages on, say, 0x999, or whatever. The payload of the message is the log message id from the enum above. With 8 bytes, you have 2^64 possible log messages.

The logging device need only record those 8 bytes to permanent storage (sd card or what have you). So it's quite space efficient.

The device that displays the logs will just need a mapping from id to the human readable version. Something like this ...

Code: Select all

const std::map<canLogMessageId, std::string> canLogMessageIdToString = {
    { BMS_BOOT,  "BMS booting up" },
    { BMS_BOOT_FROM_WATCHDOG,   "BMS has been rebooted by watchdog" },
    ...
    { BMS_CHARGE_INHIBIT_TOO_COLD, "BMS : Charge inhibit enabled : reason = battery too cold" },
    { BMS_CHARGE_INHIBIT_TOO_HOT, "BMS : Charge inhibit enabled : reason = battery too hot" },
    { BMS_CHARGE_INHIBIT_BATTERY_FULL, "BMS : Charge inhibit enabled : reason = battery full" },
    ...
    { AC_CHARGER_CHARGE_INITIATED, "AC Charger : charge started" },
    { AC_CHARGER_CHARGE_TERMINATED, "AC Charger : charge stopped" },
    ...
};
This feels like something that should exist already and I'd rather not reinvent the wheel.

Thanks!
davefiddes
Posts: 416
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 206 times
Been thanked: 256 times

Re: Sending log messages over CAN (not CAN logging)

Post by davefiddes »

OBD-II has a structured methods for transferring diagnostic codes. There's also UDS that layers on top of that. This is what the OEMs use.

CANopen SDO has mechanisms for transferring simple strings and structured binary data. It also has bulk upload/download capability for larger data transfers. There's support in libopeninv which is somewhat standards compliant but there are other FOSS libraries out there that stick more closely to the standard and are suitable for various MCU platforms.

Hopefully that'll give you some bits of string to pull on.
User avatar
chrskly
Posts: 190
Joined: Fri Feb 21, 2020 5:04 pm
Location: Dublin, Ireland
Has thanked: 73 times
Been thanked: 98 times
Contact:

Re: Sending log messages over CAN (not CAN logging)

Post by chrskly »

davefiddes wrote: Mon Sep 08, 2025 11:35 am OBD-II has a structured methods for transferring diagnostic codes. There's also UDS that layers on top of that. This is what the OEMs use.

CANopen SDO has mechanisms for transferring simple strings and structured binary data. It also has bulk upload/download capability for larger data transfers. There's support in libopeninv which is somewhat standards compliant but there are other FOSS libraries out there that stick more closely to the standard and are suitable for various MCU platforms.

Hopefully that'll give you some bits of string to pull on.
That's brilliant. Thanks a lot for that Dave. I'll dig into all of that this evening.
Post Reply