Multiple batteries reported from a single driver


My friend and I are working on a tethered multicopter project. The drone will be supplied with high-voltage DC via wire, and onboard, two step-down DC-DC converters will be connected in parallel to power the machine.

I am currently working on adding a “battery” driver for these converters. They support the PMBus protocol, and I think I can reuse a lot of the code from the battmon driver.

We plan to have two “batteries”: one for the High side of the converter and one for the Low. Values from two converters on each side can be treated as two parallel cells or averaged inside the driver and reported as a single value.

I have a couple of questions:

  1. Is it possible to have multiple I2C interfaces opened from a single driver?
  2. Is it possible to report multiple batteries from a single driver?

For the 1st, I found this TODO, but I don’t quite understand if that requires some rework somewhere deeper in the firmware.
For the 2nd, I also see that you can set an id for a battery report, but I don’t quite understand how that ties to the batteries configuration in QGroundControl.

Thanks in advance!

Usually a driver inherits from a device driver which communicates with one I2C device. You can probably make a copy of that Device driver it inherits from and implement it for two but I think it might be easier to just use one device driver per I2C device. Just make sure the two I2C devices have different addresses (or are on a separate bus).

That would be possible. You can do it using the PublicationMulti. Again, it might be easier from separate drivers though.

Technically that works, but there are a couple of problems with this approach:

  • Since we want to have High and Low sides tracked, that would require having 2 drivers per converter. And I’m not sure how I2C will behave when two different drivers ask the same device for data, potentially simultaneously :thinking:
  • The “batteries” are connected in parallel, and from what I see, PX4 doesn’t support such a configuration. So our idea was to process the data from two converters inside the driver and report it as a single battery. Having separate batteries is not ideal, but tolerable.

Do I just set BAT1_SOURCE and BAT2_SOURCE to External and publish battery reports with IDs 1 and 2?

You could create a separate topic that both drivers publish to, and then another module which subscribes to both, fuses the result and publishes it as battery status.

Hmm, I didn’t think about that.
But I feel like it will lead to many complications due to drivers’ async nature. The subscriber will have to wait for both reports and have some failsafe logic in case it can’t get one of them.
On the other hand, each driver will be reading from only one device and decoupled from other logic.

Is there any example or at least a starting point I can look at? I only see the publishers in the battmon and batt_smbus drivers, but where are the subscribers?

After looking more at the codebase, this seems like a solution that will actually require the least changes.

1 Like