Libre Solar Community Forum

Thingset with CAN

Hi everyone,

I’m working on the implementation of the thingset protocol through Can on a custom hardware these days. I’m using the same BOM than the MPPT2420 board with the TCAN334GDR chip and passives surrounding it.
The MCU used if STM32G474RE so I should be pretty close to the LibreSolar hardware.
I’m attempting to run one of the test, to check basic connectivity between two boards, one is runnign the client, and the second one is running the server.

My noob wonder is the following :
Should I use CONFIG_CAN=y or CONFIG_CAN_STM32=y in my prj.conf file ?
Is there some CONFIG_THINGSET_CAN=y features that I terribly missed in the configuration ?


Hi Jean and welcome to the forum!

The CONFIG_THINGSET_CAN is not configured in the prj.conf by default as not all boards have CAN bus support. That’s why it’s enabled in the board_defconfig if supported, see e.g. here:

CONFIG_CAN_STM32=y should not be required, it’s selected automatically if CONFIG_CAN=y.

At the moment a ThingSet client is not implemented on the charge controllers, they are always the servers of data.

The ESP32 can act as a client, but we are still working on an automatic CAN device ID assignment so that the ESP32 can detect which devices are active on the bus. See here for the ESP32 firmware.

If you have a CAN2USB dongle, you can also use the Linux ISO-TP tools. As an example, requesting all output data from the charge controller in ThingSet binary format works like this:

# Start ISO-TP receiving channel
isotprecv -s 0x1ada1400 -d 0x1ada0014 can0 -l

# Request all output data (in different terminal)
# TX using source (own) ID (ID used for sending)
# RX from destination (remote) ID (ID used for receiving, only needed for flow control here)
echo "01 18 70 A0" | isotpsend -s 0x1ada1400 -d 0x1ada0014 can0

Unfortunately, the ThingSet documentation regarding CAN is a little bit outdated, as I found some issues with filtering for the originally planned 29-bit CAN ID layout. So we are including the function code in the payload and not in the CAN ID. See here for some explanations regarding CAN ID layout:

Control messages (e.g. to align on voltage targets for parallel DC/DC converters) are not really defined yet, but I’ve got some ideas already. Let me know when you are at that point and then we can go ahead with some further planning here :slight_smile:



I have now updated the ThingSet specification aswell.


Thank you for your answer @Martin. We are working on a use case with two STM32G4 boards connected in a daisy chain to the same CAN bus. They should work as follows:

  • One power converter as a server which has data in its local registers

  • One power converter as a client which sends queries to the server and retrieves data

    If I understand you correctly there are no STM32 dedicated CAN client functionalities in ThingSet. I suppose our questions here become:

  • What is missing in the current ThingSet implementation to deploy our use case?

  • Is there a simple workaround we can use to deploy our use case?


The client/server type of communication in the ThingSet protocol is meant to be used more for user interfaces.

For M2M communication, i.e. multiple power converters aligning on common voltage targets, the publish/subscribe method on the bus should be used. As a starting point, all converters could send out their voltage setpoints and at the same time receive the setpoints of other converters. The actual control could then get the minimum of all setpoints as the control target. (just an example to demonstrate the idea)

For development purposes it’s definitely a good idea to have a USB to CAN dongle so that you can talk with the controller using your PC.

Does anyone have a working solution with Thingset over CAN?. I work with BMS5s and current git main trunk software.

I can read and decode the publication messages

pi@raspi:~ $ candump any
can0  1F00710A   [5]  FA 41 51 9B D6
can0  1F00720A   [5]  FA 00 00 00 00
can0  1F00730A   [5]  FA 41 A1 60 80

So i can see, the CAN-Address is 0x0A., but i cannot get a connection over ISO-TP:
Terminal 1 listening, nothing arrives

pi@raspi:~ $ isotprecv -l -s 0x1ada0a00 -d 0x1ada000a can0

Terminal 2, sending request to BMS:

pi@raspi:~ $ echo "01 18 70 A0" | isotpsend -s 0x1ada0a00 -d 0x1ada000a can0

The command is issued to the bus, but no matter which command, i do not get a reply. Thingset over serial (text mode) is working.

Hi @xsider.

Your commands look correct. However, the STM32F072 has very little RAM so that the ISO-TP part of the CAN is not enabled by default. As far as I remember, the RAM (and maybe flash aswell) is overflown if ISO-TP is enabled.

You can try enabling it by adding CONFIG_ISOTP=y to boards/arm/bms_5s50_sc/bms_5s50_sc_defconfig or to your prj.conf.

Maybe it’s possible to use it if you disable out some other parts of the firmware via menuconfig.

Hi @martinjaeger
It worked. Indeed the support for ISOTP was not compiled in, i didnt mentioned that. I disabled serial thingset, then it fitted in memory of STM32F072. I found out, the text mode thingset is enabled by default, even over can? I tested the eeprom-save function, it didnt work either. but i found out when i send the command over the iso-tp. the debug console gave garbled characters then controller crashed.
It also crashed when i requested ?conf, but i think that is because the answer string is longer than the text buffer. I will check the binary mode and try to find out if there is any issue with the constrained memory in F072. It is not a big issue, because i could configure over serial thingset, and use CAN only for publication messages.

Yes, the text mode is enabled by default. Reason is that it’s the only way to interact with it as human via serial. I’m using it a lot during development. And if it’s enabled for the serial, it will automatically also work for CAN. Actually, it’s currently not even possible to disable the text mode and only use the binary mode in the library. I’ll add that as an enhancement to the ThingSet library repo.

Too small buffers should not make the library crash, it should instead answer with a response that the requested data didn’t fit into the buffer.

However, there was a very nasty bug in Zephyr 2.5 / newlib-nano that resulted in garbage characters on the serial if the RAM was almost full. Maybe this is the reason also here. It is resolved in Zephyr 2.6, but the BMS firmware is not yet updated to that version.

Unfortunately, I had multiple issues with PlatformIO for the charge controller when I started porting it to Zephyr 2.6, so I’m currently thinking about abandoning PlatformIO, so that the firmware can only be built with the native Zephyr toolchain (using west etc.). Maintaining PlatformIO support is creating lots of additional effort on my end at the moment. But I know that it makes it much easier to get started, that’s why I’m still keeping it… Are you using PlatformIO or do you use native Zephyr toolchain?

I need to do further analysis on the CAN. Im not sure what caused the crash nor what caused randomly stop of pub messages also, im sure the CPU stopped, because update of OLED-display also stopped.
So i thought the garbled debug output is some kind of the same effect.

For the platformio, i build directly on command line with platformio on a debian host. No IDE (VisualStudio) used at the moment. The current systems on are still running on mbed with backported bugfixes. I never ported volkszaehler serial interface to zephyr, thats the cause why i want to change to can-bus, i can use the upstream software then.
For me any decision with/without platformio is ok. I need to learn anyway, because i have experience in FreeRTOS only, never worked with zephyr before.

Wow, the system in the C-Turm looks really cool, just read your recent update regarding the solar system. I should really finally come and visit you down in the south :slight_smile:

Ok, so the Zephyr toolchain can be used directly on the command line even more easily. The difference is just that you need to install the Zephyr SDK (containing GCC and some other stuff). But that’s also quite straightforward on Linux (see here: Getting Started Guide — Zephyr Project Documentation).

Using west you can then also benefit from nice things like menuconfig (to configure the firmware features, same as for Linux kernels) or ram_report and rom_report to analyze the memory consumption.

I will freeze the C-Turm software in the current version during the winter season. At the moment the unit works stable and reliable.
Further development will be done on a tabletop testbench. If the system with zephyr and CAN work reliable again, i will rollout the new version next spring. There are still charger units (MPPT 2420 HPX) awaiting for finishing. I try to install them next year, replace the PWM_2420_LUS.