Faking the Battery Monitor Voltage

Hey everyone,

I’m facing the following challenge:
I’m using a 2.4 kW fuel-cell–powered drone, and tank pressure is measured by a pressure sensor. The remaining fuel is displayed correctly as a percentage using BATT3_MONITOR = 18 (Generator-Fuel). So far everything works as expected.

However, my SIYI Uni RC 7 Pro displays all configured battery monitors. Since Battery Monitor 3 does not report a voltage value, the ground station constantly shows warnings and beeps because the voltage is 1 V. I cannot modify the firmware of the SIYI Uni RC 7 Pro, but I can fake a voltage on the ArduPilot side to stop the warnings.

Has anyone a clever idea to work around this?

My current idea is to use a Lua script that intercepts the BATT3 data and injects a fake voltage value, but I have never deployed a Lua script on ArduPilot before.
Are there any alternative approaches or suggestions on the lua script?

Many Thanks,
Fynn

I managed to write a simple LUA script that does the job.

It takes a vales from a batt monitor that is “internal use only” and write that together with a fixed voltage in the battmonitor 4 which has the “scripting” option selected.

In the end quite easy.

Care to share the code?

1 Like

Hey amilcarlucas,

sure thing :slight_smile:

its not pretty nor optimized, but it runs.

-- batt3_to_batt4.lua (ArduCopter 4.5)
-- Remaining von Batt3 -> Batt4
-- Requirement: BATT4_MONITOR = 29

local UPDATE_MS = 500
local INFO  = 6
local ERROR = 3

-- 0-basiert: Batt1=0 Batt2=1 Batt3=2 Batt4=3
local BATT3 = 2
local BATT4 = 3

-- letzte gesendete Werte merken
local last_rem = nil

gcs:send_text(INFO, "Lua: Battery Monitor Script started")

local function update()
    local rem_pct = battery:capacity_remaining_pct(BATT3)
    if rem_pct == nil then
        gcs:send_text(ERROR, "Lua: start fuelcell to read fuellevel value")
        return update, 2000
    end

    local volt = 55


    local st = BattMonitorScript_State()
    st:healthy(true)
    st:voltage(volt)
    st:capacity_remaining_pct(math.floor(rem_pct + 0.5))

    if battery == nil or battery.handle_scripting == nil then
        gcs:send_text(ERROR, "Lua: battery:handle_scripting() fehlt")
        return update, 2000
    end

    local ok = battery:handle_scripting(BATT4, st)
    if ok == false then
        gcs:send_text(ERROR, "Lua: handle_scripting() false (Batt4 nicht Typ 29?)")
        return update, 2000
    end

    -- 🔇 Debug nur bei Änderung
    if last_rem ~= rem_pct then
        gcs:send_text(
            INFO,
            string.format(
                "Lua: Fuellevel=%.1f%%",
                rem_pct
            )
        )
        last_rem  = rem_pct
       
    end

    return update, UPDATE_MS
end

return update()

1 Like