Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
This section introduces the types of Lua scripts supported by EdgeTX and how they may be used.
local function init()
-- init is called once when model is loaded
end
local function background()
-- background is called periodically
end
local function run(event)
-- run is called periodically only when screen is visible
end
return { run = run, background = background, init = init }The radio's special characters can be used with the following text constants.
These constants give the type of logical switch function.
file object a file object that was returned by the io.open() function. The file must be opened in read mode.mode (number) flight mode number to return (0 - 8). If mode parameterid: integer identifying the logical switch (zero for L01 etc.).file object a file object that was returned by the io.open() function.getFieldInfoduration (number) number of seconds to play. Only integral part is used.directory (string) New working directoryaddress to read/write in the bufferkey (number) key to be killed, can also include event type (only the key part is used)These constants determine the type of a Special Function
return 0 on radio without rotary encoderLua makes it easy to load and unload code modules on the fly, to save memory or to provide program extensions.
-- /SCRIPTS/TestScript.lua
local c = ...
local function f(x)
return x + c
end
return flocal chunk = loadScript("/SCRIPTS/TestScript.lua")
local f1 = chunk(1)
local y = f1(5)
-- y = 5 + 1
local f2 = chunk(3)
local z = f2(5)
-- z = 5 + 3This section describes various constants that are provided for Lua by EdgeTX.
In addition to the key events described in the previous section, radios with a color touch screen also provide touch events to the widget scripts.
local function run(event)
local ver, radio, maj, minor, rev, osname = getVersion()
print("version: "..ver)
if radio then print ("radio: "..radio) end
if maj then print ("maj: "..maj) end
if minor then print ("minor: "..minor) end
if rev then print ("rev: "..rev) end
if osname then print ("osname: "..osname) end
return 1
end
return { run=run }namepath (string) full path to wav file (i.e. “/SOUNDS/en/system/tada.wav”)title (string) title to displayfunction (unsigned number) custom function number (use 0 for CF1) if set to 'session', radio session timer is reset too
if set to 'ttimer', radio throttle timer is reset too
if set to 'tptimer', radio throttle percent timer is reset tooLUA_MIXER=Y for Custom scripts to be available.version: 2.4.0
radio: tx16s-simu
maj: 2
minor: 4
rev: 0
osname: EdgeTXCH1 [I4]Ail Weight(+100%)
:= LUA4b Weight(+100%)local input =
{
{ "Strength", SOURCE}, -- user selects source (typically slider or knob)
{ "Interval", VALUE, 0, 100, 0 } -- interval value, default = 0.
}
local output = { "Val1", "Val2" }
local function init()
-- Called once when the script is loaded
end
local function run(Strength, Interval) -- Must match input table
local v1, v2
-- Called periodically
return v1, v2 -- Must match output table
end
return { input=input, output=output, run=run, init=init }{ "<name>", SOURCE }{ "<name>", VALUE, <min>, <max>, <default> }{ "<name1>", "<name2>" }-- this is a stand-alone script
local function run(event)
print("lua io.read test") -- print() statements are visible in Debug output window
local f = io.open("foo.bar", "r")
while true do
local data = io.read(f, 10) -- read up to 10 characters (newline char also counts!)
if #data == 0 then break end -- we get zero length string back when we reach end of the file
print("data: "..data)
end
io.close(f)
return 1
end
return { run=run }-- this is a stand-alone script
local function run(event)
print("lua io.write test")
local f = io.open("foo.bar", "a") -- open file in append mode
io.write(f, "first line\r\nsecond line\r\n")
io.write(f, 4, "\r\n", 35.6778, "\r\n") -- one can write multiple items at the same time
local foo = -4.45
io.write(f, foo, "\r\n")
io.close(f)
return 1 -- this will end the script execution
end
return { run=run }This section will give some technical details for radios with a color screen.
fun, err = loadScript("/SCRIPTS/FUNCTIONS/print.lua")
if (fun ~= nil) then
fun("Hello from loadScript()")
else
print(err)
endoptions is changed by the user in the Widget Settings menu, then update will be called with a new options table, unaffected by any changes made by Lua code to the old options table.local name = "WidgetName"
-- Create a table with default options
-- Options can be changed by the user from the Widget Settings menu
-- Notice that each line is a table inside { }
local options = {
{ "Source", SOURCE, 1 },
-- BOOL is actually not a boolean, but toggles between 0 and 1
{ "Boolean", BOOL, 1 },
{ "Value", VALUE, 1, 0, 10},
{ "Color", COLOR, ORANGE },
{ "Text", STRING, "Max8chrs" }
}
local function create(zone, options)
-- Runs one time when the widget instance is registered
-- Store zone and options in the widget table for later use
local widget = {
zone = zone,
options = options
}
-- Add local variables to the widget table,
-- unless you want to share with other instances!
widget.someVariable = 3
-- Return widget table to EdgeTX
return widget
end
local function update(widget, options)
-- Runs if options are changed from the Widget Settings menu
widget.options = options
end
local function background(widget)
-- Runs periodically only when widget instance is not visible
end
local function refresh(widget, event, touchState)
-- Runs periodically only when widget instance is visible
-- If full screen, then event is 0 or event value, otherwise nil
end
return {
name = name,
options = options,
create = create,
update = update,
refresh = refresh,
background = background
}local function counter(start, step)
local x = start
return function()
local y = x
x = x + step
return y
end
endlocal function match(x, ...)
for i, y in ipairs({...}) do
if x == y then
return true
end
end
return false
endlocal function RGB(r, g, b)
local rgb = lcd.RGB(r, g, b)
if not rgb then
rgb = bit32.lshift(bit32.rshift(bit32.band(r, 0xFF), 3), 11)
rgb = rgb + bit32.lshift(bit32.rshift(bit32.band(g, 0xFF), 2), 5)
rgb = rgb + bit32.rshift(bit32.band(b, 0xFF), 3)
end
return rgb
endlocal function init()
-- init is called once when model is loaded
end
local function run(event, touchState)
-- run is called periodically only when screen is visible
-- A non-zero return value will halt the script
return x
end
return { run=run, init=init }An EdgeTX model has several data components that can be exchanged with Lua scripts. This section gives an overview.
This page describes the value that is passed to scripts in the event parameter. It is used in Telemetry and One-Time scripts, as well as widget scripts in full screen mode.
lontitle (string) text to display
-- Main telemetry script
local shared = { }
shared.screens = {
"/SCRIPTS/Test/menu1.lua",
"/SCRIPTS/Test/menu2.lua",
"/SCRIPTS/Test/menu3.lua"
}
function shared.changeScreen(delta)
shared.current = shared.current + delta
if shared.current > #shared.screens then
shared.current = 1
elseif shared.current < 1 then
shared.current = #shared.screens
end
local chunk = loadScript(shared.screens[shared.current])
chunk(shared)
end
local function init()
shared.current = 1
shared.changeScreen(0)
end
local function run(event)
shared.run(event)
end
return { run = run, init = init }-- /SCRIPTS/Test/menu1.lua
local shared = ...
function shared.run(event)
lcd.clear()
lcd.drawText(20, 10, "Screen 1", MIDSIZE)
if event == EVT_VIRTUAL_NEXT then
shared.changeScreen(1)
elseif event == EVT_VIRTUAL_PREV then
shared.changeScreen(-1)
end
end-- /SCRIPTS/Test/menu2.lua
local shared = ...
function shared.run(event)
lcd.clear()
lcd.drawText(20, 10, "Screen 2", MIDSIZE)
if event == EVT_VIRTUAL_NEXT then
shared.changeScreen(1)
elseif event == EVT_VIRTUAL_PREV then
shared.changeScreen(-1)
end
end-- /SCRIPTS/Test/menu3.lua
local shared = ...
function shared.run(event)
lcd.clear()
lcd.drawText(20, 10, "Screen 3", MIDSIZE)
if event == EVT_VIRTUAL_NEXT then
shared.changeScreen(1)
elseif event == EVT_VIRTUAL_PREV then
shared.changeScreen(-1)
end
end-- main.lua
local name = "<widget name>"
local function create(zone, options)
-- Loadable code is called immediately and returns a widget table
return loadScript("/WIDGETS/" .. name .. "/loadable.lua")(zone, options)
end
local function refresh(widget, event, touchState)
widget.refresh(event, touchState)
end
local options = {
-- default options here
}
local function update(widget, options)
widget.update(options)
end
local function background(widget)
widget.background()
end
return {
name = name,
create = create,
refresh = refresh,
options = options,
update = update,
background = background
}-- loadable.lua
local zone, options = ...
-- The widget table will be returned to the main script.
local widget = { }
function widget.refresh(event, touchState)
-- refresh code here
end
function widget.update(opt)
options = opt
-- update code here
end
function widget.background()
-- background code here
end
-- Return to the create(...) function in the main script
return widgetlocal id = getFieldInfo("trim-ele")
local eleTrim = getValue(id)local idUp = getSwitchIndex(CHAR_TRIM .. "Eu")
local idDown = getSwitchIndex(CHAR_TRIM .. "Ed")
local eleUp = getSwitchValue(idUp)
local eleDown = getSwitchValue(idDown)local idB = getFieldInfo("sb")
local swBvalue = getValue(idB) -- a value of -1024, 0 or 1024local idBup = getSwitchIndex("SB" .. CHAR_UP)
local idBdown = getSwitchIndex("SB" .. CHAR_DOWN)
local swBup = getSwitchValue(idBup)
local swBdown = getSwitchValue(idBdown)local function init()
-- Called once when the script is loaded
end
local function run()
-- Called periodically while the Special Function switch is on
end
local function background()
-- Called periodically while the Special Function switch is off
end
return { run=run, background=background, init=init }This section will discuss how interactive scripts receiving user inputs via key and touch events can be created.
-- This code chunk is loaded on demand by the widget's main script
-- when the create(...) function is run. Hence, the body of this
-- file is executed by the widget's create(...) function.
-- zone and options were passed as arguments to chunk(...)
local zone, options = ...
-- The widget table will be returned to the main script
local widget = { }
function widget.refresh(event, touchState)
if event == nil then -- Widget mode
-- Draw in widget mode. The size equals zone.w by zone.h
else -- Full screen mode
-- Draw in full screen mode. The size equals LCD_W by LCD_H
if event ~= 0 then -- Do we have an event?
if touchState then -- Only touch events come with a touchState
if event == EVT_TOUCH_FIRST then
-- When the finger first hits the screen
elseif event == EVT_TOUCH_BREAK then
-- When the finger leaves the screen and did not slide on it
elseif event == EVT_TOUCH_TAP then
-- A short tap gives TAP instead of BREAK
-- touchState.tapCount shows number of taps
elseif event == EVT_TOUCH_SLIDE then
-- Sliding the finger gives a SLIDE instead of BREAK or TAP
if touchState.swipeRight then
-- Is true if user swiped right
elseif touchState.swipeLeft then
elseif touchState.swipeUp then
elseif touchState.swipeDown then
-- etc.
else
-- Sliding but not swiping
end
end
else -- event ~= 0 and touchState == nil: key event
if event == EVT_VIRTUAL_ENTER then
-- User hit ENTER
elseif event == EVT_VIRTUAL_EXIT then
-- etc.
end
end
end
end
end