AP_Scripting: added EFI driver for DLA EFI serial protocol

a simple serial protocol, no CRC, gap framed
This commit is contained in:
Andrew Tridgell 2023-08-14 11:01:16 +10:00
parent a6d5e437ea
commit 23e4fba3f7
2 changed files with 238 additions and 0 deletions

View File

@ -0,0 +1,188 @@
--[[
DLA serial EFI protocol
Note that this protocol is gap framed, no CRC
https://www.austars-model.com/dla-232cc-uavuas-engine-optional-one-key-startauto-startergenerator_g17937.html
--]]
local PARAM_TABLE_KEY = 41
local PARAM_TABLE_PREFIX = "EFI_DLA_"
local MAV_SEVERITY = {EMERGENCY=0, ALERT=1, CRITICAL=2, ERROR=3, WARNING=4, NOTICE=5, INFO=6, DEBUG=7}
-- bind a parameter to a variable given
local function bind_param(name)
local p = Parameter()
assert(p:init(name), string.format('could not find %s parameter', name))
return p
end
-- add a parameter and bind it to a variable
local function bind_add_param(name, idx, default_value)
assert(param:add_param(PARAM_TABLE_KEY, idx, name, default_value), string.format('could not add param %s', name))
return bind_param(PARAM_TABLE_PREFIX .. name)
end
-- setup script specific parameters
assert(param:add_table(PARAM_TABLE_KEY, PARAM_TABLE_PREFIX, 8), 'could not add param table')
--[[
// @Param: EFI_DLA_ENABLE
// @DisplayName: EFI DLA enable
// @Description: Enable EFI DLA driver
// @Values: 0:Disabled,1:Enabled
// @User: Standard
--]]
EFI_DLA_ENABLE = bind_add_param("ENABLE", 1, 0)
--[[
// @Param: EFI_DLA_LPS
// @DisplayName: EFI DLA fuel scale
// @Description: EFI DLA litres of fuel per second of injection time
// @Range: 0.00001 1
// @Units: litres
// @User: Standard
--]]
EFI_DLA_LPS = bind_add_param("LPS", 2, 0.001)
if EFI_DLA_ENABLE:get() ~= 1 then
return
end
local uart = serial:find_serial(0) -- first scripting serial
if not uart then
gcs:send_text(MAV_SEVERITY.ERROR, "EFI_DLA: unable to find scripting serial")
return
end
uart:begin(115200)
local efi_backend = efi:get_backend(0)
if not efi_backend then
gcs:send_text(MAV_SEVERITY.ERROR, "EFI_DLA: unable to find EFI backend")
return
end
--[[
discard n bytes
--]]
local function discard_bytes(n)
for _ = 1, n do
uart:read()
end
end
local function read_bytes(n)
local ret = ""
for _ = 1, n do
ret = ret .. string.char(uart:read())
end
return ret
end
local state = {}
state.last_read_us = uint32_t(0)
state.total_fuel_cm3 = 0.0
--[[
check for input and parse data
--]]
local function check_input()
local n_bytes = uart:available():toint()
--gcs:send_text(MAV_SEVERITY.INFO, string.format("n_bytes=%u %.2f", n_bytes, millis():tofloat()*0.001))
if n_bytes < 82 then
return
end
if n_bytes > 82 then
discard_bytes(n_bytes)
return
end
state.seconds, state.pw1, state.pw2 = string.unpack("<HHH", read_bytes(6))
state.rpm, state.adv_deg, state.squirt = string.unpack("<HhB", read_bytes(5))
state.engine, state.afrtgt1, state.afrtgt2 = string.unpack("<BBB", read_bytes(3))
state.wbo2_en1, state.wbo2_en2, state.baro = string.unpack("<BBh", read_bytes(4))
state.map, state.mat, state.clt = string.unpack("<hhh", read_bytes(6))
state.tps, state.batt = string.unpack("<hh", read_bytes(4))
state.last_read_us = micros()
-- discard the rest
discard_bytes(uart:available():toint())
end
--[[
request more data
--]]
local function request_data()
--uart:write(string.byte("a"))
uart:write(0x61)
end
local function farenheight_to_C(v)
return (v + 459.67) * 0.55556
end
--[[
update EFI state
--]]
local function update_EFI()
if state.last_read_us == uint32_t(0) then
return
end
local cylinder_state = Cylinder_Status()
local efi_state = EFI_State()
-- 4.3.x incorrectly uses C instead of kelvin
-- local C_TO_KELVIN = 273.2
cylinder_state:cylinder_head_temperature(farenheight_to_C(state.clt*0.1))
cylinder_state:exhaust_gas_temperature(farenheight_to_C(state.mat*0.1))
cylinder_state:ignition_timing_deg(state.adv_deg*0.1)
local inj_time_ms = (state.pw1+state.pw2)*0.001
cylinder_state:injection_time_ms(inj_time_ms)
efi_state:engine_speed_rpm(state.rpm)
efi_state:atmospheric_pressure_kpa(state.baro*0.1)
efi_state:intake_manifold_pressure_kpa(state.map*0.1)
efi_state:intake_manifold_temperature(farenheight_to_C(state.mat*0.1))
efi_state:throttle_position_percent(math.floor(state.tps*0.1))
efi_state:ignition_voltage(state.batt*0.1)
local now_us = micros()
local dt = (now_us - state.last_read_us):tofloat()*1.0e-6
state.last_read_us = now_us
local revs = state.rpm * 60.0 * dt
local inj_time = revs * inj_time_ms * 0.001
local fuel_used_cm3 = EFI_DLA_LPS:get() * 0.001 * inj_time
state.total_fuel_cm3 = state.total_fuel_cm3 + fuel_used_cm3
efi_state:fuel_consumption_rate_cm3pm((fuel_used_cm3 / dt) * 60.0)
efi_state:estimated_consumed_fuel_volume_cm3(state.total_fuel_cm3)
efi_state:cylinder_status(cylinder_state)
efi_state:last_updated_ms(millis())
-- Set the EFI_State into the EFI scripting driver
efi_backend:handle_scripting(efi_state)
end
--[[
main update function
--]]
local function update()
check_input()
update_EFI()
request_data()
return update, 100
end
gcs:send_text(MAV_SEVERITY.INFO, "EFI_DLA: loaded")
return update()

View File

@ -0,0 +1,50 @@
# EFI DLA Driver
This driver implements support for the DLA EFI serial protocol for
this system:
https://www.austars-model.com/dla-232cc-uavuas-engine-optional-one-key-startauto-startergenerator_g17937.html
# Parameters
The script used the following parameters:
## EFI_DFA_ENABLE
this must be set to 1 to enable the driver
## EFI_DFA_LPS
This sets the fuel consumption rate in litres per second of injector
time. This will need to be tuned per engine to give the right value
for fuel usage and total fuel
# Operation
This driver should be loaded by placing the lua script in the
APM/SCRIPTS directory on the microSD card, which can be done either
directly or via MAVFTP. The following key parameters should be set:
- SCR_ENABLE should be set to 1
- EFI_TYPE should be set to 7
- EFI_DFA_ENABLE should be set to 1
- SERIALn_PROTOCOL should be set to 28 for the connected EFI serial
- RPM_TYPE1 should be set to 3
- ICE_ENABLE should be set to 1
then the flight controller should rebooted and parameters should be
refreshed.
Once loaded the EFI_DLA parameters will appear and should be set
according to the parameter list above.
The GCS will receive EFI_STATUS MAVLink messages which includes RPM,
cylinder head temperature, injection timing, engine load, fuel
consumption rate, throttle position atmospheric pressure and ECU
voltage.
Note that this EFI system only sends data when the enable PWM enable
signal is high. If that is hooked to the ignition control in ArduPilot
ICE system then you won't see any data until you start the engine.