2020-07-23 22:25:30 -03:00
|
|
|
--------------------------------------------------
|
|
|
|
--------------------------------------------------
|
|
|
|
--------- VTX LUA for SMARTAUDIO 2.0 -------------
|
|
|
|
------------based on work by----------------------
|
|
|
|
---------Craig Fitches 07/07/2020 ----------------
|
|
|
|
-------------Mods by H. Wurzburg -----------------
|
|
|
|
------------clean up by Peter Hall----------------
|
|
|
|
|
|
|
|
-----------------HARDWARE------------------
|
|
|
|
-- tested on CUAVv5Nano and TX8111 VTX
|
|
|
|
|
|
|
|
-- Prerequisites ----------------------------------
|
|
|
|
-- 1. Only works in Ardupilot 4.1dev or later
|
|
|
|
-- 2. FC with 2MB cache for LUA Scripting
|
|
|
|
-- 3. Currently only works with SmartAudio 2.0
|
|
|
|
|
|
|
|
------------ Instructions ------------------------
|
|
|
|
-- 1. Set an unused Serial port in Ardupilot to protocol 28 (scripting) and option 4 (half-duplex)
|
|
|
|
-- 2. Setup an rc channel's RXc_OPTION to 300 for changing power and SCR_USER1 parameter for initial power upon boot
|
|
|
|
---------and set to -1 for unchanged, 0 (PitMode),1,2,3, or 4 for power level (1 lowest,4 maximum)
|
|
|
|
-- 3. Attach the UART's TX for the Serial port chosen above to the VTX's SmartAudio input
|
|
|
|
|
2024-05-03 15:22:25 -03:00
|
|
|
---@diagnostic disable: need-check-nil
|
|
|
|
|
|
|
|
|
2020-07-23 22:25:30 -03:00
|
|
|
-- init local variables
|
|
|
|
local startup_pwr = param:get('SCR_USER1')
|
|
|
|
local scripting_rc = rc:find_channel_for_option(300)
|
|
|
|
local port = serial:find_serial(0)
|
|
|
|
local _current_power = -1
|
|
|
|
|
|
|
|
-- hexadecimal smart audio 2.0 commands
|
|
|
|
local power_commands = {}
|
|
|
|
power_commands[1] = { {0x00,0x00,0xAA,0x55,0x0B,0x01,0x01,0xF8,0x00}, "VTX Pit Mode" }
|
|
|
|
power_commands[2] = { {0x00,0x00,0xAA,0x55,0x05,0x01,0x00,0x6B,0x00}, "VTX PWR LOW" } -- SMARTAUDIO_V2_COMMAND_POWER_0
|
|
|
|
power_commands[3] = { {0x00,0x00,0xAA,0x55,0x05,0x01,0x01,0xBE,0x00}, "VTX PWR MED" } -- SMARTAUDIO_V2_COMMAND_POWER_1
|
|
|
|
power_commands[4] = { {0x00,0x00,0xAA,0x55,0x05,0x01,0x02,0x14,0x00}, "VTX PWR HIGH" } -- SMARTAUDIO_V2_COMMAND_POWER_2
|
|
|
|
power_commands[5] = { {0x00,0x00,0xAA,0x55,0x05,0x01,0x03,0xC1,0x00}, "VTX PWR MAX" } -- SMARTAUDIO_V2_COMMAND_POWER_3
|
|
|
|
|
|
|
|
|
|
|
|
-- return a power level from 1 to 5 as set with a switch
|
|
|
|
function get_power()
|
|
|
|
input = scripting_rc:norm_input() -- - 1 to 1
|
|
|
|
input = (input + 1) * 2 -- 0 to 4
|
|
|
|
return math.floor(input+0.5) + 1 -- integer 1 to 5
|
|
|
|
end
|
|
|
|
|
|
|
|
-- set the power in the range 1 to 5
|
|
|
|
function setPower(power)
|
|
|
|
if power == _current_power then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
updateSerial(power_commands[power][1])
|
|
|
|
gcs:send_text(4, power_commands[power][2])
|
|
|
|
_current_power = power
|
|
|
|
end
|
|
|
|
|
|
|
|
-- write output to the serial port
|
|
|
|
function updateSerial(value)
|
|
|
|
for count = 1, #value do
|
|
|
|
port:write(value[count])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
---- main update ---
|
|
|
|
function update()
|
|
|
|
setPower(get_power())
|
|
|
|
return update, 500
|
|
|
|
end
|
|
|
|
|
|
|
|
-- initialization
|
|
|
|
function init()
|
|
|
|
-- check if setup properly
|
|
|
|
if not port then
|
|
|
|
gcs:send_text(0, "SmartAudio: No Scripting Serial Port")
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if not scripting_rc then
|
|
|
|
gcs:send_text(0, "SmartAudio: No RC option for scripting")
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
port:begin(4800)
|
|
|
|
|
|
|
|
-- Set initial power after boot based on SCR_USER1
|
|
|
|
if startup_pwr then -- make sure we found the param
|
|
|
|
if startup_pwr >= 0 and startup_pwr < 5 then
|
|
|
|
setPower(math.floor(startup_pwr) + 1)
|
|
|
|
|
|
|
|
-- set the current power local to that requested by the rc in
|
|
|
|
-- this prevents instantly changing the power from the startup value
|
|
|
|
_current_power = get_power()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return update, 500
|
|
|
|
end
|
|
|
|
|
|
|
|
return init, 2000 --Wait 2 sec before initializing, gives time for RC in to come good in SITL, also gives a better chance to see errors
|