Multi-Instance IMU Heater: Modify Existing or New Module?

Hello PX4 Community!

I’m designing a custom flight controller with two independent IMUs, and need separate heater control loops for each (dedicated GPIO, setpoints, PID params) to reduce thermal drift. I’m currently attempting to modify the existing `heater` module to support multi-instance functionality, but have run into challenges with proper instance isolation.

Core Question

Should I:
A) Continue refining the existing `heater` module to fix multi-instance issues (with an eye toward upstream compatibility), or
B) Create a new dedicated module (e.g., `heater_multi`) for multi-IMU heater control?

Quick Pros/Cons

Approach Pros Cons
Modify Existing Reuses mature code; aligns with PX4’s design; easier for community adoption Risk of breaking single-IMU use cases; strict backward compatibility required
Create New Full flexibility for multi-IMU needs; no risk to existing functionality Code duplication; extra maintenance; less discoverable for other users

Context

  • Use case: Dual-IMU redundancy (high reliability required)
  • Goal: Long-term maintainability + compatibility with future PX4 releases
  • Would upstream PX4 accept a multi-instance PR for the `heater` module, or prefer a new module?

Any advice from those with experience in PX4 multi-instance peripheral modules would be hugely helpful!

Thanks!


**System**: PX4 v1.14+, STM32H7-based FC, BMI088 & ICM45686

As a new PX4 developer, I’ve just learned that PX4’s ModuleBase/ModuleCommand enforces single-instance modules by default (the is_running() check only verifies module name, blocking multiple “heater” instances from starting).

I need multi-instance IMU heaters, but the default framework prevents this. Is my only option to abandon ModuleBase—creating a custom multi-IMU heater driver in the board layer and manually spawning tasks with unique names via px4_task_spawn_cmd()?

Any guidance is greatly appreciated!

Yeah just get rid of ModuleBase in the existing driver. You would continue to use the lp_default work queue. Look at some of the other drivers that use ScheduledWorkItem but don’t use ModuleBase. It should be fairly easy to get multi instances going with the existing driver.

1 Like

Thanks again — this is very helpful.

I’m still getting familiar with PX4 and modern C++, so I want to ask a few related questions to make sure I’m heading in the right direction.

My current idea is to run a single heater_multi task that dynamically creates two independent heater work items (heater1, heater2) based on configuration. This keeps code reuse, but makes independently starting/stopping a specific heater awkward unless I re-implement command handling.

The brute-force alternative — duplicating the entire heater driver into two modules — does work and gives clean CLI usage like:

heater1 start
heater2 start

…but obviously wastes flash, duplicates logic, and feels pretty un-PX4 XD. I’d also like to keep using PX4’s native -i instance parameter rather than maintaining two separate drivers.

A few questions:

  1. Future upstream direction
    If this dual-heater PCB eventually becomes a publicly released production board — and the multi-heater implementation is intended to be open-sourced and proposed upstream — where would PX4 prefer this functionality to live?
    • extend the existing heater driver for multi-instance support,
    • implement a board-specific heater driver in the BSP, or
    • create a new standalone heater_multi under src/drivers?
    I’d like something consistent, maintainable, and upstream-friendly.

  2. CLI without ModuleBase
    If I drop ModuleBase as suggested, what’s the recommended way to expose the usual CLI semantics (module_name <params>, start/stop, possibly -i)?
    Since ModuleBase normally provides shell integration, I’m not sure how drivers typically handle this when using pure ScheduledWorkItem instances. Is there a lightweight pattern or example?

  3. Simpler multi-instance example
    I looked into the sensor drivers since they support multi-instances cleanly, but they’re a bit heavy for someone new to PX4 XD.
    Is there a simpler driver showing how to manage multiple independent ScheduledWorkItem objects (each with its own state) without relying on ModuleBase? A minimal example or pointer would be great.

  4. Best approach to enable/disable a single heater
    Is it more appropriate for each heater to run as its own named task/process, or for a single manager task to own multiple work items and expose toggling commands? I’m trying to understand which pattern aligns better with PX4’s expectations for multi-instance peripherals.

I don’t need hand-holding — just some direction toward the architectural pattern PX4 prefers.
Thanks again for the help!

I would create a new parameter in heater_params.c to define the number of heater instances to create. Each instance could have its own set of the existing parameters (or we use one set for all instances). Based on the value of this new parameter we’d start multiple instances of the heater driver.

I think it would be a good opportunity to rename these parameters:

SENS_TEMP_ID –> HEATER1_IMU_ID
SENS_IMU_TEMP –> HEATER1_TEMP
SENS_IMU_TEMP_FF –> HEATER1_TEMP_FF
SENS_IMU_TEMP_I –> HEATER1_TEMP_I
SENS_IMU_TEMP_P –> HEATER1_TEMP_P

etc

There is no limit on the number of instances you can start, check out how VehicleIMU work items are started:

1 Like

Thanks a lot — this really helps clarify the direction.

I’ll try reworking the existing heater driver along these lines and see how far I can get. If it looks reasonable, I’ll try to submit a PR in the near future.

One concern I have is about parameters: if supporting multi-instance requires introducing new or renamed parameters, could that potentially conflict with existing board-level configurations and break compatibility for other boards?
Is there a PX4-side mechanism to avoid this kind of issue, or is the expectation that a PR should also update affected boards’ parameter definitions manually?

Thanks again for taking the time — this gives me a much clearer path forward.

The module.yaml file is the “modern” way to define parameters for PX4 modules/drivers/libraries. Take a look at the lib/battery as an example of multi-instance parameters - for example BAT${i}_V_EMPTY.

Take a look at the schema

And the script that process it and generates the parameters

If these changes require board level reconfiguration (it will for our ARK boards) then the process is to make the changes (if you can infer them) and then tag the corresponding maintainers. In this case just tag me @dakejahl

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.