-
Notifications
You must be signed in to change notification settings - Fork 17.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AP_Scripting: added EFI driver for DLA EFI serial protocol
a simple serial protocol, no CRC, gap framed
- Loading branch information
Showing
2 changed files
with
238 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
|
||
|