From d620ca4fedc34b96b75766961d0132b57192c1c7 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 9 Oct 2019 22:21:24 +0100 Subject: [PATCH 001/193] Add to tools screen in OpenTx 2.3 --- src/SCRIPTS/TOOLS/bf.lua | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/SCRIPTS/TOOLS/bf.lua diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua new file mode 100644 index 00000000..855771e3 --- /dev/null +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -0,0 +1,15 @@ +local toolName = "TNS|Betaflight setup|TNE" +SCRIPT_HOME = "/SCRIPTS/BF" + +apiVersion = 0 + +protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() +radio = assert(loadScript(SCRIPT_HOME.."/radios.lua"))() + +assert(loadScript(radio.preLoad))() +assert(loadScript(protocol.transport))() +assert(loadScript(SCRIPT_HOME.."/MSP/common.lua"))() + +local run_ui = assert(loadScript(SCRIPT_HOME.."/ui.lua"))() + +return { run=run_ui } From 7f6fbcb3d7f99a5e0dba12bb198d67cbd87fabf6 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Thu, 10 Oct 2019 11:12:11 +0100 Subject: [PATCH 002/193] Add txt file to hint tools menu use. --- src/BF/use_tools_menu_instead_of_this.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/BF/use_tools_menu_instead_of_this.txt diff --git a/src/BF/use_tools_menu_instead_of_this.txt b/src/BF/use_tools_menu_instead_of_this.txt new file mode 100644 index 00000000..e69de29b From f95c13113f052e713a29579076c61d51df94e962 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Thu, 10 Oct 2019 13:13:40 +0100 Subject: [PATCH 003/193] removed BF/bf.lua --- src/BF/bf.lua | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 src/BF/bf.lua diff --git a/src/BF/bf.lua b/src/BF/bf.lua deleted file mode 100644 index eb4da1c0..00000000 --- a/src/BF/bf.lua +++ /dev/null @@ -1,16 +0,0 @@ -SCRIPT_HOME = "/SCRIPTS/BF" - -apiVersion = 0 - -protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() -radio = assert(loadScript(SCRIPT_HOME.."/radios.lua"))() - -assert(loadScript(radio.preLoad))() -assert(loadScript(protocol.transport))() -assert(loadScript(SCRIPT_HOME.."/MSP/common.lua"))() - -isTelemetryScript = false - -local run_ui = assert(loadScript(SCRIPT_HOME.."/ui.lua"))() - -return { run=run_ui } From b23df65d907dca4a82251e35c78673aac210368d Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 9 Oct 2019 22:34:27 +0100 Subject: [PATCH 004/193] Add menu only for tools screen. --- src/SCRIPTS/BF/HORUS/horuspre.lua | 20 +++---- src/SCRIPTS/BF/NV14/nv14pre.lua | 20 +++---- src/SCRIPTS/BF/X7/x7pre.lua | 18 +++--- src/SCRIPTS/BF/X9/x9pre.lua | 20 +++---- src/SCRIPTS/BF/ui.lua | 96 ++++++++++++++++++++++++------- src/SCRIPTS/TOOLS/bf.lua | 1 + 6 files changed, 114 insertions(+), 61 deletions(-) diff --git a/src/SCRIPTS/BF/HORUS/horuspre.lua b/src/SCRIPTS/BF/HORUS/horuspre.lua index 3164c631..1102279d 100644 --- a/src/SCRIPTS/BF/HORUS/horuspre.lua +++ b/src/SCRIPTS/BF/HORUS/horuspre.lua @@ -1,15 +1,15 @@ PageFiles = { - "pids1.lua", - "pids2.lua", - "rates.lua", - "pid_advanced.lua", - "filters.lua", - "pwm.lua", - "rx.lua", - "vtx.lua", - "rescue.lua", - "gpspids.lua", + { title = "PIDs 1", script = "pids1.lua"}, + { title = "PIDs 2", script = "pids2.lua"}, + { title = "Rates", script = "rates.lua"}, + { title = "Advanced PIDs", script = "pid_advanced.lua"}, + { title = "Filters", script = "filters.lua"}, + { title = "vTX Settings", script = "vtx.lua"}, + { title = "Gyro / Motor", script = "pwm.lua"}, + { title = "Rx", script = "rx.lua"}, + { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041}, + { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041}, } MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 } diff --git a/src/SCRIPTS/BF/NV14/nv14pre.lua b/src/SCRIPTS/BF/NV14/nv14pre.lua index 5d6ffcd1..d1071cbe 100644 --- a/src/SCRIPTS/BF/NV14/nv14pre.lua +++ b/src/SCRIPTS/BF/NV14/nv14pre.lua @@ -1,15 +1,15 @@ PageFiles = { - "pids1.lua", - "pids2.lua", - "rates.lua", - "pid_advanced.lua", - "filters.lua", - "pwm.lua", - "rx.lua", - "vtx.lua", - "rescue.lua", - "gpspids.lua", + { title = "PIDs 1", script = "pids1.lua"}, + { title = "PIDs 2", script = "pids2.lua"}, + { title = "Rates", script = "rates.lua"}, + { title = "Advanced PIDs", script = "pid_advanced.lua"}, + { title = "Filters", script = "filters.lua"}, + { title = "vTX Settings", script = "vtx.lua"}, + { title = "Gyro / Motor", script = "pwm.lua"}, + { title = "Rx", script = "rx.lua"}, + { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041}, + { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041}, } MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 } diff --git a/src/SCRIPTS/BF/X7/x7pre.lua b/src/SCRIPTS/BF/X7/x7pre.lua index 90eb3b06..b6e53000 100644 --- a/src/SCRIPTS/BF/X7/x7pre.lua +++ b/src/SCRIPTS/BF/X7/x7pre.lua @@ -1,14 +1,14 @@ PageFiles = { - "pids1.lua", - "pids2.lua", - "rates.lua", - "pid_advanced.lua", - "filters.lua", - "pwm.lua", - "vtx.lua", - "rescue.lua", - "gpspids.lua", + { title = "vTX Settings", script = "vtx.lua"}, + { title = "Gyro / Motor", script = "pwm.lua"}, + { title = "PIDs 1", script = "pids1.lua"}, + { title = "PIDs 2", script = "pids2.lua"}, + { title = "Rates", script = "rates.lua"}, + { title = "Advanced PIDs", script = "pid_advanced.lua"}, + { title = "Filters", script = "filters.lua"}, + { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041}, + { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041}, } MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 } diff --git a/src/SCRIPTS/BF/X9/x9pre.lua b/src/SCRIPTS/BF/X9/x9pre.lua index 474bbefd..c7505682 100644 --- a/src/SCRIPTS/BF/X9/x9pre.lua +++ b/src/SCRIPTS/BF/X9/x9pre.lua @@ -1,15 +1,15 @@ PageFiles = { - "pids1.lua", - "pids2.lua", - "rates.lua", - "pid_advanced.lua", - "filters.lua", - "pwm.lua", - "rx.lua", - "vtx.lua", - "rescue.lua", - "gpspids.lua", + { title = "PIDs 1", script = "pids1.lua"}, + { title = "PIDs 2", script = "pids2.lua"}, + { title = "Rates", script = "rates.lua"}, + { title = "Advanced PIDs", script = "pid_advanced.lua"}, + { title = "Filters", script = "filters.lua"}, + { title = "vTX Settings", script = "vtx.lua"}, + { title = "Gyro / Motor", script = "pwm.lua"}, + { title = "Rx", script = "rx.lua"}, + { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041}, + { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041}, } MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 } diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index afe25857..1f6b9800 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -3,7 +3,8 @@ local pageStatus = display = 2, editing = 3, saving = 4, - displayMenu = 5, + popupMenu = 5, + mainMenu = 6, } local uiMsp = @@ -12,7 +13,8 @@ local uiMsp = eepromWrite = 250 } -local currentState = pageStatus.display +local menuLine = 1 +local currentState = pageStatus.mainMenu local requestTimeout = 80 -- 800ms request timeout local currentPage = 1 local currentLine = 1 @@ -22,9 +24,10 @@ local saveRetries = 0 local saveMaxRetries = 0 local pageRequested = false local telemetryScreenActive = false -local menuActive = false +local popupMenuActive = false local lastRunTS = 0 local killEnterBreak = 0 +local stopDisplay = true local scrollPixelsY = 0 local Page = nil @@ -72,7 +75,7 @@ local function eepromWrite() protocol.mspRead(uiMsp.eepromWrite) end -local menuList = { +local popupMenuList = { { t = "save page", f = saveSettings @@ -151,8 +154,12 @@ local function incLine(inc) currentLine = clipValue(currentLine + inc, 1, #(Page.fields)) end -local function incMenu(inc) - menuActive = clipValue(menuActive + inc, 1, #(menuList)) +local function incMainMenu(inc) + menuLine = clipValue(menuLine + inc, 1, #(PageFiles)) +end + +local function incPopupMenu(inc) + popupMenuActive = clipValue(popupMenuActive + inc, 1, #(popupMenuList)) end local function requestPage() @@ -258,21 +265,21 @@ local function incValue(inc) end end -local function drawMenu() +local function drawPopupMenu() local x = MenuBox.x local y = MenuBox.y local w = MenuBox.w local h_line = MenuBox.h_line local h_offset = MenuBox.h_offset - local h = #(menuList) * h_line + h_offset*2 + local h = #(popupMenuList) * h_line + h_offset*2 lcd.drawFilledRectangle(x,y,w,h,backgroundFill) lcd.drawRectangle(x,y,w-1,h-1,foregroundColor) lcd.drawText(x+h_line/2,y+h_offset,"Menu:",globalTextOptions) - for i,e in ipairs(menuList) do + for i,e in ipairs(popupMenuList) do local text_options = globalTextOptions - if menuActive == i then + if popupMenuActive == i then text_options = text_options + INVERS end lcd.drawText(x+MenuBox.x_offset,y+(i-1)*h_line+h_offset,e.t,text_options) @@ -284,6 +291,11 @@ function run_ui(event) -- if lastRunTS old than 500ms if lastRunTS + 50 < now then invalidatePages() + if useMenu then + currentState = pageStatus.mainMenu + else + currentState = pageStatus.display + end end lastRunTS = now if (currentState == pageStatus.saving) then @@ -301,26 +313,26 @@ function run_ui(event) mspProcessTxQ() -- navigation if isTelemetryScript and event == EVT_VIRTUAL_MENU_LONG then -- telemetry script - menuActive = 1 - currentState = pageStatus.displayMenu + popupMenuActive = 1 + currentState = pageStatus.popupMenu elseif (not isTelemetryScript) and event == EVT_VIRTUAL_ENTER_LONG then -- standalone - menuActive = 1 + popupMenuActive = 1 killEnterBreak = 1 - currentState = pageStatus.displayMenu + currentState = pageStatus.popupMenu -- menu is currently displayed - elseif currentState == pageStatus.displayMenu then + elseif currentState == pageStatus.popupMenu then if event == EVT_VIRTUAL_EXIT then currentState = pageStatus.display elseif event == EVT_VIRTUAL_PREV then - incMenu(-1) + incPopupMenu(-1) elseif event == EVT_VIRTUAL_NEXT then - incMenu(1) + incPopupMenu(1) elseif event == EVT_VIRTUAL_ENTER then if killEnterBreak == 1 then killEnterBreak = 0 else currentState = pageStatus.display - menuList[menuActive].f() + popupMenuList[popupMenuActive].f() end end -- normal page viewing @@ -341,7 +353,11 @@ function run_ui(event) currentState = pageStatus.editing end elseif event == EVT_VIRTUAL_EXIT then - return protocol.exitFunc(); + if useMenu then + stopDisplay = true + else + return protocol.exitFunc(); + end end -- editing value elseif currentState == pageStatus.editing then @@ -356,7 +372,7 @@ function run_ui(event) end local nextPage = currentPage while Page == nil do - Page = assert(loadScript(radio.templateHome .. PageFiles[currentPage]))() + Page = assert(loadScript(radio.templateHome .. PageFiles[currentPage].script))() if Page.requiredVersion and apiVersion > 0 and Page.requiredVersion > apiVersion then incPage(1) @@ -379,8 +395,8 @@ function run_ui(event) if protocol.rssi() == 0 then lcd.drawText(NoTelem[1],NoTelem[2],NoTelem[3],NoTelem[4]) end - if currentState == pageStatus.displayMenu then - drawMenu() + if currentState == pageStatus.popupMenu then + drawPopupMenu() elseif currentState == pageStatus.saving then lcd.drawFilledRectangle(SaveBox.x,SaveBox.y,SaveBox.w,SaveBox.h,backgroundFill) lcd.drawRectangle(SaveBox.x,SaveBox.y,SaveBox.w,SaveBox.h,SOLID) @@ -390,6 +406,42 @@ function run_ui(event) lcd.drawText(SaveBox.x+SaveBox.x_offset,SaveBox.y+SaveBox.h_offset,"Retrying",DBLSIZE + (globalTextOptions)) end end + if currentState == pageStatus.mainMenu and useMenu then + if event == EVT_VIRTUAL_EXIT then + return 2 + elseif event == EVT_VIRTUAL_NEXT then + incMainMenu(1) + elseif event == EVT_VIRTUAL_PREV then + incMainMenu(-1) + end + lcd.clear() + lcd.drawScreenTitle("Betaflight Config", 0, 0) + for i=1, #PageFiles do + local yMinLim = 10 + local yMaxLim = LCD_H - 8 + local currentLineY = (menuLine-1)*8 + yMinLim + if currentLineY <= yMaxLim then + scrollPixelsY = 0 + elseif currentLineY - scrollPixelsY <= yMinLim then + scrollPixelsY = currentLineY - yMinLim*2 + elseif currentLineY - scrollPixelsY >= yMaxLim then + scrollPixelsY = currentLineY - yMaxLim + 6 + end + local attr = (menuLine == i and INVERS or 0) + if event == EVT_VIRTUAL_ENTER and attr == INVERS then + Page = assert(loadScript(radio.templateHome .. PageFiles[i].script))() + currentPage = i + currentState = pageStatus.display + end + if ((i-1)*8 + yMinLim - scrollPixelsY) >= yMinLim and ((i-1)*8 + yMinLim - scrollPixelsY) <= yMaxLim then + lcd.drawText(6, (i-1)*8 + yMinLim - scrollPixelsY, PageFiles[i].title, attr) + end + end + end + if stopDisplay then + currentState = pageStatus.mainMenu + stopDisplay = false + end processMspReply(mspPollReply()) return 0 end diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index 855771e3..8e93fb3a 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -2,6 +2,7 @@ local toolName = "TNS|Betaflight setup|TNE" SCRIPT_HOME = "/SCRIPTS/BF" apiVersion = 0 +useMenu = true protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() radio = assert(loadScript(SCRIPT_HOME.."/radios.lua"))() From 64af852fcbd347e2c814bcd1f4e2c0398ea4c142 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Sun, 13 Oct 2019 13:00:32 +0100 Subject: [PATCH 005/193] swap to isTelemetryScript instead of useMenu --- src/SCRIPTS/BF/ui.lua | 18 +++++++++--------- src/SCRIPTS/TELEMETRY/bf.lua | 1 - src/SCRIPTS/TOOLS/bf.lua | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 1f6b9800..dd206912 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -291,10 +291,10 @@ function run_ui(event) -- if lastRunTS old than 500ms if lastRunTS + 50 < now then invalidatePages() - if useMenu then - currentState = pageStatus.mainMenu - else + if isTelemetryScript then currentState = pageStatus.display + else + currentState = pageStatus.mainMenu end end lastRunTS = now @@ -353,11 +353,11 @@ function run_ui(event) currentState = pageStatus.editing end elseif event == EVT_VIRTUAL_EXIT then - if useMenu then - stopDisplay = true - else - return protocol.exitFunc(); - end + if isTelemetryScript then + return protocol.exitFunc(); + else + stopDisplay = true + end end -- editing value elseif currentState == pageStatus.editing then @@ -406,7 +406,7 @@ function run_ui(event) lcd.drawText(SaveBox.x+SaveBox.x_offset,SaveBox.y+SaveBox.h_offset,"Retrying",DBLSIZE + (globalTextOptions)) end end - if currentState == pageStatus.mainMenu and useMenu then + if currentState == pageStatus.mainMenu and (not isTelemetryScript) then if event == EVT_VIRTUAL_EXIT then return 2 elseif event == EVT_VIRTUAL_NEXT then diff --git a/src/SCRIPTS/TELEMETRY/bf.lua b/src/SCRIPTS/TELEMETRY/bf.lua index 1e2ea964..b6f47f95 100644 --- a/src/SCRIPTS/TELEMETRY/bf.lua +++ b/src/SCRIPTS/TELEMETRY/bf.lua @@ -20,7 +20,6 @@ local lastMenuEvent = 0 function run(event) lastMenuEvent = getTime() - run_ui(event) end diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index 8e93fb3a..444652d7 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -2,7 +2,7 @@ local toolName = "TNS|Betaflight setup|TNE" SCRIPT_HOME = "/SCRIPTS/BF" apiVersion = 0 -useMenu = true +isTelemetryScript = false protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() radio = assert(loadScript(SCRIPT_HOME.."/radios.lua"))() From 03b027fa9592d9844036b65bfb4e8e535223c999 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Sun, 13 Oct 2019 13:25:00 +0100 Subject: [PATCH 006/193] fix for telemtry script not responding to events. --- src/SCRIPTS/BF/ui.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index dd206912..21b37366 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -438,7 +438,7 @@ function run_ui(event) end end end - if stopDisplay then + if stopDisplay and (not isTelemetryScript) then currentState = pageStatus.mainMenu stopDisplay = false end From cca694c77eb163afb3bae6f319fd6b852a19a32c Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Sun, 13 Oct 2019 14:06:11 +0100 Subject: [PATCH 007/193] whitespace fix --- src/SCRIPTS/BF/ui.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 21b37366..58856080 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -354,10 +354,10 @@ function run_ui(event) end elseif event == EVT_VIRTUAL_EXIT then if isTelemetryScript then - return protocol.exitFunc(); - else + return protocol.exitFunc(); + else stopDisplay = true - end + end end -- editing value elseif currentState == pageStatus.editing then From a14059b90b81545b5589a03e3c105a1f810f8c47 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Mon, 14 Oct 2019 09:06:04 +0200 Subject: [PATCH 008/193] Handle NEXT_PAGE / PREV_PAGE only in non-telemetry scripts --- src/SCRIPTS/BF/ui.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 1f6b9800..d1e2a116 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -337,10 +337,10 @@ function run_ui(event) end -- normal page viewing elseif currentState <= pageStatus.display then - if event == EVT_VIRTUAL_PREV_PAGE then + if not isTelemetryScript and event == EVT_VIRTUAL_PREV_PAGE then incPage(-1) killEvents(event) -- X10/T16 issue: pageUp is a long press - elseif event == EVT_VIRTUAL_NEXT_PAGE or event == EVT_VIRTUAL_MENU then + elseif (not isTelemetryScript and event == EVT_VIRTUAL_NEXT_PAGE) or (isTelemetryScript and event == EVT_VIRTUAL_MENU) then incPage(1) elseif event == EVT_VIRTUAL_PREV or event == EVT_VIRTUAL_PREV_REPT then incLine(-1) From 048bdf19c7236ddedfedcc031d9fa4bbfcf77cfc Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Mon, 14 Oct 2019 09:06:50 +0200 Subject: [PATCH 009/193] Discard duplicated replies once the first reply has been received --- src/SCRIPTS/BF/MSP/common.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SCRIPTS/BF/MSP/common.lua b/src/SCRIPTS/BF/MSP/common.lua index 21c22572..d50b3ba0 100644 --- a/src/SCRIPTS/BF/MSP/common.lua +++ b/src/SCRIPTS/BF/MSP/common.lua @@ -129,6 +129,7 @@ function mspPollReply() while true do ret = protocol.mspPoll() if type(ret) == "table" then + mspLastReq = 0 return mspRxReq, ret else break From c2a84c2f27d2ba5d4c8314608ddbc7d37f6d76d2 Mon Sep 17 00:00:00 2001 From: Michael Keller Date: Tue, 15 Oct 2019 11:50:22 +1300 Subject: [PATCH 010/193] Added 'release' task to Makefile. --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index d81c3e18..b654b915 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,7 @@ all: bin/build.sh + +release: all + FILE_NAME="betaflight-tx-lua-scripts_$$(git describe --abbrev=0 --tags).zip"; \ + rm -f $${FILE_NAME}; \ + zip -r $${FILE_NAME} obj/ From de725b9e597a4ff73868d54c168ab7ec5dc7edb3 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 16 Oct 2019 11:56:52 +0100 Subject: [PATCH 011/193] Add missing rx.lua script for X7 --- src/SCRIPTS/BF/X7/rx.lua | 19 +++++++++++++++++++ src/SCRIPTS/BF/X7/x7pre.lua | 1 + 2 files changed, 20 insertions(+) create mode 100644 src/SCRIPTS/BF/X7/rx.lua diff --git a/src/SCRIPTS/BF/X7/rx.lua b/src/SCRIPTS/BF/X7/rx.lua new file mode 100644 index 00000000..b775fb76 --- /dev/null +++ b/src/SCRIPTS/BF/X7/rx.lua @@ -0,0 +1,19 @@ +return { + read = 44, -- MSP_RX_CONFIG + write = 45, -- MSP_SET_RX_CONFIG + title = "RX", + reboot = false, + eepromWrite = true, + minBytes = 23, + yMinLimit = 12, + yMaxLimit = 52, + text = {}, + fields = { + { t = "Stick Min", x = 10, y = 20, sp = 45, min = 1000, max = 2000, vals = { 6, 7 }, to = SMLSIZE }, + { t = "Stick Mid", x = 10, y = 30, sp = 45, min = 1000, max = 2000, vals = { 4, 5 }, to = SMLSIZE }, + { t = "Stick Max", x = 10, y = 40, sp = 45, min = 1000, max = 2000, vals = { 2, 3 }, to = SMLSIZE }, + { t = "Cam Angle", x = 10, y = 50, sp = 50, min = 0, max = 90, vals = { 23 }, to = SMLSIZE }, + { t = "Interp", x = 10, y = 60, sp = 50, min = 0, max = 3, vals = { 13 }, to = SMLSIZE, table={ [0]="Off", "Preset", "Auto", "Manual"} }, + { t = "Interp Int", x = 10, y = 70, sp = 50, min = 1, max = 50, vals = { 14 }, to = SMLSIZE }, + }, +} diff --git a/src/SCRIPTS/BF/X7/x7pre.lua b/src/SCRIPTS/BF/X7/x7pre.lua index b6e53000..3d80a97c 100644 --- a/src/SCRIPTS/BF/X7/x7pre.lua +++ b/src/SCRIPTS/BF/X7/x7pre.lua @@ -7,6 +7,7 @@ PageFiles = { title = "Rates", script = "rates.lua"}, { title = "Advanced PIDs", script = "pid_advanced.lua"}, { title = "Filters", script = "filters.lua"}, + { title = "Rx", script = "rx.lua"}, { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041}, { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041}, } From 31ce44ff600d1d69a370290e0d889b7c48f10c45 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 16 Oct 2019 12:59:51 +0100 Subject: [PATCH 012/193] Rationalise to screen size rather than radio --- src/SCRIPTS/BF/{X7 => 128x64}/filters.lua | 0 src/SCRIPTS/BF/{X7 => 128x64}/gpspids.lua | 0 .../BF/{X7 => 128x64}/pid_advanced.lua | 0 src/SCRIPTS/BF/{X7 => 128x64}/pids1.lua | 0 src/SCRIPTS/BF/{X7 => 128x64}/pids2.lua | 0 src/SCRIPTS/BF/128x64/pre.lua | 3 ++ src/SCRIPTS/BF/{X7 => 128x64}/pwm.lua | 0 src/SCRIPTS/BF/{X7 => 128x64}/rates.lua | 0 src/SCRIPTS/BF/{X7 => 128x64}/rescue.lua | 0 src/SCRIPTS/BF/{X7 => 128x64}/vtx.lua | 0 src/SCRIPTS/BF/{X9 => 212x64}/filters.lua | 0 src/SCRIPTS/BF/{X9 => 212x64}/gpspids.lua | 0 .../BF/{X9 => 212x64}/pid_advanced.lua | 0 src/SCRIPTS/BF/{X9 => 212x64}/pids1.lua | 0 src/SCRIPTS/BF/{X9 => 212x64}/pids2.lua | 0 src/SCRIPTS/BF/212x64/pre.lua | 3 ++ src/SCRIPTS/BF/{X9 => 212x64}/pwm.lua | 0 src/SCRIPTS/BF/{X9 => 212x64}/rates.lua | 0 src/SCRIPTS/BF/{X9 => 212x64}/rescue.lua | 0 src/SCRIPTS/BF/{X9 => 212x64}/rx.lua | 0 src/SCRIPTS/BF/{X9 => 212x64}/vtx.lua | 0 src/SCRIPTS/BF/{HORUS => 320x480}/filters.lua | 0 src/SCRIPTS/BF/{NV14 => 320x480}/gpspids.lua | 0 .../BF/{HORUS => 320x480}/pid_advanced.lua | 0 src/SCRIPTS/BF/{NV14 => 320x480}/pids1.lua | 0 src/SCRIPTS/BF/{NV14 => 320x480}/pids2.lua | 0 src/SCRIPTS/BF/320x480/pre.lua | 3 ++ src/SCRIPTS/BF/{NV14 => 320x480}/pwm.lua | 0 src/SCRIPTS/BF/{NV14 => 320x480}/rates.lua | 0 src/SCRIPTS/BF/{NV14 => 320x480}/rescue.lua | 0 src/SCRIPTS/BF/{NV14 => 320x480}/rx.lua | 0 src/SCRIPTS/BF/{NV14 => 320x480}/vtx.lua | 0 src/SCRIPTS/BF/{NV14 => 480x272}/filters.lua | 0 src/SCRIPTS/BF/{HORUS => 480x272}/gpspids.lua | 0 .../BF/{NV14 => 480x272}/pid_advanced.lua | 0 src/SCRIPTS/BF/{HORUS => 480x272}/pids1.lua | 0 src/SCRIPTS/BF/{HORUS => 480x272}/pids2.lua | 0 src/SCRIPTS/BF/480x272/pre.lua | 3 ++ src/SCRIPTS/BF/{HORUS => 480x272}/pwm.lua | 0 src/SCRIPTS/BF/{HORUS => 480x272}/rates.lua | 0 src/SCRIPTS/BF/{HORUS => 480x272}/rescue.lua | 0 src/SCRIPTS/BF/{HORUS => 480x272}/rx.lua | 0 src/SCRIPTS/BF/{HORUS => 480x272}/vtx.lua | 0 src/SCRIPTS/BF/HORUS/horuspre.lua | 17 --------- src/SCRIPTS/BF/NV14/nv14pre.lua | 17 --------- src/SCRIPTS/BF/X9/x9pre.lua | 17 --------- src/SCRIPTS/BF/{X7/x7pre.lua => pages.lua} | 12 +++---- src/SCRIPTS/BF/radios.lua | 35 ++++++++----------- src/SCRIPTS/TELEMETRY/bf.lua | 4 +-- src/SCRIPTS/TOOLS/bf.lua | 1 + 50 files changed, 33 insertions(+), 82 deletions(-) rename src/SCRIPTS/BF/{X7 => 128x64}/filters.lua (100%) rename src/SCRIPTS/BF/{X7 => 128x64}/gpspids.lua (100%) rename src/SCRIPTS/BF/{X7 => 128x64}/pid_advanced.lua (100%) rename src/SCRIPTS/BF/{X7 => 128x64}/pids1.lua (100%) rename src/SCRIPTS/BF/{X7 => 128x64}/pids2.lua (100%) create mode 100644 src/SCRIPTS/BF/128x64/pre.lua rename src/SCRIPTS/BF/{X7 => 128x64}/pwm.lua (100%) rename src/SCRIPTS/BF/{X7 => 128x64}/rates.lua (100%) rename src/SCRIPTS/BF/{X7 => 128x64}/rescue.lua (100%) rename src/SCRIPTS/BF/{X7 => 128x64}/vtx.lua (100%) rename src/SCRIPTS/BF/{X9 => 212x64}/filters.lua (100%) rename src/SCRIPTS/BF/{X9 => 212x64}/gpspids.lua (100%) rename src/SCRIPTS/BF/{X9 => 212x64}/pid_advanced.lua (100%) rename src/SCRIPTS/BF/{X9 => 212x64}/pids1.lua (100%) rename src/SCRIPTS/BF/{X9 => 212x64}/pids2.lua (100%) create mode 100644 src/SCRIPTS/BF/212x64/pre.lua rename src/SCRIPTS/BF/{X9 => 212x64}/pwm.lua (100%) rename src/SCRIPTS/BF/{X9 => 212x64}/rates.lua (100%) rename src/SCRIPTS/BF/{X9 => 212x64}/rescue.lua (100%) rename src/SCRIPTS/BF/{X9 => 212x64}/rx.lua (100%) rename src/SCRIPTS/BF/{X9 => 212x64}/vtx.lua (100%) rename src/SCRIPTS/BF/{HORUS => 320x480}/filters.lua (100%) rename src/SCRIPTS/BF/{NV14 => 320x480}/gpspids.lua (100%) rename src/SCRIPTS/BF/{HORUS => 320x480}/pid_advanced.lua (100%) rename src/SCRIPTS/BF/{NV14 => 320x480}/pids1.lua (100%) rename src/SCRIPTS/BF/{NV14 => 320x480}/pids2.lua (100%) create mode 100644 src/SCRIPTS/BF/320x480/pre.lua rename src/SCRIPTS/BF/{NV14 => 320x480}/pwm.lua (100%) rename src/SCRIPTS/BF/{NV14 => 320x480}/rates.lua (100%) rename src/SCRIPTS/BF/{NV14 => 320x480}/rescue.lua (100%) rename src/SCRIPTS/BF/{NV14 => 320x480}/rx.lua (100%) rename src/SCRIPTS/BF/{NV14 => 320x480}/vtx.lua (100%) rename src/SCRIPTS/BF/{NV14 => 480x272}/filters.lua (100%) rename src/SCRIPTS/BF/{HORUS => 480x272}/gpspids.lua (100%) rename src/SCRIPTS/BF/{NV14 => 480x272}/pid_advanced.lua (100%) rename src/SCRIPTS/BF/{HORUS => 480x272}/pids1.lua (100%) rename src/SCRIPTS/BF/{HORUS => 480x272}/pids2.lua (100%) create mode 100644 src/SCRIPTS/BF/480x272/pre.lua rename src/SCRIPTS/BF/{HORUS => 480x272}/pwm.lua (100%) rename src/SCRIPTS/BF/{HORUS => 480x272}/rates.lua (100%) rename src/SCRIPTS/BF/{HORUS => 480x272}/rescue.lua (100%) rename src/SCRIPTS/BF/{HORUS => 480x272}/rx.lua (100%) rename src/SCRIPTS/BF/{HORUS => 480x272}/vtx.lua (100%) delete mode 100644 src/SCRIPTS/BF/HORUS/horuspre.lua delete mode 100644 src/SCRIPTS/BF/NV14/nv14pre.lua delete mode 100644 src/SCRIPTS/BF/X9/x9pre.lua rename src/SCRIPTS/BF/{X7/x7pre.lua => pages.lua} (74%) diff --git a/src/SCRIPTS/BF/X7/filters.lua b/src/SCRIPTS/BF/128x64/filters.lua similarity index 100% rename from src/SCRIPTS/BF/X7/filters.lua rename to src/SCRIPTS/BF/128x64/filters.lua diff --git a/src/SCRIPTS/BF/X7/gpspids.lua b/src/SCRIPTS/BF/128x64/gpspids.lua similarity index 100% rename from src/SCRIPTS/BF/X7/gpspids.lua rename to src/SCRIPTS/BF/128x64/gpspids.lua diff --git a/src/SCRIPTS/BF/X7/pid_advanced.lua b/src/SCRIPTS/BF/128x64/pid_advanced.lua similarity index 100% rename from src/SCRIPTS/BF/X7/pid_advanced.lua rename to src/SCRIPTS/BF/128x64/pid_advanced.lua diff --git a/src/SCRIPTS/BF/X7/pids1.lua b/src/SCRIPTS/BF/128x64/pids1.lua similarity index 100% rename from src/SCRIPTS/BF/X7/pids1.lua rename to src/SCRIPTS/BF/128x64/pids1.lua diff --git a/src/SCRIPTS/BF/X7/pids2.lua b/src/SCRIPTS/BF/128x64/pids2.lua similarity index 100% rename from src/SCRIPTS/BF/X7/pids2.lua rename to src/SCRIPTS/BF/128x64/pids2.lua diff --git a/src/SCRIPTS/BF/128x64/pre.lua b/src/SCRIPTS/BF/128x64/pre.lua new file mode 100644 index 00000000..7ae69aef --- /dev/null +++ b/src/SCRIPTS/BF/128x64/pre.lua @@ -0,0 +1,3 @@ +MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 } +SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 } +NoTelem = { 30, 55, "No Telemetry", BLINK } diff --git a/src/SCRIPTS/BF/X7/pwm.lua b/src/SCRIPTS/BF/128x64/pwm.lua similarity index 100% rename from src/SCRIPTS/BF/X7/pwm.lua rename to src/SCRIPTS/BF/128x64/pwm.lua diff --git a/src/SCRIPTS/BF/X7/rates.lua b/src/SCRIPTS/BF/128x64/rates.lua similarity index 100% rename from src/SCRIPTS/BF/X7/rates.lua rename to src/SCRIPTS/BF/128x64/rates.lua diff --git a/src/SCRIPTS/BF/X7/rescue.lua b/src/SCRIPTS/BF/128x64/rescue.lua similarity index 100% rename from src/SCRIPTS/BF/X7/rescue.lua rename to src/SCRIPTS/BF/128x64/rescue.lua diff --git a/src/SCRIPTS/BF/X7/vtx.lua b/src/SCRIPTS/BF/128x64/vtx.lua similarity index 100% rename from src/SCRIPTS/BF/X7/vtx.lua rename to src/SCRIPTS/BF/128x64/vtx.lua diff --git a/src/SCRIPTS/BF/X9/filters.lua b/src/SCRIPTS/BF/212x64/filters.lua similarity index 100% rename from src/SCRIPTS/BF/X9/filters.lua rename to src/SCRIPTS/BF/212x64/filters.lua diff --git a/src/SCRIPTS/BF/X9/gpspids.lua b/src/SCRIPTS/BF/212x64/gpspids.lua similarity index 100% rename from src/SCRIPTS/BF/X9/gpspids.lua rename to src/SCRIPTS/BF/212x64/gpspids.lua diff --git a/src/SCRIPTS/BF/X9/pid_advanced.lua b/src/SCRIPTS/BF/212x64/pid_advanced.lua similarity index 100% rename from src/SCRIPTS/BF/X9/pid_advanced.lua rename to src/SCRIPTS/BF/212x64/pid_advanced.lua diff --git a/src/SCRIPTS/BF/X9/pids1.lua b/src/SCRIPTS/BF/212x64/pids1.lua similarity index 100% rename from src/SCRIPTS/BF/X9/pids1.lua rename to src/SCRIPTS/BF/212x64/pids1.lua diff --git a/src/SCRIPTS/BF/X9/pids2.lua b/src/SCRIPTS/BF/212x64/pids2.lua similarity index 100% rename from src/SCRIPTS/BF/X9/pids2.lua rename to src/SCRIPTS/BF/212x64/pids2.lua diff --git a/src/SCRIPTS/BF/212x64/pre.lua b/src/SCRIPTS/BF/212x64/pre.lua new file mode 100644 index 00000000..5152db41 --- /dev/null +++ b/src/SCRIPTS/BF/212x64/pre.lua @@ -0,0 +1,3 @@ +MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 } +SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 } +NoTelem = { 70, 55, "No Telemetry", BLINK } diff --git a/src/SCRIPTS/BF/X9/pwm.lua b/src/SCRIPTS/BF/212x64/pwm.lua similarity index 100% rename from src/SCRIPTS/BF/X9/pwm.lua rename to src/SCRIPTS/BF/212x64/pwm.lua diff --git a/src/SCRIPTS/BF/X9/rates.lua b/src/SCRIPTS/BF/212x64/rates.lua similarity index 100% rename from src/SCRIPTS/BF/X9/rates.lua rename to src/SCRIPTS/BF/212x64/rates.lua diff --git a/src/SCRIPTS/BF/X9/rescue.lua b/src/SCRIPTS/BF/212x64/rescue.lua similarity index 100% rename from src/SCRIPTS/BF/X9/rescue.lua rename to src/SCRIPTS/BF/212x64/rescue.lua diff --git a/src/SCRIPTS/BF/X9/rx.lua b/src/SCRIPTS/BF/212x64/rx.lua similarity index 100% rename from src/SCRIPTS/BF/X9/rx.lua rename to src/SCRIPTS/BF/212x64/rx.lua diff --git a/src/SCRIPTS/BF/X9/vtx.lua b/src/SCRIPTS/BF/212x64/vtx.lua similarity index 100% rename from src/SCRIPTS/BF/X9/vtx.lua rename to src/SCRIPTS/BF/212x64/vtx.lua diff --git a/src/SCRIPTS/BF/HORUS/filters.lua b/src/SCRIPTS/BF/320x480/filters.lua similarity index 100% rename from src/SCRIPTS/BF/HORUS/filters.lua rename to src/SCRIPTS/BF/320x480/filters.lua diff --git a/src/SCRIPTS/BF/NV14/gpspids.lua b/src/SCRIPTS/BF/320x480/gpspids.lua similarity index 100% rename from src/SCRIPTS/BF/NV14/gpspids.lua rename to src/SCRIPTS/BF/320x480/gpspids.lua diff --git a/src/SCRIPTS/BF/HORUS/pid_advanced.lua b/src/SCRIPTS/BF/320x480/pid_advanced.lua similarity index 100% rename from src/SCRIPTS/BF/HORUS/pid_advanced.lua rename to src/SCRIPTS/BF/320x480/pid_advanced.lua diff --git a/src/SCRIPTS/BF/NV14/pids1.lua b/src/SCRIPTS/BF/320x480/pids1.lua similarity index 100% rename from src/SCRIPTS/BF/NV14/pids1.lua rename to src/SCRIPTS/BF/320x480/pids1.lua diff --git a/src/SCRIPTS/BF/NV14/pids2.lua b/src/SCRIPTS/BF/320x480/pids2.lua similarity index 100% rename from src/SCRIPTS/BF/NV14/pids2.lua rename to src/SCRIPTS/BF/320x480/pids2.lua diff --git a/src/SCRIPTS/BF/320x480/pre.lua b/src/SCRIPTS/BF/320x480/pre.lua new file mode 100644 index 00000000..61c0eaf1 --- /dev/null +++ b/src/SCRIPTS/BF/320x480/pre.lua @@ -0,0 +1,3 @@ +MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 } +SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 } +NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", TEXT_COLOR + INVERS + BLINK } diff --git a/src/SCRIPTS/BF/NV14/pwm.lua b/src/SCRIPTS/BF/320x480/pwm.lua similarity index 100% rename from src/SCRIPTS/BF/NV14/pwm.lua rename to src/SCRIPTS/BF/320x480/pwm.lua diff --git a/src/SCRIPTS/BF/NV14/rates.lua b/src/SCRIPTS/BF/320x480/rates.lua similarity index 100% rename from src/SCRIPTS/BF/NV14/rates.lua rename to src/SCRIPTS/BF/320x480/rates.lua diff --git a/src/SCRIPTS/BF/NV14/rescue.lua b/src/SCRIPTS/BF/320x480/rescue.lua similarity index 100% rename from src/SCRIPTS/BF/NV14/rescue.lua rename to src/SCRIPTS/BF/320x480/rescue.lua diff --git a/src/SCRIPTS/BF/NV14/rx.lua b/src/SCRIPTS/BF/320x480/rx.lua similarity index 100% rename from src/SCRIPTS/BF/NV14/rx.lua rename to src/SCRIPTS/BF/320x480/rx.lua diff --git a/src/SCRIPTS/BF/NV14/vtx.lua b/src/SCRIPTS/BF/320x480/vtx.lua similarity index 100% rename from src/SCRIPTS/BF/NV14/vtx.lua rename to src/SCRIPTS/BF/320x480/vtx.lua diff --git a/src/SCRIPTS/BF/NV14/filters.lua b/src/SCRIPTS/BF/480x272/filters.lua similarity index 100% rename from src/SCRIPTS/BF/NV14/filters.lua rename to src/SCRIPTS/BF/480x272/filters.lua diff --git a/src/SCRIPTS/BF/HORUS/gpspids.lua b/src/SCRIPTS/BF/480x272/gpspids.lua similarity index 100% rename from src/SCRIPTS/BF/HORUS/gpspids.lua rename to src/SCRIPTS/BF/480x272/gpspids.lua diff --git a/src/SCRIPTS/BF/NV14/pid_advanced.lua b/src/SCRIPTS/BF/480x272/pid_advanced.lua similarity index 100% rename from src/SCRIPTS/BF/NV14/pid_advanced.lua rename to src/SCRIPTS/BF/480x272/pid_advanced.lua diff --git a/src/SCRIPTS/BF/HORUS/pids1.lua b/src/SCRIPTS/BF/480x272/pids1.lua similarity index 100% rename from src/SCRIPTS/BF/HORUS/pids1.lua rename to src/SCRIPTS/BF/480x272/pids1.lua diff --git a/src/SCRIPTS/BF/HORUS/pids2.lua b/src/SCRIPTS/BF/480x272/pids2.lua similarity index 100% rename from src/SCRIPTS/BF/HORUS/pids2.lua rename to src/SCRIPTS/BF/480x272/pids2.lua diff --git a/src/SCRIPTS/BF/480x272/pre.lua b/src/SCRIPTS/BF/480x272/pre.lua new file mode 100644 index 00000000..afc42eac --- /dev/null +++ b/src/SCRIPTS/BF/480x272/pre.lua @@ -0,0 +1,3 @@ +MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 } +SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 } +NoTelem = { 192, LCD_H - 28, "No Telemetry", TEXT_COLOR + INVERS + BLINK } diff --git a/src/SCRIPTS/BF/HORUS/pwm.lua b/src/SCRIPTS/BF/480x272/pwm.lua similarity index 100% rename from src/SCRIPTS/BF/HORUS/pwm.lua rename to src/SCRIPTS/BF/480x272/pwm.lua diff --git a/src/SCRIPTS/BF/HORUS/rates.lua b/src/SCRIPTS/BF/480x272/rates.lua similarity index 100% rename from src/SCRIPTS/BF/HORUS/rates.lua rename to src/SCRIPTS/BF/480x272/rates.lua diff --git a/src/SCRIPTS/BF/HORUS/rescue.lua b/src/SCRIPTS/BF/480x272/rescue.lua similarity index 100% rename from src/SCRIPTS/BF/HORUS/rescue.lua rename to src/SCRIPTS/BF/480x272/rescue.lua diff --git a/src/SCRIPTS/BF/HORUS/rx.lua b/src/SCRIPTS/BF/480x272/rx.lua similarity index 100% rename from src/SCRIPTS/BF/HORUS/rx.lua rename to src/SCRIPTS/BF/480x272/rx.lua diff --git a/src/SCRIPTS/BF/HORUS/vtx.lua b/src/SCRIPTS/BF/480x272/vtx.lua similarity index 100% rename from src/SCRIPTS/BF/HORUS/vtx.lua rename to src/SCRIPTS/BF/480x272/vtx.lua diff --git a/src/SCRIPTS/BF/HORUS/horuspre.lua b/src/SCRIPTS/BF/HORUS/horuspre.lua deleted file mode 100644 index 1102279d..00000000 --- a/src/SCRIPTS/BF/HORUS/horuspre.lua +++ /dev/null @@ -1,17 +0,0 @@ -PageFiles = -{ - { title = "PIDs 1", script = "pids1.lua"}, - { title = "PIDs 2", script = "pids2.lua"}, - { title = "Rates", script = "rates.lua"}, - { title = "Advanced PIDs", script = "pid_advanced.lua"}, - { title = "Filters", script = "filters.lua"}, - { title = "vTX Settings", script = "vtx.lua"}, - { title = "Gyro / Motor", script = "pwm.lua"}, - { title = "Rx", script = "rx.lua"}, - { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041}, - { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041}, -} - -MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 } -SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 } -NoTelem = { 192, LCD_H - 28, "No Telemetry", TEXT_COLOR + INVERS + BLINK } diff --git a/src/SCRIPTS/BF/NV14/nv14pre.lua b/src/SCRIPTS/BF/NV14/nv14pre.lua deleted file mode 100644 index d1071cbe..00000000 --- a/src/SCRIPTS/BF/NV14/nv14pre.lua +++ /dev/null @@ -1,17 +0,0 @@ -PageFiles = -{ - { title = "PIDs 1", script = "pids1.lua"}, - { title = "PIDs 2", script = "pids2.lua"}, - { title = "Rates", script = "rates.lua"}, - { title = "Advanced PIDs", script = "pid_advanced.lua"}, - { title = "Filters", script = "filters.lua"}, - { title = "vTX Settings", script = "vtx.lua"}, - { title = "Gyro / Motor", script = "pwm.lua"}, - { title = "Rx", script = "rx.lua"}, - { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041}, - { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041}, -} - -MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 } -SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 } -NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", TEXT_COLOR + INVERS + BLINK } diff --git a/src/SCRIPTS/BF/X9/x9pre.lua b/src/SCRIPTS/BF/X9/x9pre.lua deleted file mode 100644 index c7505682..00000000 --- a/src/SCRIPTS/BF/X9/x9pre.lua +++ /dev/null @@ -1,17 +0,0 @@ -PageFiles = -{ - { title = "PIDs 1", script = "pids1.lua"}, - { title = "PIDs 2", script = "pids2.lua"}, - { title = "Rates", script = "rates.lua"}, - { title = "Advanced PIDs", script = "pid_advanced.lua"}, - { title = "Filters", script = "filters.lua"}, - { title = "vTX Settings", script = "vtx.lua"}, - { title = "Gyro / Motor", script = "pwm.lua"}, - { title = "Rx", script = "rx.lua"}, - { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041}, - { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041}, -} - -MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 } -SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 } -NoTelem = { 70, 55, "No Telemetry", BLINK } diff --git a/src/SCRIPTS/BF/X7/x7pre.lua b/src/SCRIPTS/BF/pages.lua similarity index 74% rename from src/SCRIPTS/BF/X7/x7pre.lua rename to src/SCRIPTS/BF/pages.lua index 3d80a97c..b870d1ec 100644 --- a/src/SCRIPTS/BF/X7/x7pre.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -1,17 +1,13 @@ -PageFiles = +PageFiles = { - { title = "vTX Settings", script = "vtx.lua"}, - { title = "Gyro / Motor", script = "pwm.lua"}, { title = "PIDs 1", script = "pids1.lua"}, { title = "PIDs 2", script = "pids2.lua"}, { title = "Rates", script = "rates.lua"}, { title = "Advanced PIDs", script = "pid_advanced.lua"}, { title = "Filters", script = "filters.lua"}, + { title = "vTX Settings", script = "vtx.lua"}, + { title = "Gyro / Motor", script = "pwm.lua"}, { title = "Rx", script = "rx.lua"}, { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041}, { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041}, -} - -MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 } -SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 } -NoTelem = { 30, 55, "No Telemetry", BLINK } +} \ No newline at end of file diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index 84cb77c3..9d4bc9cb 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -4,41 +4,34 @@ lcdResolution = high = 1 } -local supportedPlatforms = { - x7 = +local supportedRadios = +{ + ["128x64"] = { - templateHome = SCRIPT_HOME.."/X7/", - preLoad = SCRIPT_HOME.."/X7/x7pre.lua", + templateHome = SCRIPT_HOME.."/128x64/", + preLoad = SCRIPT_HOME.."/128x64/pre.lua", resolution = lcdResolution.low }, - x9 = + ["212x64"] = { - templateHome = SCRIPT_HOME.."/X9/", - preLoad = SCRIPT_HOME.."/X9/x9pre.lua", + templateHome = SCRIPT_HOME.."/212x64/", + preLoad = SCRIPT_HOME.."/212x64/pre.lua", resolution = lcdResolution.low }, - horus = + ["480x272"] = { - templateHome = SCRIPT_HOME.."/HORUS/", - preLoad = SCRIPT_HOME.."/HORUS/horuspre.lua", + templateHome = SCRIPT_HOME.."/480x272/", + preLoad = SCRIPT_HOME.."/480x272/pre.lua", resolution = lcdResolution.high }, - nv14 = + ["320x480"] = { - templateHome = SCRIPT_HOME.."/NV14/", - preLoad = SCRIPT_HOME.."/NV14/nv14pre.lua", + templateHome = SCRIPT_HOME.."/320x480/", + preLoad = SCRIPT_HOME.."/320x480/pre.lua", resolution = lcdResolution.high }, } -local supportedRadios = -{ - ["128x64"] = supportedPlatforms.x7, - ["212x64"] = supportedPlatforms.x9, - ["480x272"] = supportedPlatforms.horus, - ["320x480"] = supportedPlatforms.nv14, -} - local ver, rad, maj, min, rev = getVersion() local radio = supportedRadios[tostring(LCD_W) .. "x" .. tostring(LCD_H)] diff --git a/src/SCRIPTS/TELEMETRY/bf.lua b/src/SCRIPTS/TELEMETRY/bf.lua index b6f47f95..38190fef 100644 --- a/src/SCRIPTS/TELEMETRY/bf.lua +++ b/src/SCRIPTS/TELEMETRY/bf.lua @@ -1,16 +1,16 @@ SCRIPT_HOME = "/SCRIPTS/BF" apiVersion = 0 +isTelemetryScript = true protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() radio = assert(loadScript(SCRIPT_HOME.."/radios.lua"))() +assert(loadScript(SCRIPT_HOME.."/pages.lua"))() assert(loadScript(radio.preLoad))() assert(loadScript(protocol.transport))() assert(loadScript(SCRIPT_HOME.."/MSP/common.lua"))() -isTelemetryScript = true - local run_ui = assert(loadScript(SCRIPT_HOME.."/ui.lua"))() local background = assert(loadScript(SCRIPT_HOME.."/background.lua"))() diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index 444652d7..518e12e2 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -7,6 +7,7 @@ isTelemetryScript = false protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() radio = assert(loadScript(SCRIPT_HOME.."/radios.lua"))() +assert(loadScript(SCRIPT_HOME.."/pages.lua"))() assert(loadScript(radio.preLoad))() assert(loadScript(protocol.transport))() assert(loadScript(SCRIPT_HOME.."/MSP/common.lua"))() From ff7d1c6376e5e95a2b14b7ea539f0fce16b1c360 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 16 Oct 2019 14:31:01 +0100 Subject: [PATCH 013/193] Add default pages. --- src/SCRIPTS/BF/PAGES/filters.lua | 11 ++ src/SCRIPTS/BF/PAGES/gpspids.lua | 11 ++ src/SCRIPTS/BF/PAGES/pid_advanced.lua | 11 ++ src/SCRIPTS/BF/PAGES/pids1.lua | 11 ++ src/SCRIPTS/BF/PAGES/pids2.lua | 11 ++ src/SCRIPTS/BF/PAGES/pwm.lua | 39 +++++ src/SCRIPTS/BF/PAGES/rates.lua | 10 ++ src/SCRIPTS/BF/PAGES/rescue.lua | 11 ++ src/SCRIPTS/BF/PAGES/rx.lua | 10 ++ src/SCRIPTS/BF/PAGES/vtx.lua | 241 ++++++++++++++++++++++++++ 10 files changed, 366 insertions(+) create mode 100644 src/SCRIPTS/BF/PAGES/filters.lua create mode 100644 src/SCRIPTS/BF/PAGES/gpspids.lua create mode 100644 src/SCRIPTS/BF/PAGES/pid_advanced.lua create mode 100644 src/SCRIPTS/BF/PAGES/pids1.lua create mode 100644 src/SCRIPTS/BF/PAGES/pids2.lua create mode 100644 src/SCRIPTS/BF/PAGES/pwm.lua create mode 100644 src/SCRIPTS/BF/PAGES/rates.lua create mode 100644 src/SCRIPTS/BF/PAGES/rescue.lua create mode 100644 src/SCRIPTS/BF/PAGES/rx.lua create mode 100644 src/SCRIPTS/BF/PAGES/vtx.lua diff --git a/src/SCRIPTS/BF/PAGES/filters.lua b/src/SCRIPTS/BF/PAGES/filters.lua new file mode 100644 index 00000000..dfbb415f --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/filters.lua @@ -0,0 +1,11 @@ +return { + read = 92, -- MSP_FILTER_CONFIG + write = 93, -- MSP_SET_FILTER_CONFIG + eepromWrite = true, + reboot = false, + title = "Filters", + minBytes = 37, + outputBytes = 37, + text= { }, + fields = { } +} diff --git a/src/SCRIPTS/BF/PAGES/gpspids.lua b/src/SCRIPTS/BF/PAGES/gpspids.lua new file mode 100644 index 00000000..0a90379c --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/gpspids.lua @@ -0,0 +1,11 @@ +return { + read = 136, -- MSP_GPS_RESCUE_PIDS + write = 226, -- MSP_SET_GPS_RESCUE_PIDS + title = "GPS Rescue / PIDs", + reboot = false, + eepromWrite = true, + minBytes = 14, + requiredVersion = 1.041, + text = { }, + fields = { }, +} diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua new file mode 100644 index 00000000..a5a43362 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -0,0 +1,11 @@ +return { + read = 94, -- MSP_PID_ADVANCED + write = 95, -- MSP_SET_PID_ADVANCED + title = "PID Advanced", + reboot = false, + eepromWrite = true, + minBytes = 46, + outputBytes = 46, + text = { }, + fields = { } +} diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua new file mode 100644 index 00000000..504f75d1 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -0,0 +1,11 @@ + +return { + read = 112, -- MSP_PID + write = 202, -- MSP_SET_PID + title = "PIDs (1/2)", + reboot = false, + eepromWrite = true, + minBytes = 9, + text = { }, + fields = { }, +} diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua new file mode 100644 index 00000000..5ec11ae1 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -0,0 +1,11 @@ + +return { + read = 94, -- MSP_PID_ADVANCED + write = 95, -- MSP_SET_PID_ADVANCED + title = "PIDs (2/2)", + reboot = false, + eepromWrite = true, + minBytes = 44, + text = { }, + fields = { }, +} diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua new file mode 100644 index 00000000..5a11da41 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -0,0 +1,39 @@ +return { + read = 90, -- MSP_ADVANCED_CONFIG + write = 91, -- MSP_SET_ADVANCED_CONFIG + reboot = true, + eepromWrite = true, + title = "PWM", + minBytes = 9, + text= { }, + fields = { }, + calculateGyroRates = function(self, baseRate) + self.gyroRates = {} + self.fields[2].table = {} + for i=1, 32 do + self.gyroRates[i] = baseRate/i + local fmt = nil + self.fields[2].table[i] = string.format("%.2f",baseRate/i) + end + end, + calculatePidRates = function(self, baseRate) + self.fields[3].table = {} + for i=1, 16 do + self.fields[3].table[i] = string.format("%.2f",baseRate/i) + end + end, + updateRateTables = function(self) + if self.values[9] == 0 then + self.calculateGyroRates(self, 8) + self.calculatePidRates(self, 8) + elseif self.values[9] == 1 then + self.calculateGyroRates(self, 32) + self.calculatePidRates(self, 32) + end + end, + updatePidRateTable = function(self) + local newRateIdx = self.values[1] + local newRate = self.gyroRates[newRateIdx] + self.calculatePidRates(self, newRate) + end +} diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua new file mode 100644 index 00000000..79440695 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -0,0 +1,10 @@ +return { + read = 111, -- MSP_RC_TUNING + write = 204, -- MSP_SET_RC_TUNING + title = "Rates", + reboot = false, + eepromWrite = true, + minBytes = 16, + text = { }, + fields = { }, +} diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua new file mode 100644 index 00000000..ac7b54c5 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -0,0 +1,11 @@ +return { + read = 135, -- MSP_GPS_RESCUE + write = 225, -- MSP_SET_GPS_RESCUE + title = "GPS Rescue", + reboot = false, + eepromWrite = true, + minBytes = 16, + requiredVersion = 1.041, + text = { }, + fields = { }, +} diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua new file mode 100644 index 00000000..f37f7b4e --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -0,0 +1,10 @@ +return { + read = 44, -- MSP_RX_CONFIG + write = 45, -- MSP_SET_RX_CONFIG + title = "RX", + reboot = false, + eepromWrite = true, + minBytes = 23, + text= { }, + fields = { }, +} diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua new file mode 100644 index 00000000..bd5ff9c8 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -0,0 +1,241 @@ + +return { + read = 88, -- MSP_VTX_CONFIG + write = 89, -- MSP_VTX_SET_CONFIG + eepromWrite = true, + reboot = false, + title = "VTX", + minBytes = 5, + prevBandVal = 0, + prevChanVal = 0, + prevFreqVal = 0, + lastFreqUpdTS = 0, + freqModCounter = 0, + text= { }, + fields = { }, + freqLookup = { + { 5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725 }, -- Boscam A + { 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 }, -- Boscam B + { 5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945 }, -- Boscam E + { 5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880 }, -- FatShark + { 5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 }, -- RaceBand + }, + postLoad = function (self) + if (self.values[2] or 0) < 0 or (self.values[3] or 0) == 0 or (self.values[4] or 0) == 0 then + self.values = {} + else + self.prevBandVal = 0 -- reset value trackers + self.prevChanVal = 0 + self.prevFreqVal = 0 + local rFreq + if (self.values[7] or 0) > 0 then + rFreq = math.floor(self.values[6] + (self.values[7] * 256)) + else + rFreq = 0 + end + if (self.values[2] or 0) > 0 then -- band != 0 + if rFreq > 0 then + self.prevFreqVal = rFreq + self.prevBandVal = self.values[2] + self.prevChanVal = self.values[3] + self.fields[1].min = 0 -- make sure 'U' band allowed + self.eepromWrite = true + self.fields[6].value = rFreq + self.values[6] = rFreq + else -- if user freq not supported then + self.fields[1].min = 1 -- don't allow 'U' band + self.eepromWrite = false -- don't write EEPROM on older Betaflight versions + end + else -- band == 0 + if rFreq > 0 then + self.prevFreqVal = rFreq + self.fields[1].min = 0 -- make sure 'U' band allowed + self.eepromWrite = true + self.fields[6].value = rFreq + self.values[6] = rFreq + -- set chan via freq / 100 + self.prevChanVal = clipValue(math.floor((rFreq - 5100) / 100), + self.fields[2].min, self.fields[2].max) + self.fields[2].value = self.prevChanVal + self.values[3] = self.prevChanVal + else + self.values = {} + end + end + end + end, + preSave = function(self) + local valsTemp = {} + if self.values then + local channel + if self.values[2] > 0 then -- band != 0 + channel = (self.values[2]-1)*8 + self.values[3]-1 + elseif self.fields[6].value then -- band == 0 + channel = self.fields[6].value + else + channel = 24 + end + valsTemp[1] = bit32.band(channel,0xFF) + valsTemp[2] = bit32.rshift(channel,8) + valsTemp[3] = self.values[4] + valsTemp[4] = self.values[5] + end + return valsTemp + end, + -- find closest value in freq table that is above/below given freq + findNextInFreqTable = function(self, newFreq) + local startBand + local endBand + local incFlag -- freq increasing or decreasing + if newFreq > self.prevFreqVal then + incFlag = 1 + startBand = 1 + endBand = self.fields[1].max + else + incFlag = -1 + startBand = self.fields[1].max + endBand = 1 + end + local curBand = self.values[2] + local curChan = self.values[3] + local selBand = 0 + local selChan = 0 + local selFreq = 0 + local diffVal = 9999 + local fVal + local minChan = self.fields[2].min + local maxChan = self.fields[2].max + -- need to scan bands in same "direction" as 'incFlag' + -- so same-freq selections will be handled properly (F8 & R7) + for band=startBand,endBand,incFlag do + for chan=minChan,maxChan do + if band ~= curBand or chan ~= curChan then -- don't reselect same band/chan + fVal = self.freqLookup[band][chan] + if incFlag > 0 then + if fVal >= self.prevFreqVal and fVal - self.prevFreqVal < diffVal then + -- if same freq then only select if "next" band: + if fVal ~= self.prevFreqVal or band > curBand then + selBand = band + selChan = chan + selFreq = fVal + diffVal = fVal - self.prevFreqVal + end + end + else + if fVal <= self.prevFreqVal and self.prevFreqVal - fVal < diffVal then + -- if same freq then only select if "previous" band: + if fVal ~= self.prevFreqVal or band < curBand then + selBand = band + selChan = chan + selFreq = fVal + diffVal = self.prevFreqVal - fVal + end + end + end + end + end + end + return selFreq, selBand, selChan + end, + -- returns the next user-frequency value in MHz; implements an + -- "exponential" modification rate so dialing in values is faster + getNextUserFreqValue = function(self, newFreq) + local now = getTime() -- track rate of change for possible mod speedup + if now < self.lastFreqUpdTS + 15 then + self.freqModCounter = self.freqModCounter + (15-(self.lastFreqUpdTS-now)) -- increase counter for mod speedup + else + self.freqModCounter = 0 -- no mod speedup + end + local uFreq + if self.freqModCounter > 65 then -- rate is fast enough; do mod speedup + if newFreq > self.prevFreqVal then + uFreq = clipValue(newFreq + math.floor(self.freqModCounter / 65), + self.fields[6].min, self.fields[6].max) + else + uFreq = clipValue(newFreq - math.floor(self.freqModCounter / 65), + self.fields[6].min, self.fields[6].max) + end + else + uFreq = newFreq + end + self.lastFreqUpdTS = now + return uFreq + end, + updatePowerTable = function(self) + if self.values and not self.fields[3].table then + if self.values[1] == 1 then -- RTC6705 + self.fields[3].table = { 25, 200 } + self.fields[3].max = 2 + self.fields[4].t = nil -- don't display Pit field + self.fields[4].table = { [0]="", "" } + elseif self.values[1] == 3 then -- SmartAudio + self.fields[3].table = { 25, 200, 500, 800 } + self.fields[3].max = 4 + elseif self.values[1] == 4 then -- Tramp + self.fields[3].table = { 25, 100, 200, 400, 600 } + self.fields[3].max = 5 + elseif self.values[1] == 255 then -- None/Unknown + self.fields[3].t = nil -- don't display Power field + self.fields[3].max = 1 + self.fields[3].table = { [1]="" } + self.fields[4].t = nil -- don't display Pit field + self.fields[4].table = { [0]="", "" } + end + end + end, + handleBandChanUpdate = function(self) + if (#(self.values) or 0) >= self.minBytes then + if (self.values[3] or 0) > 0 then + if self.values[2] ~= self.prevBandVal or self.values[3] ~= self.prevChanVal then + if self.values[2] > 0 then -- band != 0 + self.prevFreqVal = self.freqLookup[self.values[2]][self.values[3]] + else -- band == 0; set freq via channel*100 + self.prevFreqVal = math.floor(5100 + (self.values[3] * 100)) + end + self.fields[6].value = self.prevFreqVal + self.values[6] = self.prevFreqVal + self.prevBandVal = self.values[2] + self.prevChanVal = self.values[3] + end + end + end + end, + handleFreqValUpdate = function(self) + if (#(self.values) or 0) >= self.minBytes and (self.fields[6].value or 0) > 0 then + local newFreq = self.fields[6].value + if newFreq ~= self.prevFreqVal then + if self.values[2] == 0 then + -- band == 0 + local uFreq = self.getNextUserFreqValue(self, newFreq) + self.prevFreqVal = uFreq + if uFreq ~= newFreq then + self.fields[6].value = uFreq + self.values[6] = uFreq + end + -- set channel value via freq/100 + self.prevChanVal = clipValue(math.floor((self.prevFreqVal - 5100) / 100), + self.fields[2].min, self.fields[2].max) + self.fields[2].value = self.prevChanVal + self.values[3] = self.prevChanVal + else + -- band != 0; find closest freq in table that is above/below dialed freq + local selFreq, selBand, selChan = self.findNextInFreqTable(self, newFreq) + if selFreq > 0 then + self.prevFreqVal = selFreq + self.prevBandVal = selBand + self.prevChanVal = selChan + self.fields[6].value = selFreq -- using new freq from table + self.values[6] = selFreq + self.fields[1].value = self.prevBandVal -- set band value for freq + self.values[2] = self.prevBandVal + self.fields[2].value = self.prevChanVal -- set channel value for freq + self.values[3] = self.prevChanVal + else + self.fields[6].value = self.prevFreqVal -- if no match then revert freq + self.values[6] = self.prevFreqVal + end + end + end + end + end +} \ No newline at end of file From cfeb319abd29ec13c7c35b66d3928259a6a7929b Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 16 Oct 2019 15:43:51 +0100 Subject: [PATCH 014/193] initial refactoring part1 --- src/SCRIPTS/BF/128x64/filters.lua | 7 ------- src/SCRIPTS/BF/128x64/gpspids.lua | 8 -------- src/SCRIPTS/BF/128x64/pid_advanced.lua | 7 ------- src/SCRIPTS/BF/128x64/pids1.lua | 7 ------- src/SCRIPTS/BF/128x64/pids2.lua | 6 ------ src/SCRIPTS/BF/128x64/pre.lua | 3 --- src/SCRIPTS/BF/212x64/filters.lua | 7 ------- src/SCRIPTS/BF/212x64/gpspids.lua | 7 ------- src/SCRIPTS/BF/212x64/pre.lua | 3 --- src/SCRIPTS/BF/320x480/filters.lua | 7 ------- src/SCRIPTS/BF/320x480/gpspids.lua | 7 ------- src/SCRIPTS/BF/320x480/pre.lua | 3 --- src/SCRIPTS/BF/480x272/filters.lua | 7 ------- src/SCRIPTS/BF/480x272/gpspids.lua | 7 ------- src/SCRIPTS/BF/480x272/pre.lua | 3 --- src/SCRIPTS/BF/PAGES/filters.lua | 9 ++++++--- src/SCRIPTS/BF/PAGES/gpspids.lua | 23 ++++++++++++--------- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 23 ++++++++++++--------- src/SCRIPTS/BF/PAGES/pids1.lua | 6 +++--- src/SCRIPTS/BF/PAGES/pids2.lua | 20 +++++++++--------- src/SCRIPTS/BF/PAGES/pwm.lua | 9 ++++++--- src/SCRIPTS/BF/PAGES/rates.lua | 19 +++++++++-------- src/SCRIPTS/BF/PAGES/rescue.lua | 21 ++++++++++--------- src/SCRIPTS/BF/PAGES/rx.lua | 19 +++++++++-------- src/SCRIPTS/BF/PAGES/vtx.lua | 8 +++++--- src/SCRIPTS/BF/radios.lua | 24 ++++++++++++++-------- src/SCRIPTS/BF/ui.lua | 28 +++++++++++++------------- src/SCRIPTS/TELEMETRY/bf.lua | 1 - src/SCRIPTS/TOOLS/bf.lua | 1 - 29 files changed, 121 insertions(+), 179 deletions(-) delete mode 100644 src/SCRIPTS/BF/128x64/pre.lua delete mode 100644 src/SCRIPTS/BF/212x64/pre.lua delete mode 100644 src/SCRIPTS/BF/320x480/pre.lua delete mode 100644 src/SCRIPTS/BF/480x272/pre.lua diff --git a/src/SCRIPTS/BF/128x64/filters.lua b/src/SCRIPTS/BF/128x64/filters.lua index a5dde7d6..b94571b5 100644 --- a/src/SCRIPTS/BF/128x64/filters.lua +++ b/src/SCRIPTS/BF/128x64/filters.lua @@ -1,11 +1,4 @@ return { - read = 92, -- MSP_FILTER_CONFIG - write = 93, -- MSP_SET_FILTER_CONFIG - eepromWrite = true, - reboot = false, - title = "Filters", - minBytes = 37, - outputBytes = 37, yMinLimit = 12, yMaxLimit = 52, text= { diff --git a/src/SCRIPTS/BF/128x64/gpspids.lua b/src/SCRIPTS/BF/128x64/gpspids.lua index bbbeecab..95c35cc0 100644 --- a/src/SCRIPTS/BF/128x64/gpspids.lua +++ b/src/SCRIPTS/BF/128x64/gpspids.lua @@ -1,12 +1,4 @@ - return { - read = 136, -- MSP_GPS_RESCUE_PIDS - write = 226, -- MSP_SET_GPS_RESCUE_PIDS - title = "GPS / PIDs", - reboot = false, - eepromWrite = true, - minBytes = 14, - requiredVersion = 1.041, text = { { t = "P", x = 55, y = 14, to=SMLSIZE }, { t = "I", x = 83, y = 14, to=SMLSIZE }, diff --git a/src/SCRIPTS/BF/128x64/pid_advanced.lua b/src/SCRIPTS/BF/128x64/pid_advanced.lua index 6d51a97c..185fa766 100644 --- a/src/SCRIPTS/BF/128x64/pid_advanced.lua +++ b/src/SCRIPTS/BF/128x64/pid_advanced.lua @@ -1,11 +1,4 @@ return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PID Adv.", - reboot = false, - eepromWrite = true, - minBytes = 46, - outputBytes = 46, yMinLimit = 12, yMaxLimit = 52, text = { diff --git a/src/SCRIPTS/BF/128x64/pids1.lua b/src/SCRIPTS/BF/128x64/pids1.lua index e4519a55..c09d09c1 100644 --- a/src/SCRIPTS/BF/128x64/pids1.lua +++ b/src/SCRIPTS/BF/128x64/pids1.lua @@ -1,11 +1,4 @@ - return { - read = 112, -- MSP_PID - write = 202, -- MSP_SET_PID - title = "PIDs (1/2)", - reboot = false, - eepromWrite = true, - minBytes = 9, text = { { t = "P", x = 45, y = 14, to = SMLSIZE }, { t = "I", x = 73, y = 14, to = SMLSIZE }, diff --git a/src/SCRIPTS/BF/128x64/pids2.lua b/src/SCRIPTS/BF/128x64/pids2.lua index ee563529..09ce2217 100644 --- a/src/SCRIPTS/BF/128x64/pids2.lua +++ b/src/SCRIPTS/BF/128x64/pids2.lua @@ -1,10 +1,4 @@ - return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PIDs (2/2)", - reboot = false, - eepromWrite = true, minBytes = 44, yMinLimit = 11, yMaxLimit = 52, diff --git a/src/SCRIPTS/BF/128x64/pre.lua b/src/SCRIPTS/BF/128x64/pre.lua deleted file mode 100644 index 7ae69aef..00000000 --- a/src/SCRIPTS/BF/128x64/pre.lua +++ /dev/null @@ -1,3 +0,0 @@ -MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 } -SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 } -NoTelem = { 30, 55, "No Telemetry", BLINK } diff --git a/src/SCRIPTS/BF/212x64/filters.lua b/src/SCRIPTS/BF/212x64/filters.lua index a5dde7d6..b94571b5 100644 --- a/src/SCRIPTS/BF/212x64/filters.lua +++ b/src/SCRIPTS/BF/212x64/filters.lua @@ -1,11 +1,4 @@ return { - read = 92, -- MSP_FILTER_CONFIG - write = 93, -- MSP_SET_FILTER_CONFIG - eepromWrite = true, - reboot = false, - title = "Filters", - minBytes = 37, - outputBytes = 37, yMinLimit = 12, yMaxLimit = 52, text= { diff --git a/src/SCRIPTS/BF/212x64/gpspids.lua b/src/SCRIPTS/BF/212x64/gpspids.lua index fa721ca1..a3c4c1b5 100644 --- a/src/SCRIPTS/BF/212x64/gpspids.lua +++ b/src/SCRIPTS/BF/212x64/gpspids.lua @@ -1,11 +1,4 @@ return { - read = 136, -- MSP_GPS_RESCUE_PIDS - write = 226, -- MSP_SET_GPS_RESCUE_PIDS - title = "GPS Rescue / PIDs", - reboot = false, - eepromWrite = true, - minBytes = 14, - requiredVersion = 1.041, text = { { t = "P", x = 70, y = 14, to = SMLSIZE }, { t = "I", x = 98, y = 14, to = SMLSIZE }, diff --git a/src/SCRIPTS/BF/212x64/pre.lua b/src/SCRIPTS/BF/212x64/pre.lua deleted file mode 100644 index 5152db41..00000000 --- a/src/SCRIPTS/BF/212x64/pre.lua +++ /dev/null @@ -1,3 +0,0 @@ -MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 } -SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 } -NoTelem = { 70, 55, "No Telemetry", BLINK } diff --git a/src/SCRIPTS/BF/320x480/filters.lua b/src/SCRIPTS/BF/320x480/filters.lua index 71fc95fb..7847025b 100644 --- a/src/SCRIPTS/BF/320x480/filters.lua +++ b/src/SCRIPTS/BF/320x480/filters.lua @@ -1,11 +1,4 @@ return { - read = 92, -- MSP_FILTER_CONFIG - write = 93, -- MSP_SET_FILTER_CONFIG - eepromWrite = true, - reboot = false, - title = "Filters", - minBytes = 37, - outputBytes = 37, yMinLimit = 35, yMaxLimit = 215, text= { diff --git a/src/SCRIPTS/BF/320x480/gpspids.lua b/src/SCRIPTS/BF/320x480/gpspids.lua index fb870204..afebb378 100644 --- a/src/SCRIPTS/BF/320x480/gpspids.lua +++ b/src/SCRIPTS/BF/320x480/gpspids.lua @@ -1,11 +1,4 @@ return { - read = 136, -- MSP_GPS_RESCUE_PIDS - write = 226, -- MSP_SET_GPS_RESCUE_PIDS - title = "GPS Rescue / PIDs", - reboot = false, - eepromWrite = true, - minBytes = 14, - requiredVersion = 1.041, text = { { t = "P", x = 100, y = 48, to = MIDSIZE }, { t = "I", x = 180, y = 48, to = MIDSIZE }, diff --git a/src/SCRIPTS/BF/320x480/pre.lua b/src/SCRIPTS/BF/320x480/pre.lua deleted file mode 100644 index 61c0eaf1..00000000 --- a/src/SCRIPTS/BF/320x480/pre.lua +++ /dev/null @@ -1,3 +0,0 @@ -MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 } -SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 } -NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", TEXT_COLOR + INVERS + BLINK } diff --git a/src/SCRIPTS/BF/480x272/filters.lua b/src/SCRIPTS/BF/480x272/filters.lua index 71fc95fb..7847025b 100644 --- a/src/SCRIPTS/BF/480x272/filters.lua +++ b/src/SCRIPTS/BF/480x272/filters.lua @@ -1,11 +1,4 @@ return { - read = 92, -- MSP_FILTER_CONFIG - write = 93, -- MSP_SET_FILTER_CONFIG - eepromWrite = true, - reboot = false, - title = "Filters", - minBytes = 37, - outputBytes = 37, yMinLimit = 35, yMaxLimit = 215, text= { diff --git a/src/SCRIPTS/BF/480x272/gpspids.lua b/src/SCRIPTS/BF/480x272/gpspids.lua index 4678143a..13d55cc8 100644 --- a/src/SCRIPTS/BF/480x272/gpspids.lua +++ b/src/SCRIPTS/BF/480x272/gpspids.lua @@ -1,11 +1,4 @@ return { - read = 136, -- MSP_GPS_RESCUE_PIDS - write = 226, -- MSP_SET_GPS_RESCUE_PIDS - title = "GPS Rescue / PIDs", - reboot = false, - eepromWrite = true, - minBytes = 14, - requiredVersion = 1.041, text = { { t = "P", x = 142, y = 48, to = MIDSIZE }, { t = "I", x = 244, y = 48, to = MIDSIZE }, diff --git a/src/SCRIPTS/BF/480x272/pre.lua b/src/SCRIPTS/BF/480x272/pre.lua deleted file mode 100644 index afc42eac..00000000 --- a/src/SCRIPTS/BF/480x272/pre.lua +++ /dev/null @@ -1,3 +0,0 @@ -MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 } -SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 } -NoTelem = { 192, LCD_H - 28, "No Telemetry", TEXT_COLOR + INVERS + BLINK } diff --git a/src/SCRIPTS/BF/PAGES/filters.lua b/src/SCRIPTS/BF/PAGES/filters.lua index dfbb415f..4a5242bd 100644 --- a/src/SCRIPTS/BF/PAGES/filters.lua +++ b/src/SCRIPTS/BF/PAGES/filters.lua @@ -1,3 +1,4 @@ +local display = assert(loadScript(radio.templateHome.."filters.lua"))() return { read = 92, -- MSP_FILTER_CONFIG write = 93, -- MSP_SET_FILTER_CONFIG @@ -6,6 +7,8 @@ return { title = "Filters", minBytes = 37, outputBytes = 37, - text= { }, - fields = { } -} + yMinLimit = display.yMinLimit, + yMaxLimit = display.yMaxLimit, + text = display.text, + fields = display.fields, +} \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/gpspids.lua b/src/SCRIPTS/BF/PAGES/gpspids.lua index 0a90379c..b184c7c5 100644 --- a/src/SCRIPTS/BF/PAGES/gpspids.lua +++ b/src/SCRIPTS/BF/PAGES/gpspids.lua @@ -1,11 +1,14 @@ +local display = assert(loadScript(radio.templateHome.."gpspids.lua"))() return { - read = 136, -- MSP_GPS_RESCUE_PIDS - write = 226, -- MSP_SET_GPS_RESCUE_PIDS - title = "GPS Rescue / PIDs", - reboot = false, - eepromWrite = true, - minBytes = 14, - requiredVersion = 1.041, - text = { }, - fields = { }, -} + read = 136, -- MSP_GPS_RESCUE_PIDS + write = 226, -- MSP_SET_GPS_RESCUE_PIDS + title = "GPS Rescue / PIDs", + reboot = false, + eepromWrite = true, + minBytes = 14, + requiredVersion = 1.041, + yMinLimit = display.yMinLimit, + yMaxLimit = display.yMaxLimit, + text = display.text, + fields = display.fields, +} \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index a5a43362..556de60f 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -1,11 +1,14 @@ +local display = assert(loadScript(radio.templateHome.."pid_advanced.lua"))() return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PID Advanced", - reboot = false, - eepromWrite = true, - minBytes = 46, - outputBytes = 46, - text = { }, - fields = { } -} + read = 94, -- MSP_PID_ADVANCED + write = 95, -- MSP_SET_PID_ADVANCED + title = "PID Advanced", + reboot = false, + eepromWrite = true, + minBytes = 46, + outputBytes = 46, + yMinLimit = display.yMinLimit, + yMaxLimit = display.yMaxLimit, + text = display.text, + fields = display.fields, +} \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua index 504f75d1..c0022454 100644 --- a/src/SCRIPTS/BF/PAGES/pids1.lua +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -1,4 +1,4 @@ - +local display = assert(loadScript(radio.templateHome.."pids1.lua"))() return { read = 112, -- MSP_PID write = 202, -- MSP_SET_PID @@ -6,6 +6,6 @@ return { reboot = false, eepromWrite = true, minBytes = 9, - text = { }, - fields = { }, + text = display.text, + fields = display.fields, } diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index 5ec11ae1..2ed75b9f 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -1,11 +1,13 @@ - +local display = assert(loadScript(radio.templateHome.."pids2.lua"))() return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PIDs (2/2)", - reboot = false, - eepromWrite = true, - minBytes = 44, - text = { }, - fields = { }, + read = 94, -- MSP_PID_ADVANCED + write = 95, -- MSP_SET_PID_ADVANCED + title = "PIDs (2/2)", + reboot = false, + eepromWrite = true, + minBytes = 44, + yMinLimit = display.yMinLimit, + yMaxLimit = display.yMaxLimit, + text = display.text, + fields = display.fields, } diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index 5a11da41..47f83f55 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -1,12 +1,15 @@ +local display = assert(loadScript(radio.templateHome.."pwm.lua"))() return { read = 90, -- MSP_ADVANCED_CONFIG write = 91, -- MSP_SET_ADVANCED_CONFIG reboot = true, eepromWrite = true, title = "PWM", - minBytes = 9, - text= { }, - fields = { }, + minBytes = 9, + yMinLimit = display.yMinLimit, + yMaxLimit = display.yMaxLimit, + text = display.text, + fields = display.fields, calculateGyroRates = function(self, baseRate) self.gyroRates = {} self.fields[2].table = {} diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua index 79440695..ea84fa08 100644 --- a/src/SCRIPTS/BF/PAGES/rates.lua +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -1,10 +1,13 @@ +local display = assert(loadScript(radio.templateHome.."rates.lua"))() return { - read = 111, -- MSP_RC_TUNING - write = 204, -- MSP_SET_RC_TUNING - title = "Rates", - reboot = false, - eepromWrite = true, - minBytes = 16, - text = { }, - fields = { }, + read = 111, -- MSP_RC_TUNING + write = 204, -- MSP_SET_RC_TUNING + title = "Rates", + reboot = false, + eepromWrite = true, + minBytes = 16, + yMinLimit = display.yMinLimit, + yMaxLimit = display.yMaxLimit, + text = display.text, + fields = display.fields, } diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index ac7b54c5..90430959 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -1,11 +1,14 @@ +local display = assert(loadScript(radio.templateHome.."rescue.lua"))() return { - read = 135, -- MSP_GPS_RESCUE - write = 225, -- MSP_SET_GPS_RESCUE - title = "GPS Rescue", - reboot = false, - eepromWrite = true, - minBytes = 16, - requiredVersion = 1.041, - text = { }, - fields = { }, + read = 135, -- MSP_GPS_RESCUE + write = 225, -- MSP_SET_GPS_RESCUE + title = "GPS Rescue", + reboot = false, + eepromWrite = true, + minBytes = 16, + requiredVersion = 1.041, + yMinLimit = display.yMinLimit, + yMaxLimit = display.yMaxLimit, + text = display.text, + fields = display.fields, } diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index f37f7b4e..dbc49321 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -1,10 +1,13 @@ +local display = assert(loadScript(radio.templateHome.."rx.lua"))() return { - read = 44, -- MSP_RX_CONFIG - write = 45, -- MSP_SET_RX_CONFIG - title = "RX", - reboot = false, - eepromWrite = true, - minBytes = 23, - text= { }, - fields = { }, + read = 44, -- MSP_RX_CONFIG + write = 45, -- MSP_SET_RX_CONFIG + title = "RX", + reboot = false, + eepromWrite = true, + minBytes = 23, + yMinLimit = display.yMinLimit, + yMaxLimit = display.yMaxLimit, + text = display.text, + fields = display.fields, } diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index bd5ff9c8..7ac42125 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -1,4 +1,4 @@ - +local display = assert(loadScript(radio.templateHome.."vtx.lua"))() return { read = 88, -- MSP_VTX_CONFIG write = 89, -- MSP_VTX_SET_CONFIG @@ -11,8 +11,10 @@ return { prevFreqVal = 0, lastFreqUpdTS = 0, freqModCounter = 0, - text= { }, - fields = { }, + yMinLimit = display.yMinLimit, + yMaxLimit = display.yMaxLimit, + text = display.text, + fields = display.fields, freqLookup = { { 5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725 }, -- Boscam A { 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 }, -- Boscam B diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index 9d4bc9cb..bfbe27bb 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -9,26 +9,34 @@ local supportedRadios = ["128x64"] = { templateHome = SCRIPT_HOME.."/128x64/", - preLoad = SCRIPT_HOME.."/128x64/pre.lua", - resolution = lcdResolution.low + resolution = lcdResolution.low, + MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, + SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, + NoTelem = { 30, 55, "No Telemetry", BLINK }, }, ["212x64"] = { templateHome = SCRIPT_HOME.."/212x64/", - preLoad = SCRIPT_HOME.."/212x64/pre.lua", - resolution = lcdResolution.low + resolution = lcdResolution.low, + MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 }, + SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, + NoTelem = { 70, 55, "No Telemetry", BLINK }, }, ["480x272"] = { templateHome = SCRIPT_HOME.."/480x272/", - preLoad = SCRIPT_HOME.."/480x272/pre.lua", - resolution = lcdResolution.high + resolution = lcdResolution.high, + MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, + SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, + NoTelem = { 192, LCD_H - 28, "No Telemetry", BLINK }, }, ["320x480"] = { templateHome = SCRIPT_HOME.."/320x480/", - preLoad = SCRIPT_HOME.."/320x480/pre.lua", - resolution = lcdResolution.high + resolution = lcdResolution.high, + MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, + SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, + NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", BLINK }, }, } diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 7b93a884..1cae9749 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -266,11 +266,11 @@ local function incValue(inc) end local function drawPopupMenu() - local x = MenuBox.x - local y = MenuBox.y - local w = MenuBox.w - local h_line = MenuBox.h_line - local h_offset = MenuBox.h_offset + local x = radio.MenuBox.x + local y = radio.MenuBox.y + local w = radio.MenuBox.w + local h_line = radio.MenuBox.h_line + local h_offset = radio.MenuBox.h_offset local h = #(popupMenuList) * h_line + h_offset*2 lcd.drawFilledRectangle(x,y,w,h,backgroundFill) @@ -282,7 +282,7 @@ local function drawPopupMenu() if popupMenuActive == i then text_options = text_options + INVERS end - lcd.drawText(x+MenuBox.x_offset,y+(i-1)*h_line+h_offset,e.t,text_options) + lcd.drawText(x+radio.MenuBox.x_offset,y+(i-1)*h_line+h_offset,e.t,text_options) end end @@ -372,13 +372,13 @@ function run_ui(event) end local nextPage = currentPage while Page == nil do - Page = assert(loadScript(radio.templateHome .. PageFiles[currentPage].script))() + Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[currentPage].script))() if Page.requiredVersion and apiVersion > 0 and Page.requiredVersion > apiVersion then incPage(1) if currentPage == nextPage then lcd.clear() - lcd.drawText(NoTelem[1], NoTelem[2], "No Pages! API: " .. apiVersion, NoTelem[4]) + lcd.drawText(radio.NoTelem[1], radio.NoTelem[2], "No Pages! API: " .. apiVersion, radio.NoTelem[4]) return 1 end @@ -393,17 +393,17 @@ function run_ui(event) end drawScreen() if protocol.rssi() == 0 then - lcd.drawText(NoTelem[1],NoTelem[2],NoTelem[3],NoTelem[4]) + lcd.drawText(radio.NoTelem[1],radio.NoTelem[2],radio.NoTelem[3],radio.NoTelem[4]) end if currentState == pageStatus.popupMenu then drawPopupMenu() elseif currentState == pageStatus.saving then - lcd.drawFilledRectangle(SaveBox.x,SaveBox.y,SaveBox.w,SaveBox.h,backgroundFill) - lcd.drawRectangle(SaveBox.x,SaveBox.y,SaveBox.w,SaveBox.h,SOLID) + lcd.drawFilledRectangle(radio.SaveBox.x,radio.SaveBox.y,radio.SaveBox.w,radio.SaveBox.h,backgroundFill) + lcd.drawRectangle(radio.SaveBox.x,radio.SaveBox.y,radio.SaveBox.w,radio.SaveBox.h,SOLID) if saveRetries <= 0 then - lcd.drawText(SaveBox.x+SaveBox.x_offset,SaveBox.y+SaveBox.h_offset,"Saving...",DBLSIZE + BLINK + (globalTextOptions)) + lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,"Saving...",DBLSIZE + BLINK + (globalTextOptions)) else - lcd.drawText(SaveBox.x+SaveBox.x_offset,SaveBox.y+SaveBox.h_offset,"Retrying",DBLSIZE + (globalTextOptions)) + lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,"Retrying",DBLSIZE + (globalTextOptions)) end end if currentState == pageStatus.mainMenu and (not isTelemetryScript) then @@ -429,7 +429,7 @@ function run_ui(event) end local attr = (menuLine == i and INVERS or 0) if event == EVT_VIRTUAL_ENTER and attr == INVERS then - Page = assert(loadScript(radio.templateHome .. PageFiles[i].script))() + Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[i].script))() currentPage = i currentState = pageStatus.display end diff --git a/src/SCRIPTS/TELEMETRY/bf.lua b/src/SCRIPTS/TELEMETRY/bf.lua index 38190fef..92434f5a 100644 --- a/src/SCRIPTS/TELEMETRY/bf.lua +++ b/src/SCRIPTS/TELEMETRY/bf.lua @@ -7,7 +7,6 @@ protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() radio = assert(loadScript(SCRIPT_HOME.."/radios.lua"))() assert(loadScript(SCRIPT_HOME.."/pages.lua"))() -assert(loadScript(radio.preLoad))() assert(loadScript(protocol.transport))() assert(loadScript(SCRIPT_HOME.."/MSP/common.lua"))() diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index 518e12e2..fdbdd054 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -8,7 +8,6 @@ protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() radio = assert(loadScript(SCRIPT_HOME.."/radios.lua"))() assert(loadScript(SCRIPT_HOME.."/pages.lua"))() -assert(loadScript(radio.preLoad))() assert(loadScript(protocol.transport))() assert(loadScript(SCRIPT_HOME.."/MSP/common.lua"))() From a2faf146d99e765807847d1c730fd0e3a4c2f51e Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 16 Oct 2019 16:14:34 +0100 Subject: [PATCH 015/193] refactoring part 2 --- src/SCRIPTS/BF/128x64/filters.lua | 18 -- src/SCRIPTS/BF/128x64/gpspids.lua | 3 - src/SCRIPTS/BF/128x64/pid_advanced.lua | 8 - src/SCRIPTS/BF/128x64/pids1.lua | 3 - src/SCRIPTS/BF/128x64/pids2.lua | 10 - src/SCRIPTS/BF/128x64/pwm.lua | 35 ---- src/SCRIPTS/BF/128x64/rates.lua | 12 -- src/SCRIPTS/BF/128x64/rescue.lua | 10 - src/SCRIPTS/BF/128x64/vtx.lua | 237 --------------------- src/SCRIPTS/BF/212x64/filters.lua | 28 --- src/SCRIPTS/BF/212x64/gpspids.lua | 4 - src/SCRIPTS/BF/212x64/pid_advanced.lua | 15 -- src/SCRIPTS/BF/212x64/pids1.lua | 10 - src/SCRIPTS/BF/212x64/pids2.lua | 17 -- src/SCRIPTS/BF/212x64/pwm.lua | 35 ---- src/SCRIPTS/BF/212x64/rates.lua | 12 -- src/SCRIPTS/BF/212x64/rescue.lua | 15 +- src/SCRIPTS/BF/212x64/rx.lua | 6 - src/SCRIPTS/BF/212x64/vtx.lua | 237 --------------------- src/SCRIPTS/BF/320x480/filters.lua | 28 --- src/SCRIPTS/BF/320x480/gpspids.lua | 3 - src/SCRIPTS/BF/320x480/pid_advanced.lua | 15 -- src/SCRIPTS/BF/320x480/pids1.lua | 10 - src/SCRIPTS/BF/320x480/pids2.lua | 17 -- src/SCRIPTS/BF/320x480/pwm.lua | 47 +---- src/SCRIPTS/BF/320x480/rates.lua | 12 -- src/SCRIPTS/BF/320x480/rescue.lua | 13 +- src/SCRIPTS/BF/320x480/rx.lua | 6 - src/SCRIPTS/BF/320x480/vtx.lua | 263 +----------------------- src/SCRIPTS/BF/480x272/filters.lua | 28 --- src/SCRIPTS/BF/480x272/gpspids.lua | 3 - src/SCRIPTS/BF/480x272/pid_advanced.lua | 15 -- src/SCRIPTS/BF/480x272/pids1.lua | 9 - src/SCRIPTS/BF/480x272/pids2.lua | 17 -- src/SCRIPTS/BF/480x272/pwm.lua | 47 +---- src/SCRIPTS/BF/480x272/rates.lua | 12 -- src/SCRIPTS/BF/480x272/rescue.lua | 11 - src/SCRIPTS/BF/480x272/rx.lua | 9 +- src/SCRIPTS/BF/480x272/vtx.lua | 263 +----------------------- 39 files changed, 22 insertions(+), 1521 deletions(-) diff --git a/src/SCRIPTS/BF/128x64/filters.lua b/src/SCRIPTS/BF/128x64/filters.lua index b94571b5..0d60bbb1 100644 --- a/src/SCRIPTS/BF/128x64/filters.lua +++ b/src/SCRIPTS/BF/128x64/filters.lua @@ -6,40 +6,31 @@ return { { t = "Min Cutoff", x = 12, y = 20, to = SMLSIZE }, { t = "Max Cutoff", x = 12, y = 28, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 36, to = SMLSIZE }, - { t = "Gyro Lowpass 1", x = 2, y = 44, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 52, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 60, to = SMLSIZE }, - { t = "Gyro Lowpass 2", x = 2, y = 68, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 76, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 84, to = SMLSIZE }, - { t = "Gyro Notch 1", x = 2, y = 92, to = SMLSIZE }, { t = "Center", x = 12, y = 100, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 108, to = SMLSIZE }, - { t = "Gyro Notch 2", x = 2, y = 116, to = SMLSIZE }, { t = "Center", x = 12, y = 124, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 132, to = SMLSIZE }, - { t = "D Term Lowpass 1 Dynamic", x = 2, y = 140, to = SMLSIZE }, { t = "Min Cutoff", x = 12, y = 148, to = SMLSIZE }, { t = "Max Cutoff", x = 12, y = 156, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 164, to = SMLSIZE }, - { t = "D Term Lowpass 1", x = 2, y = 172, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 180, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 188, to = SMLSIZE }, - { t = "D Term Lowpass 2", x = 2, y = 196, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 204, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 212, to = SMLSIZE }, - { t = "D Term Notch", x = 2, y = 220, to = SMLSIZE }, { t = "Center", x = 12, y = 228, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 236, to = SMLSIZE }, - { t = "Yaw Lowpass", x = 2, y = 244, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 252, to = SMLSIZE }, }, @@ -48,40 +39,31 @@ return { { x = 87, y = 20, min = 0, max = 1000, to = SMLSIZE, vals = { 30, 31 } }, { x = 87, y = 28, min = 0, max = 1000, to = SMLSIZE, vals = { 32, 33 } }, { x = 87, y = 36, min = 0, max = 1, to = SMLSIZE, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- Gyro Lowpass 1 { x = 87, y = 52, min = 0, max = 16000, to = SMLSIZE, vals = { 21, 22 } }, { x = 87, y = 60, min = 0, max = 1, to = SMLSIZE, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- Gyro Lowpass 2 { x = 87, y = 76, min = 0, max = 16000, to = SMLSIZE, vals = { 23, 24 } }, { x = 87, y = 84, min = 0, max = 1, to = SMLSIZE, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- Gyro Notch 1 { x = 87, y = 100, min = 0, max = 16000, to = SMLSIZE, vals = { 6, 7 } }, { x = 87, y = 108, min = 0, max = 16000, to = SMLSIZE, vals = { 8, 9 } }, - -- Gyro Notch 2 { x = 87, y = 124, min = 0, max = 16000, to = SMLSIZE, vals = { 14, 15 } }, { x = 87, y = 132, min = 0, max = 16000, to = SMLSIZE, vals = { 16, 17 } }, - -- D Term Lowpass 1 Dynamic { x = 87, y = 148, min = 0, max = 1000, to = SMLSIZE, vals = { 34, 35 } }, { x = 87, y = 156, min = 0, max = 1000, to = SMLSIZE, vals = { 36, 37 } }, { x = 87, y = 164, min = 0, max = 1, to = SMLSIZE, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- D Term Lowpass 1 { x = 87, y = 180, min = 0, max = 16000, to = SMLSIZE, vals = { 2, 3 } }, { x = 87, y = 188, min = 0, max = 1, to = SMLSIZE, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- D Term Lowpass 2 { x = 87, y = 204, min = 0, max = 16000, to = SMLSIZE, vals = { 27, 28 } }, { x = 87, y = 212, min = 0, max = 1, to = SMLSIZE, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- D Term Notch { x = 87, y = 228, min = 0, max = 16000, to = SMLSIZE, vals = { 10, 11 } }, { x = 87, y = 236, min = 0, max = 16000, to = SMLSIZE, vals = { 12, 13 } }, - -- Yaw Lowpass { x = 87, y = 252, min = 0, max = 500, to = SMLSIZE, vals = { 4, 5 } }, } diff --git a/src/SCRIPTS/BF/128x64/gpspids.lua b/src/SCRIPTS/BF/128x64/gpspids.lua index 95c35cc0..2cbbcf78 100644 --- a/src/SCRIPTS/BF/128x64/gpspids.lua +++ b/src/SCRIPTS/BF/128x64/gpspids.lua @@ -8,14 +8,11 @@ return { { t = "Yaw" , x = 5, y = 46, to=SMLSIZE }, }, fields = { - -- P { x = 51, y = 26, min = 0, max = 200, vals = { 1,2 }, to=SMLSIZE }, { x = 51, y = 36, min = 0, max = 200, vals = { 7,8 }, to=SMLSIZE }, { x = 51, y = 46, min = 0, max = 500, vals = {13,14}, to = SMLSIZE }, - -- I { x = 79, y = 26, min = 0, max = 200, vals = { 3,4 }, to=SMLSIZE }, { x = 79, y = 36, min = 0, max = 200, vals = { 9,10 }, to=SMLSIZE }, - -- D { x = 107, y = 26, min = 0, max = 200, vals = { 5,6 }, to=SMLSIZE }, { x = 107, y = 36, min = 0, max = 200, vals = { 11,12 }, to=SMLSIZE }, }, diff --git a/src/SCRIPTS/BF/128x64/pid_advanced.lua b/src/SCRIPTS/BF/128x64/pid_advanced.lua index 185fa766..103419dd 100644 --- a/src/SCRIPTS/BF/128x64/pid_advanced.lua +++ b/src/SCRIPTS/BF/128x64/pid_advanced.lua @@ -4,18 +4,14 @@ return { text = { { t = "Acro Trainer", x = 2, y = 12, to = SMLSIZE }, { t = "Angle Limit", x = 12, y = 20, to = SMLSIZE }, - { t = "Throttle Boost", x = 2, y = 28, to = SMLSIZE }, { t = "Absolute Control", x = 2, y = 36, to = SMLSIZE }, { t = "I Term Rotation", x = 2, y = 44, to = SMLSIZE }, { t = "VBAT Compensation", x = 2, y = 52, to = SMLSIZE }, - { t = "I Term Relax", x = 2, y = 60, to = SMLSIZE }, { t = "Axes", x = 12, y = 68, to = SMLSIZE }, { t = "Type", x = 12, y = 76, to = SMLSIZE }, - { t = "Integrated Yaw", x = 2, y = 84, to = SMLSIZE }, - { t = "Anti Gravity", x = 2, y = 92, to = SMLSIZE }, { t = "Mode", x = 12, y = 100, to = SMLSIZE }, { t = "Gain", x = 12, y = 108, to = SMLSIZE }, @@ -23,17 +19,13 @@ return { }, fields = { { x = 87, y = 20, to=SMLSIZE, min = 20, max = 80, vals = { 32 } }, - { x = 87, y = 28, to=SMLSIZE, min = 0, max = 100, vals = { 31 } }, { x = 87, y = 36, to=SMLSIZE, min = 0, max = 20, vals = { 30 } }, { x = 87, y = 44, to=SMLSIZE, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } }, { x = 87, y = 52, to=SMLSIZE, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } }, - { x = 87, y = 68, to=SMLSIZE, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } }, { x = 87, y = 76, to=SMLSIZE, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } }, - { x = 87, y = 84, to=SMLSIZE, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } }, - { x = 87, y = 100, to=SMLSIZE, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } }, { x = 87, y = 108, to=SMLSIZE, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 }, { x = 87, y = 116, to=SMLSIZE, min = 20, max = 1000, vals = { 20, 21 } }, diff --git a/src/SCRIPTS/BF/128x64/pids1.lua b/src/SCRIPTS/BF/128x64/pids1.lua index c09d09c1..21331d7c 100644 --- a/src/SCRIPTS/BF/128x64/pids1.lua +++ b/src/SCRIPTS/BF/128x64/pids1.lua @@ -8,15 +8,12 @@ return { { t = "YAW", x = 10, y = 46, to = SMLSIZE }, }, fields = { - -- P { x = 41, y = 26, min = 0, max = 200, vals = { 1 }, to = SMLSIZE }, { x = 41, y = 36, min = 0, max = 200, vals = { 4 }, to = SMLSIZE }, { x = 41, y = 46, min = 0, max = 200, vals = { 7 }, to = SMLSIZE }, - -- I { x = 69, y = 26, min = 0, max = 200, vals = { 2 }, to = SMLSIZE }, { x = 69, y = 36, min = 0, max = 200, vals = { 5 }, to = SMLSIZE }, { x = 69, y = 46, min = 0, max = 200, vals = { 8 }, to = SMLSIZE }, - -- D { x = 97, y = 26, min = 0, max = 200, vals = { 3 }, to = SMLSIZE }, { x = 97, y = 36, min = 0, max = 200, vals = { 6 }, to = SMLSIZE }, { x = 97, y = 46, min = 0, max = 200, vals = { 9 }, to = SMLSIZE }, diff --git a/src/SCRIPTS/BF/128x64/pids2.lua b/src/SCRIPTS/BF/128x64/pids2.lua index 09ce2217..d645dc44 100644 --- a/src/SCRIPTS/BF/128x64/pids2.lua +++ b/src/SCRIPTS/BF/128x64/pids2.lua @@ -10,7 +10,6 @@ return { { t = "ROLL", x = 10, y = 26, to = SMLSIZE }, { t = "PITCH", x = 10, y = 36, to = SMLSIZE }, { t = "YAW", x = 10, y = 46, to = SMLSIZE }, - { t = "Feedforward", x = 10, y = 60, to = SMLSIZE }, { t = "Transition", x = 20, y = 68, to = SMLSIZE }, { t = "D Min", x = 10, y = 76, to = SMLSIZE }, @@ -18,23 +17,14 @@ return { { t = "Advance", x = 20, y = 92, to = SMLSIZE }, }, fields = { - -- ROLL FF { x = 48, y = 26, min = 0, max = 2000, vals = { 33, 34 }, to = SMLSIZE }, - -- PITCH FF { x = 48, y = 36, min = 0, max = 2000, vals = { 35, 36 }, to = SMLSIZE }, - -- YAW FF { x = 48, y = 46, min = 0, max = 2000, vals = { 37, 38 }, to = SMLSIZE }, - -- ROLL D MIN { x = 80, y = 26, min = 0, max = 100, vals = { 40 }, to = SMLSIZE }, - -- PITCH D MIN { x = 80, y = 36, min = 0, max = 100, vals = { 41 }, to = SMLSIZE }, - -- YAW D MIN { x = 80, y = 46, min = 0, max = 100, vals = { 42 }, to = SMLSIZE }, - -- FF TRANSITION { x = 80, y = 68, min = 0, max = 100, vals = { 9 }, to = SMLSIZE, scale = 100 }, - -- D MIN GAIN { x = 80, y = 84, min = 0, max = 100, vals = { 43 }, to = SMLSIZE }, - -- D MIN ADVANCE { x = 80, y = 92, min = 0, max = 200, vals = { 44 }, to = SMLSIZE }, }, } diff --git a/src/SCRIPTS/BF/128x64/pwm.lua b/src/SCRIPTS/BF/128x64/pwm.lua index ad40fed9..65ede20d 100644 --- a/src/SCRIPTS/BF/128x64/pwm.lua +++ b/src/SCRIPTS/BF/128x64/pwm.lua @@ -1,10 +1,4 @@ return { - read = 90, -- MSP_ADVANCED_CONFIG - write = 91, -- MSP_SET_ADVANCED_CONFIG - reboot = true, - eepromWrite = true, - title = "PWM", - minBytes = 9, text= { { t = "32K", x = 10, y = 14, to = SMLSIZE }, { t = "Gyro", x = 10, y = 24, to = SMLSIZE }, @@ -23,33 +17,4 @@ return { { x = 90, y = 34, vals = { 5, 6 }, min = 200, max = 32000, to = SMLSIZE }, { x = 90, y = 44, vals = { 7, 8 }, min = 0, max = 2000, to = SMLSIZE, scale = 100 }, }, - calculateGyroRates = function(self, baseRate) - self.gyroRates = {} - self.fields[2].table = {} - for i=1, 32 do - self.gyroRates[i] = baseRate/i - local fmt = nil - self.fields[2].table[i] = string.format("%.2f",baseRate/i) - end - end, - calculatePidRates = function(self, baseRate) - self.fields[3].table = {} - for i=1, 16 do - self.fields[3].table[i] = string.format("%.2f",baseRate/i) - end - end, - updateRateTables = function(self) - if self.values[9] == 0 then - self.calculateGyroRates(self, 8) - self.calculatePidRates(self, 8) - elseif self.values[9] == 1 then - self.calculateGyroRates(self, 32) - self.calculatePidRates(self, 32) - end - end, - updatePidRateTable = function(self) - local newRateIdx = self.values[1] - local newRate = self.gyroRates[newRateIdx] - self.calculatePidRates(self, newRate) - end } diff --git a/src/SCRIPTS/BF/128x64/rates.lua b/src/SCRIPTS/BF/128x64/rates.lua index 1724509c..ba88ad0e 100644 --- a/src/SCRIPTS/BF/128x64/rates.lua +++ b/src/SCRIPTS/BF/128x64/rates.lua @@ -1,10 +1,4 @@ return { - read = 111, -- MSP_RC_TUNING - write = 204, -- MSP_SET_RC_TUNING - title = "Rates", - reboot = false, - eepromWrite = true, - minBytes = 16, yMinLimit = 11, yMaxLimit = 52, text = { @@ -17,7 +11,6 @@ return { { t = "ROLL", x = 10, y = 26, to = SMLSIZE }, { t = "PITCH", x = 10, y = 36, to = SMLSIZE }, { t = "YAW", x = 10, y = 46, to = SMLSIZE }, - { t = "Throttle", x = 10, y = 60, to = SMLSIZE }, { t = "Mid", x = 20, y = 68, to = SMLSIZE }, { t = "Expo", x = 20, y = 76, to = SMLSIZE }, @@ -28,24 +21,19 @@ return { { t = "Breakpoint", x = 20, y = 116, to = SMLSIZE }, }, fields = { - -- RC Rates { x = 39, y = 26, vals = { 1 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, { x = 39, y = 36, vals = { 13 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, { x = 39, y = 46, vals = { 12 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - -- Super Rates { x = 66, y = 26, vals = { 3 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 66, y = 36, vals = { 4 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 66, y = 46, vals = { 5 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - -- RC Expo { x = 94, y = 26, vals = { 2 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 94, y = 36, vals = { 14 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 94, y = 46, vals = { 11 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - -- Throttle { x = 70, y = 68, vals = { 7 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 70, y = 76, vals = { 8 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 70, y = 84, vals = { 15 }, min = 0, max = 2, to = SMLSIZE, table = { [0] = "OFF", "SCALE", "CLIP" } }, { x = 70, y = 92, vals = { 16 }, min = 25, max = 100, to = SMLSIZE }, - -- TPA { x = 70, y = 108, vals = { 6 } , min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 70, y = 116, vals = { 9, 10 }, min = 1000, max = 2000, to = SMLSIZE }, }, diff --git a/src/SCRIPTS/BF/128x64/rescue.lua b/src/SCRIPTS/BF/128x64/rescue.lua index ca5623a0..2c38f80e 100644 --- a/src/SCRIPTS/BF/128x64/rescue.lua +++ b/src/SCRIPTS/BF/128x64/rescue.lua @@ -1,12 +1,4 @@ - return { - read = 135, -- MSP_GPS_RESCUE - write = 225, -- MSP_SET_GPS_RESCUE - title = "GPS / Rescue", - reboot = false, - eepromWrite = true, - minBytes = 16, - requiredVersion = 1.041, text = { { t = "Min Sats.", x = 3, y = 10, to=SMLSIZE }, @@ -14,7 +6,6 @@ return { { t = "Initial Alt", x = 3, y = 30, to=SMLSIZE }, { t = "Descent Dst", x = 3, y = 40, to=SMLSIZE }, { t = "Ground Spd", x = 3, y = 50, to=SMLSIZE }, - { t = "Snty.", x = 80, y = 10, to = SMLSIZE }, { t = "Throttle", x = 80, y = 20, to = SMLSIZE }, { t = "Min", x = 85, y = 30, to = SMLSIZE }, @@ -27,7 +18,6 @@ return { { x = 58, y = 30, min = 20, max = 100, vals = { 3,4 }, to = SMLSIZE }, { x = 58, y = 40, min = 30, max = 500, vals = { 5,6 }, to = SMLSIZE }, { x = 58, y = 50, min = 30, max =3000, vals = { 7,8 }, to = SMLSIZE }, - { x = 105, y = 10, min = 0, max = 2 , vals = { 15 }, to = SMLSIZE,table = { [0]="OFF","ON","FS_ONLY"}}, { x = 105, y = 30, min = 1000, max = 2000, vals = { 9,10 }, to = SMLSIZE }, { x = 105, y = 40, min = 1000, max = 2000, vals = { 13,14 }, to = SMLSIZE }, diff --git a/src/SCRIPTS/BF/128x64/vtx.lua b/src/SCRIPTS/BF/128x64/vtx.lua index fe051ed9..e5892dab 100644 --- a/src/SCRIPTS/BF/128x64/vtx.lua +++ b/src/SCRIPTS/BF/128x64/vtx.lua @@ -1,16 +1,4 @@ - return { - read = 88, -- MSP_VTX_CONFIG - write = 89, -- MSP_VTX_SET_CONFIG - eepromWrite = true, - reboot = false, - title = "VTX", - minBytes = 5, - prevBandVal = 0, - prevChanVal = 0, - prevFreqVal = 0, - lastFreqUpdTS = 0, - freqModCounter = 0, text = {}, fields = { { t = "Band", x = 10, y = 14, sp = 30, min=0, max=5, vals = { 2 }, to = SMLSIZE, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, @@ -20,229 +8,4 @@ return { { t = "Dev", x = 70, y = 14, sp = 25, write = false, ro = true, vals = { 1 }, to = SMLSIZE , table = { [1]="6705",[3]="SA",[4]="Tramp",[255]="None"} }, { t = "Freq", x = 70, y = 24, sp = 25, min = 5000, max = 5999, vals = { 6 }, to = SMLSIZE, upd = function(self) self.handleFreqValUpdate(self) end }, }, - freqLookup = { - { 5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725 }, -- Boscam A - { 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 }, -- Boscam B - { 5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945 }, -- Boscam E - { 5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880 }, -- FatShark - { 5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 }, -- RaceBand - }, - postLoad = function (self) - if (self.values[2] or 0) < 0 or (self.values[3] or 0) == 0 or (self.values[4] or 0) == 0 then - self.values = {} - else - self.prevBandVal = 0 -- reset value trackers - self.prevChanVal = 0 - self.prevFreqVal = 0 - local rFreq - if (self.values[7] or 0) > 0 then - rFreq = math.floor(self.values[6] + (self.values[7] * 256)) - else - rFreq = 0 - end - if (self.values[2] or 0) > 0 then -- band != 0 - if rFreq > 0 then - self.prevFreqVal = rFreq - self.prevBandVal = self.values[2] - self.prevChanVal = self.values[3] - self.fields[1].min = 0 -- make sure 'U' band allowed - self.eepromWrite = true - self.fields[6].value = rFreq - self.values[6] = rFreq - else -- if user freq not supported then - self.fields[1].min = 1 -- don't allow 'U' band - self.eepromWrite = false -- don't write EEPROM on older Betaflight versions - end - else -- band == 0 - if rFreq > 0 then - self.prevFreqVal = rFreq - self.fields[1].min = 0 -- make sure 'U' band allowed - self.eepromWrite = true - self.fields[6].value = rFreq - self.values[6] = rFreq - -- set chan via freq / 100 - self.prevChanVal = clipValue(math.floor((rFreq - 5100) / 100), - self.fields[2].min, self.fields[2].max) - self.fields[2].value = self.prevChanVal - self.values[3] = self.prevChanVal - else - self.values = {} - end - end - end - end, - preSave = function(self) - local valsTemp = {} - if self.values then - local channel - if self.values[2] > 0 then -- band != 0 - channel = (self.values[2]-1)*8 + self.values[3]-1 - elseif self.fields[6].value then -- band == 0 - channel = self.fields[6].value - else - channel = 24 - end - valsTemp[1] = bit32.band(channel,0xFF) - valsTemp[2] = bit32.rshift(channel,8) - valsTemp[3] = self.values[4] - valsTemp[4] = self.values[5] - end - return valsTemp - end, - -- find closest value in freq table that is above/below given freq - findNextInFreqTable = function(self, newFreq) - local startBand - local endBand - local incFlag -- freq increasing or decreasing - if newFreq > self.prevFreqVal then - incFlag = 1 - startBand = 1 - endBand = self.fields[1].max - else - incFlag = -1 - startBand = self.fields[1].max - endBand = 1 - end - local curBand = self.values[2] - local curChan = self.values[3] - local selBand = 0 - local selChan = 0 - local selFreq = 0 - local diffVal = 9999 - local fVal - local minChan = self.fields[2].min - local maxChan = self.fields[2].max - -- need to scan bands in same "direction" as 'incFlag' - -- so same-freq selections will be handled properly (F8 & R7) - for band=startBand,endBand,incFlag do - for chan=minChan,maxChan do - if band ~= curBand or chan ~= curChan then -- don't reselect same band/chan - fVal = self.freqLookup[band][chan] - if incFlag > 0 then - if fVal >= self.prevFreqVal and fVal - self.prevFreqVal < diffVal then - -- if same freq then only select if "next" band: - if fVal ~= self.prevFreqVal or band > curBand then - selBand = band - selChan = chan - selFreq = fVal - diffVal = fVal - self.prevFreqVal - end - end - else - if fVal <= self.prevFreqVal and self.prevFreqVal - fVal < diffVal then - -- if same freq then only select if "previous" band: - if fVal ~= self.prevFreqVal or band < curBand then - selBand = band - selChan = chan - selFreq = fVal - diffVal = self.prevFreqVal - fVal - end - end - end - end - end - end - return selFreq, selBand, selChan - end, - -- returns the next user-frequency value in MHz; implements an - -- "exponential" modification rate so dialing in values is faster - getNextUserFreqValue = function(self, newFreq) - local now = getTime() -- track rate of change for possible mod speedup - if now < self.lastFreqUpdTS + 15 then - self.freqModCounter = self.freqModCounter + (15-(self.lastFreqUpdTS-now)) -- increase counter for mod speedup - else - self.freqModCounter = 0 -- no mod speedup - end - local uFreq - if self.freqModCounter > 65 then -- rate is fast enough; do mod speedup - if newFreq > self.prevFreqVal then - uFreq = clipValue(newFreq + math.floor(self.freqModCounter / 65), - self.fields[6].min, self.fields[6].max) - else - uFreq = clipValue(newFreq - math.floor(self.freqModCounter / 65), - self.fields[6].min, self.fields[6].max) - end - else - uFreq = newFreq - end - self.lastFreqUpdTS = now - return uFreq - end, - updatePowerTable = function(self) - if self.values and not self.fields[3].table then - if self.values[1] == 1 then -- RTC6705 - self.fields[3].table = { 25, 200 } - self.fields[3].max = 2 - self.fields[4].t = nil -- don't display Pit field - self.fields[4].table = { [0]="", "" } - elseif self.values[1] == 3 then -- SmartAudio - self.fields[3].table = { 25, 200, 500, 800 } - self.fields[3].max = 4 - elseif self.values[1] == 4 then -- Tramp - self.fields[3].table = { 25, 100, 200, 400, 600 } - self.fields[3].max = 5 - elseif self.values[1] == 255 then -- None/Unknown - self.fields[3].t = nil -- don't display Power field - self.fields[3].max = 1 - self.fields[3].table = { [1]="" } - self.fields[4].t = nil -- don't display Pit field - self.fields[4].table = { [0]="", "" } - end - end - end, - handleBandChanUpdate = function(self) - if (#(self.values) or 0) >= self.minBytes then - if (self.values[3] or 0) > 0 then - if self.values[2] ~= self.prevBandVal or self.values[3] ~= self.prevChanVal then - if self.values[2] > 0 then -- band != 0 - self.prevFreqVal = self.freqLookup[self.values[2]][self.values[3]] - else -- band == 0; set freq via channel*100 - self.prevFreqVal = math.floor(5100 + (self.values[3] * 100)) - end - self.fields[6].value = self.prevFreqVal - self.values[6] = self.prevFreqVal - self.prevBandVal = self.values[2] - self.prevChanVal = self.values[3] - end - end - end - end, - handleFreqValUpdate = function(self) - if (#(self.values) or 0) >= self.minBytes and (self.fields[6].value or 0) > 0 then - local newFreq = self.fields[6].value - if newFreq ~= self.prevFreqVal then - if self.values[2] == 0 then - -- band == 0 - local uFreq = self.getNextUserFreqValue(self, newFreq) - self.prevFreqVal = uFreq - if uFreq ~= newFreq then - self.fields[6].value = uFreq - self.values[6] = uFreq - end - -- set channel value via freq/100 - self.prevChanVal = clipValue(math.floor((self.prevFreqVal - 5100) / 100), - self.fields[2].min, self.fields[2].max) - self.fields[2].value = self.prevChanVal - self.values[3] = self.prevChanVal - else - -- band != 0; find closest freq in table that is above/below dialed freq - local selFreq, selBand, selChan = self.findNextInFreqTable(self, newFreq) - if selFreq > 0 then - self.prevFreqVal = selFreq - self.prevBandVal = selBand - self.prevChanVal = selChan - self.fields[6].value = selFreq -- using new freq from table - self.values[6] = selFreq - self.fields[1].value = self.prevBandVal -- set band value for freq - self.values[2] = self.prevBandVal - self.fields[2].value = self.prevChanVal -- set channel value for freq - self.values[3] = self.prevChanVal - else - self.fields[6].value = self.prevFreqVal -- if no match then revert freq - self.values[6] = self.prevFreqVal - end - end - end - end - end } \ No newline at end of file diff --git a/src/SCRIPTS/BF/212x64/filters.lua b/src/SCRIPTS/BF/212x64/filters.lua index b94571b5..c8e09a8e 100644 --- a/src/SCRIPTS/BF/212x64/filters.lua +++ b/src/SCRIPTS/BF/212x64/filters.lua @@ -6,83 +6,55 @@ return { { t = "Min Cutoff", x = 12, y = 20, to = SMLSIZE }, { t = "Max Cutoff", x = 12, y = 28, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 36, to = SMLSIZE }, - { t = "Gyro Lowpass 1", x = 2, y = 44, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 52, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 60, to = SMLSIZE }, - { t = "Gyro Lowpass 2", x = 2, y = 68, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 76, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 84, to = SMLSIZE }, - { t = "Gyro Notch 1", x = 2, y = 92, to = SMLSIZE }, { t = "Center", x = 12, y = 100, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 108, to = SMLSIZE }, - { t = "Gyro Notch 2", x = 2, y = 116, to = SMLSIZE }, { t = "Center", x = 12, y = 124, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 132, to = SMLSIZE }, - { t = "D Term Lowpass 1 Dynamic", x = 2, y = 140, to = SMLSIZE }, { t = "Min Cutoff", x = 12, y = 148, to = SMLSIZE }, { t = "Max Cutoff", x = 12, y = 156, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 164, to = SMLSIZE }, - { t = "D Term Lowpass 1", x = 2, y = 172, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 180, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 188, to = SMLSIZE }, - { t = "D Term Lowpass 2", x = 2, y = 196, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 204, to = SMLSIZE }, { t = "Filter Type", x = 12, y = 212, to = SMLSIZE }, - { t = "D Term Notch", x = 2, y = 220, to = SMLSIZE }, { t = "Center", x = 12, y = 228, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 236, to = SMLSIZE }, - { t = "Yaw Lowpass", x = 2, y = 244, to = SMLSIZE }, { t = "Cutoff", x = 12, y = 252, to = SMLSIZE }, }, fields = { - -- Gyro Lowpass 1 Dynamic { x = 87, y = 20, min = 0, max = 1000, to = SMLSIZE, vals = { 30, 31 } }, { x = 87, y = 28, min = 0, max = 1000, to = SMLSIZE, vals = { 32, 33 } }, { x = 87, y = 36, min = 0, max = 1, to = SMLSIZE, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- Gyro Lowpass 1 { x = 87, y = 52, min = 0, max = 16000, to = SMLSIZE, vals = { 21, 22 } }, { x = 87, y = 60, min = 0, max = 1, to = SMLSIZE, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- Gyro Lowpass 2 { x = 87, y = 76, min = 0, max = 16000, to = SMLSIZE, vals = { 23, 24 } }, { x = 87, y = 84, min = 0, max = 1, to = SMLSIZE, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- Gyro Notch 1 { x = 87, y = 100, min = 0, max = 16000, to = SMLSIZE, vals = { 6, 7 } }, { x = 87, y = 108, min = 0, max = 16000, to = SMLSIZE, vals = { 8, 9 } }, - - -- Gyro Notch 2 { x = 87, y = 124, min = 0, max = 16000, to = SMLSIZE, vals = { 14, 15 } }, { x = 87, y = 132, min = 0, max = 16000, to = SMLSIZE, vals = { 16, 17 } }, - - -- D Term Lowpass 1 Dynamic { x = 87, y = 148, min = 0, max = 1000, to = SMLSIZE, vals = { 34, 35 } }, { x = 87, y = 156, min = 0, max = 1000, to = SMLSIZE, vals = { 36, 37 } }, { x = 87, y = 164, min = 0, max = 1, to = SMLSIZE, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- D Term Lowpass 1 { x = 87, y = 180, min = 0, max = 16000, to = SMLSIZE, vals = { 2, 3 } }, { x = 87, y = 188, min = 0, max = 1, to = SMLSIZE, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- D Term Lowpass 2 { x = 87, y = 204, min = 0, max = 16000, to = SMLSIZE, vals = { 27, 28 } }, { x = 87, y = 212, min = 0, max = 1, to = SMLSIZE, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- D Term Notch { x = 87, y = 228, min = 0, max = 16000, to = SMLSIZE, vals = { 10, 11 } }, { x = 87, y = 236, min = 0, max = 16000, to = SMLSIZE, vals = { 12, 13 } }, - - -- Yaw Lowpass { x = 87, y = 252, min = 0, max = 500, to = SMLSIZE, vals = { 4, 5 } }, } } diff --git a/src/SCRIPTS/BF/212x64/gpspids.lua b/src/SCRIPTS/BF/212x64/gpspids.lua index a3c4c1b5..96697ed7 100644 --- a/src/SCRIPTS/BF/212x64/gpspids.lua +++ b/src/SCRIPTS/BF/212x64/gpspids.lua @@ -8,16 +8,12 @@ return { { t = "Yaw", x = 25, y = 46, to = SMLSIZE }, }, fields = { - -- P { x = 66, y = 26, min = 0, max = 500, vals = { 1,2 }, to = SMLSIZE }, { x = 66, y = 36, min = 0, max = 500, vals = { 7,8 }, to = SMLSIZE }, { x = 66, y = 46, min = 0, max = 500, vals = {13,14}, to = SMLSIZE }, - -- I { x = 94, y = 26, min = 0, max = 500, vals = { 3,4 }, to = SMLSIZE }, { x = 94, y = 36, min = 0, max = 500, vals = { 9,10 }, to = SMLSIZE }, - -- D { x = 122, y = 26, min = 0, max = 500, vals = { 5,6 }, to = SMLSIZE }, { x = 122, y = 36, min = 0, max = 500, vals = { 11,12 }, to = SMLSIZE }, - }, } diff --git a/src/SCRIPTS/BF/212x64/pid_advanced.lua b/src/SCRIPTS/BF/212x64/pid_advanced.lua index 83fbb05c..5b87f866 100644 --- a/src/SCRIPTS/BF/212x64/pid_advanced.lua +++ b/src/SCRIPTS/BF/212x64/pid_advanced.lua @@ -1,28 +1,17 @@ return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PID Advanced", - reboot = false, - eepromWrite = true, - minBytes = 46, - outputBytes = 46, yMinLimit = 12, yMaxLimit = 52, text = { { t = "Acro Trainer", x = 2, y = 12, to = SMLSIZE }, { t = "Angle Limit", x = 12, y = 20, to = SMLSIZE }, - { t = "Throttle Boost", x = 2, y = 28, to = SMLSIZE }, { t = "Absolute Control", x = 2, y = 36, to = SMLSIZE }, { t = "I Term Rotation", x = 2, y = 44, to = SMLSIZE }, { t = "VBAT Compensation", x = 2, y = 52, to = SMLSIZE }, - { t = "I Term Relax", x = 2, y = 60, to = SMLSIZE }, { t = "Axes", x = 12, y = 68, to = SMLSIZE }, { t = "Type", x = 12, y = 76, to = SMLSIZE }, - { t = "Integrated Yaw", x = 2, y = 84, to = SMLSIZE }, - { t = "Anti Gravity", x = 2, y = 92, to = SMLSIZE }, { t = "Mode", x = 12, y = 100, to = SMLSIZE }, { t = "Gain", x = 12, y = 108, to = SMLSIZE }, @@ -30,17 +19,13 @@ return { }, fields = { { x = 87, y = 20, to=SMLSIZE, min = 20, max = 80, vals = { 32 } }, - { x = 87, y = 28, to=SMLSIZE, min = 0, max = 100, vals = { 31 } }, { x = 87, y = 36, to=SMLSIZE, min = 0, max = 20, vals = { 30 } }, { x = 87, y = 44, to=SMLSIZE, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } }, { x = 87, y = 52, to=SMLSIZE, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } }, - { x = 87, y = 68, to=SMLSIZE, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (increment only)", "RPY (increment only)" } }, { x = 87, y = 76, to=SMLSIZE, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } }, - { x = 87, y = 84, to=SMLSIZE, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } }, - { x = 87, y = 100, to=SMLSIZE, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } }, { x = 87, y = 108, to=SMLSIZE, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 }, { x = 87, y = 116, to=SMLSIZE, min = 20, max = 1000, vals = { 20, 21 } }, diff --git a/src/SCRIPTS/BF/212x64/pids1.lua b/src/SCRIPTS/BF/212x64/pids1.lua index 15843ead..72abdb10 100644 --- a/src/SCRIPTS/BF/212x64/pids1.lua +++ b/src/SCRIPTS/BF/212x64/pids1.lua @@ -1,11 +1,4 @@ - return { - read = 112, -- MSP_PID - write = 202, -- MSP_SET_PID - title = "PIDs (1/2)", - reboot = false, - eepromWrite = true, - minBytes = 9, text = { { t = "P", x = 70, y = 14, to = SMLSIZE }, { t = "I", x = 98, y = 14, to = SMLSIZE }, @@ -15,15 +8,12 @@ return { { t = "YAW", x = 25, y = 46, to = SMLSIZE }, }, fields = { - -- P { x = 66, y = 26, min = 0, max = 200, vals = { 1 }, to = SMLSIZE }, { x = 66, y = 36, min = 0, max = 200, vals = { 4 }, to = SMLSIZE }, { x = 66, y = 46, min = 0, max = 200, vals = { 7 }, to = SMLSIZE }, - -- I { x = 94, y = 26, min = 0, max = 200, vals = { 2 }, to = SMLSIZE }, { x = 94, y = 36, min = 0, max = 200, vals = { 5 }, to = SMLSIZE }, { x = 94, y = 46, min = 0, max = 200, vals = { 8 }, to = SMLSIZE }, - -- D { x = 122, y = 26, min = 0, max = 200, vals = { 3 }, to = SMLSIZE }, { x = 122, y = 36, min = 0, max = 200, vals = { 6 }, to = SMLSIZE }, { x = 122, y = 46, min = 0, max = 200, vals = { 9 }, to = SMLSIZE }, diff --git a/src/SCRIPTS/BF/212x64/pids2.lua b/src/SCRIPTS/BF/212x64/pids2.lua index 5617532e..c988f0c8 100644 --- a/src/SCRIPTS/BF/212x64/pids2.lua +++ b/src/SCRIPTS/BF/212x64/pids2.lua @@ -1,11 +1,4 @@ - return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PIDs (2/2)", - reboot = false, - eepromWrite = true, - minBytes = 44, text = { { t = "Feed", x = 46, y = 11, to = SMLSIZE }, { t = "forward", x = 38, y = 18, to = SMLSIZE }, @@ -14,7 +7,6 @@ return { { t = "ROLL", x = 8, y = 26, to = SMLSIZE }, { t = "PITCH", x = 8, y = 36, to = SMLSIZE }, { t = "YAW", x = 8, y = 46, to = SMLSIZE }, - { t = "Feedforward", x = 110, y = 14, to = SMLSIZE }, { t = "Transition", x = 120, y = 22, to = SMLSIZE }, { t = "D Min", x = 110, y = 30, to = SMLSIZE }, @@ -22,23 +14,14 @@ return { { t = "Advance", x = 120, y = 46, to = SMLSIZE }, }, fields = { - -- ROLL FF { x = 49, y = 26, min = 0, max = 2000, vals = { 33, 34 }, to = SMLSIZE }, - -- PITCH FF { x = 49, y = 36, min = 0, max = 2000, vals = { 35, 36 }, to = SMLSIZE }, - -- YAW FF { x = 49, y = 46, min = 0, max = 2000, vals = { 37, 38 }, to = SMLSIZE }, - -- ROLL D MIN { x = 81, y = 26, min = 0, max = 100, vals = { 40 }, to = SMLSIZE }, - -- PITCH D MIN { x = 81, y = 36, min = 0, max = 100, vals = { 41 }, to = SMLSIZE }, - -- YAW D MIN { x = 81, y = 46, min = 0, max = 100, vals = { 42 }, to = SMLSIZE }, - -- FF TRANSITION { x = 180, y = 22, min = 0, max = 100, vals = { 9 }, to = SMLSIZE, scale = 100 }, - -- D MIN GAIN { x = 180, y = 38, min = 0, max = 100, vals = { 43 }, to = SMLSIZE }, - -- D MIN ADVANCE { x = 180, y = 46, min = 0, max = 200, vals = { 44 }, to = SMLSIZE }, }, } diff --git a/src/SCRIPTS/BF/212x64/pwm.lua b/src/SCRIPTS/BF/212x64/pwm.lua index 8ba7ce9a..ee844f7f 100644 --- a/src/SCRIPTS/BF/212x64/pwm.lua +++ b/src/SCRIPTS/BF/212x64/pwm.lua @@ -1,10 +1,4 @@ return { - read = 90, -- MSP_ADVANCED_CONFIG - write = 91, -- MSP_SET_ADVANCED_CONFIG - reboot = true, - eepromWrite = true, - title = "PWM", - minBytes = 9, text= { { t = "32K", x = 48, y = 14, to = SMLSIZE }, { t = "Gyro Rt", x = 29, y = 24, to = SMLSIZE }, @@ -23,33 +17,4 @@ return { { x = 148, y = 34, vals = { 5, 6 }, min = 200, max = 32000, to = SMLSIZE }, { x = 148, y = 44, vals = { 7, 8 }, min = 0, max = 2000, to = SMLSIZE, scale = 100 }, }, - calculateGyroRates = function(self, baseRate) - self.gyroRates = {} - self.fields[2].table = {} - for i=1, 32 do - self.gyroRates[i] = baseRate/i - local fmt = nil - self.fields[2].table[i] = string.format("%.2f",baseRate/i) - end - end, - calculatePidRates = function(self, baseRate) - self.fields[3].table = {} - for i=1, 16 do - self.fields[3].table[i] = string.format("%.2f",baseRate/i) - end - end, - updateRateTables = function(self) - if self.values[9] == 0 then - self.calculateGyroRates(self, 8) - self.calculatePidRates(self, 8) - elseif self.values[9] == 1 then - self.calculateGyroRates(self, 32) - self.calculatePidRates(self, 32) - end - end, - updatePidRateTable = function(self) - local newRateIdx = self.values[1] - local newRate = self.gyroRates[newRateIdx] - self.calculatePidRates(self, newRate) - end } diff --git a/src/SCRIPTS/BF/212x64/rates.lua b/src/SCRIPTS/BF/212x64/rates.lua index 707529c9..a59d7761 100644 --- a/src/SCRIPTS/BF/212x64/rates.lua +++ b/src/SCRIPTS/BF/212x64/rates.lua @@ -1,10 +1,4 @@ return { - read = 111, -- MSP_RC_TUNING - write = 204, -- MSP_SET_RC_TUNING - title = "Rates", - reboot = false, - eepromWrite = true, - minBytes = 16, yMinLimit = 11, yMaxLimit = 52, text = { @@ -17,7 +11,6 @@ return { { t = "ROLL", x = 8, y = 26, to = SMLSIZE }, { t = "PITCH", x = 8, y = 36, to = SMLSIZE }, { t = "YAW", x = 8, y = 46, to = SMLSIZE }, - { t = "Throttle", x = 120, y = 12, to = SMLSIZE }, { t = "Mid", x = 130, y = 20, to = SMLSIZE }, { t = "Expo", x = 130, y = 28, to = SMLSIZE }, @@ -28,24 +21,19 @@ return { { t = "Breakpoint", x = 130, y = 68, to = SMLSIZE }, }, fields = { - -- RC Rates { x = 39, y = 26, vals = { 1 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, { x = 39, y = 36, vals = { 13 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, { x = 39, y = 46, vals = { 12 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - -- Super Rates { x = 66, y = 26, vals = { 3 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 66, y = 36, vals = { 4 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 66, y = 46, vals = { 5 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - -- RC Expo { x = 94, y = 26, vals = { 2 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 94, y = 36, vals = { 14 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 94, y = 46, vals = { 11 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - -- Throttle { x = 180, y = 20, vals = { 7 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 180, y = 28, vals = { 8 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 180, y = 36, vals = { 15 }, min = 0, max = 2, to = SMLSIZE, table = { [0] = "OFF", "SCALE", "CLIP" } }, { x = 180, y = 44, vals = { 16 }, min = 25, max = 100, to = SMLSIZE }, - -- TPA { x = 180, y = 60, vals = { 6 } , min = 0, max = 100, scale = 100, to = SMLSIZE }, { x = 180, y = 68, vals = { 9, 10 }, min = 1000, max = 2000, to = SMLSIZE }, }, diff --git a/src/SCRIPTS/BF/212x64/rescue.lua b/src/SCRIPTS/BF/212x64/rescue.lua index a79fe51e..f960aa2a 100644 --- a/src/SCRIPTS/BF/212x64/rescue.lua +++ b/src/SCRIPTS/BF/212x64/rescue.lua @@ -1,36 +1,25 @@ return { - read = 135, -- MSP_GPS_RESCUE - write = 225, -- MSP_SET_GPS_RESCUE - title = "GPS Rescue", - reboot = false, - eepromWrite = true, - minBytes = 16, - requiredVersion = 1.041, text = { { t = "Min Sats.", x = 30, y = 16, to = SMLSIZE }, { t = "Angle", x = 45, y = 26, to = SMLSIZE }, { t = "Initial Alt.", x = 18, y = 36, to = SMLSIZE }, { t = "Descent Dist.", x = 10, y = 46, to = SMLSIZE }, { t = "Ground Speed", x = 10, y = 56, to = SMLSIZE }, - { t = "Sanity Ch.", x = 125, y = 16, to = SMLSIZE }, { t = "Throttle", x = 125, y = 26, to = SMLSIZE }, - { t = "Min", x = 128, y = 36, to = SMLSIZE }, + { t = "Min", x = 128, y = 36, to = SMLSIZE }, { t = "Hover", x = 120, y = 46, to = SMLSIZE }, - { t = "Max", x = 128, y = 56, to = SMLSIZE }, + { t = "Max", x = 128, y = 56, to = SMLSIZE }, }, fields = { - { x = 75, y = 16, min = 0, max = 50, vals = { 16 }, to = SMLSIZE }, { x = 75, y = 26, min = 0, max = 200, vals = { 1 , 2 }, to = SMLSIZE }, { x = 75, y = 36, min = 20, max = 100, vals = { 3 , 4 }, to = SMLSIZE }, { x = 75, y = 46, min = 30, max = 500, vals = { 5 , 6 }, to = SMLSIZE }, { x = 75, y = 56, min = 30, max = 3000, vals = { 7, 8 }, to = SMLSIZE }, - { x = 180, y = 16, min = 0, max = 2 , vals = { 15 }, to = SMLSIZE,table = { [0]="OFF","ON","FS_ONLY"}}, { x = 150, y = 36, min = 1000, max = 2000, vals = { 9, 10 }, to = SMLSIZE }, { x = 150, y = 46, min = 1000, max = 2000, vals = { 13, 14 },to = SMLSIZE }, { x = 150, y = 56, min = 1000, max = 2000, vals = { 11,12 }, to = SMLSIZE }, - }, } diff --git a/src/SCRIPTS/BF/212x64/rx.lua b/src/SCRIPTS/BF/212x64/rx.lua index 8824a5fe..a745b212 100644 --- a/src/SCRIPTS/BF/212x64/rx.lua +++ b/src/SCRIPTS/BF/212x64/rx.lua @@ -1,10 +1,4 @@ return { - read = 44, -- MSP_RX_CONFIG - write = 45, -- MSP_SET_RX_CONFIG - title = "RX", - reboot = false, - eepromWrite = true, - minBytes = 23, text = {}, fields = { { t = "Stick Min", x = 30, y = 20, sp = 45, min = 1000, max = 2000, vals = { 6, 7 }, to = SMLSIZE }, diff --git a/src/SCRIPTS/BF/212x64/vtx.lua b/src/SCRIPTS/BF/212x64/vtx.lua index 23f99f48..3696f2ee 100644 --- a/src/SCRIPTS/BF/212x64/vtx.lua +++ b/src/SCRIPTS/BF/212x64/vtx.lua @@ -1,16 +1,4 @@ - return { - read = 88, -- MSP_VTX_CONFIG - write = 89, -- MSP_VTX_SET_CONFIG - eepromWrite = true, - reboot = false, - title = "VTX", - minBytes = 5, - prevBandVal = 0, - prevChanVal = 0, - prevFreqVal = 0, - lastFreqUpdTS = 0, - freqModCounter = 0, text = {}, fields = { { t = "Band", x = 25, y = 14, sp = 50, min=0, max=5, vals = { 2 }, to = SMLSIZE, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, @@ -20,229 +8,4 @@ return { { t = "Dev", x = 100, y = 14, sp = 32, write = false, ro = true, vals = { 1 }, to = SMLSIZE, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, { t = "Freq", x = 100, y = 24, sp = 32, min = 5000, max = 5999, vals = { 6 }, to = SMLSIZE, upd = function(self) self.handleFreqValUpdate(self) end }, }, - freqLookup = { - { 5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725 }, -- Boscam A - { 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 }, -- Boscam B - { 5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945 }, -- Boscam E - { 5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880 }, -- FatShark - { 5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 }, -- RaceBand - }, - postLoad = function (self) - if (self.values[2] or 0) < 0 or (self.values[3] or 0) == 0 or (self.values[4] or 0) == 0 then - self.values = {} - else - self.prevBandVal = 0 -- reset value trackers - self.prevChanVal = 0 - self.prevFreqVal = 0 - local rFreq - if (self.values[7] or 0) > 0 then - rFreq = math.floor(self.values[6] + (self.values[7] * 256)) - else - rFreq = 0 - end - if (self.values[2] or 0) > 0 then -- band != 0 - if rFreq > 0 then - self.prevFreqVal = rFreq - self.prevBandVal = self.values[2] - self.prevChanVal = self.values[3] - self.fields[1].min = 0 -- make sure 'U' band allowed - self.eepromWrite = true - self.fields[6].value = rFreq - self.values[6] = rFreq - else -- if user freq not supported then - self.fields[1].min = 1 -- don't allow 'U' band - self.eepromWrite = false -- don't write EEPROM on older Betaflight versions - end - else -- band == 0 - if rFreq > 0 then - self.prevFreqVal = rFreq - self.fields[1].min = 0 -- make sure 'U' band allowed - self.eepromWrite = true - self.fields[6].value = rFreq - self.values[6] = rFreq - -- set chan via freq / 100 - self.prevChanVal = clipValue(math.floor((rFreq - 5100) / 100), - self.fields[2].min, self.fields[2].max) - self.fields[2].value = self.prevChanVal - self.values[3] = self.prevChanVal - else - self.values = {} - end - end - end - end, - preSave = function(self) - local valsTemp = {} - if self.values then - local channel - if self.values[2] > 0 then -- band != 0 - channel = (self.values[2]-1)*8 + self.values[3]-1 - elseif self.fields[6].value then -- band == 0 - channel = self.fields[6].value - else - channel = 24 - end - valsTemp[1] = bit32.band(channel,0xFF) - valsTemp[2] = bit32.rshift(channel,8) - valsTemp[3] = self.values[4] - valsTemp[4] = self.values[5] - end - return valsTemp - end, - -- find closest value in freq table that is above/below given freq - findNextInFreqTable = function(self, newFreq) - local startBand - local endBand - local incFlag -- freq increasing or decreasing - if newFreq > self.prevFreqVal then - incFlag = 1 - startBand = 1 - endBand = self.fields[1].max - else - incFlag = -1 - startBand = self.fields[1].max - endBand = 1 - end - local curBand = self.values[2] - local curChan = self.values[3] - local selBand = 0 - local selChan = 0 - local selFreq = 0 - local diffVal = 9999 - local fVal - local minChan = self.fields[2].min - local maxChan = self.fields[2].max - -- need to scan bands in same "direction" as 'incFlag' - -- so same-freq selections will be handled properly (F8 & R7) - for band=startBand,endBand,incFlag do - for chan=minChan,maxChan do - if band ~= curBand or chan ~= curChan then -- don't reselect same band/chan - fVal = self.freqLookup[band][chan] - if incFlag > 0 then - if fVal >= self.prevFreqVal and fVal - self.prevFreqVal < diffVal then - -- if same freq then only select if "next" band: - if fVal ~= self.prevFreqVal or band > curBand then - selBand = band - selChan = chan - selFreq = fVal - diffVal = fVal - self.prevFreqVal - end - end - else - if fVal <= self.prevFreqVal and self.prevFreqVal - fVal < diffVal then - -- if same freq then only select if "previous" band: - if fVal ~= self.prevFreqVal or band < curBand then - selBand = band - selChan = chan - selFreq = fVal - diffVal = self.prevFreqVal - fVal - end - end - end - end - end - end - return selFreq, selBand, selChan - end, - -- returns the next user-frequency value in MHz; implements an - -- "exponential" modification rate so dialing in values is faster - getNextUserFreqValue = function(self, newFreq) - local now = getTime() -- track rate of change for possible mod speedup - if now < self.lastFreqUpdTS + 15 then - self.freqModCounter = self.freqModCounter + (15-(self.lastFreqUpdTS-now)) -- increase counter for mod speedup - else - self.freqModCounter = 0 -- no mod speedup - end - local uFreq - if self.freqModCounter > 65 then -- rate is fast enough; do mod speedup - if newFreq > self.prevFreqVal then - uFreq = clipValue(newFreq + math.floor(self.freqModCounter / 65), - self.fields[6].min, self.fields[6].max) - else - uFreq = clipValue(newFreq - math.floor(self.freqModCounter / 65), - self.fields[6].min, self.fields[6].max) - end - else - uFreq = newFreq - end - self.lastFreqUpdTS = now - return uFreq - end, - updatePowerTable = function(self) - if self.values and not self.fields[3].table then - if self.values[1] == 1 then -- RTC6705 - self.fields[3].table = { 25, 200 } - self.fields[3].max = 2 - self.fields[4].t = nil -- don't display Pit field - self.fields[4].table = { [0]="", "" } - elseif self.values[1] == 3 then -- SmartAudio - self.fields[3].table = { 25, 200, 500, 800 } - self.fields[3].max = 4 - elseif self.values[1] == 4 then -- Tramp - self.fields[3].table = { 25, 100, 200, 400, 600 } - self.fields[3].max = 5 - elseif self.values[1] == 255 then -- None/Unknown - self.fields[3].t = nil -- don't display Power field - self.fields[3].max = 1 - self.fields[3].table = { [1]="" } - self.fields[4].t = nil -- don't display Pit field - self.fields[4].table = { [0]="", "" } - end - end - end, - handleBandChanUpdate = function(self) - if (#(self.values) or 0) >= self.minBytes then - if (self.values[3] or 0) > 0 then - if self.values[2] ~= self.prevBandVal or self.values[3] ~= self.prevChanVal then - if self.values[2] > 0 then -- band != 0 - self.prevFreqVal = self.freqLookup[self.values[2]][self.values[3]] - else -- band == 0; set freq via channel*100 - self.prevFreqVal = math.floor(5100 + (self.values[3] * 100)) - end - self.fields[6].value = self.prevFreqVal - self.values[6] = self.prevFreqVal - self.prevBandVal = self.values[2] - self.prevChanVal = self.values[3] - end - end - end - end, - handleFreqValUpdate = function(self) - if (#(self.values) or 0) >= self.minBytes and (self.fields[6].value or 0) > 0 then - local newFreq = self.fields[6].value - if newFreq ~= self.prevFreqVal then - if self.values[2] == 0 then - -- band == 0 - local uFreq = self.getNextUserFreqValue(self, newFreq) - self.prevFreqVal = uFreq - if uFreq ~= newFreq then - self.fields[6].value = uFreq - self.values[6] = uFreq - end - -- set channel value via freq/100 - self.prevChanVal = clipValue(math.floor((self.prevFreqVal - 5100) / 100), - self.fields[2].min, self.fields[2].max) - self.fields[2].value = self.prevChanVal - self.values[3] = self.prevChanVal - else - -- band != 0; find closest freq in table that is above/below dialed freq - local selFreq, selBand, selChan = self.findNextInFreqTable(self, newFreq) - if selFreq > 0 then - self.prevFreqVal = selFreq - self.prevBandVal = selBand - self.prevChanVal = selChan - self.fields[6].value = selFreq -- using new freq from table - self.values[6] = selFreq - self.fields[1].value = self.prevBandVal -- set band value for freq - self.values[2] = self.prevBandVal - self.fields[2].value = self.prevChanVal -- set channel value for freq - self.values[3] = self.prevChanVal - else - self.fields[6].value = self.prevFreqVal -- if no match then revert freq - self.values[6] = self.prevFreqVal - end - end - end - end - end } diff --git a/src/SCRIPTS/BF/320x480/filters.lua b/src/SCRIPTS/BF/320x480/filters.lua index 7847025b..99bcdbcb 100644 --- a/src/SCRIPTS/BF/320x480/filters.lua +++ b/src/SCRIPTS/BF/320x480/filters.lua @@ -6,83 +6,55 @@ return { { t = "Min Cutoff", x = 35, y = 55, to = SMLSIZE }, { t = "Max Cutoff", x = 35, y = 75, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 95, to = SMLSIZE }, - { t = "Gyro Lowpass 1", x = 5, y = 115 }, { t = "Cutoff", x = 35, y = 135, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 155, to = SMLSIZE }, - { t = "Gyro Lowpass 2", x = 5, y = 175 }, { t = "Cutoff", x = 35, y = 195, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 215, to = SMLSIZE }, - { t = "Gyro Notch 1", x = 5, y = 235 }, { t = "Center", x = 35, y = 255, to = SMLSIZE }, { t = "Cutoff", x = 35, y = 275, to = SMLSIZE }, - { t = "Gyro Notch 2", x = 5, y = 295 }, { t = "Center", x = 35, y = 315, to = SMLSIZE }, { t = "Cutoff", x = 35, y = 335, to = SMLSIZE }, - { t = "D Term Lowpass 1 Dynamic", x = 5, y = 355 }, { t = "Min Cutoff", x = 35, y = 375, to = SMLSIZE }, { t = "Max Cutoff", x = 35, y = 395, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 415, to = SMLSIZE }, - { t = "D Term Lowpass 1", x = 5, y = 435 }, { t = "Cutoff", x = 35, y = 455, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 475, to = SMLSIZE }, - { t = "D Term Lowpass 2", x = 5, y = 495 }, { t = "Cutoff", x = 35, y = 515, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 535, to = SMLSIZE }, - { t = "D Term Notch", x = 5, y = 555 }, { t = "Center", x = 35, y = 575, to = SMLSIZE }, { t = "Cutoff", x = 35, y = 595, to = SMLSIZE }, - { t = "Yaw Lowpass", x = 5, y = 615 }, { t = "Cutoff", x = 35, y = 635, to = SMLSIZE }, }, fields = { - -- Gyro Lowpass 1 Dynamic { x = 200, y = 55, min = 0, max = 1000, vals = { 30, 31 } }, { x = 200, y = 75, min = 0, max = 1000, vals = { 32, 33 } }, { x = 200, y = 95, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- Gyro Lowpass 1 { x = 200, y = 135, min = 0, max = 16000, vals = { 21, 22 } }, { x = 200, y = 155, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- Gyro Lowpass 2 { x = 200, y = 195, min = 0, max = 16000, vals = { 23, 24 } }, { x = 200, y = 215, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- Gyro Notch 1 { x = 200, y = 255, min = 0, max = 16000, vals = { 6, 7 } }, { x = 200, y = 275, min = 0, max = 16000, vals = { 8, 9 } }, - - -- Gyro Notch 2 { x = 200, y = 315, min = 0, max = 16000, vals = { 14, 15 } }, { x = 200, y = 335, min = 0, max = 16000, vals = { 16, 17 } }, - - -- D Term Lowpass 1 Dynamic { x = 200, y = 375, min = 0, max = 1000, vals = { 34, 35 } }, { x = 200, y = 395, min = 0, max = 1000, vals = { 36, 37 } }, { x = 200, y = 415, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- D Term Lowpass 1 { x = 200, y = 455, min = 0, max = 16000, vals = { 2, 3 } }, { x = 200, y = 475, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- D Term Lowpass 2 { x = 200, y = 515, min = 0, max = 16000, vals = { 27, 28 } }, { x = 200, y = 535, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- D Term Notch { x = 200, y = 575, min = 0, max = 16000, vals = { 10, 11 } }, { x = 200, y = 595, min = 0, max = 16000, vals = { 12, 13 } }, - - -- Yaw Lowpass { x = 200, y = 635, min = 0, max = 500, vals = { 4, 5 } }, } } diff --git a/src/SCRIPTS/BF/320x480/gpspids.lua b/src/SCRIPTS/BF/320x480/gpspids.lua index afebb378..7f67e458 100644 --- a/src/SCRIPTS/BF/320x480/gpspids.lua +++ b/src/SCRIPTS/BF/320x480/gpspids.lua @@ -8,14 +8,11 @@ return { { t = "Yaw" , x = 10, y = 200 }, }, fields = { - -- P { x = 100, y = 100, min = 0, max = 200, vals = { 1, 3 }, to = MIDSIZE }, { x = 100, y = 150, min = 0, max = 200, vals = { 7, 8 }, to = MIDSIZE }, { x = 100, y = 200, min = 0, max = 500, vals = {13,14 }, to = MIDSIZE }, - -- I { x = 180, y = 100, min = 0, max = 200, vals = { 3, 4 }, to = MIDSIZE }, { x = 180, y = 150, min = 0, max = 200, vals = { 9,10 }, to = MIDSIZE }, - -- D { x = 260, y = 100, min = 0, max = 200, vals = { 5, 6 }, to = MIDSIZE }, { x = 260, y = 150, min = 0, max = 200, vals = { 11,12 }, to = MIDSIZE }, }, diff --git a/src/SCRIPTS/BF/320x480/pid_advanced.lua b/src/SCRIPTS/BF/320x480/pid_advanced.lua index 1421dfb4..e58a614f 100644 --- a/src/SCRIPTS/BF/320x480/pid_advanced.lua +++ b/src/SCRIPTS/BF/320x480/pid_advanced.lua @@ -1,28 +1,17 @@ return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PID Advanced", - reboot = false, - eepromWrite = true, - minBytes = 46, - outputBytes = 46, yMinLimit = 35, yMaxLimit = 215, text = { { t = "Acro Trainer", x = 5, y = 35 }, { t = "Angle Limit", x = 15, y = 55, to = SMLSIZE }, - { t = "Throttle Boost", x = 5, y = 75 }, { t = "Absolute Control", x = 5, y = 95 }, { t = "I Term Rotation", x = 5, y = 115 }, { t = "VBAT Compensation", x = 5, y = 135 }, - { t = "I Term Relax", x = 5, y = 155 }, { t = "Axes", x = 15, y = 175, to = SMLSIZE }, { t = "Type", x = 15, y = 195, to = SMLSIZE }, - { t = "Integrated Yaw", x = 5, y = 215 }, - { t = "Anti Gravity", x = 5, y = 235 }, { t = "Mode", x = 15, y = 255, to = SMLSIZE }, { t = "Gain", x = 15, y = 275, to = SMLSIZE }, @@ -30,17 +19,13 @@ return { }, fields = { { x = 200, y = 55, min = 20, max = 80, vals = { 32 } }, - { x = 200, y = 75, min = 0, max = 100, vals = { 31 } }, { x = 200, y = 95, min = 0, max = 20, vals = { 30 } }, { x = 200, y = 115, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } }, { x = 200, y = 135, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } }, - { x = 200, y = 175, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (increment only)", "RPY (increment only)" } }, { x = 200, y = 195, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } }, - { x = 200, y = 215, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } }, - { x = 200, y = 255, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } }, { x = 200, y = 275, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 }, { x = 200, y = 295, min = 20, max = 1000, vals = { 20, 21 } }, diff --git a/src/SCRIPTS/BF/320x480/pids1.lua b/src/SCRIPTS/BF/320x480/pids1.lua index c48518bb..3312ceb4 100644 --- a/src/SCRIPTS/BF/320x480/pids1.lua +++ b/src/SCRIPTS/BF/320x480/pids1.lua @@ -1,11 +1,4 @@ - return { - read = 112, -- MSP_PID - write = 202, -- MSP_SET_PID - title = "PIDs (1/2)", - reboot = false, - eepromWrite = true, - minBytes = 9, text = { { t = "P", x = 100, y = 48, to = MIDSIZE }, { t = "I", x = 180, y = 48, to = MIDSIZE }, @@ -15,15 +8,12 @@ return { { t = "YAW", x = 10, y = 200 }, }, fields = { - -- P { x = 100, y = 100, min = 0, max = 200, vals = { 1 }, to = MIDSIZE }, { x = 100, y = 150, min = 0, max = 200, vals = { 4 }, to = MIDSIZE }, { x = 100, y = 200, min = 0, max = 200, vals = { 7 }, to = MIDSIZE }, - -- I { x = 180, y = 100, min = 0, max = 200, vals = { 2 }, to = MIDSIZE }, { x = 180, y = 150, min = 0, max = 200, vals = { 5 }, to = MIDSIZE }, { x = 180, y = 200, min = 0, max = 200, vals = { 8 }, to = MIDSIZE }, - -- D { x = 260, y = 100, min = 0, max = 200, vals = { 3 }, to = MIDSIZE }, { x = 260, y = 150, min = 0, max = 200, vals = { 6 }, to = MIDSIZE }, { x = 260, y = 200, min = 0, max = 200, vals = { 9 }, to = MIDSIZE }, diff --git a/src/SCRIPTS/BF/320x480/pids2.lua b/src/SCRIPTS/BF/320x480/pids2.lua index 3080e49a..90ded627 100644 --- a/src/SCRIPTS/BF/320x480/pids2.lua +++ b/src/SCRIPTS/BF/320x480/pids2.lua @@ -1,11 +1,4 @@ - return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PIDs (2/2)", - reboot = false, - eepromWrite = true, - minBytes = 44, text = { { t = "Feed", x = 97, y = 52 }, { t = "forward", x = 82, y = 70 }, @@ -14,7 +7,6 @@ return { { t = "ROLL", x = 28, y = 100 }, { t = "PITCH", x = 28, y = 150 }, { t = "YAW", x = 28, y = 200 }, - { t = "Feedforward", x = 28, y = 250 }, { t = "Transition", x = 40, y = 270, to = SMLSIZE }, { t = "D Min", x = 28, y = 300 }, @@ -22,23 +14,14 @@ return { { t = "Advance", x = 40, y = 350, to = SMLSIZE }, }, fields = { - -- ROLL FF { x = 102, y = 100, min = 0, max = 2000, vals = { 33, 34 }, to = MIDSIZE }, - -- PITCH FF { x = 102, y = 150, min = 0, max = 2000, vals = { 35, 36 }, to = MIDSIZE }, - -- YAW FF { x = 102, y = 200, min = 0, max = 2000, vals = { 37, 38 }, to = MIDSIZE }, - -- ROLL D MIN { x = 202, y = 100, min = 0, max = 100, vals = { 40 }, to = MIDSIZE }, - -- PITCH D MIN { x = 202, y = 150, min = 0, max = 100, vals = { 41 }, to = MIDSIZE }, - -- YAW D MIN { x = 202, y = 200, min = 0, max = 100, vals = { 42 }, to = MIDSIZE }, - -- FF TRANSITION { x = 150, y = 270, min = 0, max = 100, vals = { 9 }, scale = 100 }, - -- D MIN GAIN { x = 150, y = 320, min = 0, max = 100, vals = { 43 } }, - -- D MIN ADVANCE { x = 150, y = 350, min = 0, max = 200, vals = { 44 } }, }, } diff --git a/src/SCRIPTS/BF/320x480/pwm.lua b/src/SCRIPTS/BF/320x480/pwm.lua index 9186df15..75bc9180 100644 --- a/src/SCRIPTS/BF/320x480/pwm.lua +++ b/src/SCRIPTS/BF/320x480/pwm.lua @@ -1,10 +1,4 @@ return { - read = 90, -- MSP_ADVANCED_CONFIG - write = 91, -- MSP_SET_ADVANCED_CONFIG - reboot = true, - eepromWrite = true, - title = "PWM", - minBytes = 9, text= { { t = "Protocol", x = 36, y = 68 }, { t = "32K", x = 36, y = 110 }, @@ -21,46 +15,11 @@ return { "DSHOT150", "DSHOT300", "DSHOT600","DSHOT1200", "PROSHOT1000" } }, - { x = 150, y = 110, vals = { 9 }, min = 0, max = 1, to = MIDSIZE, - table = { [0] = "OFF", "ON" }, - upd = function(self) self.updateRateTables(self) end - }, - { x = 150, y = 155, vals = { 1 }, min = 1, max = 32, to = MIDSIZE, - upd = function(self) self.updatePidRateTable(self) end - }, + { x = 150, y = 110, vals = { 9 }, min = 0, max = 1, to = MIDSIZE, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, + { x = 150, y = 155, vals = { 1 }, min = 1, max = 32, to = MIDSIZE, upd = function(self) self.updatePidRateTable(self) end }, { x = 150, y = 200, vals = { 2 }, min = 1, max = 16, to = MIDSIZE }, - { x = 150, y = 242, vals = { 3 }, min = 0, max = 1, to = MIDSIZE, - table = { [0] = "OFF", "ON" } }, + { x = 150, y = 242, vals = { 3 }, min = 0, max = 1, to = MIDSIZE, table = { [0] = "OFF", "ON" } }, { x = 150, y = 284, vals = { 5, 6 }, min = 200, max = 32000, to = MIDSIZE }, { x = 150, y = 326, vals = { 7, 8 }, min = 0, max = 2000, scale = 100, to = MIDSIZE }, }, - calculateGyroRates = function(self, baseRate) - self.gyroRates = {} - self.fields[2].table = {} - for i=1, 32 do - self.gyroRates[i] = baseRate/i - local fmt = nil - self.fields[2].table[i] = string.format("%.2f",baseRate/i) - end - end, - calculatePidRates = function(self, baseRate) - self.fields[3].table = {} - for i=1, 16 do - self.fields[3].table[i] = string.format("%.2f",baseRate/i) - end - end, - updateRateTables = function(self) - if self.values[9] == 0 then - self.calculateGyroRates(self, 8) - self.calculatePidRates(self, 8) - elseif self.values[9] == 1 then - self.calculateGyroRates(self, 32) - self.calculatePidRates(self, 32) - end - end, - updatePidRateTable = function(self) - local newRateIdx = self.values[1] - local newRate = self.gyroRates[newRateIdx] - self.calculatePidRates(self, newRate) - end } diff --git a/src/SCRIPTS/BF/320x480/rates.lua b/src/SCRIPTS/BF/320x480/rates.lua index b2539650..235062c1 100644 --- a/src/SCRIPTS/BF/320x480/rates.lua +++ b/src/SCRIPTS/BF/320x480/rates.lua @@ -1,10 +1,4 @@ return { - read = 111, -- MSP_RC_TUNING - write = 204, -- MSP_SET_RC_TUNING - title = "Rates", - reboot = false, - eepromWrite = true, - minBytes = 16, text = { { t = "RC", x = 100, y = 52 }, { t = "Rate", x = 94, y = 70 }, @@ -15,7 +9,6 @@ return { { t = "ROLL", x = 28, y = 100 }, { t = "PITCH", x = 28, y = 150 }, { t = "YAW", x = 28, y = 200 }, - { t = "Throttle", x = 28, y = 250 }, { t = "Mid", x = 40, y = 270, to = SMLSIZE }, { t = "Expo", x = 40, y = 290, to = SMLSIZE }, @@ -26,24 +19,19 @@ return { { t = "Breakpoint", x = 40, y = 390, to = SMLSIZE }, }, fields = { - -- RC Rates { x = 102, y = 100, vals = { 1 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, { x = 102, y = 150, vals = { 13 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, { x = 102, y = 200, vals = { 12 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - -- Super Rates { x = 158, y = 100, vals = { 3 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, { x = 158, y = 150, vals = { 4 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, { x = 158, y = 200, vals = { 5 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - -- RC Expo { x = 216, y = 100, vals = { 2 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, { x = 216, y = 150, vals = { 14 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, { x = 216, y = 200, vals = { 11 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - -- Throttle { x = 150, y = 270, vals = { 7 }, min = 0, max = 100, scale = 100 }, { x = 150, y = 290, vals = { 8 }, min = 0, max = 100, scale = 100 }, { x = 150, y = 310, vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, { x = 150, y = 330, vals = { 16 }, min = 25, max = 100 }, - -- TPA { x = 150, y = 370, vals = { 6 }, min = 0, max = 100, scale = 100 }, { x = 150, y = 390, vals = { 9, 10 }, min = 1000, max = 2000 }, }, diff --git a/src/SCRIPTS/BF/320x480/rescue.lua b/src/SCRIPTS/BF/320x480/rescue.lua index ec85cd86..ba27efde 100644 --- a/src/SCRIPTS/BF/320x480/rescue.lua +++ b/src/SCRIPTS/BF/320x480/rescue.lua @@ -1,18 +1,10 @@ return { - read = 135, -- MSP_GPS_RESCUE - write = 225, -- MSP_SET_GPS_RESCUE - title = "GPS Rescue", - reboot = false, - eepromWrite = true, - minBytes = 16, - requiredVersion = 1.041, text = { { t = "Min Sats.", x = 10, y = 40 }, { t = "Angle", x = 10, y = 80 }, { t = "Initial Altitude", x = 10, y = 120 }, { t = "Descent Distance", x = 10, y = 160 }, { t = "Ground Speed", x = 10, y = 200 }, - { t = "Snty.", x = 10, y = 240 }, { t = "Throttle", x = 10, y = 280 }, { t = "Min", x = 10, y = 320 }, @@ -25,12 +17,9 @@ return { { x = 260, y = 120, min = 20, max = 100, vals = { 3,4 } }, { x = 260, y = 160, min = 30, max = 500, vals = { 5,6 } }, { x = 260, y = 200, min = 30, max =3000, vals = { 7,8 } }, - - { x = 260, y = 240, min = 0, max = 2 , vals = { 15 } ,table = { [0]="OFF","ON","FS_ONLY"}}, { x = 260, y = 320, min = 1000, max = 2000, vals = { 9,10 } }, { x = 260, y = 360, min = 1000, max = 2000, vals = { 13,14 } }, { x = 260, y = 400, min = 1000, max = 2000, vals = { 11,12 } }, - }, -} +} \ No newline at end of file diff --git a/src/SCRIPTS/BF/320x480/rx.lua b/src/SCRIPTS/BF/320x480/rx.lua index 3fb30b09..361d9b00 100644 --- a/src/SCRIPTS/BF/320x480/rx.lua +++ b/src/SCRIPTS/BF/320x480/rx.lua @@ -1,10 +1,4 @@ return { - read = 44, -- MSP_RX_CONFIG - write = 45, -- MSP_SET_RX_CONFIG - title = "RX", - reboot = false, - eepromWrite = true, - minBytes = 23, text= { { t = "Stick Min", x = 36, y = 68 }, { t = "Stick Mid", x = 36, y = 110 }, diff --git a/src/SCRIPTS/BF/320x480/vtx.lua b/src/SCRIPTS/BF/320x480/vtx.lua index 1aae0762..28f8e652 100644 --- a/src/SCRIPTS/BF/320x480/vtx.lua +++ b/src/SCRIPTS/BF/320x480/vtx.lua @@ -1,16 +1,4 @@ - return { - read = 88, -- MSP_VTX_CONFIG - write = 89, -- MSP_VTX_SET_CONFIG - eepromWrite = true, - reboot = false, - title = "VTX", - minBytes = 5, - prevBandVal = 0, - prevChanVal = 0, - prevFreqVal = 0, - lastFreqUpdTS = 0, - freqModCounter = 0, text= { { t = "Band", x = 36, y = 155 }, { t = "Channel", x = 36, y = 200 }, @@ -20,250 +8,11 @@ return { { t = "Freq", x = 36, y = 110 }, }, fields = { - -- Band - { x = 150, y = 155, min=0, max=5, vals = { 2 }, to = MIDSIZE, - table = { [0]="U", "A", "B", "E", "F", "R" }, - upd = function(self) self.handleBandChanUpdate(self) end }, - -- Channel - { x = 150, y = 200, min=1, max=8, vals = { 3 }, to = MIDSIZE, - upd = function(self) self.handleBandChanUpdate(self) end }, - -- Power - { x = 150, y = 242, min=1, vals = { 4 }, to = MIDSIZE, - upd = function(self) self.updatePowerTable(self) end }, - -- Pit mode - { x = 150, y = 284, min=0, max=1, vals = { 5 }, to = MIDSIZE, - table = { [0]="OFF", "ON" } }, - -- Proto - { x = 150, y = 68, vals = { 1 }, to = MIDSIZE, - write = false, ro = true, - table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, - -- Freq - { x = 150, y = 110, min = 5000, max = 5999, vals = { 6 }, to = MIDSIZE, - upd = function(self) self.handleFreqValUpdate(self) end }, + { x = 150, y = 155, min=0, max=5, vals = { 2 }, to = MIDSIZE, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, + { x = 150, y = 200, min=1, max=8, vals = { 3 }, to = MIDSIZE, upd = function(self) self.handleBandChanUpdate(self) end }, + { x = 150, y = 242, min=1, vals = { 4 }, to = MIDSIZE, upd = function(self) self.updatePowerTable(self) end }, + { x = 150, y = 284, min=0, max=1, vals = { 5 }, to = MIDSIZE, table = { [0]="OFF", "ON" } }, + { x = 150, y = 68, vals = { 1 }, to = MIDSIZE, write = false, ro = true, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, + { x = 150, y = 110, min = 5000, max = 5999, vals = { 6 }, to = MIDSIZE, upd = function(self) self.handleFreqValUpdate(self) end }, }, - freqLookup = { - { 5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725 }, -- Boscam A - { 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 }, -- Boscam B - { 5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945 }, -- Boscam E - { 5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880 }, -- FatShark - { 5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 }, -- RaceBand - }, - postLoad = function (self) - if (self.values[2] or 0) < 0 or (self.values[3] or 0) == 0 or (self.values[4] or 0) == 0 then - self.values = {} - else - self.prevBandVal = 0 -- reset value trackers - self.prevChanVal = 0 - self.prevFreqVal = 0 - local rFreq - if (self.values[7] or 0) > 0 then - rFreq = math.floor(self.values[6] + (self.values[7] * 256)) - else - rFreq = 0 - end - if (self.values[2] or 0) > 0 then -- band != 0 - if rFreq > 0 then - self.prevFreqVal = rFreq - self.prevBandVal = self.values[2] - self.prevChanVal = self.values[3] - self.fields[1].min = 0 -- make sure 'U' band allowed - self.eepromWrite = true - self.fields[6].value = rFreq - self.values[6] = rFreq - else -- if user freq not supported then - self.fields[1].min = 1 -- don't allow 'U' band - self.eepromWrite = false -- don't write EEPROM on older Betaflight versions - end - else -- band == 0 - if rFreq > 0 then - self.prevFreqVal = rFreq - self.fields[1].min = 0 -- make sure 'U' band allowed - self.eepromWrite = true - self.fields[6].value = rFreq - self.values[6] = rFreq - -- set chan via freq / 100 - self.prevChanVal = clipValue(math.floor((rFreq - 5100) / 100), - self.fields[2].min, self.fields[2].max) - self.fields[2].value = self.prevChanVal - self.values[3] = self.prevChanVal - else - self.values = {} - end - end - end - end, - preSave = function(self) - local valsTemp = {} - if self.values then - local channel - if self.values[2] > 0 then -- band != 0 - channel = (self.values[2]-1)*8 + self.values[3]-1 - elseif self.fields[6].value then -- band == 0 - channel = self.fields[6].value - else - channel = 24 - end - valsTemp[1] = bit32.band(channel,0xFF) - valsTemp[2] = bit32.rshift(channel,8) - valsTemp[3] = self.values[4] - valsTemp[4] = self.values[5] - end - return valsTemp - end, - -- find closest value in freq table that is above/below given freq - findNextInFreqTable = function(self, newFreq) - local startBand - local endBand - local incFlag -- freq increasing or decreasing - if newFreq > self.prevFreqVal then - incFlag = 1 - startBand = 1 - endBand = self.fields[1].max - else - incFlag = -1 - startBand = self.fields[1].max - endBand = 1 - end - local curBand = self.values[2] - local curChan = self.values[3] - local selBand = 0 - local selChan = 0 - local selFreq = 0 - local diffVal = 9999 - local fVal - local minChan = self.fields[2].min - local maxChan = self.fields[2].max - -- need to scan bands in same "direction" as 'incFlag' - -- so same-freq selections will be handled properly (F8 & R7) - for band=startBand,endBand,incFlag do - for chan=minChan,maxChan do - if band ~= curBand or chan ~= curChan then -- don't reselect same band/chan - fVal = self.freqLookup[band][chan] - if incFlag > 0 then - if fVal >= self.prevFreqVal and fVal - self.prevFreqVal < diffVal then - -- if same freq then only select if "next" band: - if fVal ~= self.prevFreqVal or band > curBand then - selBand = band - selChan = chan - selFreq = fVal - diffVal = fVal - self.prevFreqVal - end - end - else - if fVal <= self.prevFreqVal and self.prevFreqVal - fVal < diffVal then - -- if same freq then only select if "previous" band: - if fVal ~= self.prevFreqVal or band < curBand then - selBand = band - selChan = chan - selFreq = fVal - diffVal = self.prevFreqVal - fVal - end - end - end - end - end - end - return selFreq, selBand, selChan - end, - -- returns the next user-frequency value in MHz; implements an - -- "exponential" modification rate so dialing in values is faster - getNextUserFreqValue = function(self, newFreq) - local now = getTime() -- track rate of change for possible mod speedup - if now < self.lastFreqUpdTS + 15 then - self.freqModCounter = self.freqModCounter + (15-(self.lastFreqUpdTS-now)) -- increase counter for mod speedup - else - self.freqModCounter = 0 -- no mod speedup - end - local uFreq - if self.freqModCounter > 65 then -- rate is fast enough; do mod speedup - if newFreq > self.prevFreqVal then - uFreq = clipValue(newFreq + math.floor(self.freqModCounter / 65), - self.fields[6].min, self.fields[6].max) - else - uFreq = clipValue(newFreq - math.floor(self.freqModCounter / 65), - self.fields[6].min, self.fields[6].max) - end - else - uFreq = newFreq - end - self.lastFreqUpdTS = now - return uFreq - end, - updatePowerTable = function(self) - if self.values and not self.fields[3].table then - if self.values[1] == 1 then -- RTC6705 - self.fields[3].table = { 25, 200 } - self.fields[3].max = 2 - self.fields[4].t = nil -- don't display Pit field - self.fields[4].table = { [0]="", "" } - elseif self.values[1] == 3 then -- SmartAudio - self.fields[3].table = { 25, 200, 500, 800 } - self.fields[3].max = 4 - elseif self.values[1] == 4 then -- Tramp - self.fields[3].table = { 25, 100, 200, 400, 600 } - self.fields[3].max = 5 - elseif self.values[1] == 255 then -- None/Unknown - self.fields[3].t = nil -- don't display Power field - self.fields[3].max = 1 - self.fields[3].table = { [1]="" } - self.fields[4].t = nil -- don't display Pit field - self.fields[4].table = { [0]="", "" } - end - end - end, - handleBandChanUpdate = function(self) - if (#(self.values) or 0) >= self.minBytes then - if (self.values[3] or 0) > 0 then - if self.values[2] ~= self.prevBandVal or self.values[3] ~= self.prevChanVal then - if self.values[2] > 0 then -- band != 0 - self.prevFreqVal = self.freqLookup[self.values[2]][self.values[3]] - else -- band == 0; set freq via channel*100 - self.prevFreqVal = math.floor(5100 + (self.values[3] * 100)) - end - self.fields[6].value = self.prevFreqVal - self.values[6] = self.prevFreqVal - self.prevBandVal = self.values[2] - self.prevChanVal = self.values[3] - end - end - end - end, - handleFreqValUpdate = function(self) - if (#(self.values) or 0) >= self.minBytes and (self.fields[6].value or 0) > 0 then - local newFreq = self.fields[6].value - if newFreq ~= self.prevFreqVal then - if self.values[2] == 0 then - -- band == 0 - local uFreq = self.getNextUserFreqValue(self, newFreq) - self.prevFreqVal = uFreq - if uFreq ~= newFreq then - self.fields[6].value = uFreq - self.values[6] = uFreq - end - -- set channel value via freq/100 - self.prevChanVal = clipValue(math.floor((self.prevFreqVal - 5100) / 100), - self.fields[2].min, self.fields[2].max) - self.fields[2].value = self.prevChanVal - self.values[3] = self.prevChanVal - else - -- band != 0; find closest freq in table that is above/below dialed freq - local selFreq, selBand, selChan = self.findNextInFreqTable(self, newFreq) - if selFreq > 0 then - self.prevFreqVal = selFreq - self.prevBandVal = selBand - self.prevChanVal = selChan - self.fields[6].value = selFreq -- using new freq from table - self.values[6] = selFreq - self.fields[1].value = self.prevBandVal -- set band value for freq - self.values[2] = self.prevBandVal - self.fields[2].value = self.prevChanVal -- set channel value for freq - self.values[3] = self.prevChanVal - else - self.fields[6].value = self.prevFreqVal -- if no match then revert freq - self.values[6] = self.prevFreqVal - end - end - end - end - end } \ No newline at end of file diff --git a/src/SCRIPTS/BF/480x272/filters.lua b/src/SCRIPTS/BF/480x272/filters.lua index 7847025b..99bcdbcb 100644 --- a/src/SCRIPTS/BF/480x272/filters.lua +++ b/src/SCRIPTS/BF/480x272/filters.lua @@ -6,83 +6,55 @@ return { { t = "Min Cutoff", x = 35, y = 55, to = SMLSIZE }, { t = "Max Cutoff", x = 35, y = 75, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 95, to = SMLSIZE }, - { t = "Gyro Lowpass 1", x = 5, y = 115 }, { t = "Cutoff", x = 35, y = 135, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 155, to = SMLSIZE }, - { t = "Gyro Lowpass 2", x = 5, y = 175 }, { t = "Cutoff", x = 35, y = 195, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 215, to = SMLSIZE }, - { t = "Gyro Notch 1", x = 5, y = 235 }, { t = "Center", x = 35, y = 255, to = SMLSIZE }, { t = "Cutoff", x = 35, y = 275, to = SMLSIZE }, - { t = "Gyro Notch 2", x = 5, y = 295 }, { t = "Center", x = 35, y = 315, to = SMLSIZE }, { t = "Cutoff", x = 35, y = 335, to = SMLSIZE }, - { t = "D Term Lowpass 1 Dynamic", x = 5, y = 355 }, { t = "Min Cutoff", x = 35, y = 375, to = SMLSIZE }, { t = "Max Cutoff", x = 35, y = 395, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 415, to = SMLSIZE }, - { t = "D Term Lowpass 1", x = 5, y = 435 }, { t = "Cutoff", x = 35, y = 455, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 475, to = SMLSIZE }, - { t = "D Term Lowpass 2", x = 5, y = 495 }, { t = "Cutoff", x = 35, y = 515, to = SMLSIZE }, { t = "Filter Type", x = 35, y = 535, to = SMLSIZE }, - { t = "D Term Notch", x = 5, y = 555 }, { t = "Center", x = 35, y = 575, to = SMLSIZE }, { t = "Cutoff", x = 35, y = 595, to = SMLSIZE }, - { t = "Yaw Lowpass", x = 5, y = 615 }, { t = "Cutoff", x = 35, y = 635, to = SMLSIZE }, }, fields = { - -- Gyro Lowpass 1 Dynamic { x = 200, y = 55, min = 0, max = 1000, vals = { 30, 31 } }, { x = 200, y = 75, min = 0, max = 1000, vals = { 32, 33 } }, { x = 200, y = 95, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- Gyro Lowpass 1 { x = 200, y = 135, min = 0, max = 16000, vals = { 21, 22 } }, { x = 200, y = 155, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- Gyro Lowpass 2 { x = 200, y = 195, min = 0, max = 16000, vals = { 23, 24 } }, { x = 200, y = 215, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- Gyro Notch 1 { x = 200, y = 255, min = 0, max = 16000, vals = { 6, 7 } }, { x = 200, y = 275, min = 0, max = 16000, vals = { 8, 9 } }, - - -- Gyro Notch 2 { x = 200, y = 315, min = 0, max = 16000, vals = { 14, 15 } }, { x = 200, y = 335, min = 0, max = 16000, vals = { 16, 17 } }, - - -- D Term Lowpass 1 Dynamic { x = 200, y = 375, min = 0, max = 1000, vals = { 34, 35 } }, { x = 200, y = 395, min = 0, max = 1000, vals = { 36, 37 } }, { x = 200, y = 415, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- D Term Lowpass 1 { x = 200, y = 455, min = 0, max = 16000, vals = { 2, 3 } }, { x = 200, y = 475, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- D Term Lowpass 2 { x = 200, y = 515, min = 0, max = 16000, vals = { 27, 28 } }, { x = 200, y = 535, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - - -- D Term Notch { x = 200, y = 575, min = 0, max = 16000, vals = { 10, 11 } }, { x = 200, y = 595, min = 0, max = 16000, vals = { 12, 13 } }, - - -- Yaw Lowpass { x = 200, y = 635, min = 0, max = 500, vals = { 4, 5 } }, } } diff --git a/src/SCRIPTS/BF/480x272/gpspids.lua b/src/SCRIPTS/BF/480x272/gpspids.lua index 13d55cc8..b2c4eeda 100644 --- a/src/SCRIPTS/BF/480x272/gpspids.lua +++ b/src/SCRIPTS/BF/480x272/gpspids.lua @@ -8,14 +8,11 @@ return { { t = "Yaw" , x = 28, y = 200 }, }, fields = { - -- P { x = 140, y = 100, min = 0, max = 200, vals = { 1, 3 }, to = MIDSIZE }, { x = 140, y = 150, min = 0, max = 200, vals = { 7, 8 }, to = MIDSIZE }, { x = 140, y = 200, min = 0, max = 500, vals = {13,14 }, to = MIDSIZE }, - -- I { x = 240, y = 100, min = 0, max = 200, vals = { 3, 4 }, to = MIDSIZE }, { x = 240, y = 150, min = 0, max = 200, vals = { 9,10 }, to = MIDSIZE }, - -- D { x = 340, y = 100, min = 0, max = 200, vals = { 5, 6 }, to = MIDSIZE }, { x = 340, y = 150, min = 0, max = 200, vals = { 11,12 }, to = MIDSIZE }, }, diff --git a/src/SCRIPTS/BF/480x272/pid_advanced.lua b/src/SCRIPTS/BF/480x272/pid_advanced.lua index 1421dfb4..e58a614f 100644 --- a/src/SCRIPTS/BF/480x272/pid_advanced.lua +++ b/src/SCRIPTS/BF/480x272/pid_advanced.lua @@ -1,28 +1,17 @@ return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PID Advanced", - reboot = false, - eepromWrite = true, - minBytes = 46, - outputBytes = 46, yMinLimit = 35, yMaxLimit = 215, text = { { t = "Acro Trainer", x = 5, y = 35 }, { t = "Angle Limit", x = 15, y = 55, to = SMLSIZE }, - { t = "Throttle Boost", x = 5, y = 75 }, { t = "Absolute Control", x = 5, y = 95 }, { t = "I Term Rotation", x = 5, y = 115 }, { t = "VBAT Compensation", x = 5, y = 135 }, - { t = "I Term Relax", x = 5, y = 155 }, { t = "Axes", x = 15, y = 175, to = SMLSIZE }, { t = "Type", x = 15, y = 195, to = SMLSIZE }, - { t = "Integrated Yaw", x = 5, y = 215 }, - { t = "Anti Gravity", x = 5, y = 235 }, { t = "Mode", x = 15, y = 255, to = SMLSIZE }, { t = "Gain", x = 15, y = 275, to = SMLSIZE }, @@ -30,17 +19,13 @@ return { }, fields = { { x = 200, y = 55, min = 20, max = 80, vals = { 32 } }, - { x = 200, y = 75, min = 0, max = 100, vals = { 31 } }, { x = 200, y = 95, min = 0, max = 20, vals = { 30 } }, { x = 200, y = 115, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } }, { x = 200, y = 135, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } }, - { x = 200, y = 175, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (increment only)", "RPY (increment only)" } }, { x = 200, y = 195, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } }, - { x = 200, y = 215, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } }, - { x = 200, y = 255, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } }, { x = 200, y = 275, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 }, { x = 200, y = 295, min = 20, max = 1000, vals = { 20, 21 } }, diff --git a/src/SCRIPTS/BF/480x272/pids1.lua b/src/SCRIPTS/BF/480x272/pids1.lua index 263c2615..6b6f6428 100644 --- a/src/SCRIPTS/BF/480x272/pids1.lua +++ b/src/SCRIPTS/BF/480x272/pids1.lua @@ -1,11 +1,5 @@ return { - read = 112, -- MSP_PID - write = 202, -- MSP_SET_PID - title = "PIDs (1/2)", - reboot = false, - eepromWrite = true, - minBytes = 9, text = { { t = "P", x = 142, y = 48, to = MIDSIZE }, { t = "I", x = 244, y = 48, to = MIDSIZE }, @@ -15,15 +9,12 @@ return { { t = "YAW", x = 28, y = 200 }, }, fields = { - -- P { x = 140, y = 100, min = 0, max = 200, vals = { 1 }, to = MIDSIZE }, { x = 140, y = 150, min = 0, max = 200, vals = { 4 }, to = MIDSIZE }, { x = 140, y = 200, min = 0, max = 200, vals = { 7 }, to = MIDSIZE }, - -- I { x = 240, y = 100, min = 0, max = 200, vals = { 2 }, to = MIDSIZE }, { x = 240, y = 150, min = 0, max = 200, vals = { 5 }, to = MIDSIZE }, { x = 240, y = 200, min = 0, max = 200, vals = { 8 }, to = MIDSIZE }, - -- D { x = 340, y = 100, min = 0, max = 200, vals = { 3 }, to = MIDSIZE }, { x = 340, y = 150, min = 0, max = 200, vals = { 6 }, to = MIDSIZE }, { x = 340, y = 200, min = 0, max = 200, vals = { 9 }, to = MIDSIZE }, diff --git a/src/SCRIPTS/BF/480x272/pids2.lua b/src/SCRIPTS/BF/480x272/pids2.lua index 8d3aaa19..d33bf91f 100644 --- a/src/SCRIPTS/BF/480x272/pids2.lua +++ b/src/SCRIPTS/BF/480x272/pids2.lua @@ -1,11 +1,4 @@ - return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PIDs (2/2)", - reboot = false, - eepromWrite = true, - minBytes = 44, text = { { t = "Feed", x = 97, y = 52 }, { t = "forward", x = 82, y = 70 }, @@ -14,7 +7,6 @@ return { { t = "ROLL", x = 28, y = 100 }, { t = "PITCH", x = 28, y = 150 }, { t = "YAW", x = 28, y = 200 }, - { t = "Feedforward", x = 290, y = 100 }, { t = "Transition", x = 300, y = 120, to = SMLSIZE }, { t = "D Min", x = 290, y = 140 }, @@ -22,23 +14,14 @@ return { { t = "Advance", x = 300, y = 180, to = SMLSIZE }, }, fields = { - -- ROLL FF { x = 102, y = 100, min = 0, max = 2000, vals = { 33, 34 }, to = MIDSIZE }, - -- PITCH FF { x = 102, y = 150, min = 0, max = 2000, vals = { 35, 36 }, to = MIDSIZE }, - -- YAW FF { x = 102, y = 200, min = 0, max = 2000, vals = { 37, 38 }, to = MIDSIZE }, - -- ROLL D MIN { x = 202, y = 100, min = 0, max = 100, vals = { 40 }, to = MIDSIZE }, - -- PITCH D MIN { x = 202, y = 150, min = 0, max = 100, vals = { 41 }, to = MIDSIZE }, - -- YAW D MIN { x = 202, y = 200, min = 0, max = 100, vals = { 42 }, to = MIDSIZE }, - -- FF TRANSITION { x = 390, y = 120, min = 0, max = 100, vals = { 9 }, scale = 100 }, - -- D MIN GAIN { x = 390, y = 160, min = 0, max = 100, vals = { 43 } }, - -- D MIN ADVANCE { x = 390, y = 180, min = 0, max = 200, vals = { 44 } }, }, } diff --git a/src/SCRIPTS/BF/480x272/pwm.lua b/src/SCRIPTS/BF/480x272/pwm.lua index 0b225e56..a6e09e3f 100644 --- a/src/SCRIPTS/BF/480x272/pwm.lua +++ b/src/SCRIPTS/BF/480x272/pwm.lua @@ -1,10 +1,4 @@ return { - read = 90, -- MSP_ADVANCED_CONFIG - write = 91, -- MSP_SET_ADVANCED_CONFIG - reboot = true, - eepromWrite = true, - title = "PWM", - minBytes = 9, text= { { t = "Protocol", x = 36, y = 68 }, { t = "32K", x = 36, y = 110 }, @@ -21,46 +15,11 @@ return { "DSHOT150", "DSHOT300", "DSHOT600","DSHOT1200", "PROSHOT1000" } }, - { x = 130, y = 110, vals = { 9 }, min = 0, max = 1, to = MIDSIZE, - table = { [0] = "OFF", "ON" }, - upd = function(self) self.updateRateTables(self) end - }, - { x = 130, y = 155, vals = { 1 }, min = 1, max = 32, to = MIDSIZE, - upd = function(self) self.updatePidRateTable(self) end - }, + { x = 130, y = 110, vals = { 9 }, min = 0, max = 1, to = MIDSIZE, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, + { x = 130, y = 155, vals = { 1 }, min = 1, max = 32, to = MIDSIZE, upd = function(self) self.updatePidRateTable(self) end }, { x = 130, y = 200, vals = { 2 }, min = 1, max = 16, to = MIDSIZE }, - { x = 350, y = 110, vals = { 3 }, min = 0, max = 1, to = MIDSIZE, - table = { [0] = "OFF", "ON" } }, + { x = 350, y = 110, vals = { 3 }, min = 0, max = 1, to = MIDSIZE, table = { [0] = "OFF", "ON" } }, { x = 350, y = 155, vals = { 5, 6 }, min = 200, max = 32000, to = MIDSIZE }, { x = 350, y = 200, vals = { 7, 8 }, min = 0, max = 2000, scale = 100, to = MIDSIZE }, }, - calculateGyroRates = function(self, baseRate) - self.gyroRates = {} - self.fields[2].table = {} - for i=1, 32 do - self.gyroRates[i] = baseRate/i - local fmt = nil - self.fields[2].table[i] = string.format("%.2f",baseRate/i) - end - end, - calculatePidRates = function(self, baseRate) - self.fields[3].table = {} - for i=1, 16 do - self.fields[3].table[i] = string.format("%.2f",baseRate/i) - end - end, - updateRateTables = function(self) - if self.values[9] == 0 then - self.calculateGyroRates(self, 8) - self.calculatePidRates(self, 8) - elseif self.values[9] == 1 then - self.calculateGyroRates(self, 32) - self.calculatePidRates(self, 32) - end - end, - updatePidRateTable = function(self) - local newRateIdx = self.values[1] - local newRate = self.gyroRates[newRateIdx] - self.calculatePidRates(self, newRate) - end } diff --git a/src/SCRIPTS/BF/480x272/rates.lua b/src/SCRIPTS/BF/480x272/rates.lua index 0cb196b6..abb8b7b8 100644 --- a/src/SCRIPTS/BF/480x272/rates.lua +++ b/src/SCRIPTS/BF/480x272/rates.lua @@ -1,10 +1,4 @@ return { - read = 111, -- MSP_RC_TUNING - write = 204, -- MSP_SET_RC_TUNING - title = "Rates", - reboot = false, - eepromWrite = true, - minBytes = 16, text = { { t = "RC", x = 100, y = 52 }, { t = "Rate", x = 94, y = 70 }, @@ -15,7 +9,6 @@ return { { t = "ROLL", x = 28, y = 100 }, { t = "PITCH", x = 28, y = 150 }, { t = "YAW", x = 28, y = 200 }, - { t = "Throttle", x = 290, y = 60 }, { t = "Mid", x = 300, y = 80, to = SMLSIZE }, { t = "Expo", x = 300, y = 100, to = SMLSIZE }, @@ -26,24 +19,19 @@ return { { t = "Breakpoint", x = 300, y = 200, to = SMLSIZE }, }, fields = { - -- RC Rates { x = 102, y = 100, vals = { 1 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, { x = 102, y = 150, vals = { 13 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, { x = 102, y = 200, vals = { 12 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - -- Super Rates { x = 158, y = 100, vals = { 3 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, { x = 158, y = 150, vals = { 4 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, { x = 158, y = 200, vals = { 5 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - -- RC Expo { x = 216, y = 100, vals = { 2 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, { x = 216, y = 150, vals = { 14 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, { x = 216, y = 200, vals = { 11 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - -- Throttle { x = 390, y = 80, vals = { 7 }, min = 0, max = 100, scale = 100 }, { x = 390, y = 100, vals = { 8 }, min = 0, max = 100, scale = 100 }, { x = 390, y = 120, vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, { x = 390, y = 140, vals = { 16 }, min = 25, max = 100 }, - -- TPA { x = 390, y = 180, vals = { 6 }, min = 0, max = 100, scale = 100 }, { x = 390, y = 200, vals = { 9, 10 }, min = 1000, max = 2000 }, }, diff --git a/src/SCRIPTS/BF/480x272/rescue.lua b/src/SCRIPTS/BF/480x272/rescue.lua index 48595a0f..4360ea53 100644 --- a/src/SCRIPTS/BF/480x272/rescue.lua +++ b/src/SCRIPTS/BF/480x272/rescue.lua @@ -1,18 +1,10 @@ return { - read = 135, -- MSP_GPS_RESCUE - write = 225, -- MSP_SET_GPS_RESCUE - title = "GPS Rescue", - reboot = false, - eepromWrite = true, - minBytes = 16, - requiredVersion = 1.041, text = { { t = "Min Sats.", x =130, y = 40, to = MIDSIZE }, { t = "Angle", x =150, y = 80, to = MIDSIZE }, { t = "Initial Altitude", x = 60, y = 120, to = MIDSIZE }, { t = "Descent Distance", x = 10, y = 160, to = MIDSIZE }, { t = "Ground Speed", x = 50, y = 200, to = MIDSIZE }, - { t = "Snty.", x = 310, y = 40, to = MIDSIZE }, { t = "Throttle", x = 350, y = 80, to = MIDSIZE }, { t = "Min", x = 330, y = 120, to = MIDSIZE }, @@ -25,12 +17,9 @@ return { { x = 260, y = 120, min = 20, max = 100, vals = { 3,4 }, to = MIDSIZE }, { x = 260, y = 160, min = 30, max = 500, vals = { 5,6 }, to = MIDSIZE }, { x = 260, y = 200, min = 30, max =3000, vals = { 7,8 }, to = MIDSIZE }, - - { x = 400, y = 40, min = 0, max = 2 , vals = { 15 }, to = MIDSIZE,table = { [0]="OFF","ON","FS_ONLY"}}, { x = 400, y = 120, min = 1000, max = 2000, vals = { 9,10 }, to = MIDSIZE }, { x = 400, y = 160, min = 1000, max = 2000, vals = { 13,14 }, to = MIDSIZE }, { x = 400, y = 200, min = 1000, max = 2000, vals = { 11,12 }, to = MIDSIZE }, - }, } diff --git a/src/SCRIPTS/BF/480x272/rx.lua b/src/SCRIPTS/BF/480x272/rx.lua index d245d514..6c76ce48 100644 --- a/src/SCRIPTS/BF/480x272/rx.lua +++ b/src/SCRIPTS/BF/480x272/rx.lua @@ -1,10 +1,4 @@ return { - read = 44, -- MSP_RX_CONFIG - write = 45, -- MSP_SET_RX_CONFIG - title = "RX", - reboot = false, - eepromWrite = true, - minBytes = 23, text= { { t = "Stick Min", x = 36, y = 68 }, { t = "Stick Mid", x = 36, y = 110 }, @@ -18,8 +12,7 @@ return { { x = 130, y = 110, min = 1000, max = 2000, vals = { 4, 5 }, to = MIDSIZE }, { x = 130, y = 155, min = 1000, max = 2000, vals = { 2, 3 }, to = MIDSIZE }, { x = 350, y = 68, min = 0, max = 90, vals = { 23 }, to = MIDSIZE }, - { x = 350, y = 110, min = 0, max = 3, vals = { 13 }, to = MIDSIZE, - table={ [0]="Off", "Preset", "Auto", "Manual"} }, + { x = 350, y = 110, min = 0, max = 3, vals = { 13 }, to = MIDSIZE, table={ [0]="Off", "Preset", "Auto", "Manual"} }, { x = 350, y = 155, min = 1, max = 50, vals = { 14 }, to = MIDSIZE } }, } diff --git a/src/SCRIPTS/BF/480x272/vtx.lua b/src/SCRIPTS/BF/480x272/vtx.lua index 73878548..ee3147cf 100644 --- a/src/SCRIPTS/BF/480x272/vtx.lua +++ b/src/SCRIPTS/BF/480x272/vtx.lua @@ -1,16 +1,4 @@ - return { - read = 88, -- MSP_VTX_CONFIG - write = 89, -- MSP_VTX_SET_CONFIG - eepromWrite = true, - reboot = false, - title = "VTX", - minBytes = 5, - prevBandVal = 0, - prevChanVal = 0, - prevFreqVal = 0, - lastFreqUpdTS = 0, - freqModCounter = 0, text= { { t = "Band", x = 36, y = 110 }, { t = "Channel", x = 36, y = 155 }, @@ -20,250 +8,11 @@ return { { t = "Freq", x = 232, y = 68 }, }, fields = { - -- Band - { x = 130, y = 110, min=0, max=5, vals = { 2 }, to = MIDSIZE, - table = { [0]="U", "A", "B", "E", "F", "R" }, - upd = function(self) self.handleBandChanUpdate(self) end }, - -- Channel - { x = 130, y = 155, min=1, max=8, vals = { 3 }, to = MIDSIZE, - upd = function(self) self.handleBandChanUpdate(self) end }, - -- Power - { x = 350, y = 110, min=1, vals = { 4 }, to = MIDSIZE, - upd = function(self) self.updatePowerTable(self) end }, - -- Pit mode - { x = 350, y = 155, min=0, max=1, vals = { 5 }, to = MIDSIZE, - table = { [0]="OFF", "ON" } }, - -- Proto - { x = 130, y = 68, vals = { 1 }, to = MIDSIZE, - write = false, ro = true, - table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, - -- Freq - { x = 350, y = 68, min = 5000, max = 5999, vals = { 6 }, to = MIDSIZE, - upd = function(self) self.handleFreqValUpdate(self) end }, + { x = 130, y = 110, min=0, max=5, vals = { 2 }, to = MIDSIZE, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, + { x = 130, y = 155, min=1, max=8, vals = { 3 }, to = MIDSIZE, upd = function(self) self.handleBandChanUpdate(self) end }, + { x = 350, y = 110, min=1, vals = { 4 }, to = MIDSIZE, upd = function(self) self.updatePowerTable(self) end }, + { x = 350, y = 155, min=0, max=1, vals = { 5 }, to = MIDSIZE, table = { [0]="OFF", "ON" } }, + { x = 130, y = 68, vals = { 1 }, to = MIDSIZE, write = false, ro = true, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, + { x = 350, y = 68, min = 5000, max = 5999, vals = { 6 }, to = MIDSIZE, upd = function(self) self.handleFreqValUpdate(self) end }, }, - freqLookup = { - { 5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725 }, -- Boscam A - { 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 }, -- Boscam B - { 5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945 }, -- Boscam E - { 5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880 }, -- FatShark - { 5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 }, -- RaceBand - }, - postLoad = function (self) - if (self.values[2] or 0) < 0 or (self.values[3] or 0) == 0 or (self.values[4] or 0) == 0 then - self.values = {} - else - self.prevBandVal = 0 -- reset value trackers - self.prevChanVal = 0 - self.prevFreqVal = 0 - local rFreq - if (self.values[7] or 0) > 0 then - rFreq = math.floor(self.values[6] + (self.values[7] * 256)) - else - rFreq = 0 - end - if (self.values[2] or 0) > 0 then -- band != 0 - if rFreq > 0 then - self.prevFreqVal = rFreq - self.prevBandVal = self.values[2] - self.prevChanVal = self.values[3] - self.fields[1].min = 0 -- make sure 'U' band allowed - self.eepromWrite = true - self.fields[6].value = rFreq - self.values[6] = rFreq - else -- if user freq not supported then - self.fields[1].min = 1 -- don't allow 'U' band - self.eepromWrite = false -- don't write EEPROM on older Betaflight versions - end - else -- band == 0 - if rFreq > 0 then - self.prevFreqVal = rFreq - self.fields[1].min = 0 -- make sure 'U' band allowed - self.eepromWrite = true - self.fields[6].value = rFreq - self.values[6] = rFreq - -- set chan via freq / 100 - self.prevChanVal = clipValue(math.floor((rFreq - 5100) / 100), - self.fields[2].min, self.fields[2].max) - self.fields[2].value = self.prevChanVal - self.values[3] = self.prevChanVal - else - self.values = {} - end - end - end - end, - preSave = function(self) - local valsTemp = {} - if self.values then - local channel - if self.values[2] > 0 then -- band != 0 - channel = (self.values[2]-1)*8 + self.values[3]-1 - elseif self.fields[6].value then -- band == 0 - channel = self.fields[6].value - else - channel = 24 - end - valsTemp[1] = bit32.band(channel,0xFF) - valsTemp[2] = bit32.rshift(channel,8) - valsTemp[3] = self.values[4] - valsTemp[4] = self.values[5] - end - return valsTemp - end, - -- find closest value in freq table that is above/below given freq - findNextInFreqTable = function(self, newFreq) - local startBand - local endBand - local incFlag -- freq increasing or decreasing - if newFreq > self.prevFreqVal then - incFlag = 1 - startBand = 1 - endBand = self.fields[1].max - else - incFlag = -1 - startBand = self.fields[1].max - endBand = 1 - end - local curBand = self.values[2] - local curChan = self.values[3] - local selBand = 0 - local selChan = 0 - local selFreq = 0 - local diffVal = 9999 - local fVal - local minChan = self.fields[2].min - local maxChan = self.fields[2].max - -- need to scan bands in same "direction" as 'incFlag' - -- so same-freq selections will be handled properly (F8 & R7) - for band=startBand,endBand,incFlag do - for chan=minChan,maxChan do - if band ~= curBand or chan ~= curChan then -- don't reselect same band/chan - fVal = self.freqLookup[band][chan] - if incFlag > 0 then - if fVal >= self.prevFreqVal and fVal - self.prevFreqVal < diffVal then - -- if same freq then only select if "next" band: - if fVal ~= self.prevFreqVal or band > curBand then - selBand = band - selChan = chan - selFreq = fVal - diffVal = fVal - self.prevFreqVal - end - end - else - if fVal <= self.prevFreqVal and self.prevFreqVal - fVal < diffVal then - -- if same freq then only select if "previous" band: - if fVal ~= self.prevFreqVal or band < curBand then - selBand = band - selChan = chan - selFreq = fVal - diffVal = self.prevFreqVal - fVal - end - end - end - end - end - end - return selFreq, selBand, selChan - end, - -- returns the next user-frequency value in MHz; implements an - -- "exponential" modification rate so dialing in values is faster - getNextUserFreqValue = function(self, newFreq) - local now = getTime() -- track rate of change for possible mod speedup - if now < self.lastFreqUpdTS + 15 then - self.freqModCounter = self.freqModCounter + (15-(self.lastFreqUpdTS-now)) -- increase counter for mod speedup - else - self.freqModCounter = 0 -- no mod speedup - end - local uFreq - if self.freqModCounter > 65 then -- rate is fast enough; do mod speedup - if newFreq > self.prevFreqVal then - uFreq = clipValue(newFreq + math.floor(self.freqModCounter / 65), - self.fields[6].min, self.fields[6].max) - else - uFreq = clipValue(newFreq - math.floor(self.freqModCounter / 65), - self.fields[6].min, self.fields[6].max) - end - else - uFreq = newFreq - end - self.lastFreqUpdTS = now - return uFreq - end, - updatePowerTable = function(self) - if self.values and not self.fields[3].table then - if self.values[1] == 1 then -- RTC6705 - self.fields[3].table = { 25, 200 } - self.fields[3].max = 2 - self.fields[4].t = nil -- don't display Pit field - self.fields[4].table = { [0]="", "" } - elseif self.values[1] == 3 then -- SmartAudio - self.fields[3].table = { 25, 200, 500, 800 } - self.fields[3].max = 4 - elseif self.values[1] == 4 then -- Tramp - self.fields[3].table = { 25, 100, 200, 400, 600 } - self.fields[3].max = 5 - elseif self.values[1] == 255 then -- None/Unknown - self.fields[3].t = nil -- don't display Power field - self.fields[3].max = 1 - self.fields[3].table = { [1]="" } - self.fields[4].t = nil -- don't display Pit field - self.fields[4].table = { [0]="", "" } - end - end - end, - handleBandChanUpdate = function(self) - if (#(self.values) or 0) >= self.minBytes then - if (self.values[3] or 0) > 0 then - if self.values[2] ~= self.prevBandVal or self.values[3] ~= self.prevChanVal then - if self.values[2] > 0 then -- band != 0 - self.prevFreqVal = self.freqLookup[self.values[2]][self.values[3]] - else -- band == 0; set freq via channel*100 - self.prevFreqVal = math.floor(5100 + (self.values[3] * 100)) - end - self.fields[6].value = self.prevFreqVal - self.values[6] = self.prevFreqVal - self.prevBandVal = self.values[2] - self.prevChanVal = self.values[3] - end - end - end - end, - handleFreqValUpdate = function(self) - if (#(self.values) or 0) >= self.minBytes and (self.fields[6].value or 0) > 0 then - local newFreq = self.fields[6].value - if newFreq ~= self.prevFreqVal then - if self.values[2] == 0 then - -- band == 0 - local uFreq = self.getNextUserFreqValue(self, newFreq) - self.prevFreqVal = uFreq - if uFreq ~= newFreq then - self.fields[6].value = uFreq - self.values[6] = uFreq - end - -- set channel value via freq/100 - self.prevChanVal = clipValue(math.floor((self.prevFreqVal - 5100) / 100), - self.fields[2].min, self.fields[2].max) - self.fields[2].value = self.prevChanVal - self.values[3] = self.prevChanVal - else - -- band != 0; find closest freq in table that is above/below dialed freq - local selFreq, selBand, selChan = self.findNextInFreqTable(self, newFreq) - if selFreq > 0 then - self.prevFreqVal = selFreq - self.prevBandVal = selBand - self.prevChanVal = selChan - self.fields[6].value = selFreq -- using new freq from table - self.values[6] = selFreq - self.fields[1].value = self.prevBandVal -- set band value for freq - self.values[2] = self.prevBandVal - self.fields[2].value = self.prevChanVal -- set channel value for freq - self.values[3] = self.prevChanVal - else - self.fields[6].value = self.prevFreqVal -- if no match then revert freq - self.values[6] = self.prevFreqVal - end - end - end - end - end } \ No newline at end of file From 08eabd9a54b55dbc35822ff65dfa44468f794101 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 16 Oct 2019 16:22:43 +0100 Subject: [PATCH 016/193] move layouts to layout folder --- src/SCRIPTS/BF/{ => LAYOUT}/128x64/filters.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/128x64/gpspids.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/128x64/pid_advanced.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/128x64/pids1.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/128x64/pids2.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/128x64/pwm.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/128x64/rates.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/128x64/rescue.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/128x64/vtx.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/212x64/filters.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/212x64/gpspids.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/212x64/pid_advanced.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/212x64/pids1.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/212x64/pids2.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/212x64/pwm.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/212x64/rates.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/212x64/rescue.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/212x64/rx.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/212x64/vtx.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/320x480/filters.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/320x480/gpspids.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/320x480/pid_advanced.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/320x480/pids1.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/320x480/pids2.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/320x480/pwm.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/320x480/rates.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/320x480/rescue.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/320x480/rx.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/320x480/vtx.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/480x272/filters.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/480x272/gpspids.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/480x272/pid_advanced.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/480x272/pids1.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/480x272/pids2.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/480x272/pwm.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/480x272/rates.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/480x272/rescue.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/480x272/rx.lua | 0 src/SCRIPTS/BF/{ => LAYOUT}/480x272/vtx.lua | 0 src/SCRIPTS/BF/radios.lua | 8 ++++---- 40 files changed, 4 insertions(+), 4 deletions(-) rename src/SCRIPTS/BF/{ => LAYOUT}/128x64/filters.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/128x64/gpspids.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/128x64/pid_advanced.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/128x64/pids1.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/128x64/pids2.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/128x64/pwm.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/128x64/rates.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/128x64/rescue.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/128x64/vtx.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/212x64/filters.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/212x64/gpspids.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/212x64/pid_advanced.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/212x64/pids1.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/212x64/pids2.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/212x64/pwm.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/212x64/rates.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/212x64/rescue.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/212x64/rx.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/212x64/vtx.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/320x480/filters.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/320x480/gpspids.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/320x480/pid_advanced.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/320x480/pids1.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/320x480/pids2.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/320x480/pwm.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/320x480/rates.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/320x480/rescue.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/320x480/rx.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/320x480/vtx.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/480x272/filters.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/480x272/gpspids.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/480x272/pid_advanced.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/480x272/pids1.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/480x272/pids2.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/480x272/pwm.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/480x272/rates.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/480x272/rescue.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/480x272/rx.lua (100%) rename src/SCRIPTS/BF/{ => LAYOUT}/480x272/vtx.lua (100%) diff --git a/src/SCRIPTS/BF/128x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua similarity index 100% rename from src/SCRIPTS/BF/128x64/filters.lua rename to src/SCRIPTS/BF/LAYOUT/128x64/filters.lua diff --git a/src/SCRIPTS/BF/128x64/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua similarity index 100% rename from src/SCRIPTS/BF/128x64/gpspids.lua rename to src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua diff --git a/src/SCRIPTS/BF/128x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua similarity index 100% rename from src/SCRIPTS/BF/128x64/pid_advanced.lua rename to src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua diff --git a/src/SCRIPTS/BF/128x64/pids1.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua similarity index 100% rename from src/SCRIPTS/BF/128x64/pids1.lua rename to src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua diff --git a/src/SCRIPTS/BF/128x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua similarity index 100% rename from src/SCRIPTS/BF/128x64/pids2.lua rename to src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua diff --git a/src/SCRIPTS/BF/128x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua similarity index 100% rename from src/SCRIPTS/BF/128x64/pwm.lua rename to src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua diff --git a/src/SCRIPTS/BF/128x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua similarity index 100% rename from src/SCRIPTS/BF/128x64/rates.lua rename to src/SCRIPTS/BF/LAYOUT/128x64/rates.lua diff --git a/src/SCRIPTS/BF/128x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua similarity index 100% rename from src/SCRIPTS/BF/128x64/rescue.lua rename to src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua diff --git a/src/SCRIPTS/BF/128x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua similarity index 100% rename from src/SCRIPTS/BF/128x64/vtx.lua rename to src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua diff --git a/src/SCRIPTS/BF/212x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua similarity index 100% rename from src/SCRIPTS/BF/212x64/filters.lua rename to src/SCRIPTS/BF/LAYOUT/212x64/filters.lua diff --git a/src/SCRIPTS/BF/212x64/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua similarity index 100% rename from src/SCRIPTS/BF/212x64/gpspids.lua rename to src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua diff --git a/src/SCRIPTS/BF/212x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua similarity index 100% rename from src/SCRIPTS/BF/212x64/pid_advanced.lua rename to src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua diff --git a/src/SCRIPTS/BF/212x64/pids1.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua similarity index 100% rename from src/SCRIPTS/BF/212x64/pids1.lua rename to src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua diff --git a/src/SCRIPTS/BF/212x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua similarity index 100% rename from src/SCRIPTS/BF/212x64/pids2.lua rename to src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua diff --git a/src/SCRIPTS/BF/212x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua similarity index 100% rename from src/SCRIPTS/BF/212x64/pwm.lua rename to src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua diff --git a/src/SCRIPTS/BF/212x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua similarity index 100% rename from src/SCRIPTS/BF/212x64/rates.lua rename to src/SCRIPTS/BF/LAYOUT/212x64/rates.lua diff --git a/src/SCRIPTS/BF/212x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua similarity index 100% rename from src/SCRIPTS/BF/212x64/rescue.lua rename to src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua diff --git a/src/SCRIPTS/BF/212x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua similarity index 100% rename from src/SCRIPTS/BF/212x64/rx.lua rename to src/SCRIPTS/BF/LAYOUT/212x64/rx.lua diff --git a/src/SCRIPTS/BF/212x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua similarity index 100% rename from src/SCRIPTS/BF/212x64/vtx.lua rename to src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua diff --git a/src/SCRIPTS/BF/320x480/filters.lua b/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua similarity index 100% rename from src/SCRIPTS/BF/320x480/filters.lua rename to src/SCRIPTS/BF/LAYOUT/320x480/filters.lua diff --git a/src/SCRIPTS/BF/320x480/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua similarity index 100% rename from src/SCRIPTS/BF/320x480/gpspids.lua rename to src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua diff --git a/src/SCRIPTS/BF/320x480/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua similarity index 100% rename from src/SCRIPTS/BF/320x480/pid_advanced.lua rename to src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua diff --git a/src/SCRIPTS/BF/320x480/pids1.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua similarity index 100% rename from src/SCRIPTS/BF/320x480/pids1.lua rename to src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua diff --git a/src/SCRIPTS/BF/320x480/pids2.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua similarity index 100% rename from src/SCRIPTS/BF/320x480/pids2.lua rename to src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua diff --git a/src/SCRIPTS/BF/320x480/pwm.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua similarity index 100% rename from src/SCRIPTS/BF/320x480/pwm.lua rename to src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua diff --git a/src/SCRIPTS/BF/320x480/rates.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua similarity index 100% rename from src/SCRIPTS/BF/320x480/rates.lua rename to src/SCRIPTS/BF/LAYOUT/320x480/rates.lua diff --git a/src/SCRIPTS/BF/320x480/rescue.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua similarity index 100% rename from src/SCRIPTS/BF/320x480/rescue.lua rename to src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua diff --git a/src/SCRIPTS/BF/320x480/rx.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua similarity index 100% rename from src/SCRIPTS/BF/320x480/rx.lua rename to src/SCRIPTS/BF/LAYOUT/320x480/rx.lua diff --git a/src/SCRIPTS/BF/320x480/vtx.lua b/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua similarity index 100% rename from src/SCRIPTS/BF/320x480/vtx.lua rename to src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua diff --git a/src/SCRIPTS/BF/480x272/filters.lua b/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua similarity index 100% rename from src/SCRIPTS/BF/480x272/filters.lua rename to src/SCRIPTS/BF/LAYOUT/480x272/filters.lua diff --git a/src/SCRIPTS/BF/480x272/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua similarity index 100% rename from src/SCRIPTS/BF/480x272/gpspids.lua rename to src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua diff --git a/src/SCRIPTS/BF/480x272/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua similarity index 100% rename from src/SCRIPTS/BF/480x272/pid_advanced.lua rename to src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua diff --git a/src/SCRIPTS/BF/480x272/pids1.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua similarity index 100% rename from src/SCRIPTS/BF/480x272/pids1.lua rename to src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua diff --git a/src/SCRIPTS/BF/480x272/pids2.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua similarity index 100% rename from src/SCRIPTS/BF/480x272/pids2.lua rename to src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua diff --git a/src/SCRIPTS/BF/480x272/pwm.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua similarity index 100% rename from src/SCRIPTS/BF/480x272/pwm.lua rename to src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua diff --git a/src/SCRIPTS/BF/480x272/rates.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua similarity index 100% rename from src/SCRIPTS/BF/480x272/rates.lua rename to src/SCRIPTS/BF/LAYOUT/480x272/rates.lua diff --git a/src/SCRIPTS/BF/480x272/rescue.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua similarity index 100% rename from src/SCRIPTS/BF/480x272/rescue.lua rename to src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua diff --git a/src/SCRIPTS/BF/480x272/rx.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua similarity index 100% rename from src/SCRIPTS/BF/480x272/rx.lua rename to src/SCRIPTS/BF/LAYOUT/480x272/rx.lua diff --git a/src/SCRIPTS/BF/480x272/vtx.lua b/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua similarity index 100% rename from src/SCRIPTS/BF/480x272/vtx.lua rename to src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index bfbe27bb..ec025e46 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -8,7 +8,7 @@ local supportedRadios = { ["128x64"] = { - templateHome = SCRIPT_HOME.."/128x64/", + templateHome = SCRIPT_HOME.."/LAYOUT/128x64/", resolution = lcdResolution.low, MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, @@ -16,7 +16,7 @@ local supportedRadios = }, ["212x64"] = { - templateHome = SCRIPT_HOME.."/212x64/", + templateHome = SCRIPT_HOME.."/LAYOUT/212x64/", resolution = lcdResolution.low, MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 }, SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, @@ -24,7 +24,7 @@ local supportedRadios = }, ["480x272"] = { - templateHome = SCRIPT_HOME.."/480x272/", + templateHome = SCRIPT_HOME.."/LAYOUT/480x272/", resolution = lcdResolution.high, MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, @@ -32,7 +32,7 @@ local supportedRadios = }, ["320x480"] = { - templateHome = SCRIPT_HOME.."/320x480/", + templateHome = SCRIPT_HOME.."/LAYOUT/320x480/", resolution = lcdResolution.high, MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, From 08bba446485ad599b2655ad4cab7454470b3726a Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 16 Oct 2019 16:24:22 +0100 Subject: [PATCH 017/193] add rx.lua for 128x64 screens --- src/SCRIPTS/BF/LAYOUT/128x64/rx.lua | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/SCRIPTS/BF/LAYOUT/128x64/rx.lua diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua new file mode 100644 index 00000000..0f3baf4b --- /dev/null +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua @@ -0,0 +1,13 @@ +return { + yMinLimit = 12, + yMaxLimit = 52, + text = {}, + fields = { + { t = "Stick Min", x = 10, y = 20, sp = 45, min = 1000, max = 2000, vals = { 6, 7 }, to = SMLSIZE }, + { t = "Stick Mid", x = 10, y = 30, sp = 45, min = 1000, max = 2000, vals = { 4, 5 }, to = SMLSIZE }, + { t = "Stick Max", x = 10, y = 40, sp = 45, min = 1000, max = 2000, vals = { 2, 3 }, to = SMLSIZE }, + { t = "Cam Angle", x = 10, y = 50, sp = 50, min = 0, max = 90, vals = { 23 }, to = SMLSIZE }, + { t = "Interp", x = 10, y = 60, sp = 50, min = 0, max = 3, vals = { 13 }, to = SMLSIZE, table={ [0]="Off", "Preset", "Auto", "Manual"} }, + { t = "Interp Int", x = 10, y = 70, sp = 50, min = 1, max = 50, vals = { 14 }, to = SMLSIZE }, + }, + } \ No newline at end of file From 7fcf0ec7a7aa07cbe0d230189a382f02202dff60 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 16 Oct 2019 17:03:51 +0100 Subject: [PATCH 018/193] refactor text_size up to radio level variable --- src/SCRIPTS/BF/LAYOUT/128x64/filters.lua | 114 ++++++++---------- src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua | 26 ++-- src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua | 28 ++--- src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua | 30 ++--- src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua | 43 ++++--- src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua | 28 ++--- src/SCRIPTS/BF/LAYOUT/128x64/rates.lua | 64 +++++----- src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua | 38 +++--- src/SCRIPTS/BF/LAYOUT/128x64/rx.lua | 12 +- src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua | 12 +- src/SCRIPTS/BF/LAYOUT/212x64/filters.lua | 104 ++++++++-------- src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua | 26 ++-- src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua | 28 ++--- src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua | 30 ++--- src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua | 42 +++---- src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua | 28 ++--- src/SCRIPTS/BF/LAYOUT/212x64/rates.lua | 64 +++++----- src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua | 38 +++--- src/SCRIPTS/BF/LAYOUT/212x64/rx.lua | 12 +- src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua | 12 +- src/SCRIPTS/BF/LAYOUT/320x480/filters.lua | 62 +++++----- src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua | 26 ++-- .../BF/LAYOUT/320x480/pid_advanced.lua | 28 ++--- src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua | 30 ++--- src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua | 36 +++--- src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua | 14 +-- src/SCRIPTS/BF/LAYOUT/320x480/rates.lua | 56 ++++----- src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua | 6 +- src/SCRIPTS/BF/LAYOUT/320x480/rx.lua | 24 ++-- src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua | 12 +- src/SCRIPTS/BF/LAYOUT/480x272/filters.lua | 60 ++++----- src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua | 26 ++-- .../BF/LAYOUT/480x272/pid_advanced.lua | 28 ++--- src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua | 30 ++--- src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua | 12 +- src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua | 19 ++- src/SCRIPTS/BF/LAYOUT/480x272/rates.lua | 56 ++++----- src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua | 38 +++--- src/SCRIPTS/BF/LAYOUT/480x272/rx.lua | 12 +- src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua | 12 +- src/SCRIPTS/BF/radios.lua | 4 + src/SCRIPTS/BF/ui.lua | 4 +- 42 files changed, 682 insertions(+), 692 deletions(-) diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua index 0d60bbb1..074045ff 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua @@ -2,69 +2,59 @@ return { yMinLimit = 12, yMaxLimit = 52, text= { - { t = "Gyro Lowpass 1 Dynamic", x = 2, y = 12, to = SMLSIZE }, - { t = "Min Cutoff", x = 12, y = 20, to = SMLSIZE }, - { t = "Max Cutoff", x = 12, y = 28, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 36, to = SMLSIZE }, - { t = "Gyro Lowpass 1", x = 2, y = 44, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 52, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 60, to = SMLSIZE }, - { t = "Gyro Lowpass 2", x = 2, y = 68, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 76, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 84, to = SMLSIZE }, - { t = "Gyro Notch 1", x = 2, y = 92, to = SMLSIZE }, - { t = "Center", x = 12, y = 100, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 108, to = SMLSIZE }, - { t = "Gyro Notch 2", x = 2, y = 116, to = SMLSIZE }, - { t = "Center", x = 12, y = 124, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 132, to = SMLSIZE }, - { t = "D Term Lowpass 1 Dynamic", x = 2, y = 140, to = SMLSIZE }, - { t = "Min Cutoff", x = 12, y = 148, to = SMLSIZE }, - { t = "Max Cutoff", x = 12, y = 156, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 164, to = SMLSIZE }, - { t = "D Term Lowpass 1", x = 2, y = 172, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 180, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 188, to = SMLSIZE }, - { t = "D Term Lowpass 2", x = 2, y = 196, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 204, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 212, to = SMLSIZE }, - { t = "D Term Notch", x = 2, y = 220, to = SMLSIZE }, - { t = "Center", x = 12, y = 228, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 236, to = SMLSIZE }, - { t = "Yaw Lowpass", x = 2, y = 244, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 252, to = SMLSIZE }, + { t = "Gyro Lowpass 1 Dynamic", x = 2, y = 12, }, + { t = "Min Cutoff", x = 12, y = 20, }, + { t = "Max Cutoff", x = 12, y = 28, }, + { t = "Filter Type", x = 12, y = 36, }, + { t = "Gyro Lowpass 1", x = 2, y = 44, }, + { t = "Cutoff", x = 12, y = 52, }, + { t = "Filter Type", x = 12, y = 60, }, + { t = "Gyro Lowpass 2", x = 2, y = 68, }, + { t = "Cutoff", x = 12, y = 76, }, + { t = "Filter Type", x = 12, y = 84, }, + { t = "Gyro Notch 1", x = 2, y = 92, }, + { t = "Center", x = 12, y = 100, }, + { t = "Cutoff", x = 12, y = 108, }, + { t = "Gyro Notch 2", x = 2, y = 116, }, + { t = "Center", x = 12, y = 124, }, + { t = "Cutoff", x = 12, y = 132, }, + { t = "D Term Lowpass 1 Dynamic", x = 2, y = 140, }, + { t = "Min Cutoff", x = 12, y = 148, }, + { t = "Max Cutoff", x = 12, y = 156, }, + { t = "Filter Type", x = 12, y = 164, }, + { t = "D Term Lowpass 1", x = 2, y = 172, }, + { t = "Cutoff", x = 12, y = 180, }, + { t = "Filter Type", x = 12, y = 188, }, + { t = "D Term Lowpass 2", x = 2, y = 196, }, + { t = "Cutoff", x = 12, y = 204, }, + { t = "Filter Type", x = 12, y = 212, }, + { t = "D Term Notch", x = 2, y = 220, }, + { t = "Center", x = 12, y = 228, }, + { t = "Cutoff", x = 12, y = 236, }, + { t = "Yaw Lowpass", x = 2, y = 244, }, + { t = "Cutoff", x = 12, y = 252, }, }, fields = { - -- Gyro Lowpass 1 Dynamic - { x = 87, y = 20, min = 0, max = 1000, to = SMLSIZE, vals = { 30, 31 } }, - { x = 87, y = 28, min = 0, max = 1000, to = SMLSIZE, vals = { 32, 33 } }, - { x = 87, y = 36, min = 0, max = 1, to = SMLSIZE, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- Gyro Lowpass 1 - { x = 87, y = 52, min = 0, max = 16000, to = SMLSIZE, vals = { 21, 22 } }, - { x = 87, y = 60, min = 0, max = 1, to = SMLSIZE, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- Gyro Lowpass 2 - { x = 87, y = 76, min = 0, max = 16000, to = SMLSIZE, vals = { 23, 24 } }, - { x = 87, y = 84, min = 0, max = 1, to = SMLSIZE, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- Gyro Notch 1 - { x = 87, y = 100, min = 0, max = 16000, to = SMLSIZE, vals = { 6, 7 } }, - { x = 87, y = 108, min = 0, max = 16000, to = SMLSIZE, vals = { 8, 9 } }, - -- Gyro Notch 2 - { x = 87, y = 124, min = 0, max = 16000, to = SMLSIZE, vals = { 14, 15 } }, - { x = 87, y = 132, min = 0, max = 16000, to = SMLSIZE, vals = { 16, 17 } }, - -- D Term Lowpass 1 Dynamic - { x = 87, y = 148, min = 0, max = 1000, to = SMLSIZE, vals = { 34, 35 } }, - { x = 87, y = 156, min = 0, max = 1000, to = SMLSIZE, vals = { 36, 37 } }, - { x = 87, y = 164, min = 0, max = 1, to = SMLSIZE, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- D Term Lowpass 1 - { x = 87, y = 180, min = 0, max = 16000, to = SMLSIZE, vals = { 2, 3 } }, - { x = 87, y = 188, min = 0, max = 1, to = SMLSIZE, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- D Term Lowpass 2 - { x = 87, y = 204, min = 0, max = 16000, to = SMLSIZE, vals = { 27, 28 } }, - { x = 87, y = 212, min = 0, max = 1, to = SMLSIZE, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - -- D Term Notch - { x = 87, y = 228, min = 0, max = 16000, to = SMLSIZE, vals = { 10, 11 } }, - { x = 87, y = 236, min = 0, max = 16000, to = SMLSIZE, vals = { 12, 13 } }, - -- Yaw Lowpass - { x = 87, y = 252, min = 0, max = 500, to = SMLSIZE, vals = { 4, 5 } }, + { x = 87, y = 20, min = 0, max = 1000, vals = { 30, 31 } }, + { x = 87, y = 28, min = 0, max = 1000, vals = { 32, 33 } }, + { x = 87, y = 36, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 52, min = 0, max = 16000, vals = { 21, 22 } }, + { x = 87, y = 60, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 76, min = 0, max = 16000, vals = { 23, 24 } }, + { x = 87, y = 84, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 100, min = 0, max = 16000, vals = { 6, 7 } }, + { x = 87, y = 108, min = 0, max = 16000, vals = { 8, 9 } }, + { x = 87, y = 124, min = 0, max = 16000, vals = { 14, 15 } }, + { x = 87, y = 132, min = 0, max = 16000, vals = { 16, 17 } }, + { x = 87, y = 148, min = 0, max = 1000, vals = { 34, 35 } }, + { x = 87, y = 156, min = 0, max = 1000, vals = { 36, 37 } }, + { x = 87, y = 164, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 180, min = 0, max = 16000, vals = { 2, 3 } }, + { x = 87, y = 188, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 204, min = 0, max = 16000, vals = { 27, 28 } }, + { x = 87, y = 212, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 228, min = 0, max = 16000, vals = { 10, 11 } }, + { x = 87, y = 236, min = 0, max = 16000, vals = { 12, 13 } }, + { x = 87, y = 252, min = 0, max = 500, vals = { 4, 5 } }, } } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua index 2cbbcf78..4cb3cdbd 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua @@ -1,19 +1,19 @@ return { text = { - { t = "P", x = 55, y = 14, to=SMLSIZE }, - { t = "I", x = 83, y = 14, to=SMLSIZE }, - { t = "D", x = 111, y = 14, to=SMLSIZE }, - { t = "Throttle", x = 5, y = 26, to=SMLSIZE }, - { t = "Velocity", x = 5, y = 36, to=SMLSIZE }, - { t = "Yaw" , x = 5, y = 46, to=SMLSIZE }, + { t = "P", x = 55, y = 14, }, + { t = "I", x = 83, y = 14, }, + { t = "D", x = 111, y = 14, }, + { t = "Throttle", x = 5, y = 26, }, + { t = "Velocity", x = 5, y = 36, }, + { t = "Yaw" , x = 5, y = 46, }, }, fields = { - { x = 51, y = 26, min = 0, max = 200, vals = { 1,2 }, to=SMLSIZE }, - { x = 51, y = 36, min = 0, max = 200, vals = { 7,8 }, to=SMLSIZE }, - { x = 51, y = 46, min = 0, max = 500, vals = {13,14}, to = SMLSIZE }, - { x = 79, y = 26, min = 0, max = 200, vals = { 3,4 }, to=SMLSIZE }, - { x = 79, y = 36, min = 0, max = 200, vals = { 9,10 }, to=SMLSIZE }, - { x = 107, y = 26, min = 0, max = 200, vals = { 5,6 }, to=SMLSIZE }, - { x = 107, y = 36, min = 0, max = 200, vals = { 11,12 }, to=SMLSIZE }, + { x = 51, y = 26, min = 0, max = 200, vals = { 1,2 }, }, + { x = 51, y = 36, min = 0, max = 200, vals = { 7,8 }, }, + { x = 51, y = 46, min = 0, max = 500, vals = { 13,14 }, }, + { x = 79, y = 26, min = 0, max = 200, vals = { 3,4 }, }, + { x = 79, y = 36, min = 0, max = 200, vals = { 9,10 }, }, + { x = 107, y = 26, min = 0, max = 200, vals = { 5,6 }, }, + { x = 107, y = 36, min = 0, max = 200, vals = { 11,12 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua index 103419dd..79b55498 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua @@ -2,20 +2,20 @@ return { yMinLimit = 12, yMaxLimit = 52, text = { - { t = "Acro Trainer", x = 2, y = 12, to = SMLSIZE }, - { t = "Angle Limit", x = 12, y = 20, to = SMLSIZE }, - { t = "Throttle Boost", x = 2, y = 28, to = SMLSIZE }, - { t = "Absolute Control", x = 2, y = 36, to = SMLSIZE }, - { t = "I Term Rotation", x = 2, y = 44, to = SMLSIZE }, - { t = "VBAT Compensation", x = 2, y = 52, to = SMLSIZE }, - { t = "I Term Relax", x = 2, y = 60, to = SMLSIZE }, - { t = "Axes", x = 12, y = 68, to = SMLSIZE }, - { t = "Type", x = 12, y = 76, to = SMLSIZE }, - { t = "Integrated Yaw", x = 2, y = 84, to = SMLSIZE }, - { t = "Anti Gravity", x = 2, y = 92, to = SMLSIZE }, - { t = "Mode", x = 12, y = 100, to = SMLSIZE }, - { t = "Gain", x = 12, y = 108, to = SMLSIZE }, - { t = "Threshold", x = 12, y = 116, to = SMLSIZE }, + { t = "Acro Trainer", x = 2, y = 12, }, + { t = "Angle Limit", x = 12, y = 20, }, + { t = "Throttle Boost", x = 2, y = 28, }, + { t = "Absolute Control", x = 2, y = 36, }, + { t = "I Term Rotation", x = 2, y = 44, }, + { t = "VBAT Compensation", x = 2, y = 52, }, + { t = "I Term Relax", x = 2, y = 60, }, + { t = "Axes", x = 12, y = 68, }, + { t = "Type", x = 12, y = 76, }, + { t = "Integrated Yaw", x = 2, y = 84, }, + { t = "Anti Gravity", x = 2, y = 92, }, + { t = "Mode", x = 12, y = 100, }, + { t = "Gain", x = 12, y = 108, }, + { t = "Threshold", x = 12, y = 116, }, }, fields = { { x = 87, y = 20, to=SMLSIZE, min = 20, max = 80, vals = { 32 } }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua index 21331d7c..4cb333e8 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua @@ -1,21 +1,21 @@ return { text = { - { t = "P", x = 45, y = 14, to = SMLSIZE }, - { t = "I", x = 73, y = 14, to = SMLSIZE }, - { t = "D", x = 101, y = 14, to = SMLSIZE }, - { t = "ROLL", x = 10, y = 26, to = SMLSIZE }, - { t = "PITCH", x = 10, y = 36, to = SMLSIZE }, - { t = "YAW", x = 10, y = 46, to = SMLSIZE }, + { t = "P", x = 45, y = 14, }, + { t = "I", x = 73, y = 14, }, + { t = "D", x = 101, y = 14, }, + { t = "ROLL", x = 10, y = 26, }, + { t = "PITCH", x = 10, y = 36, }, + { t = "YAW", x = 10, y = 46, }, }, fields = { - { x = 41, y = 26, min = 0, max = 200, vals = { 1 }, to = SMLSIZE }, - { x = 41, y = 36, min = 0, max = 200, vals = { 4 }, to = SMLSIZE }, - { x = 41, y = 46, min = 0, max = 200, vals = { 7 }, to = SMLSIZE }, - { x = 69, y = 26, min = 0, max = 200, vals = { 2 }, to = SMLSIZE }, - { x = 69, y = 36, min = 0, max = 200, vals = { 5 }, to = SMLSIZE }, - { x = 69, y = 46, min = 0, max = 200, vals = { 8 }, to = SMLSIZE }, - { x = 97, y = 26, min = 0, max = 200, vals = { 3 }, to = SMLSIZE }, - { x = 97, y = 36, min = 0, max = 200, vals = { 6 }, to = SMLSIZE }, - { x = 97, y = 46, min = 0, max = 200, vals = { 9 }, to = SMLSIZE }, + { x = 41, y = 26, min = 0, max = 200, vals = { 1 }, }, + { x = 41, y = 36, min = 0, max = 200, vals = { 4 }, }, + { x = 41, y = 46, min = 0, max = 200, vals = { 7 }, }, + { x = 69, y = 26, min = 0, max = 200, vals = { 2 }, }, + { x = 69, y = 36, min = 0, max = 200, vals = { 5 }, }, + { x = 69, y = 46, min = 0, max = 200, vals = { 8 }, }, + { x = 97, y = 26, min = 0, max = 200, vals = { 3 }, }, + { x = 97, y = 36, min = 0, max = 200, vals = { 6 }, }, + { x = 97, y = 46, min = 0, max = 200, vals = { 9 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua index d645dc44..e2e0e145 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua @@ -1,30 +1,29 @@ return { - minBytes = 44, yMinLimit = 11, yMaxLimit = 52, text = { - { t = "Feed", x = 45, y = 11, to = SMLSIZE }, - { t = "forward", x = 37, y = 18, to = SMLSIZE }, - { t = "D", x = 85, y = 11, to = SMLSIZE }, - { t = "Min", x = 80, y = 18, to = SMLSIZE }, - { t = "ROLL", x = 10, y = 26, to = SMLSIZE }, - { t = "PITCH", x = 10, y = 36, to = SMLSIZE }, - { t = "YAW", x = 10, y = 46, to = SMLSIZE }, - { t = "Feedforward", x = 10, y = 60, to = SMLSIZE }, - { t = "Transition", x = 20, y = 68, to = SMLSIZE }, - { t = "D Min", x = 10, y = 76, to = SMLSIZE }, - { t = "Gain", x = 20, y = 84, to = SMLSIZE }, - { t = "Advance", x = 20, y = 92, to = SMLSIZE }, + { t = "Feed", x = 45, y = 11, }, + { t = "forward", x = 37, y = 18, }, + { t = "D", x = 85, y = 11, }, + { t = "Min", x = 80, y = 18, }, + { t = "ROLL", x = 10, y = 26, }, + { t = "PITCH", x = 10, y = 36, }, + { t = "YAW", x = 10, y = 46, }, + { t = "Feedforward", x = 10, y = 60, }, + { t = "Transition", x = 20, y = 68, }, + { t = "D Min", x = 10, y = 76, }, + { t = "Gain", x = 20, y = 84, }, + { t = "Advance", x = 20, y = 92, }, }, fields = { - { x = 48, y = 26, min = 0, max = 2000, vals = { 33, 34 }, to = SMLSIZE }, - { x = 48, y = 36, min = 0, max = 2000, vals = { 35, 36 }, to = SMLSIZE }, - { x = 48, y = 46, min = 0, max = 2000, vals = { 37, 38 }, to = SMLSIZE }, - { x = 80, y = 26, min = 0, max = 100, vals = { 40 }, to = SMLSIZE }, - { x = 80, y = 36, min = 0, max = 100, vals = { 41 }, to = SMLSIZE }, - { x = 80, y = 46, min = 0, max = 100, vals = { 42 }, to = SMLSIZE }, - { x = 80, y = 68, min = 0, max = 100, vals = { 9 }, to = SMLSIZE, scale = 100 }, - { x = 80, y = 84, min = 0, max = 100, vals = { 43 }, to = SMLSIZE }, - { x = 80, y = 92, min = 0, max = 200, vals = { 44 }, to = SMLSIZE }, + { x = 48, y = 26, min = 0, max = 2000, vals = { 33, 34 }, }, + { x = 48, y = 36, min = 0, max = 2000, vals = { 35, 36 }, }, + { x = 48, y = 46, min = 0, max = 2000, vals = { 37, 38 }, }, + { x = 80, y = 26, min = 0, max = 100, vals = { 40 }, }, + { x = 80, y = 36, min = 0, max = 100, vals = { 41 }, }, + { x = 80, y = 46, min = 0, max = 100, vals = { 42 }, }, + { x = 80, y = 68, min = 0, max = 100, vals = { 9 }, scale = 100 }, + { x = 80, y = 84, min = 0, max = 100, vals = { 43 }, }, + { x = 80, y = 92, min = 0, max = 200, vals = { 44 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua index 65ede20d..a58eae39 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua @@ -1,20 +1,20 @@ return { text= { - { t = "32K", x = 10, y = 14, to = SMLSIZE }, - { t = "Gyro", x = 10, y = 24, to = SMLSIZE }, - { t = "PID", x = 10, y = 34, to = SMLSIZE }, - { t = "Prot", x = 58, y = 14, to = SMLSIZE }, - { t = "Unsync", x = 58, y = 24, to = SMLSIZE }, - { t = "PWM", x = 58, y = 34, to = SMLSIZE }, - { t = "Idle", x = 58, y = 44, to = SMLSIZE } + { t = "32K", x = 10, y = 14, }, + { t = "Gyro", x = 10, y = 24, }, + { t = "PID", x = 10, y = 34, }, + { t = "Prot", x = 58, y = 14, }, + { t = "Unsync", x = 58, y = 24, }, + { t = "PWM", x = 58, y = 34, }, + { t = "Idle", x = 58, y = 44, } }, fields = { - { x = 32, y = 14, vals = { 9 }, min = 0, max = 1, to = SMLSIZE, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, - { x = 32, y = 24, vals = { 1 }, min = 1, max = 32, to = SMLSIZE, upd = function(self) self.updatePidRateTable(self) end }, - { x = 32, y = 34, vals = { 2 }, min = 1, max = 16, to = SMLSIZE, }, - { x = 90, y = 14, vals = { 4 }, min = 0, max = 9, to = SMLSIZE, table = { [0] = "OFF", "OS125", "OS42", "MSHOT","BRSH", "DS150", "DS300", "DS600","DS1200", "PS1000" } }, - { x = 90, y = 24, vals = { 3 }, min = 0, max = 1, to = SMLSIZE, table = { [0] = "OFF", "ON" } }, - { x = 90, y = 34, vals = { 5, 6 }, min = 200, max = 32000, to = SMLSIZE }, - { x = 90, y = 44, vals = { 7, 8 }, min = 0, max = 2000, to = SMLSIZE, scale = 100 }, + { x = 32, y = 14, vals = { 9 }, min = 0, max = 1, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, + { x = 32, y = 24, vals = { 1 }, min = 1, max = 32, upd = function(self) self.updatePidRateTable(self) end }, + { x = 32, y = 34, vals = { 2 }, min = 1, max = 16, }, + { x = 90, y = 14, vals = { 4 }, min = 0, max = 9, table = { [0] = "OFF", "OS125", "OS42", "MSHOT","BRSH", "DS150", "DS300", "DS600","DS1200", "PS1000" } }, + { x = 90, y = 24, vals = { 3 }, min = 0, max = 1, table = { [0] = "OFF", "ON" } }, + { x = 90, y = 34, vals = { 5, 6 }, min = 200, max = 32000, }, + { x = 90, y = 44, vals = { 7, 8 }, min = 0, max = 2000, scale = 100 }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua index ba88ad0e..7781a363 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua @@ -2,39 +2,39 @@ return { yMinLimit = 11, yMaxLimit = 52, text = { - { t = "RC", x = 43, y = 11, to = SMLSIZE }, - { t = "Rate", x = 38, y = 18, to = SMLSIZE }, - { t = "Super", x = 63, y = 11, to = SMLSIZE }, - { t = "Rate", x = 66, y = 18, to = SMLSIZE }, - { t = "RC", x = 99, y = 11, to = SMLSIZE }, - { t = "Expo", x = 94, y = 18, to = SMLSIZE }, - { t = "ROLL", x = 10, y = 26, to = SMLSIZE }, - { t = "PITCH", x = 10, y = 36, to = SMLSIZE }, - { t = "YAW", x = 10, y = 46, to = SMLSIZE }, - { t = "Throttle", x = 10, y = 60, to = SMLSIZE }, - { t = "Mid", x = 20, y = 68, to = SMLSIZE }, - { t = "Expo", x = 20, y = 76, to = SMLSIZE }, - { t = "Limit Type", x = 20, y = 84, to = SMLSIZE }, - { t = "Limit %", x = 20, y = 92, to = SMLSIZE }, - { t = "TPA", x = 10, y = 100, to = SMLSIZE }, - { t = "Rate", x = 20, y = 108, to = SMLSIZE }, - { t = "Breakpoint", x = 20, y = 116, to = SMLSIZE }, + { t = "RC", x = 43, y = 11, }, + { t = "Rate", x = 38, y = 18, }, + { t = "Super", x = 63, y = 11, }, + { t = "Rate", x = 66, y = 18, }, + { t = "RC", x = 99, y = 11, }, + { t = "Expo", x = 94, y = 18, }, + { t = "ROLL", x = 10, y = 26, }, + { t = "PITCH", x = 10, y = 36, }, + { t = "YAW", x = 10, y = 46, }, + { t = "Throttle", x = 10, y = 60, }, + { t = "Mid", x = 20, y = 68, }, + { t = "Expo", x = 20, y = 76, }, + { t = "Limit Type", x = 20, y = 84, }, + { t = "Limit %", x = 20, y = 92, }, + { t = "TPA", x = 10, y = 100, }, + { t = "Rate", x = 20, y = 108, }, + { t = "Breakpoint", x = 20, y = 116, }, }, fields = { - { x = 39, y = 26, vals = { 1 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - { x = 39, y = 36, vals = { 13 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - { x = 39, y = 46, vals = { 12 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - { x = 66, y = 26, vals = { 3 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 66, y = 36, vals = { 4 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 66, y = 46, vals = { 5 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - { x = 94, y = 26, vals = { 2 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 94, y = 36, vals = { 14 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 94, y = 46, vals = { 11 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 70, y = 68, vals = { 7 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 70, y = 76, vals = { 8 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 70, y = 84, vals = { 15 }, min = 0, max = 2, to = SMLSIZE, table = { [0] = "OFF", "SCALE", "CLIP" } }, - { x = 70, y = 92, vals = { 16 }, min = 25, max = 100, to = SMLSIZE }, - { x = 70, y = 108, vals = { 6 } , min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 70, y = 116, vals = { 9, 10 }, min = 1000, max = 2000, to = SMLSIZE }, + { x = 39, y = 26, vals = { 1 }, min = 0, max = 255, scale = 100, }, + { x = 39, y = 36, vals = { 13 }, min = 0, max = 255, scale = 100, }, + { x = 39, y = 46, vals = { 12 }, min = 0, max = 255, scale = 100, }, + { x = 66, y = 26, vals = { 3 }, min = 0, max = 100, scale = 100, }, + { x = 66, y = 36, vals = { 4 }, min = 0, max = 100, scale = 100, }, + { x = 66, y = 46, vals = { 5 }, min = 0, max = 255, scale = 100, }, + { x = 94, y = 26, vals = { 2 }, min = 0, max = 100, scale = 100, }, + { x = 94, y = 36, vals = { 14 }, min = 0, max = 100, scale = 100, }, + { x = 94, y = 46, vals = { 11 }, min = 0, max = 100, scale = 100, }, + { x = 70, y = 68, vals = { 7 }, min = 0, max = 100, scale = 100, }, + { x = 70, y = 76, vals = { 8 }, min = 0, max = 100, scale = 100, }, + { x = 70, y = 84, vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, + { x = 70, y = 92, vals = { 16 }, min = 25, max = 100, }, + { x = 70, y = 108, vals = { 6 } , min = 0, max = 100, scale = 100, }, + { x = 70, y = 116, vals = { 9, 10 }, min = 1000, max = 2000, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua index 2c38f80e..78b2a0c9 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua @@ -1,26 +1,26 @@ return { text = { - { t = "Min Sats.", x = 3, y = 10, to=SMLSIZE }, - { t = "Angle", x = 3, y = 20, to=SMLSIZE }, - { t = "Initial Alt", x = 3, y = 30, to=SMLSIZE }, - { t = "Descent Dst", x = 3, y = 40, to=SMLSIZE }, - { t = "Ground Spd", x = 3, y = 50, to=SMLSIZE }, - { t = "Snty.", x = 80, y = 10, to = SMLSIZE }, - { t = "Throttle", x = 80, y = 20, to = SMLSIZE }, - { t = "Min", x = 85, y = 30, to = SMLSIZE }, - { t = "Hover", x = 80, y = 40, to = SMLSIZE }, - { t = "Max", x = 85, y = 50, to = SMLSIZE }, + { t = "Min Sats.", x = 3, y = 10, }, + { t = "Angle", x = 3, y = 20, }, + { t = "Initial Alt", x = 3, y = 30, }, + { t = "Descent Dst", x = 3, y = 40, }, + { t = "Ground Spd", x = 3, y = 50, }, + { t = "Snty.", x = 80, y = 10, }, + { t = "Throttle", x = 80, y = 20, }, + { t = "Min", x = 85, y = 30, }, + { t = "Hover", x = 80, y = 40, }, + { t = "Max", x = 85, y = 50, }, }, fields = { - { x = 58, y = 10, min = 0, max = 50, vals = { 16 }, to = SMLSIZE }, - { x = 58, y = 20, min = 0, max = 200, vals = { 1,2 }, to = SMLSIZE }, - { x = 58, y = 30, min = 20, max = 100, vals = { 3,4 }, to = SMLSIZE }, - { x = 58, y = 40, min = 30, max = 500, vals = { 5,6 }, to = SMLSIZE }, - { x = 58, y = 50, min = 30, max =3000, vals = { 7,8 }, to = SMLSIZE }, - { x = 105, y = 10, min = 0, max = 2 , vals = { 15 }, to = SMLSIZE,table = { [0]="OFF","ON","FS_ONLY"}}, - { x = 105, y = 30, min = 1000, max = 2000, vals = { 9,10 }, to = SMLSIZE }, - { x = 105, y = 40, min = 1000, max = 2000, vals = { 13,14 }, to = SMLSIZE }, - { x = 105, y = 50, min = 1000, max = 2000, vals = { 11,12 }, to = SMLSIZE }, + { x = 58, y = 10, min = 0, max = 50, vals = { 16 }, }, + { x = 58, y = 20, min = 0, max = 200, vals = { 1,2 }, }, + { x = 58, y = 30, min = 20, max = 100, vals = { 3,4 }, }, + { x = 58, y = 40, min = 30, max = 500, vals = { 5,6 }, }, + { x = 58, y = 50, min = 30, max =3000, vals = { 7,8 }, }, + { x = 105, y = 10, min = 0, max = 2 , vals = { 15 } ,table = { [0]="OFF","ON","FS_ONLY"}, }, + { x = 105, y = 30, min = 1000, max = 2000, vals = { 9,10 }, }, + { x = 105, y = 40, min = 1000, max = 2000, vals = { 13,14 }, }, + { x = 105, y = 50, min = 1000, max = 2000, vals = { 11,12 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua index 0f3baf4b..5e77753f 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua @@ -3,11 +3,11 @@ return { yMaxLimit = 52, text = {}, fields = { - { t = "Stick Min", x = 10, y = 20, sp = 45, min = 1000, max = 2000, vals = { 6, 7 }, to = SMLSIZE }, - { t = "Stick Mid", x = 10, y = 30, sp = 45, min = 1000, max = 2000, vals = { 4, 5 }, to = SMLSIZE }, - { t = "Stick Max", x = 10, y = 40, sp = 45, min = 1000, max = 2000, vals = { 2, 3 }, to = SMLSIZE }, - { t = "Cam Angle", x = 10, y = 50, sp = 50, min = 0, max = 90, vals = { 23 }, to = SMLSIZE }, - { t = "Interp", x = 10, y = 60, sp = 50, min = 0, max = 3, vals = { 13 }, to = SMLSIZE, table={ [0]="Off", "Preset", "Auto", "Manual"} }, - { t = "Interp Int", x = 10, y = 70, sp = 50, min = 1, max = 50, vals = { 14 }, to = SMLSIZE }, + { t = "Stick Min", x = 10, y = 20, sp = 45, min = 1000, max = 2000, vals = { 6, 7 }, }, + { t = "Stick Mid", x = 10, y = 30, sp = 45, min = 1000, max = 2000, vals = { 4, 5 }, }, + { t = "Stick Max", x = 10, y = 40, sp = 45, min = 1000, max = 2000, vals = { 2, 3 }, }, + { t = "Cam Angle", x = 10, y = 50, sp = 50, min = 0, max = 90, vals = { 23 }, }, + { t = "Interp", x = 10, y = 60, sp = 50, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} }, + { t = "Interp Int", x = 10, y = 70, sp = 50, min = 1, max = 50, vals = { 14 }, }, }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua index e5892dab..af664f98 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua @@ -1,11 +1,11 @@ return { text = {}, fields = { - { t = "Band", x = 10, y = 14, sp = 30, min=0, max=5, vals = { 2 }, to = SMLSIZE, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, - { t = "Chan", x = 10, y = 24, sp = 30, min=1, max=8, vals = { 3 }, to = SMLSIZE, upd = function(self) self.handleBandChanUpdate(self) end }, - { t = "Power", x = 10, y = 34, sp = 30, min=1, vals = { 4 }, to = SMLSIZE, upd = function(self) self.updatePowerTable(self) end }, - { t = "Pit", x = 10, y = 44, sp = 30, min=0, max=1, vals = { 5 }, to = SMLSIZE, table = { [0]="OFF", "ON" } }, - { t = "Dev", x = 70, y = 14, sp = 25, write = false, ro = true, vals = { 1 }, to = SMLSIZE , table = { [1]="6705",[3]="SA",[4]="Tramp",[255]="None"} }, - { t = "Freq", x = 70, y = 24, sp = 25, min = 5000, max = 5999, vals = { 6 }, to = SMLSIZE, upd = function(self) self.handleFreqValUpdate(self) end }, + { t = "Band", x = 10, y = 14, sp = 30, min=0, max=5, vals = { 2 }, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, + { t = "Chan", x = 10, y = 24, sp = 30, min=1, max=8, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, + { t = "Power", x = 10, y = 34, sp = 30, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, + { t = "Pit", x = 10, y = 44, sp = 30, min=0, max=1, vals = { 5 }, table = { [0]="OFF", "ON" } }, + { t = "Dev", x = 70, y = 14, sp = 25, write = false, ro = true, vals = { 1 }, table = { [1]="6705",[3]="SA",[4]="Tramp",[255]="None"} }, + { t = "Freq", x = 70, y = 24, sp = 25, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua index c8e09a8e..074045ff 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua @@ -2,59 +2,59 @@ return { yMinLimit = 12, yMaxLimit = 52, text= { - { t = "Gyro Lowpass 1 Dynamic", x = 2, y = 12, to = SMLSIZE }, - { t = "Min Cutoff", x = 12, y = 20, to = SMLSIZE }, - { t = "Max Cutoff", x = 12, y = 28, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 36, to = SMLSIZE }, - { t = "Gyro Lowpass 1", x = 2, y = 44, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 52, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 60, to = SMLSIZE }, - { t = "Gyro Lowpass 2", x = 2, y = 68, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 76, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 84, to = SMLSIZE }, - { t = "Gyro Notch 1", x = 2, y = 92, to = SMLSIZE }, - { t = "Center", x = 12, y = 100, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 108, to = SMLSIZE }, - { t = "Gyro Notch 2", x = 2, y = 116, to = SMLSIZE }, - { t = "Center", x = 12, y = 124, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 132, to = SMLSIZE }, - { t = "D Term Lowpass 1 Dynamic", x = 2, y = 140, to = SMLSIZE }, - { t = "Min Cutoff", x = 12, y = 148, to = SMLSIZE }, - { t = "Max Cutoff", x = 12, y = 156, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 164, to = SMLSIZE }, - { t = "D Term Lowpass 1", x = 2, y = 172, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 180, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 188, to = SMLSIZE }, - { t = "D Term Lowpass 2", x = 2, y = 196, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 204, to = SMLSIZE }, - { t = "Filter Type", x = 12, y = 212, to = SMLSIZE }, - { t = "D Term Notch", x = 2, y = 220, to = SMLSIZE }, - { t = "Center", x = 12, y = 228, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 236, to = SMLSIZE }, - { t = "Yaw Lowpass", x = 2, y = 244, to = SMLSIZE }, - { t = "Cutoff", x = 12, y = 252, to = SMLSIZE }, + { t = "Gyro Lowpass 1 Dynamic", x = 2, y = 12, }, + { t = "Min Cutoff", x = 12, y = 20, }, + { t = "Max Cutoff", x = 12, y = 28, }, + { t = "Filter Type", x = 12, y = 36, }, + { t = "Gyro Lowpass 1", x = 2, y = 44, }, + { t = "Cutoff", x = 12, y = 52, }, + { t = "Filter Type", x = 12, y = 60, }, + { t = "Gyro Lowpass 2", x = 2, y = 68, }, + { t = "Cutoff", x = 12, y = 76, }, + { t = "Filter Type", x = 12, y = 84, }, + { t = "Gyro Notch 1", x = 2, y = 92, }, + { t = "Center", x = 12, y = 100, }, + { t = "Cutoff", x = 12, y = 108, }, + { t = "Gyro Notch 2", x = 2, y = 116, }, + { t = "Center", x = 12, y = 124, }, + { t = "Cutoff", x = 12, y = 132, }, + { t = "D Term Lowpass 1 Dynamic", x = 2, y = 140, }, + { t = "Min Cutoff", x = 12, y = 148, }, + { t = "Max Cutoff", x = 12, y = 156, }, + { t = "Filter Type", x = 12, y = 164, }, + { t = "D Term Lowpass 1", x = 2, y = 172, }, + { t = "Cutoff", x = 12, y = 180, }, + { t = "Filter Type", x = 12, y = 188, }, + { t = "D Term Lowpass 2", x = 2, y = 196, }, + { t = "Cutoff", x = 12, y = 204, }, + { t = "Filter Type", x = 12, y = 212, }, + { t = "D Term Notch", x = 2, y = 220, }, + { t = "Center", x = 12, y = 228, }, + { t = "Cutoff", x = 12, y = 236, }, + { t = "Yaw Lowpass", x = 2, y = 244, }, + { t = "Cutoff", x = 12, y = 252, }, }, fields = { - { x = 87, y = 20, min = 0, max = 1000, to = SMLSIZE, vals = { 30, 31 } }, - { x = 87, y = 28, min = 0, max = 1000, to = SMLSIZE, vals = { 32, 33 } }, - { x = 87, y = 36, min = 0, max = 1, to = SMLSIZE, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 52, min = 0, max = 16000, to = SMLSIZE, vals = { 21, 22 } }, - { x = 87, y = 60, min = 0, max = 1, to = SMLSIZE, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 76, min = 0, max = 16000, to = SMLSIZE, vals = { 23, 24 } }, - { x = 87, y = 84, min = 0, max = 1, to = SMLSIZE, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 100, min = 0, max = 16000, to = SMLSIZE, vals = { 6, 7 } }, - { x = 87, y = 108, min = 0, max = 16000, to = SMLSIZE, vals = { 8, 9 } }, - { x = 87, y = 124, min = 0, max = 16000, to = SMLSIZE, vals = { 14, 15 } }, - { x = 87, y = 132, min = 0, max = 16000, to = SMLSIZE, vals = { 16, 17 } }, - { x = 87, y = 148, min = 0, max = 1000, to = SMLSIZE, vals = { 34, 35 } }, - { x = 87, y = 156, min = 0, max = 1000, to = SMLSIZE, vals = { 36, 37 } }, - { x = 87, y = 164, min = 0, max = 1, to = SMLSIZE, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 180, min = 0, max = 16000, to = SMLSIZE, vals = { 2, 3 } }, - { x = 87, y = 188, min = 0, max = 1, to = SMLSIZE, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 204, min = 0, max = 16000, to = SMLSIZE, vals = { 27, 28 } }, - { x = 87, y = 212, min = 0, max = 1, to = SMLSIZE, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 228, min = 0, max = 16000, to = SMLSIZE, vals = { 10, 11 } }, - { x = 87, y = 236, min = 0, max = 16000, to = SMLSIZE, vals = { 12, 13 } }, - { x = 87, y = 252, min = 0, max = 500, to = SMLSIZE, vals = { 4, 5 } }, + { x = 87, y = 20, min = 0, max = 1000, vals = { 30, 31 } }, + { x = 87, y = 28, min = 0, max = 1000, vals = { 32, 33 } }, + { x = 87, y = 36, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 52, min = 0, max = 16000, vals = { 21, 22 } }, + { x = 87, y = 60, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 76, min = 0, max = 16000, vals = { 23, 24 } }, + { x = 87, y = 84, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 100, min = 0, max = 16000, vals = { 6, 7 } }, + { x = 87, y = 108, min = 0, max = 16000, vals = { 8, 9 } }, + { x = 87, y = 124, min = 0, max = 16000, vals = { 14, 15 } }, + { x = 87, y = 132, min = 0, max = 16000, vals = { 16, 17 } }, + { x = 87, y = 148, min = 0, max = 1000, vals = { 34, 35 } }, + { x = 87, y = 156, min = 0, max = 1000, vals = { 36, 37 } }, + { x = 87, y = 164, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 180, min = 0, max = 16000, vals = { 2, 3 } }, + { x = 87, y = 188, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 204, min = 0, max = 16000, vals = { 27, 28 } }, + { x = 87, y = 212, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { x = 87, y = 228, min = 0, max = 16000, vals = { 10, 11 } }, + { x = 87, y = 236, min = 0, max = 16000, vals = { 12, 13 } }, + { x = 87, y = 252, min = 0, max = 500, vals = { 4, 5 } }, } } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua index 96697ed7..0b706a0e 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua @@ -1,19 +1,19 @@ return { text = { - { t = "P", x = 70, y = 14, to = SMLSIZE }, - { t = "I", x = 98, y = 14, to = SMLSIZE }, - { t = "D", x = 126, y = 14, to = SMLSIZE }, - { t = "Throttle", x = 25, y = 26, to = SMLSIZE }, - { t = "Velocity", x = 25, y = 36, to = SMLSIZE }, - { t = "Yaw", x = 25, y = 46, to = SMLSIZE }, + { t = "P", x = 70, y = 14, }, + { t = "I", x = 98, y = 14, }, + { t = "D", x = 126, y = 14, }, + { t = "Throttle", x = 25, y = 26, }, + { t = "Velocity", x = 25, y = 36, }, + { t = "Yaw", x = 25, y = 46, }, }, fields = { - { x = 66, y = 26, min = 0, max = 500, vals = { 1,2 }, to = SMLSIZE }, - { x = 66, y = 36, min = 0, max = 500, vals = { 7,8 }, to = SMLSIZE }, - { x = 66, y = 46, min = 0, max = 500, vals = {13,14}, to = SMLSIZE }, - { x = 94, y = 26, min = 0, max = 500, vals = { 3,4 }, to = SMLSIZE }, - { x = 94, y = 36, min = 0, max = 500, vals = { 9,10 }, to = SMLSIZE }, - { x = 122, y = 26, min = 0, max = 500, vals = { 5,6 }, to = SMLSIZE }, - { x = 122, y = 36, min = 0, max = 500, vals = { 11,12 }, to = SMLSIZE }, + { x = 66, y = 26, min = 0, max = 500, vals = { 1,2 }, }, + { x = 66, y = 36, min = 0, max = 500, vals = { 7,8 }, }, + { x = 66, y = 46, min = 0, max = 500, vals = {13,14}, }, + { x = 94, y = 26, min = 0, max = 500, vals = { 3,4 }, }, + { x = 94, y = 36, min = 0, max = 500, vals = { 9,10 }, }, + { x = 122, y = 26, min = 0, max = 500, vals = { 5,6 }, }, + { x = 122, y = 36, min = 0, max = 500, vals = { 11,12 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua index 5b87f866..6ad5638e 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua @@ -2,20 +2,20 @@ return { yMinLimit = 12, yMaxLimit = 52, text = { - { t = "Acro Trainer", x = 2, y = 12, to = SMLSIZE }, - { t = "Angle Limit", x = 12, y = 20, to = SMLSIZE }, - { t = "Throttle Boost", x = 2, y = 28, to = SMLSIZE }, - { t = "Absolute Control", x = 2, y = 36, to = SMLSIZE }, - { t = "I Term Rotation", x = 2, y = 44, to = SMLSIZE }, - { t = "VBAT Compensation", x = 2, y = 52, to = SMLSIZE }, - { t = "I Term Relax", x = 2, y = 60, to = SMLSIZE }, - { t = "Axes", x = 12, y = 68, to = SMLSIZE }, - { t = "Type", x = 12, y = 76, to = SMLSIZE }, - { t = "Integrated Yaw", x = 2, y = 84, to = SMLSIZE }, - { t = "Anti Gravity", x = 2, y = 92, to = SMLSIZE }, - { t = "Mode", x = 12, y = 100, to = SMLSIZE }, - { t = "Gain", x = 12, y = 108, to = SMLSIZE }, - { t = "Threshold", x = 12, y = 116, to = SMLSIZE }, + { t = "Acro Trainer", x = 2, y = 12, }, + { t = "Angle Limit", x = 12, y = 20, }, + { t = "Throttle Boost", x = 2, y = 28, }, + { t = "Absolute Control", x = 2, y = 36, }, + { t = "I Term Rotation", x = 2, y = 44, }, + { t = "VBAT Compensation", x = 2, y = 52, }, + { t = "I Term Relax", x = 2, y = 60, }, + { t = "Axes", x = 12, y = 68, }, + { t = "Type", x = 12, y = 76, }, + { t = "Integrated Yaw", x = 2, y = 84, }, + { t = "Anti Gravity", x = 2, y = 92, }, + { t = "Mode", x = 12, y = 100, }, + { t = "Gain", x = 12, y = 108, }, + { t = "Threshold", x = 12, y = 116, }, }, fields = { { x = 87, y = 20, to=SMLSIZE, min = 20, max = 80, vals = { 32 } }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua index 72abdb10..fe624022 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua @@ -1,21 +1,21 @@ return { text = { - { t = "P", x = 70, y = 14, to = SMLSIZE }, - { t = "I", x = 98, y = 14, to = SMLSIZE }, - { t = "D", x = 126, y = 14, to = SMLSIZE }, - { t = "ROLL", x = 25, y = 26, to = SMLSIZE }, - { t = "PITCH", x = 25, y = 36, to = SMLSIZE }, - { t = "YAW", x = 25, y = 46, to = SMLSIZE }, + { t = "P", x = 70, y = 14, }, + { t = "I", x = 98, y = 14, }, + { t = "D", x = 126, y = 14, }, + { t = "ROLL", x = 25, y = 26, }, + { t = "PITCH", x = 25, y = 36, }, + { t = "YAW", x = 25, y = 46, }, }, fields = { - { x = 66, y = 26, min = 0, max = 200, vals = { 1 }, to = SMLSIZE }, - { x = 66, y = 36, min = 0, max = 200, vals = { 4 }, to = SMLSIZE }, - { x = 66, y = 46, min = 0, max = 200, vals = { 7 }, to = SMLSIZE }, - { x = 94, y = 26, min = 0, max = 200, vals = { 2 }, to = SMLSIZE }, - { x = 94, y = 36, min = 0, max = 200, vals = { 5 }, to = SMLSIZE }, - { x = 94, y = 46, min = 0, max = 200, vals = { 8 }, to = SMLSIZE }, - { x = 122, y = 26, min = 0, max = 200, vals = { 3 }, to = SMLSIZE }, - { x = 122, y = 36, min = 0, max = 200, vals = { 6 }, to = SMLSIZE }, - { x = 122, y = 46, min = 0, max = 200, vals = { 9 }, to = SMLSIZE }, + { x = 66, y = 26, min = 0, max = 200, vals = { 1 }, }, + { x = 66, y = 36, min = 0, max = 200, vals = { 4 }, }, + { x = 66, y = 46, min = 0, max = 200, vals = { 7 }, }, + { x = 94, y = 26, min = 0, max = 200, vals = { 2 }, }, + { x = 94, y = 36, min = 0, max = 200, vals = { 5 }, }, + { x = 94, y = 46, min = 0, max = 200, vals = { 8 }, }, + { x = 122, y = 26, min = 0, max = 200, vals = { 3 }, }, + { x = 122, y = 36, min = 0, max = 200, vals = { 6 }, }, + { x = 122, y = 46, min = 0, max = 200, vals = { 9 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua index c988f0c8..d54a441b 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua @@ -1,27 +1,27 @@ return { text = { - { t = "Feed", x = 46, y = 11, to = SMLSIZE }, - { t = "forward", x = 38, y = 18, to = SMLSIZE }, - { t = "D", x = 86, y = 11, to = SMLSIZE }, - { t = "Min", x = 81, y = 18, to = SMLSIZE }, - { t = "ROLL", x = 8, y = 26, to = SMLSIZE }, - { t = "PITCH", x = 8, y = 36, to = SMLSIZE }, - { t = "YAW", x = 8, y = 46, to = SMLSIZE }, - { t = "Feedforward", x = 110, y = 14, to = SMLSIZE }, - { t = "Transition", x = 120, y = 22, to = SMLSIZE }, - { t = "D Min", x = 110, y = 30, to = SMLSIZE }, - { t = "Gain", x = 120, y = 38, to = SMLSIZE }, - { t = "Advance", x = 120, y = 46, to = SMLSIZE }, + { t = "Feed", x = 46, y = 11, }, + { t = "forward", x = 38, y = 18, }, + { t = "D", x = 86, y = 11, }, + { t = "Min", x = 81, y = 18, }, + { t = "ROLL", x = 8, y = 26, }, + { t = "PITCH", x = 8, y = 36, }, + { t = "YAW", x = 8, y = 46, }, + { t = "Feedforward", x = 110, y = 14, }, + { t = "Transition", x = 120, y = 22, }, + { t = "D Min", x = 110, y = 30, }, + { t = "Gain", x = 120, y = 38, }, + { t = "Advance", x = 120, y = 46, }, }, fields = { - { x = 49, y = 26, min = 0, max = 2000, vals = { 33, 34 }, to = SMLSIZE }, - { x = 49, y = 36, min = 0, max = 2000, vals = { 35, 36 }, to = SMLSIZE }, - { x = 49, y = 46, min = 0, max = 2000, vals = { 37, 38 }, to = SMLSIZE }, - { x = 81, y = 26, min = 0, max = 100, vals = { 40 }, to = SMLSIZE }, - { x = 81, y = 36, min = 0, max = 100, vals = { 41 }, to = SMLSIZE }, - { x = 81, y = 46, min = 0, max = 100, vals = { 42 }, to = SMLSIZE }, - { x = 180, y = 22, min = 0, max = 100, vals = { 9 }, to = SMLSIZE, scale = 100 }, - { x = 180, y = 38, min = 0, max = 100, vals = { 43 }, to = SMLSIZE }, - { x = 180, y = 46, min = 0, max = 200, vals = { 44 }, to = SMLSIZE }, + { x = 49, y = 26, min = 0, max = 2000, vals = { 33, 34 }, }, + { x = 49, y = 36, min = 0, max = 2000, vals = { 35, 36 }, }, + { x = 49, y = 46, min = 0, max = 2000, vals = { 37, 38 }, }, + { x = 81, y = 26, min = 0, max = 100, vals = { 40 }, }, + { x = 81, y = 36, min = 0, max = 100, vals = { 41 }, }, + { x = 81, y = 46, min = 0, max = 100, vals = { 42 }, }, + { x = 180, y = 22, min = 0, max = 100, vals = { 9 }, scale = 100 }, + { x = 180, y = 38, min = 0, max = 100, vals = { 43 }, }, + { x = 180, y = 46, min = 0, max = 200, vals = { 44 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua index ee844f7f..17a961f2 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua @@ -1,20 +1,20 @@ return { text= { - { t = "32K", x = 48, y = 14, to = SMLSIZE }, - { t = "Gyro Rt", x = 29, y = 24, to = SMLSIZE }, - { t = "PID Rt", x = 35, y = 34, to = SMLSIZE }, - { t = "Protocol", x = 107, y = 14, to = SMLSIZE }, - { t = "Unsynced", x = 106, y = 24, to = SMLSIZE }, - { t = "PWM Rate", x = 105, y = 34, to = SMLSIZE }, - { t = "Idle Offset", x =94, y = 44, to = SMLSIZE } + { t = "32K", x = 48, y = 14, }, + { t = "Gyro Rt", x = 29, y = 24, }, + { t = "PID Rt", x = 35, y = 34, }, + { t = "Protocol", x = 107, y = 14, }, + { t = "Unsynced", x = 106, y = 24, }, + { t = "PWM Rate", x = 105, y = 34, }, + { t = "Idle Offset", x =94, y = 44, } }, fields = { - { x = 65, y = 14, vals = { 9 }, min = 0, max = 1, to = SMLSIZE, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, - { x = 65, y = 24, vals = { 1 }, min = 1, max = 32, to = SMLSIZE, upd = function(self) self.updatePidRateTable(self) end }, - { x = 65, y = 34, vals = { 2 }, min = 1, max = 16, to = SMLSIZE, }, - { x = 148, y = 14, vals = { 4 }, min = 0, max = 9, to = SMLSIZE, table = { [0] = "OFF", "ONESHOT125", "ONESHOT42", "MULTISHOT","BRUSHED", "DSHOT150", "DSHOT300", "DSHOT600","DSHOT1200", "PROSHOT1000" } }, - { x = 148, y = 24, vals = { 3 }, min = 0, max = 1, to = SMLSIZE, table = { [0] = "OFF", "ON" } }, - { x = 148, y = 34, vals = { 5, 6 }, min = 200, max = 32000, to = SMLSIZE }, - { x = 148, y = 44, vals = { 7, 8 }, min = 0, max = 2000, to = SMLSIZE, scale = 100 }, + { x = 65, y = 14, vals = { 9 }, min = 0, max = 1, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, + { x = 65, y = 24, vals = { 1 }, min = 1, max = 32, upd = function(self) self.updatePidRateTable(self) end }, + { x = 65, y = 34, vals = { 2 }, min = 1, max = 16, }, + { x = 148, y = 14, vals = { 4 }, min = 0, max = 9, table = { [0] = "OFF", "ONESHOT125", "ONESHOT42", "MULTISHOT","BRUSHED", "DSHOT150", "DSHOT300", "DSHOT600","DSHOT1200", "PROSHOT1000" } }, + { x = 148, y = 24, vals = { 3 }, min = 0, max = 1, table = { [0] = "OFF", "ON" } }, + { x = 148, y = 34, vals = { 5, 6 }, min = 200, max = 32000, }, + { x = 148, y = 44, vals = { 7, 8 }, min = 0, max = 2000, scale = 100 }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua index a59d7761..d6e8ddd8 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua @@ -2,39 +2,39 @@ return { yMinLimit = 11, yMaxLimit = 52, text = { - { t = "RC", x = 43, y = 11, to = SMLSIZE }, - { t = "Rate", x = 38, y = 18, to = SMLSIZE }, - { t = "Super", x = 63, y = 11, to = SMLSIZE }, - { t = "Rate", x = 66, y = 18, to = SMLSIZE }, - { t = "RC", x = 99, y = 11, to = SMLSIZE }, - { t = "Expo", x = 94, y = 18, to = SMLSIZE }, - { t = "ROLL", x = 8, y = 26, to = SMLSIZE }, - { t = "PITCH", x = 8, y = 36, to = SMLSIZE }, - { t = "YAW", x = 8, y = 46, to = SMLSIZE }, - { t = "Throttle", x = 120, y = 12, to = SMLSIZE }, - { t = "Mid", x = 130, y = 20, to = SMLSIZE }, - { t = "Expo", x = 130, y = 28, to = SMLSIZE }, - { t = "Limit Type", x = 130, y = 36, to = SMLSIZE }, - { t = "Limit %", x = 130, y = 44, to = SMLSIZE }, - { t = "TPA", x = 120, y = 52, to = SMLSIZE }, - { t = "Rate", x = 130, y = 60, to = SMLSIZE }, - { t = "Breakpoint", x = 130, y = 68, to = SMLSIZE }, + { t = "RC", x = 43, y = 11, }, + { t = "Rate", x = 38, y = 18, }, + { t = "Super", x = 63, y = 11, }, + { t = "Rate", x = 66, y = 18, }, + { t = "RC", x = 99, y = 11, }, + { t = "Expo", x = 94, y = 18, }, + { t = "ROLL", x = 8, y = 26, }, + { t = "PITCH", x = 8, y = 36, }, + { t = "YAW", x = 8, y = 46, }, + { t = "Throttle", x = 120, y = 12, }, + { t = "Mid", x = 130, y = 20, }, + { t = "Expo", x = 130, y = 28, }, + { t = "Limit Type", x = 130, y = 36, }, + { t = "Limit %", x = 130, y = 44, }, + { t = "TPA", x = 120, y = 52, }, + { t = "Rate", x = 130, y = 60, }, + { t = "Breakpoint", x = 130, y = 68, }, }, fields = { - { x = 39, y = 26, vals = { 1 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - { x = 39, y = 36, vals = { 13 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - { x = 39, y = 46, vals = { 12 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - { x = 66, y = 26, vals = { 3 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 66, y = 36, vals = { 4 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 66, y = 46, vals = { 5 }, min = 0, max = 255, scale = 100, to = SMLSIZE }, - { x = 94, y = 26, vals = { 2 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 94, y = 36, vals = { 14 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 94, y = 46, vals = { 11 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 180, y = 20, vals = { 7 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 180, y = 28, vals = { 8 }, min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 180, y = 36, vals = { 15 }, min = 0, max = 2, to = SMLSIZE, table = { [0] = "OFF", "SCALE", "CLIP" } }, - { x = 180, y = 44, vals = { 16 }, min = 25, max = 100, to = SMLSIZE }, - { x = 180, y = 60, vals = { 6 } , min = 0, max = 100, scale = 100, to = SMLSIZE }, - { x = 180, y = 68, vals = { 9, 10 }, min = 1000, max = 2000, to = SMLSIZE }, + { x = 39, y = 26, vals = { 1 }, min = 0, max = 255, scale = 100, }, + { x = 39, y = 36, vals = { 13 }, min = 0, max = 255, scale = 100, }, + { x = 39, y = 46, vals = { 12 }, min = 0, max = 255, scale = 100, }, + { x = 66, y = 26, vals = { 3 }, min = 0, max = 100, scale = 100, }, + { x = 66, y = 36, vals = { 4 }, min = 0, max = 100, scale = 100, }, + { x = 66, y = 46, vals = { 5 }, min = 0, max = 255, scale = 100, }, + { x = 94, y = 26, vals = { 2 }, min = 0, max = 100, scale = 100, }, + { x = 94, y = 36, vals = { 14 }, min = 0, max = 100, scale = 100, }, + { x = 94, y = 46, vals = { 11 }, min = 0, max = 100, scale = 100, }, + { x = 180, y = 20, vals = { 7 }, min = 0, max = 100, scale = 100, }, + { x = 180, y = 28, vals = { 8 }, min = 0, max = 100, scale = 100, }, + { x = 180, y = 36, vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, + { x = 180, y = 44, vals = { 16 }, min = 25, max = 100, }, + { x = 180, y = 60, vals = { 6 } , min = 0, max = 100, scale = 100, }, + { x = 180, y = 68, vals = { 9, 10 }, min = 1000, max = 2000, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua index f960aa2a..77f119f4 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua @@ -1,25 +1,25 @@ return { text = { - { t = "Min Sats.", x = 30, y = 16, to = SMLSIZE }, - { t = "Angle", x = 45, y = 26, to = SMLSIZE }, - { t = "Initial Alt.", x = 18, y = 36, to = SMLSIZE }, - { t = "Descent Dist.", x = 10, y = 46, to = SMLSIZE }, - { t = "Ground Speed", x = 10, y = 56, to = SMLSIZE }, - { t = "Sanity Ch.", x = 125, y = 16, to = SMLSIZE }, - { t = "Throttle", x = 125, y = 26, to = SMLSIZE }, - { t = "Min", x = 128, y = 36, to = SMLSIZE }, - { t = "Hover", x = 120, y = 46, to = SMLSIZE }, - { t = "Max", x = 128, y = 56, to = SMLSIZE }, + { t = "Min Sats.", x = 30, y = 16, }, + { t = "Angle", x = 45, y = 26, }, + { t = "Initial Alt.", x = 18, y = 36, }, + { t = "Descent Dist.", x = 10, y = 46, }, + { t = "Ground Speed", x = 10, y = 56, }, + { t = "Sanity Ch.", x = 125, y = 16, }, + { t = "Throttle", x = 125, y = 26, }, + { t = "Min", x = 128, y = 36, }, + { t = "Hover", x = 120, y = 46, }, + { t = "Max", x = 128, y = 56, }, }, fields = { - { x = 75, y = 16, min = 0, max = 50, vals = { 16 }, to = SMLSIZE }, - { x = 75, y = 26, min = 0, max = 200, vals = { 1 , 2 }, to = SMLSIZE }, - { x = 75, y = 36, min = 20, max = 100, vals = { 3 , 4 }, to = SMLSIZE }, - { x = 75, y = 46, min = 30, max = 500, vals = { 5 , 6 }, to = SMLSIZE }, - { x = 75, y = 56, min = 30, max = 3000, vals = { 7, 8 }, to = SMLSIZE }, - { x = 180, y = 16, min = 0, max = 2 , vals = { 15 }, to = SMLSIZE,table = { [0]="OFF","ON","FS_ONLY"}}, - { x = 150, y = 36, min = 1000, max = 2000, vals = { 9, 10 }, to = SMLSIZE }, - { x = 150, y = 46, min = 1000, max = 2000, vals = { 13, 14 },to = SMLSIZE }, - { x = 150, y = 56, min = 1000, max = 2000, vals = { 11,12 }, to = SMLSIZE }, + { x = 75, y = 16, min = 0, max = 50, vals = { 16 }, }, + { x = 75, y = 26, min = 0, max = 200, vals = { 1 , 2 }, }, + { x = 75, y = 36, min = 20, max = 100, vals = { 3 , 4 }, }, + { x = 75, y = 46, min = 30, max = 500, vals = { 5 , 6 }, }, + { x = 75, y = 56, min = 30, max = 3000, vals = { 7, 8 }, }, + { x = 180, y = 16, min = 0, max = 2 , vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"}}, + { x = 150, y = 36, min = 1000, max = 2000, vals = { 9, 10 }, }, + { x = 150, y = 46, min = 1000, max = 2000, vals = { 13, 14 }, }, + { x = 150, y = 56, min = 1000, max = 2000, vals = { 11,12 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua index a745b212..9a01f7e6 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua @@ -1,11 +1,11 @@ return { text = {}, fields = { - { t = "Stick Min", x = 30, y = 20, sp = 45, min = 1000, max = 2000, vals = { 6, 7 }, to = SMLSIZE }, - { t = "Stick Mid", x = 30, y = 30, sp = 45, min = 1000, max = 2000, vals = { 4, 5 }, to = SMLSIZE }, - { t = "Stick Max", x = 30, y = 40, sp = 45, min = 1000, max = 2000, vals = { 2, 3 }, to = SMLSIZE }, - { t = "Cam Angle", x = 110, y = 20, sp = 50, min = 0, max = 90, vals = { 23 }, to = SMLSIZE }, - { t = "Interp", x = 110, y = 30, sp = 50, min = 0, max = 3, vals = { 13 }, to = SMLSIZE, table={ [0]="Off", "Preset", "Auto", "Manual"} }, - { t = "Interp Int", x = 110, y = 40, sp = 50, min = 1, max = 50, vals = { 14 }, to = SMLSIZE }, + { t = "Stick Min", x = 30, y = 20, sp = 45, min = 1000, max = 2000, vals = { 6, 7 }, }, + { t = "Stick Mid", x = 30, y = 30, sp = 45, min = 1000, max = 2000, vals = { 4, 5 }, }, + { t = "Stick Max", x = 30, y = 40, sp = 45, min = 1000, max = 2000, vals = { 2, 3 }, }, + { t = "Cam Angle", x = 110, y = 20, sp = 50, min = 0, max = 90, vals = { 23 }, }, + { t = "Interp", x = 110, y = 30, sp = 50, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} }, + { t = "Interp Int", x = 110, y = 40, sp = 50, min = 1, max = 50, vals = { 14 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua index 3696f2ee..227cdb1d 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua @@ -1,11 +1,11 @@ return { text = {}, fields = { - { t = "Band", x = 25, y = 14, sp = 50, min=0, max=5, vals = { 2 }, to = SMLSIZE, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, - { t = "Channel", x = 25, y = 24, sp = 50, min=1, max=8, vals = { 3 }, to = SMLSIZE, upd = function(self) self.handleBandChanUpdate(self) end }, - { t = "Power", x = 25, y = 34, sp = 50, min=1, vals = { 4 }, to = SMLSIZE, upd = function(self) self.updatePowerTable(self) end }, - { t = "Pit", x = 25, y = 44, sp = 50, min=0, max=1, vals = { 5 }, to = SMLSIZE, table = { [0]="OFF", "ON" } }, - { t = "Dev", x = 100, y = 14, sp = 32, write = false, ro = true, vals = { 1 }, to = SMLSIZE, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, - { t = "Freq", x = 100, y = 24, sp = 32, min = 5000, max = 5999, vals = { 6 }, to = SMLSIZE, upd = function(self) self.handleFreqValUpdate(self) end }, + { t = "Band", x = 25, y = 14, sp = 50, min=0, max=5, vals = { 2 }, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, + { t = "Channel", x = 25, y = 24, sp = 50, min=1, max=8, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, + { t = "Power", x = 25, y = 34, sp = 50, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, + { t = "Pit", x = 25, y = 44, sp = 50, min=0, max=1, vals = { 5 }, table = { [0]="OFF", "ON" } }, + { t = "Dev", x = 100, y = 14, sp = 32, write = false, ro = true, vals = { 1 }, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, + { t = "Freq", x = 100, y = 24, sp = 32, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua b/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua index 99bcdbcb..3cdbe3ab 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua @@ -2,37 +2,37 @@ return { yMinLimit = 35, yMaxLimit = 215, text= { - { t = "Gyro Lowpass 1 Dynamic", x = 5, y = 35 }, - { t = "Min Cutoff", x = 35, y = 55, to = SMLSIZE }, - { t = "Max Cutoff", x = 35, y = 75, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 95, to = SMLSIZE }, - { t = "Gyro Lowpass 1", x = 5, y = 115 }, - { t = "Cutoff", x = 35, y = 135, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 155, to = SMLSIZE }, - { t = "Gyro Lowpass 2", x = 5, y = 175 }, - { t = "Cutoff", x = 35, y = 195, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 215, to = SMLSIZE }, - { t = "Gyro Notch 1", x = 5, y = 235 }, - { t = "Center", x = 35, y = 255, to = SMLSIZE }, - { t = "Cutoff", x = 35, y = 275, to = SMLSIZE }, - { t = "Gyro Notch 2", x = 5, y = 295 }, - { t = "Center", x = 35, y = 315, to = SMLSIZE }, - { t = "Cutoff", x = 35, y = 335, to = SMLSIZE }, - { t = "D Term Lowpass 1 Dynamic", x = 5, y = 355 }, - { t = "Min Cutoff", x = 35, y = 375, to = SMLSIZE }, - { t = "Max Cutoff", x = 35, y = 395, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 415, to = SMLSIZE }, - { t = "D Term Lowpass 1", x = 5, y = 435 }, - { t = "Cutoff", x = 35, y = 455, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 475, to = SMLSIZE }, - { t = "D Term Lowpass 2", x = 5, y = 495 }, - { t = "Cutoff", x = 35, y = 515, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 535, to = SMLSIZE }, - { t = "D Term Notch", x = 5, y = 555 }, - { t = "Center", x = 35, y = 575, to = SMLSIZE }, - { t = "Cutoff", x = 35, y = 595, to = SMLSIZE }, - { t = "Yaw Lowpass", x = 5, y = 615 }, - { t = "Cutoff", x = 35, y = 635, to = SMLSIZE }, + { t = "Gyro Lowpass 1 Dynamic", x = 5, y = 35, }, + { t = "Min Cutoff", x = 35, y = 55, }, + { t = "Max Cutoff", x = 35, y = 75, }, + { t = "Filter Type", x = 35, y = 95, }, + { t = "Gyro Lowpass 1", x = 5, y = 115, }, + { t = "Cutoff", x = 35, y = 135, }, + { t = "Filter Type", x = 35, y = 155, }, + { t = "Gyro Lowpass 2", x = 5, y = 175, }, + { t = "Cutoff", x = 35, y = 195, }, + { t = "Filter Type", x = 35, y = 215, }, + { t = "Gyro Notch 1", x = 5, y = 235, }, + { t = "Center", x = 35, y = 255, }, + { t = "Cutoff", x = 35, y = 275, }, + { t = "Gyro Notch 2", x = 5, y = 295, }, + { t = "Center", x = 35, y = 315, }, + { t = "Cutoff", x = 35, y = 335, }, + { t = "D Term Lowpass 1 Dynamic", x = 5, y = 355, }, + { t = "Min Cutoff", x = 35, y = 375, }, + { t = "Max Cutoff", x = 35, y = 395, }, + { t = "Filter Type", x = 35, y = 415, }, + { t = "D Term Lowpass 1", x = 5, y = 435, }, + { t = "Cutoff", x = 35, y = 455, }, + { t = "Filter Type", x = 35, y = 475, }, + { t = "D Term Lowpass 2", x = 5, y = 495, }, + { t = "Cutoff", x = 35, y = 515, }, + { t = "Filter Type", x = 35, y = 535, }, + { t = "D Term Notch", x = 5, y = 555, }, + { t = "Center", x = 35, y = 575, }, + { t = "Cutoff", x = 35, y = 595, }, + { t = "Yaw Lowpass", x = 5, y = 615, }, + { t = "Cutoff", x = 35, y = 635, }, }, fields = { { x = 200, y = 55, min = 0, max = 1000, vals = { 30, 31 } }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua index 7f67e458..c2d464d6 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua @@ -1,19 +1,19 @@ return { text = { - { t = "P", x = 100, y = 48, to = MIDSIZE }, - { t = "I", x = 180, y = 48, to = MIDSIZE }, - { t = "D", x = 260, y = 48, to = MIDSIZE }, - { t = "Throttle", x = 10, y = 100 }, - { t = "Velocity", x = 10, y = 150 }, - { t = "Yaw" , x = 10, y = 200 }, + { t = "P", x = 100, y = 48, }, + { t = "I", x = 180, y = 48, }, + { t = "D", x = 260, y = 48, }, + { t = "Throttle", x = 10, y = 100, }, + { t = "Velocity", x = 10, y = 150, }, + { t = "Yaw" , x = 10, y = 200, }, }, fields = { - { x = 100, y = 100, min = 0, max = 200, vals = { 1, 3 }, to = MIDSIZE }, - { x = 100, y = 150, min = 0, max = 200, vals = { 7, 8 }, to = MIDSIZE }, - { x = 100, y = 200, min = 0, max = 500, vals = {13,14 }, to = MIDSIZE }, - { x = 180, y = 100, min = 0, max = 200, vals = { 3, 4 }, to = MIDSIZE }, - { x = 180, y = 150, min = 0, max = 200, vals = { 9,10 }, to = MIDSIZE }, - { x = 260, y = 100, min = 0, max = 200, vals = { 5, 6 }, to = MIDSIZE }, - { x = 260, y = 150, min = 0, max = 200, vals = { 11,12 }, to = MIDSIZE }, + { x = 100, y = 100, min = 0, max = 200, vals = { 1, 3 }, }, + { x = 100, y = 150, min = 0, max = 200, vals = { 7, 8 }, }, + { x = 100, y = 200, min = 0, max = 500, vals = {13,14 }, }, + { x = 180, y = 100, min = 0, max = 200, vals = { 3, 4 }, }, + { x = 180, y = 150, min = 0, max = 200, vals = { 9,10 }, }, + { x = 260, y = 100, min = 0, max = 200, vals = { 5, 6 }, }, + { x = 260, y = 150, min = 0, max = 200, vals = { 11,12 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua index e58a614f..e1d6a5ee 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua @@ -2,20 +2,20 @@ return { yMinLimit = 35, yMaxLimit = 215, text = { - { t = "Acro Trainer", x = 5, y = 35 }, - { t = "Angle Limit", x = 15, y = 55, to = SMLSIZE }, - { t = "Throttle Boost", x = 5, y = 75 }, - { t = "Absolute Control", x = 5, y = 95 }, - { t = "I Term Rotation", x = 5, y = 115 }, - { t = "VBAT Compensation", x = 5, y = 135 }, - { t = "I Term Relax", x = 5, y = 155 }, - { t = "Axes", x = 15, y = 175, to = SMLSIZE }, - { t = "Type", x = 15, y = 195, to = SMLSIZE }, - { t = "Integrated Yaw", x = 5, y = 215 }, - { t = "Anti Gravity", x = 5, y = 235 }, - { t = "Mode", x = 15, y = 255, to = SMLSIZE }, - { t = "Gain", x = 15, y = 275, to = SMLSIZE }, - { t = "Threshold", x = 15, y = 295, to = SMLSIZE }, + { t = "Acro Trainer", x = 5, y = 35, }, + { t = "Angle Limit", x = 15, y = 55, }, + { t = "Throttle Boost", x = 5, y = 75, }, + { t = "Absolute Control", x = 5, y = 95, }, + { t = "I Term Rotation", x = 5, y = 115, }, + { t = "VBAT Compensation", x = 5, y = 135, }, + { t = "I Term Relax", x = 5, y = 155, }, + { t = "Axes", x = 15, y = 175, }, + { t = "Type", x = 15, y = 195, }, + { t = "Integrated Yaw", x = 5, y = 215, }, + { t = "Anti Gravity", x = 5, y = 235, }, + { t = "Mode", x = 15, y = 255, }, + { t = "Gain", x = 15, y = 275, }, + { t = "Threshold", x = 15, y = 295, }, }, fields = { { x = 200, y = 55, min = 20, max = 80, vals = { 32 } }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua index 3312ceb4..f39b1286 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua @@ -1,21 +1,21 @@ return { text = { - { t = "P", x = 100, y = 48, to = MIDSIZE }, - { t = "I", x = 180, y = 48, to = MIDSIZE }, - { t = "D", x = 260, y = 48, to = MIDSIZE }, - { t = "ROLL", x = 10, y = 100 }, - { t = "PITCH", x = 10, y = 150 }, - { t = "YAW", x = 10, y = 200 }, + { t = "P", x = 100, y = 48, }, + { t = "I", x = 180, y = 48, }, + { t = "D", x = 260, y = 48, }, + { t = "ROLL", x = 10, y = 100, }, + { t = "PITCH", x = 10, y = 150, }, + { t = "YAW", x = 10, y = 200, }, }, fields = { - { x = 100, y = 100, min = 0, max = 200, vals = { 1 }, to = MIDSIZE }, - { x = 100, y = 150, min = 0, max = 200, vals = { 4 }, to = MIDSIZE }, - { x = 100, y = 200, min = 0, max = 200, vals = { 7 }, to = MIDSIZE }, - { x = 180, y = 100, min = 0, max = 200, vals = { 2 }, to = MIDSIZE }, - { x = 180, y = 150, min = 0, max = 200, vals = { 5 }, to = MIDSIZE }, - { x = 180, y = 200, min = 0, max = 200, vals = { 8 }, to = MIDSIZE }, - { x = 260, y = 100, min = 0, max = 200, vals = { 3 }, to = MIDSIZE }, - { x = 260, y = 150, min = 0, max = 200, vals = { 6 }, to = MIDSIZE }, - { x = 260, y = 200, min = 0, max = 200, vals = { 9 }, to = MIDSIZE }, + { x = 100, y = 100, min = 0, max = 200, vals = { 1 }, }, + { x = 100, y = 150, min = 0, max = 200, vals = { 4 }, }, + { x = 100, y = 200, min = 0, max = 200, vals = { 7 }, }, + { x = 180, y = 100, min = 0, max = 200, vals = { 2 }, }, + { x = 180, y = 150, min = 0, max = 200, vals = { 5 }, }, + { x = 180, y = 200, min = 0, max = 200, vals = { 8 }, }, + { x = 260, y = 100, min = 0, max = 200, vals = { 3 }, }, + { x = 260, y = 150, min = 0, max = 200, vals = { 6 }, }, + { x = 260, y = 200, min = 0, max = 200, vals = { 9 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua index 90ded627..9b10823e 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua @@ -1,25 +1,25 @@ return { text = { - { t = "Feed", x = 97, y = 52 }, - { t = "forward", x = 82, y = 70 }, - { t = "D", x = 207, y = 52 }, - { t = "Min", x = 202, y = 70 }, - { t = "ROLL", x = 28, y = 100 }, - { t = "PITCH", x = 28, y = 150 }, - { t = "YAW", x = 28, y = 200 }, - { t = "Feedforward", x = 28, y = 250 }, - { t = "Transition", x = 40, y = 270, to = SMLSIZE }, - { t = "D Min", x = 28, y = 300 }, - { t = "Gain", x = 40, y = 320, to = SMLSIZE }, - { t = "Advance", x = 40, y = 350, to = SMLSIZE }, + { t = "Feed", x = 97, y = 52, }, + { t = "forward", x = 82, y = 70, }, + { t = "D", x = 207, y = 52, }, + { t = "Min", x = 202, y = 70, }, + { t = "ROLL", x = 28, y = 100, }, + { t = "PITCH", x = 28, y = 150, }, + { t = "YAW", x = 28, y = 200, }, + { t = "Feedforward", x = 28, y = 250, }, + { t = "Transition", x = 40, y = 270, }, + { t = "D Min", x = 28, y = 300, }, + { t = "Gain", x = 40, y = 320, }, + { t = "Advance", x = 40, y = 350, }, }, fields = { - { x = 102, y = 100, min = 0, max = 2000, vals = { 33, 34 }, to = MIDSIZE }, - { x = 102, y = 150, min = 0, max = 2000, vals = { 35, 36 }, to = MIDSIZE }, - { x = 102, y = 200, min = 0, max = 2000, vals = { 37, 38 }, to = MIDSIZE }, - { x = 202, y = 100, min = 0, max = 100, vals = { 40 }, to = MIDSIZE }, - { x = 202, y = 150, min = 0, max = 100, vals = { 41 }, to = MIDSIZE }, - { x = 202, y = 200, min = 0, max = 100, vals = { 42 }, to = MIDSIZE }, + { x = 102, y = 100, min = 0, max = 2000, vals = { 33, 34 }, }, + { x = 102, y = 150, min = 0, max = 2000, vals = { 35, 36 }, }, + { x = 102, y = 200, min = 0, max = 2000, vals = { 37, 38 }, }, + { x = 202, y = 100, min = 0, max = 100, vals = { 40 }, }, + { x = 202, y = 150, min = 0, max = 100, vals = { 41 }, }, + { x = 202, y = 200, min = 0, max = 100, vals = { 42 }, }, { x = 150, y = 270, min = 0, max = 100, vals = { 9 }, scale = 100 }, { x = 150, y = 320, min = 0, max = 100, vals = { 43 } }, { x = 150, y = 350, min = 0, max = 200, vals = { 44 } }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua index 75bc9180..aedf420c 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua @@ -9,17 +9,17 @@ return { { t = "Idle Offset", x = 36, y = 326 } }, fields = { - { x = 150, y = 68, vals = { 4 }, min = 0, max = 9, to = MIDSIZE, + { x = 150, y = 68, vals = { 4 }, min = 0, max = 9, table = { [0] = "OFF", "ONESHOT125", "ONESHOT42", "MULTISHOT","BRUSHED", "DSHOT150", "DSHOT300", "DSHOT600","DSHOT1200", "PROSHOT1000" } }, - { x = 150, y = 110, vals = { 9 }, min = 0, max = 1, to = MIDSIZE, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, - { x = 150, y = 155, vals = { 1 }, min = 1, max = 32, to = MIDSIZE, upd = function(self) self.updatePidRateTable(self) end }, - { x = 150, y = 200, vals = { 2 }, min = 1, max = 16, to = MIDSIZE }, - { x = 150, y = 242, vals = { 3 }, min = 0, max = 1, to = MIDSIZE, table = { [0] = "OFF", "ON" } }, - { x = 150, y = 284, vals = { 5, 6 }, min = 200, max = 32000, to = MIDSIZE }, - { x = 150, y = 326, vals = { 7, 8 }, min = 0, max = 2000, scale = 100, to = MIDSIZE }, + { x = 150, y = 110, vals = { 9 }, min = 0, max = 1, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, + { x = 150, y = 155, vals = { 1 }, min = 1, max = 32, upd = function(self) self.updatePidRateTable(self) end }, + { x = 150, y = 200, vals = { 2 }, min = 1, max = 16, }, + { x = 150, y = 242, vals = { 3 }, min = 0, max = 1, table = { [0] = "OFF", "ON" } }, + { x = 150, y = 284, vals = { 5, 6 }, min = 200, max = 32000, }, + { x = 150, y = 326, vals = { 7, 8 }, min = 0, max = 2000, scale = 100, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua index 235062c1..0acfcf0c 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua @@ -1,35 +1,35 @@ return { text = { - { t = "RC", x = 100, y = 52 }, - { t = "Rate", x = 94, y = 70 }, - { t = "Super", x = 148, y = 52 }, - { t = "Rate", x = 152, y = 70 }, - { t = "RC", x = 214, y = 52 }, - { t = "Expo", x = 207, y = 70 }, - { t = "ROLL", x = 28, y = 100 }, - { t = "PITCH", x = 28, y = 150 }, - { t = "YAW", x = 28, y = 200 }, - { t = "Throttle", x = 28, y = 250 }, - { t = "Mid", x = 40, y = 270, to = SMLSIZE }, - { t = "Expo", x = 40, y = 290, to = SMLSIZE }, - { t = "Limit Type", x = 40, y = 310, to = SMLSIZE }, - { t = "Limit %", x = 40, y = 330, to = SMLSIZE }, - { t = "TPA", x = 28, y = 350 }, - { t = "Rate", x = 40, y = 370, to = SMLSIZE }, - { t = "Breakpoint", x = 40, y = 390, to = SMLSIZE }, + { t = "RC", x = 100, y = 52 }, + { t = "Rate", x = 94, y = 70 }, + { t = "Super", x = 148, y = 52 }, + { t = "Rate", x = 152, y = 70 }, + { t = "RC", x = 214, y = 52 }, + { t = "Expo", x = 207, y = 70 }, + { t = "ROLL", x = 28, y = 100 }, + { t = "PITCH", x = 28, y = 150 }, + { t = "YAW", x = 28, y = 200 }, + { t = "Throttle", x = 28, y = 250 }, + { t = "Mid", x = 40, y = 270, }, + { t = "Expo", x = 40, y = 290, }, + { t = "Limit Type", x = 40, y = 310, }, + { t = "Limit %", x = 40, y = 330, }, + { t = "TPA", x = 28, y = 350, }, + { t = "Rate", x = 40, y = 370, }, + { t = "Breakpoint", x = 40, y = 390, }, }, fields = { - { x = 102, y = 100, vals = { 1 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - { x = 102, y = 150, vals = { 13 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - { x = 102, y = 200, vals = { 12 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - { x = 158, y = 100, vals = { 3 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - { x = 158, y = 150, vals = { 4 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - { x = 158, y = 200, vals = { 5 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - { x = 216, y = 100, vals = { 2 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - { x = 216, y = 150, vals = { 14 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - { x = 216, y = 200, vals = { 11 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - { x = 150, y = 270, vals = { 7 }, min = 0, max = 100, scale = 100 }, - { x = 150, y = 290, vals = { 8 }, min = 0, max = 100, scale = 100 }, + { x = 102, y = 100, vals = { 1 }, min = 0, max = 255, scale = 100, }, + { x = 102, y = 150, vals = { 13 }, min = 0, max = 255, scale = 100, }, + { x = 102, y = 200, vals = { 12 }, min = 0, max = 255, scale = 100, }, + { x = 158, y = 100, vals = { 3 }, min = 0, max = 100, scale = 100, }, + { x = 158, y = 150, vals = { 4 }, min = 0, max = 100, scale = 100, }, + { x = 158, y = 200, vals = { 5 }, min = 0, max = 255, scale = 100, }, + { x = 216, y = 100, vals = { 2 }, min = 0, max = 100, scale = 100, }, + { x = 216, y = 150, vals = { 14 }, min = 0, max = 100, scale = 100, }, + { x = 216, y = 200, vals = { 11 }, min = 0, max = 100, scale = 100, }, + { x = 150, y = 270, vals = { 7 }, min = 0, max = 100, scale = 100, }, + { x = 150, y = 290, vals = { 8 }, min = 0, max = 100, scale = 100, }, { x = 150, y = 310, vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, { x = 150, y = 330, vals = { 16 }, min = 25, max = 100 }, { x = 150, y = 370, vals = { 6 }, min = 0, max = 100, scale = 100 }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua index ba27efde..3a567f90 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua @@ -12,12 +12,12 @@ return { { t = "Max", x = 10, y = 400 }, }, fields = { - { x = 260, y = 40, min = 0, max = 50, vals = { 16 } }, - { x = 260, y = 80, min = 0, max = 200, vals = { 1,2 } }, + { x = 260, y = 40, min = 0, max = 50, vals = { 16 } }, + { x = 260, y = 80, min = 0, max = 200, vals = { 1,2 } }, { x = 260, y = 120, min = 20, max = 100, vals = { 3,4 } }, { x = 260, y = 160, min = 30, max = 500, vals = { 5,6 } }, { x = 260, y = 200, min = 30, max =3000, vals = { 7,8 } }, - { x = 260, y = 240, min = 0, max = 2 , vals = { 15 } ,table = { [0]="OFF","ON","FS_ONLY"}}, + { x = 260, y = 240, min = 0, max = 2 , vals = { 15 } ,table = { [0]="OFF","ON","FS_ONLY"}, }, { x = 260, y = 320, min = 1000, max = 2000, vals = { 9,10 } }, { x = 260, y = 360, min = 1000, max = 2000, vals = { 13,14 } }, { x = 260, y = 400, min = 1000, max = 2000, vals = { 11,12 } }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua index 361d9b00..b731c518 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua @@ -1,18 +1,18 @@ return { text= { - { t = "Stick Min", x = 36, y = 68 }, - { t = "Stick Mid", x = 36, y = 110 }, - { t = "Stick Max", x = 36, y = 155 }, - { t = "Cam Angle", x = 36, y = 200 }, - { t = "Interp", x = 36, y = 242 }, - { t = "Interp Int", x = 36, y = 284 } + { t = "Stick Min", x = 36, y = 68 }, + { t = "Stick Mid", x = 36, y = 110 }, + { t = "Stick Max", x = 36, y = 155 }, + { t = "Cam Angle", x = 36, y = 200 }, + { t = "Interp", x = 36, y = 242 }, + { t = "Interp Int", x = 36, y = 284 } }, fields = { - { x = 150, y = 68, min = 1000, max = 2000, vals = { 6, 7 }, to = MIDSIZE }, - { x = 150, y = 110, min = 1000, max = 2000, vals = { 4, 5 }, to = MIDSIZE }, - { x = 150, y = 155, min = 1000, max = 2000, vals = { 2, 3 }, to = MIDSIZE }, - { x = 150, y = 200, min = 0, max = 90, vals = { 23 }, to = MIDSIZE }, - { x = 150, y = 242, min = 0, max = 3, vals = { 13 }, to = MIDSIZE, table={ [0]="Off", "Preset", "Auto", "Manual"} }, - { x = 150, y = 284, min = 1, max = 50, vals = { 14 }, to = MIDSIZE } + { x = 150, y = 68, min = 1000, max = 2000, vals = { 6, 7 }, }, + { x = 150, y = 110, min = 1000, max = 2000, vals = { 4, 5 }, }, + { x = 150, y = 155, min = 1000, max = 2000, vals = { 2, 3 }, }, + { x = 150, y = 200, min = 0, max = 90, vals = { 23 }, }, + { x = 150, y = 242, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} }, + { x = 150, y = 284, min = 1, max = 50, vals = { 14 }, } }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua b/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua index 28f8e652..09ac190f 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua @@ -8,11 +8,11 @@ return { { t = "Freq", x = 36, y = 110 }, }, fields = { - { x = 150, y = 155, min=0, max=5, vals = { 2 }, to = MIDSIZE, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, - { x = 150, y = 200, min=1, max=8, vals = { 3 }, to = MIDSIZE, upd = function(self) self.handleBandChanUpdate(self) end }, - { x = 150, y = 242, min=1, vals = { 4 }, to = MIDSIZE, upd = function(self) self.updatePowerTable(self) end }, - { x = 150, y = 284, min=0, max=1, vals = { 5 }, to = MIDSIZE, table = { [0]="OFF", "ON" } }, - { x = 150, y = 68, vals = { 1 }, to = MIDSIZE, write = false, ro = true, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, - { x = 150, y = 110, min = 5000, max = 5999, vals = { 6 }, to = MIDSIZE, upd = function(self) self.handleFreqValUpdate(self) end }, + { x = 150, y = 155, min=0, max=5, vals = { 2 }, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, + { x = 150, y = 200, min=1, max=8, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, + { x = 150, y = 242, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, + { x = 150, y = 284, min=0, max=1, vals = { 5 }, table = { [0]="OFF", "ON" } }, + { x = 150, y = 68, vals = { 1 }, write = false, ro = true, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, + { x = 150, y = 110, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua b/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua index 99bcdbcb..2abe7559 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua @@ -3,36 +3,36 @@ return { yMaxLimit = 215, text= { { t = "Gyro Lowpass 1 Dynamic", x = 5, y = 35 }, - { t = "Min Cutoff", x = 35, y = 55, to = SMLSIZE }, - { t = "Max Cutoff", x = 35, y = 75, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 95, to = SMLSIZE }, - { t = "Gyro Lowpass 1", x = 5, y = 115 }, - { t = "Cutoff", x = 35, y = 135, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 155, to = SMLSIZE }, - { t = "Gyro Lowpass 2", x = 5, y = 175 }, - { t = "Cutoff", x = 35, y = 195, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 215, to = SMLSIZE }, - { t = "Gyro Notch 1", x = 5, y = 235 }, - { t = "Center", x = 35, y = 255, to = SMLSIZE }, - { t = "Cutoff", x = 35, y = 275, to = SMLSIZE }, - { t = "Gyro Notch 2", x = 5, y = 295 }, - { t = "Center", x = 35, y = 315, to = SMLSIZE }, - { t = "Cutoff", x = 35, y = 335, to = SMLSIZE }, - { t = "D Term Lowpass 1 Dynamic", x = 5, y = 355 }, - { t = "Min Cutoff", x = 35, y = 375, to = SMLSIZE }, - { t = "Max Cutoff", x = 35, y = 395, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 415, to = SMLSIZE }, - { t = "D Term Lowpass 1", x = 5, y = 435 }, - { t = "Cutoff", x = 35, y = 455, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 475, to = SMLSIZE }, - { t = "D Term Lowpass 2", x = 5, y = 495 }, - { t = "Cutoff", x = 35, y = 515, to = SMLSIZE }, - { t = "Filter Type", x = 35, y = 535, to = SMLSIZE }, - { t = "D Term Notch", x = 5, y = 555 }, - { t = "Center", x = 35, y = 575, to = SMLSIZE }, - { t = "Cutoff", x = 35, y = 595, to = SMLSIZE }, - { t = "Yaw Lowpass", x = 5, y = 615 }, - { t = "Cutoff", x = 35, y = 635, to = SMLSIZE }, + { t = "Min Cutoff", x = 35, y = 55, }, + { t = "Max Cutoff", x = 35, y = 75, }, + { t = "Filter Type", x = 35, y = 95, }, + { t = "Gyro Lowpass 1", x = 5, y = 115, }, + { t = "Cutoff", x = 35, y = 135, }, + { t = "Filter Type", x = 35, y = 155, }, + { t = "Gyro Lowpass 2", x = 5, y = 175, }, + { t = "Cutoff", x = 35, y = 195, }, + { t = "Filter Type", x = 35, y = 215, }, + { t = "Gyro Notch 1", x = 5, y = 235, }, + { t = "Center", x = 35, y = 255, }, + { t = "Cutoff", x = 35, y = 275, }, + { t = "Gyro Notch 2", x = 5, y = 295, }, + { t = "Center", x = 35, y = 315, }, + { t = "Cutoff", x = 35, y = 335, }, + { t = "D Term Lowpass 1 Dynamic", x = 5, y = 355, }, + { t = "Min Cutoff", x = 35, y = 375, }, + { t = "Max Cutoff", x = 35, y = 395, }, + { t = "Filter Type", x = 35, y = 415, }, + { t = "D Term Lowpass 1", x = 5, y = 435, }, + { t = "Cutoff", x = 35, y = 455, }, + { t = "Filter Type", x = 35, y = 475, }, + { t = "D Term Lowpass 2", x = 5, y = 495, }, + { t = "Cutoff", x = 35, y = 515, }, + { t = "Filter Type", x = 35, y = 535, }, + { t = "D Term Notch", x = 5, y = 555, }, + { t = "Center", x = 35, y = 575, }, + { t = "Cutoff", x = 35, y = 595, }, + { t = "Yaw Lowpass", x = 5, y = 615, }, + { t = "Cutoff", x = 35, y = 635, }, }, fields = { { x = 200, y = 55, min = 0, max = 1000, vals = { 30, 31 } }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua index b2c4eeda..f98a0f2b 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua @@ -1,19 +1,19 @@ return { text = { - { t = "P", x = 142, y = 48, to = MIDSIZE }, - { t = "I", x = 244, y = 48, to = MIDSIZE }, - { t = "D", x = 342, y = 48, to = MIDSIZE }, - { t = "Throttle", x = 28, y = 100 }, - { t = "Velocity", x = 28, y = 150 }, - { t = "Yaw" , x = 28, y = 200 }, + { t = "P", x = 142, y = 48, }, + { t = "I", x = 244, y = 48, }, + { t = "D", x = 342, y = 48, }, + { t = "Throttle", x = 28, y = 100, }, + { t = "Velocity", x = 28, y = 150, }, + { t = "Yaw" , x = 28, y = 200, }, }, fields = { - { x = 140, y = 100, min = 0, max = 200, vals = { 1, 3 }, to = MIDSIZE }, - { x = 140, y = 150, min = 0, max = 200, vals = { 7, 8 }, to = MIDSIZE }, - { x = 140, y = 200, min = 0, max = 500, vals = {13,14 }, to = MIDSIZE }, - { x = 240, y = 100, min = 0, max = 200, vals = { 3, 4 }, to = MIDSIZE }, - { x = 240, y = 150, min = 0, max = 200, vals = { 9,10 }, to = MIDSIZE }, - { x = 340, y = 100, min = 0, max = 200, vals = { 5, 6 }, to = MIDSIZE }, - { x = 340, y = 150, min = 0, max = 200, vals = { 11,12 }, to = MIDSIZE }, + { x = 140, y = 100, min = 0, max = 200, vals = { 1, 3 }, }, + { x = 140, y = 150, min = 0, max = 200, vals = { 7, 8 }, }, + { x = 140, y = 200, min = 0, max = 500, vals = {13,14 }, }, + { x = 240, y = 100, min = 0, max = 200, vals = { 3, 4 }, }, + { x = 240, y = 150, min = 0, max = 200, vals = { 9,10 }, }, + { x = 340, y = 100, min = 0, max = 200, vals = { 5, 6 }, }, + { x = 340, y = 150, min = 0, max = 200, vals = { 11,12 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua index e58a614f..e1d6a5ee 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua @@ -2,20 +2,20 @@ return { yMinLimit = 35, yMaxLimit = 215, text = { - { t = "Acro Trainer", x = 5, y = 35 }, - { t = "Angle Limit", x = 15, y = 55, to = SMLSIZE }, - { t = "Throttle Boost", x = 5, y = 75 }, - { t = "Absolute Control", x = 5, y = 95 }, - { t = "I Term Rotation", x = 5, y = 115 }, - { t = "VBAT Compensation", x = 5, y = 135 }, - { t = "I Term Relax", x = 5, y = 155 }, - { t = "Axes", x = 15, y = 175, to = SMLSIZE }, - { t = "Type", x = 15, y = 195, to = SMLSIZE }, - { t = "Integrated Yaw", x = 5, y = 215 }, - { t = "Anti Gravity", x = 5, y = 235 }, - { t = "Mode", x = 15, y = 255, to = SMLSIZE }, - { t = "Gain", x = 15, y = 275, to = SMLSIZE }, - { t = "Threshold", x = 15, y = 295, to = SMLSIZE }, + { t = "Acro Trainer", x = 5, y = 35, }, + { t = "Angle Limit", x = 15, y = 55, }, + { t = "Throttle Boost", x = 5, y = 75, }, + { t = "Absolute Control", x = 5, y = 95, }, + { t = "I Term Rotation", x = 5, y = 115, }, + { t = "VBAT Compensation", x = 5, y = 135, }, + { t = "I Term Relax", x = 5, y = 155, }, + { t = "Axes", x = 15, y = 175, }, + { t = "Type", x = 15, y = 195, }, + { t = "Integrated Yaw", x = 5, y = 215, }, + { t = "Anti Gravity", x = 5, y = 235, }, + { t = "Mode", x = 15, y = 255, }, + { t = "Gain", x = 15, y = 275, }, + { t = "Threshold", x = 15, y = 295, }, }, fields = { { x = 200, y = 55, min = 20, max = 80, vals = { 32 } }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua index 6b6f6428..98589722 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua @@ -1,22 +1,22 @@ return { text = { - { t = "P", x = 142, y = 48, to = MIDSIZE }, - { t = "I", x = 244, y = 48, to = MIDSIZE }, - { t = "D", x = 342, y = 48, to = MIDSIZE }, - { t = "ROLL", x = 28, y = 100 }, - { t = "PITCH", x = 28, y = 150 }, - { t = "YAW", x = 28, y = 200 }, + { t = "P", x = 142, y = 48, }, + { t = "I", x = 244, y = 48, }, + { t = "D", x = 342, y = 48, }, + { t = "ROLL", x = 28, y = 100, }, + { t = "PITCH", x = 28, y = 150, }, + { t = "YAW", x = 28, y = 200, }, }, fields = { - { x = 140, y = 100, min = 0, max = 200, vals = { 1 }, to = MIDSIZE }, - { x = 140, y = 150, min = 0, max = 200, vals = { 4 }, to = MIDSIZE }, - { x = 140, y = 200, min = 0, max = 200, vals = { 7 }, to = MIDSIZE }, - { x = 240, y = 100, min = 0, max = 200, vals = { 2 }, to = MIDSIZE }, - { x = 240, y = 150, min = 0, max = 200, vals = { 5 }, to = MIDSIZE }, - { x = 240, y = 200, min = 0, max = 200, vals = { 8 }, to = MIDSIZE }, - { x = 340, y = 100, min = 0, max = 200, vals = { 3 }, to = MIDSIZE }, - { x = 340, y = 150, min = 0, max = 200, vals = { 6 }, to = MIDSIZE }, - { x = 340, y = 200, min = 0, max = 200, vals = { 9 }, to = MIDSIZE }, + { x = 140, y = 100, min = 0, max = 200, vals = { 1 }, }, + { x = 140, y = 150, min = 0, max = 200, vals = { 4 }, }, + { x = 140, y = 200, min = 0, max = 200, vals = { 7 }, }, + { x = 240, y = 100, min = 0, max = 200, vals = { 2 }, }, + { x = 240, y = 150, min = 0, max = 200, vals = { 5 }, }, + { x = 240, y = 200, min = 0, max = 200, vals = { 8 }, }, + { x = 340, y = 100, min = 0, max = 200, vals = { 3 }, }, + { x = 340, y = 150, min = 0, max = 200, vals = { 6 }, }, + { x = 340, y = 200, min = 0, max = 200, vals = { 9 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua index d33bf91f..8aba0553 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua @@ -14,12 +14,12 @@ return { { t = "Advance", x = 300, y = 180, to = SMLSIZE }, }, fields = { - { x = 102, y = 100, min = 0, max = 2000, vals = { 33, 34 }, to = MIDSIZE }, - { x = 102, y = 150, min = 0, max = 2000, vals = { 35, 36 }, to = MIDSIZE }, - { x = 102, y = 200, min = 0, max = 2000, vals = { 37, 38 }, to = MIDSIZE }, - { x = 202, y = 100, min = 0, max = 100, vals = { 40 }, to = MIDSIZE }, - { x = 202, y = 150, min = 0, max = 100, vals = { 41 }, to = MIDSIZE }, - { x = 202, y = 200, min = 0, max = 100, vals = { 42 }, to = MIDSIZE }, + { x = 102, y = 100, min = 0, max = 2000, vals = { 33, 34 }, }, + { x = 102, y = 150, min = 0, max = 2000, vals = { 35, 36 }, }, + { x = 102, y = 200, min = 0, max = 2000, vals = { 37, 38 }, }, + { x = 202, y = 100, min = 0, max = 100, vals = { 40 }, }, + { x = 202, y = 150, min = 0, max = 100, vals = { 41 }, }, + { x = 202, y = 200, min = 0, max = 100, vals = { 42 }, }, { x = 390, y = 120, min = 0, max = 100, vals = { 9 }, scale = 100 }, { x = 390, y = 160, min = 0, max = 100, vals = { 43 } }, { x = 390, y = 180, min = 0, max = 200, vals = { 44 } }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua index a6e09e3f..46fbee51 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua @@ -9,17 +9,14 @@ return { { t = "Idle Offset", x = 232, y = 200 } }, fields = { - { x = 130, y = 68, vals = { 4 }, min = 0, max = 9, to = MIDSIZE, - table = { [0] = "OFF", "ONESHOT125", "ONESHOT42", - "MULTISHOT","BRUSHED", - "DSHOT150", "DSHOT300", "DSHOT600","DSHOT1200", - "PROSHOT1000" } + { x = 130, y = 68, vals = { 4 }, min = 0, max = 9, table = { [0] = "OFF", "ONESHOT125", "ONESHOT42", "MULTISHOT", "BRUSHED", "DSHOT150", "DSHOT300", + "DSHOT600", "DSHOT1200", "PROSHOT1000" } }, - { x = 130, y = 110, vals = { 9 }, min = 0, max = 1, to = MIDSIZE, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, - { x = 130, y = 155, vals = { 1 }, min = 1, max = 32, to = MIDSIZE, upd = function(self) self.updatePidRateTable(self) end }, - { x = 130, y = 200, vals = { 2 }, min = 1, max = 16, to = MIDSIZE }, - { x = 350, y = 110, vals = { 3 }, min = 0, max = 1, to = MIDSIZE, table = { [0] = "OFF", "ON" } }, - { x = 350, y = 155, vals = { 5, 6 }, min = 200, max = 32000, to = MIDSIZE }, - { x = 350, y = 200, vals = { 7, 8 }, min = 0, max = 2000, scale = 100, to = MIDSIZE }, + { x = 130, y = 110, vals = { 9 }, min = 0, max = 1, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, + { x = 130, y = 155, vals = { 1 }, min = 1, max = 32, upd = function(self) self.updatePidRateTable(self) end }, + { x = 130, y = 200, vals = { 2 }, min = 1, max = 16, }, + { x = 350, y = 110, vals = { 3 }, min = 0, max = 1, table = { [0] = "OFF", "ON" } }, + { x = 350, y = 155, vals = { 5, 6 }, min = 200, max = 32000, }, + { x = 350, y = 200, vals = { 7, 8 }, min = 0, max = 2000, scale = 100, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua index abb8b7b8..4137c7e1 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua @@ -1,35 +1,35 @@ return { text = { - { t = "RC", x = 100, y = 52 }, - { t = "Rate", x = 94, y = 70 }, - { t = "Super", x = 148, y = 52 }, - { t = "Rate", x = 152, y = 70 }, - { t = "RC", x = 214, y = 52 }, - { t = "Expo", x = 207, y = 70 }, - { t = "ROLL", x = 28, y = 100 }, - { t = "PITCH", x = 28, y = 150 }, - { t = "YAW", x = 28, y = 200 }, - { t = "Throttle", x = 290, y = 60 }, - { t = "Mid", x = 300, y = 80, to = SMLSIZE }, - { t = "Expo", x = 300, y = 100, to = SMLSIZE }, - { t = "Limit Type", x = 300, y = 120, to = SMLSIZE }, - { t = "Limit %", x = 300, y = 140, to = SMLSIZE }, - { t = "TPA", x = 290, y = 160 }, - { t = "Rate", x = 300, y = 180, to = SMLSIZE }, - { t = "Breakpoint", x = 300, y = 200, to = SMLSIZE }, + { t = "RC", x = 100, y = 52, }, + { t = "Rate", x = 94, y = 70, }, + { t = "Super", x = 148, y = 52, }, + { t = "Rate", x = 152, y = 70, }, + { t = "RC", x = 214, y = 52, }, + { t = "Expo", x = 207, y = 70, }, + { t = "ROLL", x = 28, y = 100, }, + { t = "PITCH", x = 28, y = 150, }, + { t = "YAW", x = 28, y = 200, }, + { t = "Throttle", x = 290, y = 60, }, + { t = "Mid", x = 300, y = 80, }, + { t = "Expo", x = 300, y = 100, }, + { t = "Limit Type", x = 300, y = 120, }, + { t = "Limit %", x = 300, y = 140, }, + { t = "TPA", x = 290, y = 160, }, + { t = "Rate", x = 300, y = 180, }, + { t = "Breakpoint", x = 300, y = 200, }, }, fields = { - { x = 102, y = 100, vals = { 1 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - { x = 102, y = 150, vals = { 13 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - { x = 102, y = 200, vals = { 12 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - { x = 158, y = 100, vals = { 3 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - { x = 158, y = 150, vals = { 4 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - { x = 158, y = 200, vals = { 5 }, min = 0, max = 255, scale = 100, to = MIDSIZE }, - { x = 216, y = 100, vals = { 2 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - { x = 216, y = 150, vals = { 14 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - { x = 216, y = 200, vals = { 11 }, min = 0, max = 100, scale = 100, to = MIDSIZE }, - { x = 390, y = 80, vals = { 7 }, min = 0, max = 100, scale = 100 }, - { x = 390, y = 100, vals = { 8 }, min = 0, max = 100, scale = 100 }, + { x = 102, y = 100, vals = { 1 }, min = 0, max = 255, scale = 100, }, + { x = 102, y = 150, vals = { 13 }, min = 0, max = 255, scale = 100, }, + { x = 102, y = 200, vals = { 12 }, min = 0, max = 255, scale = 100, }, + { x = 158, y = 100, vals = { 3 }, min = 0, max = 100, scale = 100, }, + { x = 158, y = 150, vals = { 4 }, min = 0, max = 100, scale = 100, }, + { x = 158, y = 200, vals = { 5 }, min = 0, max = 255, scale = 100, }, + { x = 216, y = 100, vals = { 2 }, min = 0, max = 100, scale = 100, }, + { x = 216, y = 150, vals = { 14 }, min = 0, max = 100, scale = 100, }, + { x = 216, y = 200, vals = { 11 }, min = 0, max = 100, scale = 100, }, + { x = 390, y = 80, vals = { 7 }, min = 0, max = 100, scale = 100, }, + { x = 390, y = 100, vals = { 8 }, min = 0, max = 100, scale = 100, }, { x = 390, y = 120, vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, { x = 390, y = 140, vals = { 16 }, min = 25, max = 100 }, { x = 390, y = 180, vals = { 6 }, min = 0, max = 100, scale = 100 }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua index 4360ea53..c1b6e715 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua @@ -1,25 +1,25 @@ return { text = { - { t = "Min Sats.", x =130, y = 40, to = MIDSIZE }, - { t = "Angle", x =150, y = 80, to = MIDSIZE }, - { t = "Initial Altitude", x = 60, y = 120, to = MIDSIZE }, - { t = "Descent Distance", x = 10, y = 160, to = MIDSIZE }, - { t = "Ground Speed", x = 50, y = 200, to = MIDSIZE }, - { t = "Snty.", x = 310, y = 40, to = MIDSIZE }, - { t = "Throttle", x = 350, y = 80, to = MIDSIZE }, - { t = "Min", x = 330, y = 120, to = MIDSIZE }, - { t = "Hover", x = 310, y = 160, to = MIDSIZE }, - { t = "Max", x = 330, y = 200, to = MIDSIZE }, + { t = "Min Sats.", x =130, y = 40, }, + { t = "Angle", x =150, y = 80, }, + { t = "Initial Altitude", x = 60, y = 120, }, + { t = "Descent Distance", x = 10, y = 160, }, + { t = "Ground Speed", x = 50, y = 200, }, + { t = "Snty.", x = 310, y = 40, }, + { t = "Throttle", x = 350, y = 80, }, + { t = "Min", x = 330, y = 120, }, + { t = "Hover", x = 310, y = 160, }, + { t = "Max", x = 330, y = 200, }, }, fields = { - { x = 260, y = 40, min = 0, max = 50, vals = { 16 }, to = MIDSIZE }, - { x = 260, y = 80, min = 0, max = 200, vals = { 1,2 }, to = MIDSIZE }, - { x = 260, y = 120, min = 20, max = 100, vals = { 3,4 }, to = MIDSIZE }, - { x = 260, y = 160, min = 30, max = 500, vals = { 5,6 }, to = MIDSIZE }, - { x = 260, y = 200, min = 30, max =3000, vals = { 7,8 }, to = MIDSIZE }, - { x = 400, y = 40, min = 0, max = 2 , vals = { 15 }, to = MIDSIZE,table = { [0]="OFF","ON","FS_ONLY"}}, - { x = 400, y = 120, min = 1000, max = 2000, vals = { 9,10 }, to = MIDSIZE }, - { x = 400, y = 160, min = 1000, max = 2000, vals = { 13,14 }, to = MIDSIZE }, - { x = 400, y = 200, min = 1000, max = 2000, vals = { 11,12 }, to = MIDSIZE }, + { x = 260, y = 40, min = 0, max = 50, vals = { 16 }, }, + { x = 260, y = 80, min = 0, max = 200, vals = { 1,2 }, }, + { x = 260, y = 120, min = 20, max = 100, vals = { 3,4 }, }, + { x = 260, y = 160, min = 30, max = 500, vals = { 5,6 }, }, + { x = 260, y = 200, min = 30, max =3000, vals = { 7,8 }, }, + { x = 400, y = 40, min = 0, max = 2 , vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"}}, + { x = 400, y = 120, min = 1000, max = 2000, vals = { 9,10 }, }, + { x = 400, y = 160, min = 1000, max = 2000, vals = { 13,14 }, }, + { x = 400, y = 200, min = 1000, max = 2000, vals = { 11,12 }, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua index 6c76ce48..6ffc67c6 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua @@ -8,11 +8,11 @@ return { { t = "Interp Int", x = 232, y = 155 } }, fields = { - { x = 130, y = 68, min = 1000, max = 2000, vals = { 6, 7 }, to = MIDSIZE }, - { x = 130, y = 110, min = 1000, max = 2000, vals = { 4, 5 }, to = MIDSIZE }, - { x = 130, y = 155, min = 1000, max = 2000, vals = { 2, 3 }, to = MIDSIZE }, - { x = 350, y = 68, min = 0, max = 90, vals = { 23 }, to = MIDSIZE }, - { x = 350, y = 110, min = 0, max = 3, vals = { 13 }, to = MIDSIZE, table={ [0]="Off", "Preset", "Auto", "Manual"} }, - { x = 350, y = 155, min = 1, max = 50, vals = { 14 }, to = MIDSIZE } + { x = 130, y = 68, min = 1000, max = 2000, vals = { 6, 7 }, }, + { x = 130, y = 110, min = 1000, max = 2000, vals = { 4, 5 }, }, + { x = 130, y = 155, min = 1000, max = 2000, vals = { 2, 3 }, }, + { x = 350, y = 68, min = 0, max = 90, vals = { 23 }, }, + { x = 350, y = 110, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} }, + { x = 350, y = 155, min = 1, max = 50, vals = { 14 }, } }, } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua b/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua index ee3147cf..56d2b9c9 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua @@ -8,11 +8,11 @@ return { { t = "Freq", x = 232, y = 68 }, }, fields = { - { x = 130, y = 110, min=0, max=5, vals = { 2 }, to = MIDSIZE, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, - { x = 130, y = 155, min=1, max=8, vals = { 3 }, to = MIDSIZE, upd = function(self) self.handleBandChanUpdate(self) end }, - { x = 350, y = 110, min=1, vals = { 4 }, to = MIDSIZE, upd = function(self) self.updatePowerTable(self) end }, - { x = 350, y = 155, min=0, max=1, vals = { 5 }, to = MIDSIZE, table = { [0]="OFF", "ON" } }, - { x = 130, y = 68, vals = { 1 }, to = MIDSIZE, write = false, ro = true, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, - { x = 350, y = 68, min = 5000, max = 5999, vals = { 6 }, to = MIDSIZE, upd = function(self) self.handleFreqValUpdate(self) end }, + { x = 130, y = 110, min=0, max=5, vals = { 2 }, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, + { x = 130, y = 155, min=1, max=8, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, + { x = 350, y = 110, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, + { x = 350, y = 155, min=0, max=1, vals = { 5 }, table = { [0]="OFF", "ON" } }, + { x = 130, y = 68, vals = { 1 }, write = false, ro = true, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, + { x = 350, y = 68, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index ec025e46..6ed6b2f9 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -13,6 +13,7 @@ local supportedRadios = MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, NoTelem = { 30, 55, "No Telemetry", BLINK }, + textSize = SMLSIZE, }, ["212x64"] = { @@ -21,6 +22,7 @@ local supportedRadios = MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 }, SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, NoTelem = { 70, 55, "No Telemetry", BLINK }, + textSize = SMLSIZE, }, ["480x272"] = { @@ -29,6 +31,7 @@ local supportedRadios = MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, NoTelem = { 192, LCD_H - 28, "No Telemetry", BLINK }, + textSize = MIDSIZE, }, ["320x480"] = { @@ -37,6 +40,7 @@ local supportedRadios = MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", BLINK }, + textSize = MIDSIZE, }, } diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 1cae9749..dac64b35 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -194,7 +194,7 @@ local function drawScreen() end for i=1,#(Page.text) do local f = Page.text[i] - local textOptions = (f.to or 0) + globalTextOptions + local textOptions = radio.textSize + globalTextOptions if (f.y - scrollPixelsY) >= yMinLim and (f.y - scrollPixelsY) <= yMaxLim then lcd.drawText(f.x, f.y - scrollPixelsY, f.t, textOptions) end @@ -202,7 +202,7 @@ local function drawScreen() local val = "---" for i=1,#(Page.fields) do local f = Page.fields[i] - local text_options = (f.to or 0) + globalTextOptions + local text_options = radio.textSize + globalTextOptions local heading_options = text_options local value_options = text_options if i == currentLine then From 03e0efc17a5014662da064eb9439bceeea3caeea Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 16 Oct 2019 23:54:23 +0100 Subject: [PATCH 019/193] separate fields and layout. --- src/SCRIPTS/BF/LAYOUT/128x64/filters.lua | 44 +++++++++---------- src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua | 16 +++---- src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua | 24 +++++----- src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua | 20 ++++----- src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua | 20 ++++----- src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua | 14 +++--- src/SCRIPTS/BF/LAYOUT/128x64/rates.lua | 30 ++++++------- src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua | 41 +++++++++-------- src/SCRIPTS/BF/LAYOUT/128x64/rx.lua | 27 +++++++----- src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua | 23 ++++++---- src/SCRIPTS/BF/LAYOUT/212x64/filters.lua | 44 +++++++++---------- src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua | 16 +++---- src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua | 24 +++++----- src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua | 20 ++++----- src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua | 20 ++++----- src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua | 30 ++++++------- src/SCRIPTS/BF/LAYOUT/212x64/rates.lua | 32 +++++++------- src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua | 40 ++++++++--------- src/SCRIPTS/BF/LAYOUT/212x64/rx.lua | 23 ++++++---- src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua | 23 ++++++---- src/SCRIPTS/BF/LAYOUT/320x480/filters.lua | 44 +++++++++---------- src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua | 16 +++---- .../BF/LAYOUT/320x480/pid_advanced.lua | 24 +++++----- src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua | 20 ++++----- src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua | 30 ++++++------- src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua | 29 +++++------- src/SCRIPTS/BF/LAYOUT/320x480/rates.lua | 32 +++++++------- src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua | 40 ++++++++--------- src/SCRIPTS/BF/LAYOUT/320x480/rx.lua | 14 +++--- src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua | 14 +++--- src/SCRIPTS/BF/LAYOUT/480x272/filters.lua | 44 +++++++++---------- src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua | 28 ++++++------ .../BF/LAYOUT/480x272/pid_advanced.lua | 24 +++++----- src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua | 20 ++++----- src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua | 44 +++++++++---------- src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua | 20 ++++----- src/SCRIPTS/BF/LAYOUT/480x272/rates.lua | 32 +++++++------- src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua | 32 +++++++------- src/SCRIPTS/BF/LAYOUT/480x272/rx.lua | 16 +++---- src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua | 14 +++--- src/SCRIPTS/BF/PAGES/filters.lua | 25 ++++++++++- src/SCRIPTS/BF/PAGES/gpspids.lua | 11 ++++- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 15 ++++++- src/SCRIPTS/BF/PAGES/pids1.lua | 13 +++++- src/SCRIPTS/BF/PAGES/pids2.lua | 13 +++++- src/SCRIPTS/BF/PAGES/pwm.lua | 11 ++++- src/SCRIPTS/BF/PAGES/rates.lua | 19 +++++++- src/SCRIPTS/BF/PAGES/rescue.lua | 13 +++++- src/SCRIPTS/BF/PAGES/rx.lua | 28 +++++++----- src/SCRIPTS/BF/PAGES/vtx.lua | 16 +++++-- src/SCRIPTS/BF/ui.lua | 22 +++------- 51 files changed, 691 insertions(+), 563 deletions(-) diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua index 074045ff..7553b09a 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua @@ -34,27 +34,27 @@ return { { t = "Yaw Lowpass", x = 2, y = 244, }, { t = "Cutoff", x = 12, y = 252, }, }, - fields = { - { x = 87, y = 20, min = 0, max = 1000, vals = { 30, 31 } }, - { x = 87, y = 28, min = 0, max = 1000, vals = { 32, 33 } }, - { x = 87, y = 36, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 52, min = 0, max = 16000, vals = { 21, 22 } }, - { x = 87, y = 60, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 76, min = 0, max = 16000, vals = { 23, 24 } }, - { x = 87, y = 84, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 100, min = 0, max = 16000, vals = { 6, 7 } }, - { x = 87, y = 108, min = 0, max = 16000, vals = { 8, 9 } }, - { x = 87, y = 124, min = 0, max = 16000, vals = { 14, 15 } }, - { x = 87, y = 132, min = 0, max = 16000, vals = { 16, 17 } }, - { x = 87, y = 148, min = 0, max = 1000, vals = { 34, 35 } }, - { x = 87, y = 156, min = 0, max = 1000, vals = { 36, 37 } }, - { x = 87, y = 164, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 180, min = 0, max = 16000, vals = { 2, 3 } }, - { x = 87, y = 188, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 204, min = 0, max = 16000, vals = { 27, 28 } }, - { x = 87, y = 212, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 228, min = 0, max = 16000, vals = { 10, 11 } }, - { x = 87, y = 236, min = 0, max = 16000, vals = { 12, 13 } }, - { x = 87, y = 252, min = 0, max = 500, vals = { 4, 5 } }, + fieldLayout = { + { x = 87, y = 20, }, + { x = 87, y = 28, }, + { x = 87, y = 36, }, + { x = 87, y = 52, }, + { x = 87, y = 60, }, + { x = 87, y = 76, }, + { x = 87, y = 84, }, + { x = 87, y = 100, }, + { x = 87, y = 108, }, + { x = 87, y = 124, }, + { x = 87, y = 132, }, + { x = 87, y = 148, }, + { x = 87, y = 156, }, + { x = 87, y = 164, }, + { x = 87, y = 180, }, + { x = 87, y = 188, }, + { x = 87, y = 204, }, + { x = 87, y = 212, }, + { x = 87, y = 228, }, + { x = 87, y = 236, }, + { x = 87, y = 252, }, } } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua index 4cb3cdbd..998f0b65 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua @@ -7,13 +7,13 @@ return { { t = "Velocity", x = 5, y = 36, }, { t = "Yaw" , x = 5, y = 46, }, }, - fields = { - { x = 51, y = 26, min = 0, max = 200, vals = { 1,2 }, }, - { x = 51, y = 36, min = 0, max = 200, vals = { 7,8 }, }, - { x = 51, y = 46, min = 0, max = 500, vals = { 13,14 }, }, - { x = 79, y = 26, min = 0, max = 200, vals = { 3,4 }, }, - { x = 79, y = 36, min = 0, max = 200, vals = { 9,10 }, }, - { x = 107, y = 26, min = 0, max = 200, vals = { 5,6 }, }, - { x = 107, y = 36, min = 0, max = 200, vals = { 11,12 }, }, + fieldLayout = { + { x = 51, y = 26, }, + { x = 51, y = 36, }, + { x = 51, y = 46, }, + { x = 79, y = 26, }, + { x = 79, y = 36, }, + { x = 107, y = 26, }, + { x = 107, y = 36, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua index 79b55498..262b678d 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua @@ -17,17 +17,17 @@ return { { t = "Gain", x = 12, y = 108, }, { t = "Threshold", x = 12, y = 116, }, }, - fields = { - { x = 87, y = 20, to=SMLSIZE, min = 20, max = 80, vals = { 32 } }, - { x = 87, y = 28, to=SMLSIZE, min = 0, max = 100, vals = { 31 } }, - { x = 87, y = 36, to=SMLSIZE, min = 0, max = 20, vals = { 30 } }, - { x = 87, y = 44, to=SMLSIZE, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } }, - { x = 87, y = 52, to=SMLSIZE, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } }, - { x = 87, y = 68, to=SMLSIZE, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } }, - { x = 87, y = 76, to=SMLSIZE, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } }, - { x = 87, y = 84, to=SMLSIZE, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } }, - { x = 87, y = 100, to=SMLSIZE, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } }, - { x = 87, y = 108, to=SMLSIZE, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 }, - { x = 87, y = 116, to=SMLSIZE, min = 20, max = 1000, vals = { 20, 21 } }, + fieldLayout = { + { x = 87, y = 20, }, + { x = 87, y = 28, }, + { x = 87, y = 36, }, + { x = 87, y = 44, }, + { x = 87, y = 52, }, + { x = 87, y = 68, }, + { x = 87, y = 76, }, + { x = 87, y = 84, }, + { x = 87, y = 100, }, + { x = 87, y = 108, }, + { x = 87, y = 116, }, } } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua index 4cb333e8..7e3dce95 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua @@ -7,15 +7,15 @@ return { { t = "PITCH", x = 10, y = 36, }, { t = "YAW", x = 10, y = 46, }, }, - fields = { - { x = 41, y = 26, min = 0, max = 200, vals = { 1 }, }, - { x = 41, y = 36, min = 0, max = 200, vals = { 4 }, }, - { x = 41, y = 46, min = 0, max = 200, vals = { 7 }, }, - { x = 69, y = 26, min = 0, max = 200, vals = { 2 }, }, - { x = 69, y = 36, min = 0, max = 200, vals = { 5 }, }, - { x = 69, y = 46, min = 0, max = 200, vals = { 8 }, }, - { x = 97, y = 26, min = 0, max = 200, vals = { 3 }, }, - { x = 97, y = 36, min = 0, max = 200, vals = { 6 }, }, - { x = 97, y = 46, min = 0, max = 200, vals = { 9 }, }, + fieldLayout = { + { x = 41, y = 26, }, + { x = 41, y = 36, }, + { x = 41, y = 46, }, + { x = 69, y = 26, }, + { x = 69, y = 36, }, + { x = 69, y = 46, }, + { x = 97, y = 26, }, + { x = 97, y = 36, }, + { x = 97, y = 46, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua index e2e0e145..041cea90 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua @@ -15,15 +15,15 @@ return { { t = "Gain", x = 20, y = 84, }, { t = "Advance", x = 20, y = 92, }, }, - fields = { - { x = 48, y = 26, min = 0, max = 2000, vals = { 33, 34 }, }, - { x = 48, y = 36, min = 0, max = 2000, vals = { 35, 36 }, }, - { x = 48, y = 46, min = 0, max = 2000, vals = { 37, 38 }, }, - { x = 80, y = 26, min = 0, max = 100, vals = { 40 }, }, - { x = 80, y = 36, min = 0, max = 100, vals = { 41 }, }, - { x = 80, y = 46, min = 0, max = 100, vals = { 42 }, }, - { x = 80, y = 68, min = 0, max = 100, vals = { 9 }, scale = 100 }, - { x = 80, y = 84, min = 0, max = 100, vals = { 43 }, }, - { x = 80, y = 92, min = 0, max = 200, vals = { 44 }, }, + fieldLayout = { + { x = 48, y = 26, }, + { x = 48, y = 36, }, + { x = 48, y = 46, }, + { x = 80, y = 26, }, + { x = 80, y = 36, }, + { x = 80, y = 46, }, + { x = 80, y = 68, }, + { x = 80, y = 84, }, + { x = 80, y = 92, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua index a58eae39..d7125a2e 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua @@ -9,12 +9,12 @@ return { { t = "Idle", x = 58, y = 44, } }, fields = { - { x = 32, y = 14, vals = { 9 }, min = 0, max = 1, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, - { x = 32, y = 24, vals = { 1 }, min = 1, max = 32, upd = function(self) self.updatePidRateTable(self) end }, - { x = 32, y = 34, vals = { 2 }, min = 1, max = 16, }, - { x = 90, y = 14, vals = { 4 }, min = 0, max = 9, table = { [0] = "OFF", "OS125", "OS42", "MSHOT","BRSH", "DS150", "DS300", "DS600","DS1200", "PS1000" } }, - { x = 90, y = 24, vals = { 3 }, min = 0, max = 1, table = { [0] = "OFF", "ON" } }, - { x = 90, y = 34, vals = { 5, 6 }, min = 200, max = 32000, }, - { x = 90, y = 44, vals = { 7, 8 }, min = 0, max = 2000, scale = 100 }, + { x = 32, y = 14, }, + { x = 32, y = 24, }, + { x = 32, y = 34, }, + { x = 90, y = 14, }, + { x = 90, y = 24, }, + { x = 90, y = 34, }, + { x = 90, y = 44, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua index 7781a363..17fb26b8 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua @@ -21,20 +21,20 @@ return { { t = "Breakpoint", x = 20, y = 116, }, }, fields = { - { x = 39, y = 26, vals = { 1 }, min = 0, max = 255, scale = 100, }, - { x = 39, y = 36, vals = { 13 }, min = 0, max = 255, scale = 100, }, - { x = 39, y = 46, vals = { 12 }, min = 0, max = 255, scale = 100, }, - { x = 66, y = 26, vals = { 3 }, min = 0, max = 100, scale = 100, }, - { x = 66, y = 36, vals = { 4 }, min = 0, max = 100, scale = 100, }, - { x = 66, y = 46, vals = { 5 }, min = 0, max = 255, scale = 100, }, - { x = 94, y = 26, vals = { 2 }, min = 0, max = 100, scale = 100, }, - { x = 94, y = 36, vals = { 14 }, min = 0, max = 100, scale = 100, }, - { x = 94, y = 46, vals = { 11 }, min = 0, max = 100, scale = 100, }, - { x = 70, y = 68, vals = { 7 }, min = 0, max = 100, scale = 100, }, - { x = 70, y = 76, vals = { 8 }, min = 0, max = 100, scale = 100, }, - { x = 70, y = 84, vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, - { x = 70, y = 92, vals = { 16 }, min = 25, max = 100, }, - { x = 70, y = 108, vals = { 6 } , min = 0, max = 100, scale = 100, }, - { x = 70, y = 116, vals = { 9, 10 }, min = 1000, max = 2000, }, + { x = 39, y = 26, }, + { x = 39, y = 36, }, + { x = 39, y = 46, }, + { x = 66, y = 26, }, + { x = 66, y = 36, }, + { x = 66, y = 46, }, + { x = 94, y = 26, }, + { x = 94, y = 36, }, + { x = 94, y = 46, }, + { x = 70, y = 68, }, + { x = 70, y = 76, }, + { x = 70, y = 84, }, + { x = 70, y = 92, }, + { x = 70, y = 108, }, + { x = 70, y = 116, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua index 78b2a0c9..b91353ba 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua @@ -1,26 +1,25 @@ return { text = { - - { t = "Min Sats.", x = 3, y = 10, }, - { t = "Angle", x = 3, y = 20, }, - { t = "Initial Alt", x = 3, y = 30, }, - { t = "Descent Dst", x = 3, y = 40, }, - { t = "Ground Spd", x = 3, y = 50, }, - { t = "Snty.", x = 80, y = 10, }, - { t = "Throttle", x = 80, y = 20, }, - { t = "Min", x = 85, y = 30, }, - { t = "Hover", x = 80, y = 40, }, - { t = "Max", x = 85, y = 50, }, + { t = "Min Sats.", x = 3, y = 10, }, + { t = "Angle", x = 3, y = 20, }, + { t = "Initial Alt", x = 3, y = 30, }, + { t = "Descent Dst", x = 3, y = 40, }, + { t = "Ground Spd", x = 3, y = 50, }, + { t = "Snty.", x = 80, y = 10, }, + { t = "Throttle", x = 80, y = 20, }, + { t = "Min", x = 85, y = 30, }, + { t = "Hover", x = 80, y = 40, }, + { t = "Max", x = 85, y = 50, }, }, - fields = { - { x = 58, y = 10, min = 0, max = 50, vals = { 16 }, }, - { x = 58, y = 20, min = 0, max = 200, vals = { 1,2 }, }, - { x = 58, y = 30, min = 20, max = 100, vals = { 3,4 }, }, - { x = 58, y = 40, min = 30, max = 500, vals = { 5,6 }, }, - { x = 58, y = 50, min = 30, max =3000, vals = { 7,8 }, }, - { x = 105, y = 10, min = 0, max = 2 , vals = { 15 } ,table = { [0]="OFF","ON","FS_ONLY"}, }, - { x = 105, y = 30, min = 1000, max = 2000, vals = { 9,10 }, }, - { x = 105, y = 40, min = 1000, max = 2000, vals = { 13,14 }, }, - { x = 105, y = 50, min = 1000, max = 2000, vals = { 11,12 }, }, + fieldLayout = { + { x = 58, y = 10, }, + { x = 58, y = 20, }, + { x = 58, y = 30, }, + { x = 58, y = 40, }, + { x = 58, y = 50, }, + { x = 105, y = 10, }, + { x = 105, y = 30, }, + { x = 105, y = 40, }, + { x = 105, y = 50, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua index 5e77753f..67aaa6b7 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua @@ -1,13 +1,18 @@ return { - yMinLimit = 12, - yMaxLimit = 52, - text = {}, - fields = { - { t = "Stick Min", x = 10, y = 20, sp = 45, min = 1000, max = 2000, vals = { 6, 7 }, }, - { t = "Stick Mid", x = 10, y = 30, sp = 45, min = 1000, max = 2000, vals = { 4, 5 }, }, - { t = "Stick Max", x = 10, y = 40, sp = 45, min = 1000, max = 2000, vals = { 2, 3 }, }, - { t = "Cam Angle", x = 10, y = 50, sp = 50, min = 0, max = 90, vals = { 23 }, }, - { t = "Interp", x = 10, y = 60, sp = 50, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} }, - { t = "Interp Int", x = 10, y = 70, sp = 50, min = 1, max = 50, vals = { 14 }, }, - }, + text= { + { t = "Stick Min", x = 10, y = 20 }, + { t = "Stick Mid", x = 10, y = 30 }, + { t = "Stick Max", x = 10, y = 40 }, + { t = "Cam Angle", x = 10, y = 50 }, + { t = "Interp", x = 10, y = 60 }, + { t = "Interp Int", x = 10, y = 70 }, + }, + fieldLayout = { + { x = 70, y = 20, }, + { x = 70, y = 30, }, + { x = 70, y = 40, }, + { x = 70, y = 50, }, + { x = 70, y = 60, }, + { x = 70, y = 70, } + }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua index af664f98..c154bd61 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua @@ -1,11 +1,18 @@ return { - text = {}, - fields = { - { t = "Band", x = 10, y = 14, sp = 30, min=0, max=5, vals = { 2 }, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, - { t = "Chan", x = 10, y = 24, sp = 30, min=1, max=8, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, - { t = "Power", x = 10, y = 34, sp = 30, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, - { t = "Pit", x = 10, y = 44, sp = 30, min=0, max=1, vals = { 5 }, table = { [0]="OFF", "ON" } }, - { t = "Dev", x = 70, y = 14, sp = 25, write = false, ro = true, vals = { 1 }, table = { [1]="6705",[3]="SA",[4]="Tramp",[255]="None"} }, - { t = "Freq", x = 70, y = 24, sp = 25, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, + text= { + { t = "Band", x = 10, y = 14 }, + { t = "Channel", x = 10, y = 24 }, + { t = "Power", x = 10, y = 34 }, + { t = "Pit", x = 10, y = 44 }, + { t = "Proto", x = 70, y = 14 }, + { t = "Freq", x = 70, y = 24 }, + }, + fieldLayout = { + { x = 40, y = 14, }, + { x = 40, y = 24, }, + { x = 40, y = 34, }, + { x = 40, y = 44, }, + { x = 100, y = 14, }, + { x = 100, y = 24, }, }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua index 074045ff..97ba3a96 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua @@ -34,27 +34,27 @@ return { { t = "Yaw Lowpass", x = 2, y = 244, }, { t = "Cutoff", x = 12, y = 252, }, }, - fields = { - { x = 87, y = 20, min = 0, max = 1000, vals = { 30, 31 } }, - { x = 87, y = 28, min = 0, max = 1000, vals = { 32, 33 } }, - { x = 87, y = 36, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 52, min = 0, max = 16000, vals = { 21, 22 } }, - { x = 87, y = 60, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 76, min = 0, max = 16000, vals = { 23, 24 } }, - { x = 87, y = 84, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 100, min = 0, max = 16000, vals = { 6, 7 } }, - { x = 87, y = 108, min = 0, max = 16000, vals = { 8, 9 } }, - { x = 87, y = 124, min = 0, max = 16000, vals = { 14, 15 } }, - { x = 87, y = 132, min = 0, max = 16000, vals = { 16, 17 } }, - { x = 87, y = 148, min = 0, max = 1000, vals = { 34, 35 } }, - { x = 87, y = 156, min = 0, max = 1000, vals = { 36, 37 } }, - { x = 87, y = 164, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 180, min = 0, max = 16000, vals = { 2, 3 } }, - { x = 87, y = 188, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 204, min = 0, max = 16000, vals = { 27, 28 } }, - { x = 87, y = 212, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 87, y = 228, min = 0, max = 16000, vals = { 10, 11 } }, - { x = 87, y = 236, min = 0, max = 16000, vals = { 12, 13 } }, - { x = 87, y = 252, min = 0, max = 500, vals = { 4, 5 } }, + fieldLayout = { + { x = 87, y = 20, }, + { x = 87, y = 28, }, + { x = 87, y = 36, }, + { x = 87, y = 52, }, + { x = 87, y = 60, }, + { x = 87, y = 76, }, + { x = 87, y = 84, }, + { x = 87, y = 100, }, + { x = 87, y = 108, }, + { x = 87, y = 124, }, + { x = 87, y = 132, }, + { x = 87, y = 148, }, + { x = 87, y = 156, }, + { x = 87, y = 164, }, + { x = 87, y = 180, }, + { x = 87, y = 188, }, + { x = 87, y = 204, }, + { x = 87, y = 212, }, + { x = 87, y = 228, }, + { x = 87, y = 236, }, + { x = 87, y = 252, }, } } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua index 0b706a0e..5a2b5f7f 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua @@ -7,13 +7,13 @@ return { { t = "Velocity", x = 25, y = 36, }, { t = "Yaw", x = 25, y = 46, }, }, - fields = { - { x = 66, y = 26, min = 0, max = 500, vals = { 1,2 }, }, - { x = 66, y = 36, min = 0, max = 500, vals = { 7,8 }, }, - { x = 66, y = 46, min = 0, max = 500, vals = {13,14}, }, - { x = 94, y = 26, min = 0, max = 500, vals = { 3,4 }, }, - { x = 94, y = 36, min = 0, max = 500, vals = { 9,10 }, }, - { x = 122, y = 26, min = 0, max = 500, vals = { 5,6 }, }, - { x = 122, y = 36, min = 0, max = 500, vals = { 11,12 }, }, + fieldLayout = { + { x = 66, y = 26, }, + { x = 66, y = 36, }, + { x = 66, y = 46, }, + { x = 94, y = 26, }, + { x = 94, y = 36, }, + { x = 122, y = 26, }, + { x = 122, y = 36, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua index 6ad5638e..262b678d 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua @@ -17,17 +17,17 @@ return { { t = "Gain", x = 12, y = 108, }, { t = "Threshold", x = 12, y = 116, }, }, - fields = { - { x = 87, y = 20, to=SMLSIZE, min = 20, max = 80, vals = { 32 } }, - { x = 87, y = 28, to=SMLSIZE, min = 0, max = 100, vals = { 31 } }, - { x = 87, y = 36, to=SMLSIZE, min = 0, max = 20, vals = { 30 } }, - { x = 87, y = 44, to=SMLSIZE, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } }, - { x = 87, y = 52, to=SMLSIZE, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } }, - { x = 87, y = 68, to=SMLSIZE, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (increment only)", "RPY (increment only)" } }, - { x = 87, y = 76, to=SMLSIZE, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } }, - { x = 87, y = 84, to=SMLSIZE, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } }, - { x = 87, y = 100, to=SMLSIZE, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } }, - { x = 87, y = 108, to=SMLSIZE, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 }, - { x = 87, y = 116, to=SMLSIZE, min = 20, max = 1000, vals = { 20, 21 } }, + fieldLayout = { + { x = 87, y = 20, }, + { x = 87, y = 28, }, + { x = 87, y = 36, }, + { x = 87, y = 44, }, + { x = 87, y = 52, }, + { x = 87, y = 68, }, + { x = 87, y = 76, }, + { x = 87, y = 84, }, + { x = 87, y = 100, }, + { x = 87, y = 108, }, + { x = 87, y = 116, }, } } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua index fe624022..791d52c5 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua @@ -7,15 +7,15 @@ return { { t = "PITCH", x = 25, y = 36, }, { t = "YAW", x = 25, y = 46, }, }, - fields = { - { x = 66, y = 26, min = 0, max = 200, vals = { 1 }, }, - { x = 66, y = 36, min = 0, max = 200, vals = { 4 }, }, - { x = 66, y = 46, min = 0, max = 200, vals = { 7 }, }, - { x = 94, y = 26, min = 0, max = 200, vals = { 2 }, }, - { x = 94, y = 36, min = 0, max = 200, vals = { 5 }, }, - { x = 94, y = 46, min = 0, max = 200, vals = { 8 }, }, - { x = 122, y = 26, min = 0, max = 200, vals = { 3 }, }, - { x = 122, y = 36, min = 0, max = 200, vals = { 6 }, }, - { x = 122, y = 46, min = 0, max = 200, vals = { 9 }, }, + fieldLayout = { + { x = 66, y = 26, }, + { x = 66, y = 36, }, + { x = 66, y = 46, }, + { x = 94, y = 26, }, + { x = 94, y = 36, }, + { x = 94, y = 46, }, + { x = 122, y = 26, }, + { x = 122, y = 36, }, + { x = 122, y = 46, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua index d54a441b..17da5c79 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua @@ -13,15 +13,15 @@ return { { t = "Gain", x = 120, y = 38, }, { t = "Advance", x = 120, y = 46, }, }, - fields = { - { x = 49, y = 26, min = 0, max = 2000, vals = { 33, 34 }, }, - { x = 49, y = 36, min = 0, max = 2000, vals = { 35, 36 }, }, - { x = 49, y = 46, min = 0, max = 2000, vals = { 37, 38 }, }, - { x = 81, y = 26, min = 0, max = 100, vals = { 40 }, }, - { x = 81, y = 36, min = 0, max = 100, vals = { 41 }, }, - { x = 81, y = 46, min = 0, max = 100, vals = { 42 }, }, - { x = 180, y = 22, min = 0, max = 100, vals = { 9 }, scale = 100 }, - { x = 180, y = 38, min = 0, max = 100, vals = { 43 }, }, - { x = 180, y = 46, min = 0, max = 200, vals = { 44 }, }, + fieldLayout = { + { x = 49, y = 26, }, + { x = 49, y = 36, }, + { x = 49, y = 46, }, + { x = 81, y = 26, }, + { x = 81, y = 36, }, + { x = 81, y = 46, }, + { x = 180, y = 22, }, + { x = 180, y = 38, }, + { x = 180, y = 46, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua index 17a961f2..b2c45f31 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua @@ -1,20 +1,20 @@ return { text= { - { t = "32K", x = 48, y = 14, }, - { t = "Gyro Rt", x = 29, y = 24, }, - { t = "PID Rt", x = 35, y = 34, }, - { t = "Protocol", x = 107, y = 14, }, - { t = "Unsynced", x = 106, y = 24, }, - { t = "PWM Rate", x = 105, y = 34, }, - { t = "Idle Offset", x =94, y = 44, } + { t = "32K", x = 48, y = 14, }, + { t = "Gyro Rt", x = 29, y = 24, }, + { t = "PID Rt", x = 35, y = 34, }, + { t = "Protocol", x = 107, y = 14, }, + { t = "Unsynced", x = 106, y = 24, }, + { t = "PWM Rate", x = 105, y = 34, }, + { t = "Idle Offset", x = 94, y = 44, } }, - fields = { - { x = 65, y = 14, vals = { 9 }, min = 0, max = 1, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, - { x = 65, y = 24, vals = { 1 }, min = 1, max = 32, upd = function(self) self.updatePidRateTable(self) end }, - { x = 65, y = 34, vals = { 2 }, min = 1, max = 16, }, - { x = 148, y = 14, vals = { 4 }, min = 0, max = 9, table = { [0] = "OFF", "ONESHOT125", "ONESHOT42", "MULTISHOT","BRUSHED", "DSHOT150", "DSHOT300", "DSHOT600","DSHOT1200", "PROSHOT1000" } }, - { x = 148, y = 24, vals = { 3 }, min = 0, max = 1, table = { [0] = "OFF", "ON" } }, - { x = 148, y = 34, vals = { 5, 6 }, min = 200, max = 32000, }, - { x = 148, y = 44, vals = { 7, 8 }, min = 0, max = 2000, scale = 100 }, + fieldLayout = { + { x = 65, y = 14, }, + { x = 65, y = 24, }, + { x = 65, y = 34, }, + { x = 148, y = 14, }, + { x = 148, y = 24, }, + { x = 148, y = 34, }, + { x = 148, y = 44, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua index d6e8ddd8..1cd6b48d 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua @@ -20,21 +20,21 @@ return { { t = "Rate", x = 130, y = 60, }, { t = "Breakpoint", x = 130, y = 68, }, }, - fields = { - { x = 39, y = 26, vals = { 1 }, min = 0, max = 255, scale = 100, }, - { x = 39, y = 36, vals = { 13 }, min = 0, max = 255, scale = 100, }, - { x = 39, y = 46, vals = { 12 }, min = 0, max = 255, scale = 100, }, - { x = 66, y = 26, vals = { 3 }, min = 0, max = 100, scale = 100, }, - { x = 66, y = 36, vals = { 4 }, min = 0, max = 100, scale = 100, }, - { x = 66, y = 46, vals = { 5 }, min = 0, max = 255, scale = 100, }, - { x = 94, y = 26, vals = { 2 }, min = 0, max = 100, scale = 100, }, - { x = 94, y = 36, vals = { 14 }, min = 0, max = 100, scale = 100, }, - { x = 94, y = 46, vals = { 11 }, min = 0, max = 100, scale = 100, }, - { x = 180, y = 20, vals = { 7 }, min = 0, max = 100, scale = 100, }, - { x = 180, y = 28, vals = { 8 }, min = 0, max = 100, scale = 100, }, - { x = 180, y = 36, vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, - { x = 180, y = 44, vals = { 16 }, min = 25, max = 100, }, - { x = 180, y = 60, vals = { 6 } , min = 0, max = 100, scale = 100, }, - { x = 180, y = 68, vals = { 9, 10 }, min = 1000, max = 2000, }, + fieldLayout = { + { x = 39, y = 26, }, + { x = 39, y = 36, }, + { x = 39, y = 46, }, + { x = 66, y = 26, }, + { x = 66, y = 36, }, + { x = 66, y = 46, }, + { x = 94, y = 26, }, + { x = 94, y = 36, }, + { x = 94, y = 46, }, + { x = 180, y = 20, }, + { x = 180, y = 28, }, + { x = 180, y = 36, }, + { x = 180, y = 44, }, + { x = 180, y = 60, }, + { x = 180, y = 68, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua index 77f119f4..7044b470 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua @@ -1,25 +1,25 @@ return { text = { - { t = "Min Sats.", x = 30, y = 16, }, - { t = "Angle", x = 45, y = 26, }, - { t = "Initial Alt.", x = 18, y = 36, }, - { t = "Descent Dist.", x = 10, y = 46, }, - { t = "Ground Speed", x = 10, y = 56, }, - { t = "Sanity Ch.", x = 125, y = 16, }, - { t = "Throttle", x = 125, y = 26, }, - { t = "Min", x = 128, y = 36, }, - { t = "Hover", x = 120, y = 46, }, - { t = "Max", x = 128, y = 56, }, + { t = "Min Sats.", x = 30, y = 16, }, + { t = "Angle", x = 45, y = 26, }, + { t = "Initial Alt.", x = 18, y = 36, }, + { t = "Descent Dist.", x = 10, y = 46, }, + { t = "Ground Speed", x = 10, y = 56, }, + { t = "Sanity Ch.", x = 125, y = 16, }, + { t = "Throttle", x = 125, y = 26, }, + { t = "Min", x = 128, y = 36, }, + { t = "Hover", x = 120, y = 46, }, + { t = "Max", x = 128, y = 56, }, }, - fields = { - { x = 75, y = 16, min = 0, max = 50, vals = { 16 }, }, - { x = 75, y = 26, min = 0, max = 200, vals = { 1 , 2 }, }, - { x = 75, y = 36, min = 20, max = 100, vals = { 3 , 4 }, }, - { x = 75, y = 46, min = 30, max = 500, vals = { 5 , 6 }, }, - { x = 75, y = 56, min = 30, max = 3000, vals = { 7, 8 }, }, - { x = 180, y = 16, min = 0, max = 2 , vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"}}, - { x = 150, y = 36, min = 1000, max = 2000, vals = { 9, 10 }, }, - { x = 150, y = 46, min = 1000, max = 2000, vals = { 13, 14 }, }, - { x = 150, y = 56, min = 1000, max = 2000, vals = { 11,12 }, }, + fieldLayout = { + { x = 75, y = 16, }, + { x = 75, y = 26, }, + { x = 75, y = 36, }, + { x = 75, y = 46, }, + { x = 75, y = 56, }, + { x = 180, y = 16, }, + { x = 150, y = 36, }, + { x = 150, y = 46, }, + { x = 150, y = 56, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua index 9a01f7e6..13d683b1 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua @@ -1,11 +1,18 @@ return { - text = {}, - fields = { - { t = "Stick Min", x = 30, y = 20, sp = 45, min = 1000, max = 2000, vals = { 6, 7 }, }, - { t = "Stick Mid", x = 30, y = 30, sp = 45, min = 1000, max = 2000, vals = { 4, 5 }, }, - { t = "Stick Max", x = 30, y = 40, sp = 45, min = 1000, max = 2000, vals = { 2, 3 }, }, - { t = "Cam Angle", x = 110, y = 20, sp = 50, min = 0, max = 90, vals = { 23 }, }, - { t = "Interp", x = 110, y = 30, sp = 50, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} }, - { t = "Interp Int", x = 110, y = 40, sp = 50, min = 1, max = 50, vals = { 14 }, }, + text= { + { t = "Stick Min", x = 30, y = 20 }, + { t = "Stick Mid", x = 30, y = 30 }, + { t = "Stick Max", x = 30, y = 40 }, + { t = "Cam Angle", x = 110, y = 20 }, + { t = "Interp", x = 110, y = 30 }, + { t = "Interp Int", x = 110, y = 40 }, + }, + fieldLayout = { + { x = 80, y = 20, }, + { x = 80, y = 30, }, + { x = 80, y = 40, }, + { x = 160, y = 20, }, + { x = 160, y = 30, }, + { x = 160, y = 40, } }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua index 227cdb1d..718b40a4 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua @@ -1,11 +1,18 @@ return { - text = {}, - fields = { - { t = "Band", x = 25, y = 14, sp = 50, min=0, max=5, vals = { 2 }, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, - { t = "Channel", x = 25, y = 24, sp = 50, min=1, max=8, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, - { t = "Power", x = 25, y = 34, sp = 50, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, - { t = "Pit", x = 25, y = 44, sp = 50, min=0, max=1, vals = { 5 }, table = { [0]="OFF", "ON" } }, - { t = "Dev", x = 100, y = 14, sp = 32, write = false, ro = true, vals = { 1 }, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, - { t = "Freq", x = 100, y = 24, sp = 32, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, + text= { + { t = "Band", x = 25, y = 14 }, + { t = "Channel", x = 25, y = 24 }, + { t = "Power", x = 25, y = 34 }, + { t = "Pit", x = 25, y = 44 }, + { t = "Proto", x = 100, y = 14 }, + { t = "Freq", x = 100, y = 24 }, + }, + fieldLayout = { + { x = 75, y = 155, }, + { x = 75, y = 200, }, + { x = 75, y = 242, }, + { x = 75, y = 284, }, + { x = 150, y = 68, }, + { x = 150, y = 110, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua b/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua index 3cdbe3ab..ccdfcdb4 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua @@ -34,27 +34,27 @@ return { { t = "Yaw Lowpass", x = 5, y = 615, }, { t = "Cutoff", x = 35, y = 635, }, }, - fields = { - { x = 200, y = 55, min = 0, max = 1000, vals = { 30, 31 } }, - { x = 200, y = 75, min = 0, max = 1000, vals = { 32, 33 } }, - { x = 200, y = 95, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 135, min = 0, max = 16000, vals = { 21, 22 } }, - { x = 200, y = 155, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 195, min = 0, max = 16000, vals = { 23, 24 } }, - { x = 200, y = 215, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 255, min = 0, max = 16000, vals = { 6, 7 } }, - { x = 200, y = 275, min = 0, max = 16000, vals = { 8, 9 } }, - { x = 200, y = 315, min = 0, max = 16000, vals = { 14, 15 } }, - { x = 200, y = 335, min = 0, max = 16000, vals = { 16, 17 } }, - { x = 200, y = 375, min = 0, max = 1000, vals = { 34, 35 } }, - { x = 200, y = 395, min = 0, max = 1000, vals = { 36, 37 } }, - { x = 200, y = 415, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 455, min = 0, max = 16000, vals = { 2, 3 } }, - { x = 200, y = 475, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 515, min = 0, max = 16000, vals = { 27, 28 } }, - { x = 200, y = 535, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 575, min = 0, max = 16000, vals = { 10, 11 } }, - { x = 200, y = 595, min = 0, max = 16000, vals = { 12, 13 } }, - { x = 200, y = 635, min = 0, max = 500, vals = { 4, 5 } }, + fieldLayout = { + { x = 200, y = 55, }, + { x = 200, y = 75, }, + { x = 200, y = 95, }, + { x = 200, y = 135, }, + { x = 200, y = 155, }, + { x = 200, y = 195, }, + { x = 200, y = 215, }, + { x = 200, y = 255, }, + { x = 200, y = 275, }, + { x = 200, y = 315, }, + { x = 200, y = 335, }, + { x = 200, y = 375, }, + { x = 200, y = 395, }, + { x = 200, y = 415, }, + { x = 200, y = 455, }, + { x = 200, y = 475, }, + { x = 200, y = 515, }, + { x = 200, y = 535, }, + { x = 200, y = 575, }, + { x = 200, y = 595, }, + { x = 200, y = 635, }, } } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua index c2d464d6..f976a691 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua @@ -7,13 +7,13 @@ return { { t = "Velocity", x = 10, y = 150, }, { t = "Yaw" , x = 10, y = 200, }, }, - fields = { - { x = 100, y = 100, min = 0, max = 200, vals = { 1, 3 }, }, - { x = 100, y = 150, min = 0, max = 200, vals = { 7, 8 }, }, - { x = 100, y = 200, min = 0, max = 500, vals = {13,14 }, }, - { x = 180, y = 100, min = 0, max = 200, vals = { 3, 4 }, }, - { x = 180, y = 150, min = 0, max = 200, vals = { 9,10 }, }, - { x = 260, y = 100, min = 0, max = 200, vals = { 5, 6 }, }, - { x = 260, y = 150, min = 0, max = 200, vals = { 11,12 }, }, + fieldLayout = { + { x = 100, y = 100, }, + { x = 100, y = 150, }, + { x = 100, y = 200, }, + { x = 180, y = 100, }, + { x = 180, y = 150, }, + { x = 260, y = 100, }, + { x = 260, y = 150, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua index e1d6a5ee..5d52bfba 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua @@ -17,17 +17,17 @@ return { { t = "Gain", x = 15, y = 275, }, { t = "Threshold", x = 15, y = 295, }, }, - fields = { - { x = 200, y = 55, min = 20, max = 80, vals = { 32 } }, - { x = 200, y = 75, min = 0, max = 100, vals = { 31 } }, - { x = 200, y = 95, min = 0, max = 20, vals = { 30 } }, - { x = 200, y = 115, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } }, - { x = 200, y = 135, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } }, - { x = 200, y = 175, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (increment only)", "RPY (increment only)" } }, - { x = 200, y = 195, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } }, - { x = 200, y = 215, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } }, - { x = 200, y = 255, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } }, - { x = 200, y = 275, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 }, - { x = 200, y = 295, min = 20, max = 1000, vals = { 20, 21 } }, + fieldLayout = { + { x = 200, y = 55, }, + { x = 200, y = 75, }, + { x = 200, y = 95, }, + { x = 200, y = 115, }, + { x = 200, y = 135, }, + { x = 200, y = 175, }, + { x = 200, y = 195, }, + { x = 200, y = 215, }, + { x = 200, y = 255, }, + { x = 200, y = 275, }, + { x = 200, y = 295, }, } } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua index f39b1286..6e92e4ef 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua @@ -7,15 +7,15 @@ return { { t = "PITCH", x = 10, y = 150, }, { t = "YAW", x = 10, y = 200, }, }, - fields = { - { x = 100, y = 100, min = 0, max = 200, vals = { 1 }, }, - { x = 100, y = 150, min = 0, max = 200, vals = { 4 }, }, - { x = 100, y = 200, min = 0, max = 200, vals = { 7 }, }, - { x = 180, y = 100, min = 0, max = 200, vals = { 2 }, }, - { x = 180, y = 150, min = 0, max = 200, vals = { 5 }, }, - { x = 180, y = 200, min = 0, max = 200, vals = { 8 }, }, - { x = 260, y = 100, min = 0, max = 200, vals = { 3 }, }, - { x = 260, y = 150, min = 0, max = 200, vals = { 6 }, }, - { x = 260, y = 200, min = 0, max = 200, vals = { 9 }, }, + fieldLayout = { + { x = 100, y = 100, }, + { x = 100, y = 150, }, + { x = 100, y = 200, }, + { x = 180, y = 100, }, + { x = 180, y = 150, }, + { x = 180, y = 200, }, + { x = 260, y = 100, }, + { x = 260, y = 150, }, + { x = 260, y = 200, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua index 9b10823e..8314d40f 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua @@ -7,21 +7,21 @@ return { { t = "ROLL", x = 28, y = 100, }, { t = "PITCH", x = 28, y = 150, }, { t = "YAW", x = 28, y = 200, }, - { t = "Feedforward", x = 28, y = 250, }, - { t = "Transition", x = 40, y = 270, }, - { t = "D Min", x = 28, y = 300, }, - { t = "Gain", x = 40, y = 320, }, - { t = "Advance", x = 40, y = 350, }, + { t = "Feedforward", x = 28, y = 250, }, + { t = "Transition", x = 40, y = 270, }, + { t = "D Min", x = 28, y = 300, }, + { t = "Gain", x = 40, y = 320, }, + { t = "Advance", x = 40, y = 350, }, }, - fields = { - { x = 102, y = 100, min = 0, max = 2000, vals = { 33, 34 }, }, - { x = 102, y = 150, min = 0, max = 2000, vals = { 35, 36 }, }, - { x = 102, y = 200, min = 0, max = 2000, vals = { 37, 38 }, }, - { x = 202, y = 100, min = 0, max = 100, vals = { 40 }, }, - { x = 202, y = 150, min = 0, max = 100, vals = { 41 }, }, - { x = 202, y = 200, min = 0, max = 100, vals = { 42 }, }, - { x = 150, y = 270, min = 0, max = 100, vals = { 9 }, scale = 100 }, - { x = 150, y = 320, min = 0, max = 100, vals = { 43 } }, - { x = 150, y = 350, min = 0, max = 200, vals = { 44 } }, + fieldLayout = { + { x = 102, y = 100, }, + { x = 102, y = 150, }, + { x = 102, y = 200, }, + { x = 202, y = 100, }, + { x = 202, y = 150, }, + { x = 202, y = 200, }, + { x = 150, y = 270, }, + { x = 150, y = 320, }, + { x = 150, y = 350, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua index aedf420c..b9f6c164 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua @@ -1,25 +1,20 @@ return { text= { - { t = "Protocol", x = 36, y = 68 }, - { t = "32K", x = 36, y = 110 }, - { t = "Gyro Rt", x = 36, y = 155 }, - { t = "PID Rt", x = 36, y = 200 }, + { t = "Protocol", x = 36, y = 68 }, + { t = "32K", x = 36, y = 110 }, + { t = "Gyro Rt", x = 36, y = 155 }, + { t = "PID Rt", x = 36, y = 200 }, { t = "Unsynced", x = 36, y = 242 }, { t = "PWM Rate", x = 36, y = 284 }, { t = "Idle Offset", x = 36, y = 326 } }, - fields = { - { x = 150, y = 68, vals = { 4 }, min = 0, max = 9, - table = { [0] = "OFF", "ONESHOT125", "ONESHOT42", - "MULTISHOT","BRUSHED", - "DSHOT150", "DSHOT300", "DSHOT600","DSHOT1200", - "PROSHOT1000" } - }, - { x = 150, y = 110, vals = { 9 }, min = 0, max = 1, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, - { x = 150, y = 155, vals = { 1 }, min = 1, max = 32, upd = function(self) self.updatePidRateTable(self) end }, - { x = 150, y = 200, vals = { 2 }, min = 1, max = 16, }, - { x = 150, y = 242, vals = { 3 }, min = 0, max = 1, table = { [0] = "OFF", "ON" } }, - { x = 150, y = 284, vals = { 5, 6 }, min = 200, max = 32000, }, - { x = 150, y = 326, vals = { 7, 8 }, min = 0, max = 2000, scale = 100, }, + fieldLayout = { + { x = 150, y = 68, }, + { x = 150, y = 110, }, + { x = 150, y = 155, }, + { x = 150, y = 200, }, + { x = 150, y = 242, }, + { x = 150, y = 284, }, + { x = 150, y = 326, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua index 0acfcf0c..1fbd50a5 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua @@ -18,21 +18,21 @@ return { { t = "Rate", x = 40, y = 370, }, { t = "Breakpoint", x = 40, y = 390, }, }, - fields = { - { x = 102, y = 100, vals = { 1 }, min = 0, max = 255, scale = 100, }, - { x = 102, y = 150, vals = { 13 }, min = 0, max = 255, scale = 100, }, - { x = 102, y = 200, vals = { 12 }, min = 0, max = 255, scale = 100, }, - { x = 158, y = 100, vals = { 3 }, min = 0, max = 100, scale = 100, }, - { x = 158, y = 150, vals = { 4 }, min = 0, max = 100, scale = 100, }, - { x = 158, y = 200, vals = { 5 }, min = 0, max = 255, scale = 100, }, - { x = 216, y = 100, vals = { 2 }, min = 0, max = 100, scale = 100, }, - { x = 216, y = 150, vals = { 14 }, min = 0, max = 100, scale = 100, }, - { x = 216, y = 200, vals = { 11 }, min = 0, max = 100, scale = 100, }, - { x = 150, y = 270, vals = { 7 }, min = 0, max = 100, scale = 100, }, - { x = 150, y = 290, vals = { 8 }, min = 0, max = 100, scale = 100, }, - { x = 150, y = 310, vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, - { x = 150, y = 330, vals = { 16 }, min = 25, max = 100 }, - { x = 150, y = 370, vals = { 6 }, min = 0, max = 100, scale = 100 }, - { x = 150, y = 390, vals = { 9, 10 }, min = 1000, max = 2000 }, + fieldLayout = { + { x = 102, y = 100, }, + { x = 102, y = 150, }, + { x = 102, y = 200, }, + { x = 158, y = 100, }, + { x = 158, y = 150, }, + { x = 158, y = 200, }, + { x = 216, y = 100, }, + { x = 216, y = 150, }, + { x = 216, y = 200, }, + { x = 150, y = 270, }, + { x = 150, y = 290, }, + { x = 150, y = 310, }, + { x = 150, y = 330, }, + { x = 150, y = 370, }, + { x = 150, y = 390, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua index 3a567f90..6acf9cb6 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua @@ -1,25 +1,25 @@ return { text = { - { t = "Min Sats.", x = 10, y = 40 }, - { t = "Angle", x = 10, y = 80 }, - { t = "Initial Altitude", x = 10, y = 120 }, - { t = "Descent Distance", x = 10, y = 160 }, - { t = "Ground Speed", x = 10, y = 200 }, - { t = "Snty.", x = 10, y = 240 }, - { t = "Throttle", x = 10, y = 280 }, - { t = "Min", x = 10, y = 320 }, - { t = "Hover", x = 10, y = 360 }, - { t = "Max", x = 10, y = 400 }, + { t = "Min Sats.", x = 10, y = 40 }, + { t = "Angle", x = 10, y = 80 }, + { t = "Initial Altitude", x = 10, y = 120 }, + { t = "Descent Distance", x = 10, y = 160 }, + { t = "Ground Speed", x = 10, y = 200 }, + { t = "Snty.", x = 10, y = 240 }, + { t = "Throttle", x = 10, y = 280 }, + { t = "Min", x = 10, y = 320 }, + { t = "Hover", x = 10, y = 360 }, + { t = "Max", x = 10, y = 400 }, }, - fields = { - { x = 260, y = 40, min = 0, max = 50, vals = { 16 } }, - { x = 260, y = 80, min = 0, max = 200, vals = { 1,2 } }, - { x = 260, y = 120, min = 20, max = 100, vals = { 3,4 } }, - { x = 260, y = 160, min = 30, max = 500, vals = { 5,6 } }, - { x = 260, y = 200, min = 30, max =3000, vals = { 7,8 } }, - { x = 260, y = 240, min = 0, max = 2 , vals = { 15 } ,table = { [0]="OFF","ON","FS_ONLY"}, }, - { x = 260, y = 320, min = 1000, max = 2000, vals = { 9,10 } }, - { x = 260, y = 360, min = 1000, max = 2000, vals = { 13,14 } }, - { x = 260, y = 400, min = 1000, max = 2000, vals = { 11,12 } }, + fieldLayout = { + { x = 260, y = 40, }, + { x = 260, y = 80, }, + { x = 260, y = 120, }, + { x = 260, y = 160, }, + { x = 260, y = 200, }, + { x = 260, y = 240, }, + { x = 260, y = 320, }, + { x = 260, y = 360, }, + { x = 260, y = 400, }, }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua index b731c518..f6817383 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua @@ -7,12 +7,12 @@ return { { t = "Interp", x = 36, y = 242 }, { t = "Interp Int", x = 36, y = 284 } }, - fields = { - { x = 150, y = 68, min = 1000, max = 2000, vals = { 6, 7 }, }, - { x = 150, y = 110, min = 1000, max = 2000, vals = { 4, 5 }, }, - { x = 150, y = 155, min = 1000, max = 2000, vals = { 2, 3 }, }, - { x = 150, y = 200, min = 0, max = 90, vals = { 23 }, }, - { x = 150, y = 242, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} }, - { x = 150, y = 284, min = 1, max = 50, vals = { 14 }, } + fieldLayout = { + { x = 150, y = 68, }, + { x = 150, y = 110, }, + { x = 150, y = 155, }, + { x = 150, y = 200, }, + { x = 150, y = 242, }, + { x = 150, y = 284, } }, } diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua b/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua index 09ac190f..5daad798 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua @@ -7,12 +7,12 @@ return { { t = "Proto", x = 36, y = 68 }, { t = "Freq", x = 36, y = 110 }, }, - fields = { - { x = 150, y = 155, min=0, max=5, vals = { 2 }, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, - { x = 150, y = 200, min=1, max=8, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, - { x = 150, y = 242, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, - { x = 150, y = 284, min=0, max=1, vals = { 5 }, table = { [0]="OFF", "ON" } }, - { x = 150, y = 68, vals = { 1 }, write = false, ro = true, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, - { x = 150, y = 110, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, + fieldLayout = { + { x = 150, y = 155, }, + { x = 150, y = 200, }, + { x = 150, y = 242, }, + { x = 150, y = 284, }, + { x = 150, y = 68, }, + { x = 150, y = 110, }, }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua b/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua index 2abe7559..82975e1f 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua @@ -34,27 +34,27 @@ return { { t = "Yaw Lowpass", x = 5, y = 615, }, { t = "Cutoff", x = 35, y = 635, }, }, - fields = { - { x = 200, y = 55, min = 0, max = 1000, vals = { 30, 31 } }, - { x = 200, y = 75, min = 0, max = 1000, vals = { 32, 33 } }, - { x = 200, y = 95, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 135, min = 0, max = 16000, vals = { 21, 22 } }, - { x = 200, y = 155, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 195, min = 0, max = 16000, vals = { 23, 24 } }, - { x = 200, y = 215, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 255, min = 0, max = 16000, vals = { 6, 7 } }, - { x = 200, y = 275, min = 0, max = 16000, vals = { 8, 9 } }, - { x = 200, y = 315, min = 0, max = 16000, vals = { 14, 15 } }, - { x = 200, y = 335, min = 0, max = 16000, vals = { 16, 17 } }, - { x = 200, y = 375, min = 0, max = 1000, vals = { 34, 35 } }, - { x = 200, y = 395, min = 0, max = 1000, vals = { 36, 37 } }, - { x = 200, y = 415, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 455, min = 0, max = 16000, vals = { 2, 3 } }, - { x = 200, y = 475, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 515, min = 0, max = 16000, vals = { 27, 28 } }, - { x = 200, y = 535, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { x = 200, y = 575, min = 0, max = 16000, vals = { 10, 11 } }, - { x = 200, y = 595, min = 0, max = 16000, vals = { 12, 13 } }, - { x = 200, y = 635, min = 0, max = 500, vals = { 4, 5 } }, + fieldLayout = { + { x = 200, y = 55, }, + { x = 200, y = 75, }, + { x = 200, y = 95, }, + { x = 200, y = 135, }, + { x = 200, y = 155, }, + { x = 200, y = 195, }, + { x = 200, y = 215, }, + { x = 200, y = 255, }, + { x = 200, y = 275, }, + { x = 200, y = 315, }, + { x = 200, y = 335, }, + { x = 200, y = 375, }, + { x = 200, y = 395, }, + { x = 200, y = 415, }, + { x = 200, y = 455, }, + { x = 200, y = 475, }, + { x = 200, y = 515, }, + { x = 200, y = 535, }, + { x = 200, y = 575, }, + { x = 200, y = 595, }, + { x = 200, y = 635, }, } } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua index f98a0f2b..26067a95 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua @@ -1,19 +1,19 @@ return { text = { - { t = "P", x = 142, y = 48, }, - { t = "I", x = 244, y = 48, }, - { t = "D", x = 342, y = 48, }, - { t = "Throttle", x = 28, y = 100, }, - { t = "Velocity", x = 28, y = 150, }, - { t = "Yaw" , x = 28, y = 200, }, + { t = "P", x = 142, y = 48, }, + { t = "I", x = 244, y = 48, }, + { t = "D", x = 342, y = 48, }, + { t = "Throttle", x = 28, y = 100, }, + { t = "Velocity", x = 28, y = 150, }, + { t = "Yaw" , x = 28, y = 200, }, }, - fields = { - { x = 140, y = 100, min = 0, max = 200, vals = { 1, 3 }, }, - { x = 140, y = 150, min = 0, max = 200, vals = { 7, 8 }, }, - { x = 140, y = 200, min = 0, max = 500, vals = {13,14 }, }, - { x = 240, y = 100, min = 0, max = 200, vals = { 3, 4 }, }, - { x = 240, y = 150, min = 0, max = 200, vals = { 9,10 }, }, - { x = 340, y = 100, min = 0, max = 200, vals = { 5, 6 }, }, - { x = 340, y = 150, min = 0, max = 200, vals = { 11,12 }, }, + fieldLayout = { + { x = 140, y = 100, }, + { x = 140, y = 150, }, + { x = 140, y = 200, }, + { x = 240, y = 100, }, + { x = 240, y = 150, }, + { x = 340, y = 100, }, + { x = 340, y = 150, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua index e1d6a5ee..5d52bfba 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua @@ -17,17 +17,17 @@ return { { t = "Gain", x = 15, y = 275, }, { t = "Threshold", x = 15, y = 295, }, }, - fields = { - { x = 200, y = 55, min = 20, max = 80, vals = { 32 } }, - { x = 200, y = 75, min = 0, max = 100, vals = { 31 } }, - { x = 200, y = 95, min = 0, max = 20, vals = { 30 } }, - { x = 200, y = 115, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } }, - { x = 200, y = 135, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } }, - { x = 200, y = 175, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (increment only)", "RPY (increment only)" } }, - { x = 200, y = 195, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } }, - { x = 200, y = 215, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } }, - { x = 200, y = 255, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } }, - { x = 200, y = 275, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 }, - { x = 200, y = 295, min = 20, max = 1000, vals = { 20, 21 } }, + fieldLayout = { + { x = 200, y = 55, }, + { x = 200, y = 75, }, + { x = 200, y = 95, }, + { x = 200, y = 115, }, + { x = 200, y = 135, }, + { x = 200, y = 175, }, + { x = 200, y = 195, }, + { x = 200, y = 215, }, + { x = 200, y = 255, }, + { x = 200, y = 275, }, + { x = 200, y = 295, }, } } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua index 98589722..457e6ab1 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua @@ -8,15 +8,15 @@ return { { t = "PITCH", x = 28, y = 150, }, { t = "YAW", x = 28, y = 200, }, }, - fields = { - { x = 140, y = 100, min = 0, max = 200, vals = { 1 }, }, - { x = 140, y = 150, min = 0, max = 200, vals = { 4 }, }, - { x = 140, y = 200, min = 0, max = 200, vals = { 7 }, }, - { x = 240, y = 100, min = 0, max = 200, vals = { 2 }, }, - { x = 240, y = 150, min = 0, max = 200, vals = { 5 }, }, - { x = 240, y = 200, min = 0, max = 200, vals = { 8 }, }, - { x = 340, y = 100, min = 0, max = 200, vals = { 3 }, }, - { x = 340, y = 150, min = 0, max = 200, vals = { 6 }, }, - { x = 340, y = 200, min = 0, max = 200, vals = { 9 }, }, + fieldLayout = { + { x = 140, y = 100, }, + { x = 140, y = 150, }, + { x = 140, y = 200, }, + { x = 240, y = 100, }, + { x = 240, y = 150, }, + { x = 240, y = 200, }, + { x = 340, y = 100, }, + { x = 340, y = 150, }, + { x = 340, y = 200, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua index 8aba0553..b3e7642b 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua @@ -1,27 +1,27 @@ return { text = { - { t = "Feed", x = 97, y = 52 }, - { t = "forward", x = 82, y = 70 }, - { t = "D", x = 207, y = 52 }, - { t = "Min", x = 202, y = 70 }, - { t = "ROLL", x = 28, y = 100 }, - { t = "PITCH", x = 28, y = 150 }, - { t = "YAW", x = 28, y = 200 }, - { t = "Feedforward", x = 290, y = 100 }, - { t = "Transition", x = 300, y = 120, to = SMLSIZE }, - { t = "D Min", x = 290, y = 140 }, - { t = "Gain", x = 300, y = 160, to = SMLSIZE }, - { t = "Advance", x = 300, y = 180, to = SMLSIZE }, + { t = "Feed", x = 97, y = 52, }, + { t = "forward", x = 82, y = 70, }, + { t = "D", x = 207, y = 52, }, + { t = "Min", x = 202, y = 70, }, + { t = "ROLL", x = 28, y = 100, }, + { t = "PITCH", x = 28, y = 150, }, + { t = "YAW", x = 28, y = 200, }, + { t = "Feedforward", x = 290, y = 100, }, + { t = "Transition", x = 300, y = 120, }, + { t = "D Min", x = 290, y = 140, }, + { t = "Gain", x = 300, y = 160, }, + { t = "Advance", x = 300, y = 180, }, }, - fields = { - { x = 102, y = 100, min = 0, max = 2000, vals = { 33, 34 }, }, - { x = 102, y = 150, min = 0, max = 2000, vals = { 35, 36 }, }, - { x = 102, y = 200, min = 0, max = 2000, vals = { 37, 38 }, }, - { x = 202, y = 100, min = 0, max = 100, vals = { 40 }, }, - { x = 202, y = 150, min = 0, max = 100, vals = { 41 }, }, - { x = 202, y = 200, min = 0, max = 100, vals = { 42 }, }, - { x = 390, y = 120, min = 0, max = 100, vals = { 9 }, scale = 100 }, - { x = 390, y = 160, min = 0, max = 100, vals = { 43 } }, - { x = 390, y = 180, min = 0, max = 200, vals = { 44 } }, + fieldLayout = { + { x = 102, y = 100, }, + { x = 102, y = 150, }, + { x = 102, y = 200, }, + { x = 202, y = 100, }, + { x = 202, y = 150, }, + { x = 202, y = 200, }, + { x = 390, y = 120, }, + { x = 390, y = 160, }, + { x = 390, y = 180, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua index 46fbee51..f612a152 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua @@ -6,17 +6,15 @@ return { { t = "PID Rt", x = 36, y = 200 }, { t = "Unsynced", x = 232, y = 110 }, { t = "PWM Rate", x = 232, y = 155 }, - { t = "Idle Offset", x = 232, y = 200 } + { t = "Idle Offset", x = 232, y = 200 }, }, - fields = { - { x = 130, y = 68, vals = { 4 }, min = 0, max = 9, table = { [0] = "OFF", "ONESHOT125", "ONESHOT42", "MULTISHOT", "BRUSHED", "DSHOT150", "DSHOT300", - "DSHOT600", "DSHOT1200", "PROSHOT1000" } - }, - { x = 130, y = 110, vals = { 9 }, min = 0, max = 1, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, - { x = 130, y = 155, vals = { 1 }, min = 1, max = 32, upd = function(self) self.updatePidRateTable(self) end }, - { x = 130, y = 200, vals = { 2 }, min = 1, max = 16, }, - { x = 350, y = 110, vals = { 3 }, min = 0, max = 1, table = { [0] = "OFF", "ON" } }, - { x = 350, y = 155, vals = { 5, 6 }, min = 200, max = 32000, }, - { x = 350, y = 200, vals = { 7, 8 }, min = 0, max = 2000, scale = 100, }, + fieldLayout = { + { x = 130, y = 68, }, + { x = 130, y = 110, }, + { x = 130, y = 155, }, + { x = 130, y = 200, }, + { x = 350, y = 110, }, + { x = 350, y = 155, }, + { x = 350, y = 200, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua index 4137c7e1..3d8506b6 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua @@ -18,21 +18,21 @@ return { { t = "Rate", x = 300, y = 180, }, { t = "Breakpoint", x = 300, y = 200, }, }, - fields = { - { x = 102, y = 100, vals = { 1 }, min = 0, max = 255, scale = 100, }, - { x = 102, y = 150, vals = { 13 }, min = 0, max = 255, scale = 100, }, - { x = 102, y = 200, vals = { 12 }, min = 0, max = 255, scale = 100, }, - { x = 158, y = 100, vals = { 3 }, min = 0, max = 100, scale = 100, }, - { x = 158, y = 150, vals = { 4 }, min = 0, max = 100, scale = 100, }, - { x = 158, y = 200, vals = { 5 }, min = 0, max = 255, scale = 100, }, - { x = 216, y = 100, vals = { 2 }, min = 0, max = 100, scale = 100, }, - { x = 216, y = 150, vals = { 14 }, min = 0, max = 100, scale = 100, }, - { x = 216, y = 200, vals = { 11 }, min = 0, max = 100, scale = 100, }, - { x = 390, y = 80, vals = { 7 }, min = 0, max = 100, scale = 100, }, - { x = 390, y = 100, vals = { 8 }, min = 0, max = 100, scale = 100, }, - { x = 390, y = 120, vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, - { x = 390, y = 140, vals = { 16 }, min = 25, max = 100 }, - { x = 390, y = 180, vals = { 6 }, min = 0, max = 100, scale = 100 }, - { x = 390, y = 200, vals = { 9, 10 }, min = 1000, max = 2000 }, + fieldLayout = { + { x = 102, y = 100, }, + { x = 102, y = 150, }, + { x = 102, y = 200, }, + { x = 158, y = 100, }, + { x = 158, y = 150, }, + { x = 158, y = 200, }, + { x = 216, y = 100, }, + { x = 216, y = 150, }, + { x = 216, y = 200, }, + { x = 390, y = 80, }, + { x = 390, y = 100, }, + { x = 390, y = 120, }, + { x = 390, y = 140, }, + { x = 390, y = 180, }, + { x = 390, y = 200, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua index c1b6e715..72ca6709 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua @@ -5,21 +5,21 @@ return { { t = "Initial Altitude", x = 60, y = 120, }, { t = "Descent Distance", x = 10, y = 160, }, { t = "Ground Speed", x = 50, y = 200, }, - { t = "Snty.", x = 310, y = 40, }, - { t = "Throttle", x = 350, y = 80, }, - { t = "Min", x = 330, y = 120, }, - { t = "Hover", x = 310, y = 160, }, - { t = "Max", x = 330, y = 200, }, + { t = "Snty.", x = 310, y = 40, }, + { t = "Throttle", x = 350, y = 80, }, + { t = "Min", x = 330, y = 120, }, + { t = "Hover", x = 310, y = 160, }, + { t = "Max", x = 330, y = 200, }, }, - fields = { - { x = 260, y = 40, min = 0, max = 50, vals = { 16 }, }, - { x = 260, y = 80, min = 0, max = 200, vals = { 1,2 }, }, - { x = 260, y = 120, min = 20, max = 100, vals = { 3,4 }, }, - { x = 260, y = 160, min = 30, max = 500, vals = { 5,6 }, }, - { x = 260, y = 200, min = 30, max =3000, vals = { 7,8 }, }, - { x = 400, y = 40, min = 0, max = 2 , vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"}}, - { x = 400, y = 120, min = 1000, max = 2000, vals = { 9,10 }, }, - { x = 400, y = 160, min = 1000, max = 2000, vals = { 13,14 }, }, - { x = 400, y = 200, min = 1000, max = 2000, vals = { 11,12 }, }, + fieldLayout = { + { x = 260, y = 40, }, + { x = 260, y = 80, }, + { x = 260, y = 120, }, + { x = 260, y = 160, }, + { x = 260, y = 200, }, + { x = 400, y = 40, }, + { x = 400, y = 120, }, + { x = 400, y = 160, }, + { x = 400, y = 200, }, }, -} +} \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua index 6ffc67c6..1db53a8a 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua @@ -5,14 +5,14 @@ return { { t = "Stick Max", x = 36, y = 155 }, { t = "Cam Angle", x = 232, y = 68 }, { t = "Interp", x = 232, y = 110 }, - { t = "Interp Int", x = 232, y = 155 } + { t = "Interp Int", x = 232, y = 155 }, }, - fields = { - { x = 130, y = 68, min = 1000, max = 2000, vals = { 6, 7 }, }, - { x = 130, y = 110, min = 1000, max = 2000, vals = { 4, 5 }, }, - { x = 130, y = 155, min = 1000, max = 2000, vals = { 2, 3 }, }, - { x = 350, y = 68, min = 0, max = 90, vals = { 23 }, }, - { x = 350, y = 110, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} }, - { x = 350, y = 155, min = 1, max = 50, vals = { 14 }, } + fieldLayout = { + { x = 130, y = 68, }, + { x = 130, y = 110, }, + { x = 130, y = 155, }, + { x = 350, y = 68, }, + { x = 350, y = 110, }, + { x = 350, y = 155, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua b/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua index 56d2b9c9..e0bce1a1 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua @@ -7,12 +7,12 @@ return { { t = "Proto", x = 36, y = 68 }, { t = "Freq", x = 232, y = 68 }, }, - fields = { - { x = 130, y = 110, min=0, max=5, vals = { 2 }, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, - { x = 130, y = 155, min=1, max=8, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, - { x = 350, y = 110, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, - { x = 350, y = 155, min=0, max=1, vals = { 5 }, table = { [0]="OFF", "ON" } }, - { x = 130, y = 68, vals = { 1 }, write = false, ro = true, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, - { x = 350, y = 68, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, + fieldLayout = { + { x = 130, y = 110, }, + { x = 130, y = 155, }, + { x = 350, y = 110, }, + { x = 350, y = 155, }, + { x = 130, y = 68, }, + { x = 350, y = 68, }, }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/filters.lua b/src/SCRIPTS/BF/PAGES/filters.lua index 4a5242bd..d7b5599b 100644 --- a/src/SCRIPTS/BF/PAGES/filters.lua +++ b/src/SCRIPTS/BF/PAGES/filters.lua @@ -10,5 +10,28 @@ return { yMinLimit = display.yMinLimit, yMaxLimit = display.yMaxLimit, text = display.text, - fields = display.fields, + fieldLayout = display.fieldLayout, + fields = { + { min = 0, max = 1000, vals = { 30, 31 } }, + { min = 0, max = 1000, vals = { 32, 33 } }, + { min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { min = 0, max = 16000, vals = { 21, 22 } }, + { min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { min = 0, max = 16000, vals = { 23, 24 } }, + { min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { min = 0, max = 16000, vals = { 6, 7 } }, + { min = 0, max = 16000, vals = { 8, 9 } }, + { min = 0, max = 16000, vals = { 14, 15 } }, + { min = 0, max = 16000, vals = { 16, 17 } }, + { min = 0, max = 1000, vals = { 34, 35 } }, + { min = 0, max = 1000, vals = { 36, 37 } }, + { min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { min = 0, max = 16000, vals = { 2, 3 } }, + { min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { min = 0, max = 16000, vals = { 27, 28 } }, + { min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, + { min = 0, max = 16000, vals = { 10, 11 } }, + { min = 0, max = 16000, vals = { 12, 13 } }, + { min = 0, max = 500, vals = { 4, 5 } }, + }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/gpspids.lua b/src/SCRIPTS/BF/PAGES/gpspids.lua index b184c7c5..7ba1744e 100644 --- a/src/SCRIPTS/BF/PAGES/gpspids.lua +++ b/src/SCRIPTS/BF/PAGES/gpspids.lua @@ -10,5 +10,14 @@ return { yMinLimit = display.yMinLimit, yMaxLimit = display.yMaxLimit, text = display.text, - fields = display.fields, + fieldLayout = display.fieldLayout, + fields = { + { min = 0, max = 200, vals = { 1,2 }, }, + { min = 0, max = 200, vals = { 7,8 }, }, + { min = 0, max = 500, vals = { 13,14 }, }, + { min = 0, max = 200, vals = { 3,4 }, }, + { min = 0, max = 200, vals = { 9,10 }, }, + { min = 0, max = 200, vals = { 5,6 }, }, + { min = 0, max = 200, vals = { 11,12 }, }, + }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 556de60f..f9ea3b81 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -10,5 +10,18 @@ return { yMinLimit = display.yMinLimit, yMaxLimit = display.yMaxLimit, text = display.text, - fields = display.fields, + fieldLayout = display.fieldLayout, + fields = { + { min = 20, max = 80, vals = { 32 } }, + { min = 0, max = 100, vals = { 31 } }, + { min = 0, max = 20, vals = { 30 } }, + { min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } }, + { min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } }, + { min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } }, + { min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } }, + { min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } }, + { min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } }, + { min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 }, + { min = 20, max = 1000, vals = { 20, 21 } }, + } } \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua index c0022454..e0936f4a 100644 --- a/src/SCRIPTS/BF/PAGES/pids1.lua +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -7,5 +7,16 @@ return { eepromWrite = true, minBytes = 9, text = display.text, - fields = display.fields, + fieldLayout = display.fieldLayout, + fields = { + { min = 0, max = 200, vals = { 1 }, }, + { min = 0, max = 200, vals = { 4 }, }, + { min = 0, max = 200, vals = { 7 }, }, + { min = 0, max = 200, vals = { 2 }, }, + { min = 0, max = 200, vals = { 5 }, }, + { min = 0, max = 200, vals = { 8 }, }, + { min = 0, max = 200, vals = { 3 }, }, + { min = 0, max = 200, vals = { 6 }, }, + { min = 0, max = 200, vals = { 9 }, }, + }, } diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index 2ed75b9f..21e9d82b 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -9,5 +9,16 @@ return { yMinLimit = display.yMinLimit, yMaxLimit = display.yMaxLimit, text = display.text, - fields = display.fields, + fieldLayout = display.fieldLayout, + fields = { + { min = 0, max = 2000, vals = { 33, 34 }, }, + { min = 0, max = 2000, vals = { 35, 36 }, }, + { min = 0, max = 2000, vals = { 37, 38 }, }, + { min = 0, max = 100, vals = { 40 }, }, + { min = 0, max = 100, vals = { 41 }, }, + { min = 0, max = 100, vals = { 42 }, }, + { min = 0, max = 100, vals = { 9 }, scale = 100 }, + { min = 0, max = 100, vals = { 43 }, }, + { min = 0, max = 200, vals = { 44 }, }, + }, } diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index 47f83f55..70a89e4a 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -9,7 +9,16 @@ return { yMinLimit = display.yMinLimit, yMaxLimit = display.yMaxLimit, text = display.text, - fields = display.fields, + fieldLayout = display.fieldLayout, + fields = { + { vals = { 9 }, min = 0, max = 1, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, + { vals = { 1 }, min = 1, max = 32, upd = function(self) self.updatePidRateTable(self) end }, + { vals = { 2 }, min = 1, max = 16, }, + { vals = { 4 }, min = 0, max = 9, table = { [0] = "OFF", "OS125", "OS42", "MSHOT","BRSH", "DS150", "DS300", "DS600","DS1200", "PS1000" } }, + { vals = { 3 }, min = 0, max = 1, table = { [0] = "OFF", "ON" } }, + { vals = { 5, 6 }, min = 200, max = 32000, }, + { vals = { 7, 8 }, min = 0, max = 2000, scale = 100 }, + }, calculateGyroRates = function(self, baseRate) self.gyroRates = {} self.fields[2].table = {} diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua index ea84fa08..51b20fb8 100644 --- a/src/SCRIPTS/BF/PAGES/rates.lua +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -9,5 +9,22 @@ return { yMinLimit = display.yMinLimit, yMaxLimit = display.yMaxLimit, text = display.text, - fields = display.fields, + fieldLayout = display.fieldLayout, + fields = { + { vals = { 1 }, min = 0, max = 255, scale = 100, }, + { vals = { 13 }, min = 0, max = 255, scale = 100, }, + { vals = { 12 }, min = 0, max = 255, scale = 100, }, + { vals = { 3 }, min = 0, max = 100, scale = 100, }, + { vals = { 4 }, min = 0, max = 100, scale = 100, }, + { vals = { 5 }, min = 0, max = 255, scale = 100, }, + { vals = { 2 }, min = 0, max = 100, scale = 100, }, + { vals = { 14 }, min = 0, max = 100, scale = 100, }, + { vals = { 11 }, min = 0, max = 100, scale = 100, }, + { vals = { 7 }, min = 0, max = 100, scale = 100, }, + { vals = { 8 }, min = 0, max = 100, scale = 100, }, + { vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, + { vals = { 16 }, min = 25, max = 100, }, + { vals = { 6 } , min = 0, max = 100, scale = 100, }, + { vals = { 9, 10 }, min = 1000, max = 2000, }, + }, } diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index 90430959..ed681f1a 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -10,5 +10,16 @@ return { yMinLimit = display.yMinLimit, yMaxLimit = display.yMaxLimit, text = display.text, - fields = display.fields, + fieldLayout = display.fieldLayout, + fields = { + { min = 0, max = 50, vals = { 16 }, }, + { min = 0, max = 200, vals = { 1,2 }, }, + { min = 20, max = 100, vals = { 3,4 }, }, + { min = 30, max = 500, vals = { 5,6 }, }, + { min = 30, max = 3000, vals = { 7,8 }, }, + { min = 0, max = 2, vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"}, }, + { min = 1000, max = 2000, vals = { 9,10 }, }, + { min = 1000, max = 2000, vals = { 13,14 }, }, + { min = 1000, max = 2000, vals = { 11,12 }, }, + }, } diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index dbc49321..29e1542f 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -1,13 +1,21 @@ local display = assert(loadScript(radio.templateHome.."rx.lua"))() return { - read = 44, -- MSP_RX_CONFIG - write = 45, -- MSP_SET_RX_CONFIG - title = "RX", - reboot = false, - eepromWrite = true, - minBytes = 23, - yMinLimit = display.yMinLimit, - yMaxLimit = display.yMaxLimit, - text = display.text, - fields = display.fields, + read = 44, -- MSP_RX_CONFIG + write = 45, -- MSP_SET_RX_CONFIG + title = "RX", + reboot = false, + eepromWrite = true, + minBytes = 23, + yMinLimit = display.yMinLimit, + yMaxLimit = display.yMaxLimit, + text = display.text, + fieldLayout = display.fieldLayout, + fields = { + { min = 1000, max = 2000, vals = { 6, 7 }, }, + { min = 1000, max = 2000, vals = { 4, 5 }, }, + { min = 1000, max = 2000, vals = { 2, 3 }, }, + { min = 0, max = 90, vals = { 23 }, }, + { min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} }, + { min = 1, max = 50, vals = { 14 }, } + }, } diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index 7ac42125..4687e89d 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -11,10 +11,18 @@ return { prevFreqVal = 0, lastFreqUpdTS = 0, freqModCounter = 0, - yMinLimit = display.yMinLimit, - yMaxLimit = display.yMaxLimit, - text = display.text, - fields = display.fields, + yMinLimit = display.yMinLimit, + yMaxLimit = display.yMaxLimit, + text = display.text, + fieldLayout = display.fieldLayout, + fields = { + { min=0, max=5, vals = { 2 }, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, + { min=1, max=8, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, + { min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, + { min=0, max=1, vals = { 5 }, table = { [0]="OFF", "ON" } }, + { vals = { 1 }, write = false, ro = true, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, + { min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, + }, freqLookup = { { 5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725 }, -- Boscam A { 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 }, -- Boscam B diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index dac64b35..20877989 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -182,10 +182,10 @@ end local function drawScreen() local yMinLim = Page.yMinLimit or 0 local yMaxLim = Page.yMaxLimit or LCD_H - local currentLineY = Page.fields[currentLine].y + local currentLineY = Page.fieldLayout[currentLine].y local screen_title = Page.title drawScreenTitle("Betaflight / "..screen_title) - if currentLineY <= Page.fields[1].y then + if currentLineY <= Page.fieldLayout[1].y then scrollPixelsY = 0 elseif currentLineY - scrollPixelsY <= yMinLim then scrollPixelsY = currentLineY - yMinLim @@ -202,6 +202,7 @@ local function drawScreen() local val = "---" for i=1,#(Page.fields) do local f = Page.fields[i] + local pos = Page.fieldLayout[i] local text_options = radio.textSize + globalTextOptions local heading_options = text_options local value_options = text_options @@ -210,18 +211,7 @@ local function drawScreen() if currentState == pageStatus.editing then value_options = value_options + BLINK end - end - local spacing = 20 - if f.t ~= nil then - if (f.y - scrollPixelsY) >= yMinLim and (f.y - scrollPixelsY) <= yMaxLim then - lcd.drawText(f.x, f.y - scrollPixelsY, f.t, heading_options) - end - if f.sp ~= nil then - spacing = f.sp - end - else - spacing = 0 - end + end if f.value then if f.upd and Page.values then f.upd(Page) @@ -231,8 +221,8 @@ local function drawScreen() val = f.table[f.value] end end - if (f.y - scrollPixelsY) >= yMinLim and (f.y - scrollPixelsY) <= yMaxLim then - lcd.drawText(f.x + spacing, f.y - scrollPixelsY, val, value_options) + if (pos.y - scrollPixelsY) >= yMinLim and (pos.y - scrollPixelsY) <= yMaxLim then + lcd.drawText(pos.x, pos.y - scrollPixelsY, val, value_options) end end end From 144c8aa89134c4306756b228823cf9c21c2af69a Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Thu, 17 Oct 2019 00:04:25 +0100 Subject: [PATCH 020/193] move y limits to radio level --- src/SCRIPTS/BF/LAYOUT/128x64/filters.lua | 2 -- src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua | 2 -- src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua | 2 -- src/SCRIPTS/BF/LAYOUT/128x64/rates.lua | 2 -- src/SCRIPTS/BF/LAYOUT/128x64/rx.lua | 2 ++ src/SCRIPTS/BF/LAYOUT/212x64/filters.lua | 2 -- src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua | 2 -- src/SCRIPTS/BF/LAYOUT/212x64/rates.lua | 2 -- src/SCRIPTS/BF/LAYOUT/320x480/filters.lua | 2 -- src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua | 2 -- src/SCRIPTS/BF/LAYOUT/480x272/filters.lua | 2 -- src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua | 2 -- src/SCRIPTS/BF/PAGES/filters.lua | 2 -- src/SCRIPTS/BF/PAGES/gpspids.lua | 2 -- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 2 -- src/SCRIPTS/BF/PAGES/pids1.lua | 4 ++-- src/SCRIPTS/BF/PAGES/pids2.lua | 2 -- src/SCRIPTS/BF/PAGES/pwm.lua | 2 -- src/SCRIPTS/BF/PAGES/rates.lua | 2 -- src/SCRIPTS/BF/PAGES/rescue.lua | 2 -- src/SCRIPTS/BF/PAGES/rx.lua | 2 -- src/SCRIPTS/BF/PAGES/vtx.lua | 2 -- src/SCRIPTS/BF/radios.lua | 8 ++++++++ src/SCRIPTS/BF/ui.lua | 4 ++-- 24 files changed, 14 insertions(+), 44 deletions(-) diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua index 7553b09a..45dab9ce 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua @@ -1,6 +1,4 @@ return { - yMinLimit = 12, - yMaxLimit = 52, text= { { t = "Gyro Lowpass 1 Dynamic", x = 2, y = 12, }, { t = "Min Cutoff", x = 12, y = 20, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua index 262b678d..37d63203 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua @@ -1,6 +1,4 @@ return { - yMinLimit = 12, - yMaxLimit = 52, text = { { t = "Acro Trainer", x = 2, y = 12, }, { t = "Angle Limit", x = 12, y = 20, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua index 041cea90..85e7979f 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua @@ -1,6 +1,4 @@ return { - yMinLimit = 11, - yMaxLimit = 52, text = { { t = "Feed", x = 45, y = 11, }, { t = "forward", x = 37, y = 18, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua index 17fb26b8..d5d3cab0 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua @@ -1,6 +1,4 @@ return { - yMinLimit = 11, - yMaxLimit = 52, text = { { t = "RC", x = 43, y = 11, }, { t = "Rate", x = 38, y = 18, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua index 67aaa6b7..34e6c4be 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua @@ -1,4 +1,6 @@ return { + yMinLimit = 11, + yMaxLimit = 52, text= { { t = "Stick Min", x = 10, y = 20 }, { t = "Stick Mid", x = 10, y = 30 }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua index 97ba3a96..7ab3b423 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua @@ -1,6 +1,4 @@ return { - yMinLimit = 12, - yMaxLimit = 52, text= { { t = "Gyro Lowpass 1 Dynamic", x = 2, y = 12, }, { t = "Min Cutoff", x = 12, y = 20, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua index 262b678d..37d63203 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua @@ -1,6 +1,4 @@ return { - yMinLimit = 12, - yMaxLimit = 52, text = { { t = "Acro Trainer", x = 2, y = 12, }, { t = "Angle Limit", x = 12, y = 20, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua index 1cd6b48d..451dbb48 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua @@ -1,6 +1,4 @@ return { - yMinLimit = 11, - yMaxLimit = 52, text = { { t = "RC", x = 43, y = 11, }, { t = "Rate", x = 38, y = 18, }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua b/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua index ccdfcdb4..85e174cf 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua @@ -1,6 +1,4 @@ return { - yMinLimit = 35, - yMaxLimit = 215, text= { { t = "Gyro Lowpass 1 Dynamic", x = 5, y = 35, }, { t = "Min Cutoff", x = 35, y = 55, }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua index 5d52bfba..22147e5b 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua @@ -1,6 +1,4 @@ return { - yMinLimit = 35, - yMaxLimit = 215, text = { { t = "Acro Trainer", x = 5, y = 35, }, { t = "Angle Limit", x = 15, y = 55, }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua b/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua index 82975e1f..78a27e04 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua @@ -1,6 +1,4 @@ return { - yMinLimit = 35, - yMaxLimit = 215, text= { { t = "Gyro Lowpass 1 Dynamic", x = 5, y = 35 }, { t = "Min Cutoff", x = 35, y = 55, }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua index 5d52bfba..22147e5b 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua @@ -1,6 +1,4 @@ return { - yMinLimit = 35, - yMaxLimit = 215, text = { { t = "Acro Trainer", x = 5, y = 35, }, { t = "Angle Limit", x = 15, y = 55, }, diff --git a/src/SCRIPTS/BF/PAGES/filters.lua b/src/SCRIPTS/BF/PAGES/filters.lua index d7b5599b..a8e185fc 100644 --- a/src/SCRIPTS/BF/PAGES/filters.lua +++ b/src/SCRIPTS/BF/PAGES/filters.lua @@ -7,8 +7,6 @@ return { title = "Filters", minBytes = 37, outputBytes = 37, - yMinLimit = display.yMinLimit, - yMaxLimit = display.yMaxLimit, text = display.text, fieldLayout = display.fieldLayout, fields = { diff --git a/src/SCRIPTS/BF/PAGES/gpspids.lua b/src/SCRIPTS/BF/PAGES/gpspids.lua index 7ba1744e..636afb86 100644 --- a/src/SCRIPTS/BF/PAGES/gpspids.lua +++ b/src/SCRIPTS/BF/PAGES/gpspids.lua @@ -7,8 +7,6 @@ return { eepromWrite = true, minBytes = 14, requiredVersion = 1.041, - yMinLimit = display.yMinLimit, - yMaxLimit = display.yMaxLimit, text = display.text, fieldLayout = display.fieldLayout, fields = { diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index f9ea3b81..49585339 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -7,8 +7,6 @@ return { eepromWrite = true, minBytes = 46, outputBytes = 46, - yMinLimit = display.yMinLimit, - yMaxLimit = display.yMaxLimit, text = display.text, fieldLayout = display.fieldLayout, fields = { diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua index e0936f4a..2e1eac9a 100644 --- a/src/SCRIPTS/BF/PAGES/pids1.lua +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -6,8 +6,8 @@ return { reboot = false, eepromWrite = true, minBytes = 9, - text = display.text, - fieldLayout = display.fieldLayout, + text = display.text, + fieldLayout = display.fieldLayout, fields = { { min = 0, max = 200, vals = { 1 }, }, { min = 0, max = 200, vals = { 4 }, }, diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index 21e9d82b..d6311123 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -6,8 +6,6 @@ return { reboot = false, eepromWrite = true, minBytes = 44, - yMinLimit = display.yMinLimit, - yMaxLimit = display.yMaxLimit, text = display.text, fieldLayout = display.fieldLayout, fields = { diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index 70a89e4a..d4169aae 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -6,8 +6,6 @@ return { eepromWrite = true, title = "PWM", minBytes = 9, - yMinLimit = display.yMinLimit, - yMaxLimit = display.yMaxLimit, text = display.text, fieldLayout = display.fieldLayout, fields = { diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua index 51b20fb8..f8e5e31b 100644 --- a/src/SCRIPTS/BF/PAGES/rates.lua +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -6,8 +6,6 @@ return { reboot = false, eepromWrite = true, minBytes = 16, - yMinLimit = display.yMinLimit, - yMaxLimit = display.yMaxLimit, text = display.text, fieldLayout = display.fieldLayout, fields = { diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index ed681f1a..dd53bd29 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -7,8 +7,6 @@ return { eepromWrite = true, minBytes = 16, requiredVersion = 1.041, - yMinLimit = display.yMinLimit, - yMaxLimit = display.yMaxLimit, text = display.text, fieldLayout = display.fieldLayout, fields = { diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index 29e1542f..0976e77d 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -6,8 +6,6 @@ return { reboot = false, eepromWrite = true, minBytes = 23, - yMinLimit = display.yMinLimit, - yMaxLimit = display.yMaxLimit, text = display.text, fieldLayout = display.fieldLayout, fields = { diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index 4687e89d..9efa7098 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -11,8 +11,6 @@ return { prevFreqVal = 0, lastFreqUpdTS = 0, freqModCounter = 0, - yMinLimit = display.yMinLimit, - yMaxLimit = display.yMaxLimit, text = display.text, fieldLayout = display.fieldLayout, fields = { diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index 6ed6b2f9..651180f5 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -14,6 +14,8 @@ local supportedRadios = SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, NoTelem = { 30, 55, "No Telemetry", BLINK }, textSize = SMLSIZE, + yMinLimit = 11, + yMaxLimit = 52, }, ["212x64"] = { @@ -23,6 +25,8 @@ local supportedRadios = SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, NoTelem = { 70, 55, "No Telemetry", BLINK }, textSize = SMLSIZE, + yMinLimit = 12, + yMaxLimit = 52, }, ["480x272"] = { @@ -32,6 +36,8 @@ local supportedRadios = SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, NoTelem = { 192, LCD_H - 28, "No Telemetry", BLINK }, textSize = MIDSIZE, + yMinLimit = 35, + yMaxLimit = 215, }, ["320x480"] = { @@ -41,6 +47,8 @@ local supportedRadios = SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", BLINK }, textSize = MIDSIZE, + yMinLimit = 35, + yMaxLimit = 215, }, } diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 20877989..fa73f087 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -180,8 +180,8 @@ function drawScreenTitle(screen_title) end local function drawScreen() - local yMinLim = Page.yMinLimit or 0 - local yMaxLim = Page.yMaxLimit or LCD_H + local yMinLim = radio.yMinLimit or 0 + local yMaxLim = radio.yMaxLimit or LCD_H local currentLineY = Page.fieldLayout[currentLine].y local screen_title = Page.title drawScreenTitle("Betaflight / "..screen_title) From 99288406d4e5253bbeefce5b9825b41c30540e56 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Thu, 17 Oct 2019 20:04:59 +0100 Subject: [PATCH 021/193] rename page.text to page.lables --- src/SCRIPTS/BF/LAYOUT/128x64/filters.lua | 2 +- src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua | 2 +- src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua | 2 +- src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua | 2 +- src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua | 2 +- src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua | 2 +- src/SCRIPTS/BF/LAYOUT/128x64/rates.lua | 2 +- src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua | 2 +- src/SCRIPTS/BF/LAYOUT/128x64/rx.lua | 4 +--- src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua | 2 +- src/SCRIPTS/BF/LAYOUT/212x64/filters.lua | 2 +- src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua | 2 +- src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua | 2 +- src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua | 2 +- src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua | 2 +- src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua | 2 +- src/SCRIPTS/BF/LAYOUT/212x64/rates.lua | 2 +- src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua | 2 +- src/SCRIPTS/BF/LAYOUT/212x64/rx.lua | 2 +- src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua | 2 +- src/SCRIPTS/BF/LAYOUT/320x480/filters.lua | 2 +- src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua | 2 +- src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua | 2 +- src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua | 2 +- src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua | 2 +- src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua | 2 +- src/SCRIPTS/BF/LAYOUT/320x480/rates.lua | 2 +- src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua | 2 +- src/SCRIPTS/BF/LAYOUT/320x480/rx.lua | 2 +- src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua | 2 +- src/SCRIPTS/BF/LAYOUT/480x272/filters.lua | 2 +- src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua | 2 +- src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua | 2 +- src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua | 2 +- src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua | 2 +- src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua | 2 +- src/SCRIPTS/BF/LAYOUT/480x272/rates.lua | 2 +- src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua | 2 +- src/SCRIPTS/BF/LAYOUT/480x272/rx.lua | 2 +- src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua | 2 +- src/SCRIPTS/BF/PAGES/filters.lua | 2 +- src/SCRIPTS/BF/PAGES/gpspids.lua | 2 +- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 2 +- src/SCRIPTS/BF/PAGES/pids1.lua | 2 +- src/SCRIPTS/BF/PAGES/pids2.lua | 2 +- src/SCRIPTS/BF/PAGES/pwm.lua | 2 +- src/SCRIPTS/BF/PAGES/rates.lua | 2 +- src/SCRIPTS/BF/PAGES/rescue.lua | 2 +- src/SCRIPTS/BF/PAGES/rx.lua | 2 +- src/SCRIPTS/BF/PAGES/vtx.lua | 2 +- src/SCRIPTS/BF/ui.lua | 4 ++-- 51 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua index 45dab9ce..b76da948 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Gyro Lowpass 1 Dynamic", x = 2, y = 12, }, { t = "Min Cutoff", x = 12, y = 20, }, { t = "Max Cutoff", x = 12, y = 28, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua index 998f0b65..06abe9e5 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "P", x = 55, y = 14, }, { t = "I", x = 83, y = 14, }, { t = "D", x = 111, y = 14, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua index 37d63203..37b6fdb3 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Acro Trainer", x = 2, y = 12, }, { t = "Angle Limit", x = 12, y = 20, }, { t = "Throttle Boost", x = 2, y = 28, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua index 7e3dce95..1efeb2e7 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "P", x = 45, y = 14, }, { t = "I", x = 73, y = 14, }, { t = "D", x = 101, y = 14, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua index 85e7979f..2d01f0fe 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Feed", x = 45, y = 11, }, { t = "forward", x = 37, y = 18, }, { t = "D", x = 85, y = 11, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua index d7125a2e..db32f042 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "32K", x = 10, y = 14, }, { t = "Gyro", x = 10, y = 24, }, { t = "PID", x = 10, y = 34, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua index d5d3cab0..010347c5 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "RC", x = 43, y = 11, }, { t = "Rate", x = 38, y = 18, }, { t = "Super", x = 63, y = 11, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua index b91353ba..6f410660 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Min Sats.", x = 3, y = 10, }, { t = "Angle", x = 3, y = 20, }, { t = "Initial Alt", x = 3, y = 30, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua index 34e6c4be..2f267174 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua @@ -1,7 +1,5 @@ return { - yMinLimit = 11, - yMaxLimit = 52, - text= { + labels = { { t = "Stick Min", x = 10, y = 20 }, { t = "Stick Mid", x = 10, y = 30 }, { t = "Stick Max", x = 10, y = 40 }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua index c154bd61..abecf4c0 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Band", x = 10, y = 14 }, { t = "Channel", x = 10, y = 24 }, { t = "Power", x = 10, y = 34 }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua index 7ab3b423..f5edfbb8 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Gyro Lowpass 1 Dynamic", x = 2, y = 12, }, { t = "Min Cutoff", x = 12, y = 20, }, { t = "Max Cutoff", x = 12, y = 28, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua index 5a2b5f7f..178b5232 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "P", x = 70, y = 14, }, { t = "I", x = 98, y = 14, }, { t = "D", x = 126, y = 14, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua index 37d63203..37b6fdb3 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Acro Trainer", x = 2, y = 12, }, { t = "Angle Limit", x = 12, y = 20, }, { t = "Throttle Boost", x = 2, y = 28, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua index 791d52c5..66ccafb5 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "P", x = 70, y = 14, }, { t = "I", x = 98, y = 14, }, { t = "D", x = 126, y = 14, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua index 17da5c79..345e7362 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Feed", x = 46, y = 11, }, { t = "forward", x = 38, y = 18, }, { t = "D", x = 86, y = 11, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua index b2c45f31..17254082 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "32K", x = 48, y = 14, }, { t = "Gyro Rt", x = 29, y = 24, }, { t = "PID Rt", x = 35, y = 34, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua index 451dbb48..e4198473 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "RC", x = 43, y = 11, }, { t = "Rate", x = 38, y = 18, }, { t = "Super", x = 63, y = 11, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua index 7044b470..5b61bde7 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Min Sats.", x = 30, y = 16, }, { t = "Angle", x = 45, y = 26, }, { t = "Initial Alt.", x = 18, y = 36, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua index 13d683b1..f539f9de 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Stick Min", x = 30, y = 20 }, { t = "Stick Mid", x = 30, y = 30 }, { t = "Stick Max", x = 30, y = 40 }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua index 718b40a4..3b770256 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Band", x = 25, y = 14 }, { t = "Channel", x = 25, y = 24 }, { t = "Power", x = 25, y = 34 }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua b/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua index 85e174cf..b75db021 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Gyro Lowpass 1 Dynamic", x = 5, y = 35, }, { t = "Min Cutoff", x = 35, y = 55, }, { t = "Max Cutoff", x = 35, y = 75, }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua index f976a691..c7dd58c8 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "P", x = 100, y = 48, }, { t = "I", x = 180, y = 48, }, { t = "D", x = 260, y = 48, }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua index 22147e5b..a35a9904 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Acro Trainer", x = 5, y = 35, }, { t = "Angle Limit", x = 15, y = 55, }, { t = "Throttle Boost", x = 5, y = 75, }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua index 6e92e4ef..5ace790b 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "P", x = 100, y = 48, }, { t = "I", x = 180, y = 48, }, { t = "D", x = 260, y = 48, }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua index 8314d40f..730c81ac 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Feed", x = 97, y = 52, }, { t = "forward", x = 82, y = 70, }, { t = "D", x = 207, y = 52, }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua index b9f6c164..a05535ca 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Protocol", x = 36, y = 68 }, { t = "32K", x = 36, y = 110 }, { t = "Gyro Rt", x = 36, y = 155 }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua index 1fbd50a5..95f3d156 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "RC", x = 100, y = 52 }, { t = "Rate", x = 94, y = 70 }, { t = "Super", x = 148, y = 52 }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua index 6acf9cb6..f020b756 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Min Sats.", x = 10, y = 40 }, { t = "Angle", x = 10, y = 80 }, { t = "Initial Altitude", x = 10, y = 120 }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua index f6817383..d9c5ae83 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Stick Min", x = 36, y = 68 }, { t = "Stick Mid", x = 36, y = 110 }, { t = "Stick Max", x = 36, y = 155 }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua b/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua index 5daad798..fedff593 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Band", x = 36, y = 155 }, { t = "Channel", x = 36, y = 200 }, { t = "Power", x = 36, y = 242 }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua b/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua index 78a27e04..39267df6 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Gyro Lowpass 1 Dynamic", x = 5, y = 35 }, { t = "Min Cutoff", x = 35, y = 55, }, { t = "Max Cutoff", x = 35, y = 75, }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua index 26067a95..42c82a6a 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "P", x = 142, y = 48, }, { t = "I", x = 244, y = 48, }, { t = "D", x = 342, y = 48, }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua index 22147e5b..a35a9904 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Acro Trainer", x = 5, y = 35, }, { t = "Angle Limit", x = 15, y = 55, }, { t = "Throttle Boost", x = 5, y = 75, }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua index 457e6ab1..2896075d 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua @@ -1,6 +1,6 @@ return { - text = { + labels = { { t = "P", x = 142, y = 48, }, { t = "I", x = 244, y = 48, }, { t = "D", x = 342, y = 48, }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua index b3e7642b..8f4bc5da 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Feed", x = 97, y = 52, }, { t = "forward", x = 82, y = 70, }, { t = "D", x = 207, y = 52, }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua index f612a152..31dad642 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Protocol", x = 36, y = 68 }, { t = "32K", x = 36, y = 110 }, { t = "Gyro Rt", x = 36, y = 155 }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua index 3d8506b6..85425eb2 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "RC", x = 100, y = 52, }, { t = "Rate", x = 94, y = 70, }, { t = "Super", x = 148, y = 52, }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua index 72ca6709..140d2bbd 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua @@ -1,5 +1,5 @@ return { - text = { + labels = { { t = "Min Sats.", x =130, y = 40, }, { t = "Angle", x =150, y = 80, }, { t = "Initial Altitude", x = 60, y = 120, }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua index 1db53a8a..175e8bf2 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Stick Min", x = 36, y = 68 }, { t = "Stick Mid", x = 36, y = 110 }, { t = "Stick Max", x = 36, y = 155 }, diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua b/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua index e0bce1a1..b844b488 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua @@ -1,5 +1,5 @@ return { - text= { + labels = { { t = "Band", x = 36, y = 110 }, { t = "Channel", x = 36, y = 155 }, { t = "Power", x = 232, y = 110 }, diff --git a/src/SCRIPTS/BF/PAGES/filters.lua b/src/SCRIPTS/BF/PAGES/filters.lua index a8e185fc..8b4d53fe 100644 --- a/src/SCRIPTS/BF/PAGES/filters.lua +++ b/src/SCRIPTS/BF/PAGES/filters.lua @@ -7,7 +7,7 @@ return { title = "Filters", minBytes = 37, outputBytes = 37, - text = display.text, + labels = display.labels, fieldLayout = display.fieldLayout, fields = { { min = 0, max = 1000, vals = { 30, 31 } }, diff --git a/src/SCRIPTS/BF/PAGES/gpspids.lua b/src/SCRIPTS/BF/PAGES/gpspids.lua index 636afb86..0fbfabe4 100644 --- a/src/SCRIPTS/BF/PAGES/gpspids.lua +++ b/src/SCRIPTS/BF/PAGES/gpspids.lua @@ -7,7 +7,7 @@ return { eepromWrite = true, minBytes = 14, requiredVersion = 1.041, - text = display.text, + labels = display.labels, fieldLayout = display.fieldLayout, fields = { { min = 0, max = 200, vals = { 1,2 }, }, diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 49585339..fb23a25a 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -7,7 +7,7 @@ return { eepromWrite = true, minBytes = 46, outputBytes = 46, - text = display.text, + labels = display.labels, fieldLayout = display.fieldLayout, fields = { { min = 20, max = 80, vals = { 32 } }, diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua index 2e1eac9a..727585b7 100644 --- a/src/SCRIPTS/BF/PAGES/pids1.lua +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -6,7 +6,7 @@ return { reboot = false, eepromWrite = true, minBytes = 9, - text = display.text, + labels = display.labels, fieldLayout = display.fieldLayout, fields = { { min = 0, max = 200, vals = { 1 }, }, diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index d6311123..248dfd09 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -6,7 +6,7 @@ return { reboot = false, eepromWrite = true, minBytes = 44, - text = display.text, + labels = display.labels, fieldLayout = display.fieldLayout, fields = { { min = 0, max = 2000, vals = { 33, 34 }, }, diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index d4169aae..72dfd2b9 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -6,7 +6,7 @@ return { eepromWrite = true, title = "PWM", minBytes = 9, - text = display.text, + labels = display.labels, fieldLayout = display.fieldLayout, fields = { { vals = { 9 }, min = 0, max = 1, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua index f8e5e31b..96fa2b4d 100644 --- a/src/SCRIPTS/BF/PAGES/rates.lua +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -6,7 +6,7 @@ return { reboot = false, eepromWrite = true, minBytes = 16, - text = display.text, + labels = display.labels, fieldLayout = display.fieldLayout, fields = { { vals = { 1 }, min = 0, max = 255, scale = 100, }, diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index dd53bd29..7ea57cc7 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -7,7 +7,7 @@ return { eepromWrite = true, minBytes = 16, requiredVersion = 1.041, - text = display.text, + labels = display.labels, fieldLayout = display.fieldLayout, fields = { { min = 0, max = 50, vals = { 16 }, }, diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index 0976e77d..4ca09d14 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -6,7 +6,7 @@ return { reboot = false, eepromWrite = true, minBytes = 23, - text = display.text, + labels = display.labels, fieldLayout = display.fieldLayout, fields = { { min = 1000, max = 2000, vals = { 6, 7 }, }, diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index 9efa7098..35d4346d 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -11,7 +11,7 @@ return { prevFreqVal = 0, lastFreqUpdTS = 0, freqModCounter = 0, - text = display.text, + labels = display.labels, fieldLayout = display.fieldLayout, fields = { { min=0, max=5, vals = { 2 }, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index fa73f087..616c9a4c 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -192,8 +192,8 @@ local function drawScreen() elseif currentLineY - scrollPixelsY >= yMaxLim then scrollPixelsY = currentLineY - yMaxLim end - for i=1,#(Page.text) do - local f = Page.text[i] + for i=1,#(Page.labels) do + local f = Page.labels[i] local textOptions = radio.textSize + globalTextOptions if (f.y - scrollPixelsY) >= yMinLim and (f.y - scrollPixelsY) <= yMaxLim then lcd.drawText(f.x, f.y - scrollPixelsY, f.t, textOptions) From 78b7945643fa522bf48798207d0d0f6779cf17aa Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Thu, 17 Oct 2019 20:37:10 +0100 Subject: [PATCH 022/193] fix menu spacing on high res screens. --- src/SCRIPTS/BF/pages.lua | 20 ++++++++--------- src/SCRIPTS/BF/ui.lua | 48 ++++++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index b870d1ec..3f6b997c 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -1,13 +1,13 @@ PageFiles = { - { title = "PIDs 1", script = "pids1.lua"}, - { title = "PIDs 2", script = "pids2.lua"}, - { title = "Rates", script = "rates.lua"}, - { title = "Advanced PIDs", script = "pid_advanced.lua"}, - { title = "Filters", script = "filters.lua"}, - { title = "vTX Settings", script = "vtx.lua"}, - { title = "Gyro / Motor", script = "pwm.lua"}, - { title = "Rx", script = "rx.lua"}, - { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041}, - { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041}, + { title = "PIDs 1", script = "pids1.lua" }, + { title = "PIDs 2", script = "pids2.lua" }, + { title = "Rates", script = "rates.lua" }, + { title = "Advanced PIDs", script = "pid_advanced.lua" }, + { title = "Filters", script = "filters.lua" }, + { title = "vTX Settings", script = "vtx.lua" }, + { title = "Gyro / Motor", script = "pwm.lua" }, + { title = "Rx", script = "rx.lua" }, + { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041 }, + { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041 }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 616c9a4c..f765d83f 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -362,14 +362,12 @@ function run_ui(event) end local nextPage = currentPage while Page == nil do - Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[currentPage].script))() + Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[currentPage].script))() if Page.requiredVersion and apiVersion > 0 and Page.requiredVersion > apiVersion then incPage(1) - if currentPage == nextPage then lcd.clear() lcd.drawText(radio.NoTelem[1], radio.NoTelem[2], "No Pages! API: " .. apiVersion, radio.NoTelem[4]) - return 1 end end @@ -405,26 +403,32 @@ function run_ui(event) incMainMenu(-1) end lcd.clear() - lcd.drawScreenTitle("Betaflight Config", 0, 0) + drawScreenTitle("Betaflight Config", 0, 0) + local yMinLim = radio.yMinLimit + local yMaxLim = radio.yMaxLimit + local lineSpacing = 10 + if radio.resolution == lcdResolution.high then + lineSpacing = 25 + end for i=1, #PageFiles do - local yMinLim = 10 - local yMaxLim = LCD_H - 8 - local currentLineY = (menuLine-1)*8 + yMinLim - if currentLineY <= yMaxLim then - scrollPixelsY = 0 - elseif currentLineY - scrollPixelsY <= yMinLim then - scrollPixelsY = currentLineY - yMinLim*2 - elseif currentLineY - scrollPixelsY >= yMaxLim then - scrollPixelsY = currentLineY - yMaxLim + 6 - end - local attr = (menuLine == i and INVERS or 0) - if event == EVT_VIRTUAL_ENTER and attr == INVERS then - Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[i].script))() - currentPage = i - currentState = pageStatus.display - end - if ((i-1)*8 + yMinLim - scrollPixelsY) >= yMinLim and ((i-1)*8 + yMinLim - scrollPixelsY) <= yMaxLim then - lcd.drawText(6, (i-1)*8 + yMinLim - scrollPixelsY, PageFiles[i].title, attr) + if not Page.requiredVersion or (apiVersion > 0 and Page.requiredVersion < apiVersion) then + local currentLineY = (menuLine-1)*lineSpacing + yMinLim + if currentLineY <= yMaxLim then + scrollPixelsY = 0 + elseif currentLineY - scrollPixelsY <= yMinLim then + scrollPixelsY = currentLineY - yMinLim + elseif currentLineY - scrollPixelsY >= yMaxLim then + scrollPixelsY = currentLineY - yMaxLim + end + local attr = (menuLine == i and INVERS or 0) + if event == EVT_VIRTUAL_ENTER and attr == INVERS then + Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[i].script))() + currentPage = i + currentState = pageStatus.display + end + if ((i-1)*lineSpacing + yMinLim - scrollPixelsY) >= yMinLim and ((i-1)*lineSpacing + yMinLim - scrollPixelsY) <= yMaxLim then + lcd.drawText(6, (i-1)*lineSpacing + yMinLim - scrollPixelsY, PageFiles[i].title, attr) + end end end end From 80898a54c1ad4f714d68fd130670f5c730d1b7c7 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Thu, 17 Oct 2019 20:41:12 +0100 Subject: [PATCH 023/193] menu text tweek. --- src/SCRIPTS/BF/pages.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index 3f6b997c..ef003801 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -1,13 +1,13 @@ PageFiles = { + { title = "VTX Settings", script = "vtx.lua" }, { title = "PIDs 1", script = "pids1.lua" }, { title = "PIDs 2", script = "pids2.lua" }, { title = "Rates", script = "rates.lua" }, { title = "Advanced PIDs", script = "pid_advanced.lua" }, { title = "Filters", script = "filters.lua" }, - { title = "vTX Settings", script = "vtx.lua" }, { title = "Gyro / Motor", script = "pwm.lua" }, - { title = "Rx", script = "rx.lua" }, + { title = "Receiver", script = "rx.lua" }, { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041 }, { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041 }, } \ No newline at end of file From 000b0af6611378b74f5897834d0ae6f7d687526f Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Thu, 17 Oct 2019 20:51:52 +0100 Subject: [PATCH 024/193] fix broken layouts. --- src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua | 2 +- src/SCRIPTS/BF/LAYOUT/128x64/rates.lua | 2 +- src/SCRIPTS/BF/PAGES/pids1.lua | 2 +- src/SCRIPTS/BF/PAGES/rx.lua | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua index db32f042..e5b098a9 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua @@ -8,7 +8,7 @@ return { { t = "PWM", x = 58, y = 34, }, { t = "Idle", x = 58, y = 44, } }, - fields = { + fieldLayout = { { x = 32, y = 14, }, { x = 32, y = 24, }, { x = 32, y = 34, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua index 010347c5..067f3320 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua @@ -18,7 +18,7 @@ return { { t = "Rate", x = 20, y = 108, }, { t = "Breakpoint", x = 20, y = 116, }, }, - fields = { + fieldLayout = { { x = 39, y = 26, }, { x = 39, y = 36, }, { x = 39, y = 46, }, diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua index 727585b7..6a5fd4ba 100644 --- a/src/SCRIPTS/BF/PAGES/pids1.lua +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -8,7 +8,7 @@ return { minBytes = 9, labels = display.labels, fieldLayout = display.fieldLayout, - fields = { + fields = { { min = 0, max = 200, vals = { 1 }, }, { min = 0, max = 200, vals = { 4 }, }, { min = 0, max = 200, vals = { 7 }, }, diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index 4ca09d14..6323f104 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -8,7 +8,7 @@ return { minBytes = 23, labels = display.labels, fieldLayout = display.fieldLayout, - fields = { + fields = { { min = 1000, max = 2000, vals = { 6, 7 }, }, { min = 1000, max = 2000, vals = { 4, 5 }, }, { min = 1000, max = 2000, vals = { 2, 3 }, }, From a6f90313704c207b1c686f1984278e854c09d2b5 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Mon, 21 Oct 2019 19:27:07 +0100 Subject: [PATCH 025/193] delete x7\rx.lua that snuck back in --- src/SCRIPTS/BF/X7/rx.lua | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 src/SCRIPTS/BF/X7/rx.lua diff --git a/src/SCRIPTS/BF/X7/rx.lua b/src/SCRIPTS/BF/X7/rx.lua deleted file mode 100644 index b775fb76..00000000 --- a/src/SCRIPTS/BF/X7/rx.lua +++ /dev/null @@ -1,19 +0,0 @@ -return { - read = 44, -- MSP_RX_CONFIG - write = 45, -- MSP_SET_RX_CONFIG - title = "RX", - reboot = false, - eepromWrite = true, - minBytes = 23, - yMinLimit = 12, - yMaxLimit = 52, - text = {}, - fields = { - { t = "Stick Min", x = 10, y = 20, sp = 45, min = 1000, max = 2000, vals = { 6, 7 }, to = SMLSIZE }, - { t = "Stick Mid", x = 10, y = 30, sp = 45, min = 1000, max = 2000, vals = { 4, 5 }, to = SMLSIZE }, - { t = "Stick Max", x = 10, y = 40, sp = 45, min = 1000, max = 2000, vals = { 2, 3 }, to = SMLSIZE }, - { t = "Cam Angle", x = 10, y = 50, sp = 50, min = 0, max = 90, vals = { 23 }, to = SMLSIZE }, - { t = "Interp", x = 10, y = 60, sp = 50, min = 0, max = 3, vals = { 13 }, to = SMLSIZE, table={ [0]="Off", "Preset", "Auto", "Manual"} }, - { t = "Interp Int", x = 10, y = 70, sp = 50, min = 1, max = 50, vals = { 14 }, to = SMLSIZE }, - }, -} From 4b0dd6620cd94615cfc1dc075d88857bc8d852bf Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Mon, 21 Oct 2019 19:27:57 +0100 Subject: [PATCH 026/193] fix menu with api limited pages --- src/SCRIPTS/BF/ui.lua | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index f765d83f..66a0c1fd 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -14,6 +14,7 @@ local uiMsp = } local menuLine = 1 +local pageCount = 1 local currentState = pageStatus.mainMenu local requestTimeout = 80 -- 800ms request timeout local currentPage = 1 @@ -37,6 +38,15 @@ local foregroundColor = LINE_COLOR or SOLID local globalTextOptions = TEXT_COLOR or 0 +local function getPageCount() + pageCount = 0 + for i=1,#(PageFiles) do + if (not PageFiles[i].requiredVersion) or (apiVersion == 0) or (apiVersion > 0 and PageFiles[i].requiredVersion < apiVersion) then + pageCount = pageCount + 1 + end + end +end + local function saveSettings(new) if Page.values then if Page.preSave then @@ -155,7 +165,7 @@ local function incLine(inc) end local function incMainMenu(inc) - menuLine = clipValue(menuLine + inc, 1, #(PageFiles)) + menuLine = clipValue(menuLine + inc, 1, pageCount) end local function incPopupMenu(inc) @@ -277,6 +287,7 @@ local function drawPopupMenu() end function run_ui(event) + getPageCount() local now = getTime() -- if lastRunTS old than 500ms if lastRunTS + 50 < now then @@ -411,8 +422,8 @@ function run_ui(event) lineSpacing = 25 end for i=1, #PageFiles do - if not Page.requiredVersion or (apiVersion > 0 and Page.requiredVersion < apiVersion) then - local currentLineY = (menuLine-1)*lineSpacing + yMinLim + if (not PageFiles[i].requiredVersion) or (apiVersion == 0) or (apiVersion > 0 and PageFiles[i].requiredVersion < apiVersion) then + local currentLineY = (menuLine-1)*lineSpacing + yMinLim + 1 if currentLineY <= yMaxLim then scrollPixelsY = 0 elseif currentLineY - scrollPixelsY <= yMinLim then From 53d76ee1d1ce7debb887946877501628accb57a5 Mon Sep 17 00:00:00 2001 From: kaweksl Date: Tue, 22 Oct 2019 12:24:08 +0200 Subject: [PATCH 027/193] Added option Arming without fix to GPS Rescue --- src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua | 42 +++++++++++++----------- src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua | 2 ++ src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua | 12 ++++--- src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua | 2 ++ src/SCRIPTS/BF/PAGES/rescue.lua | 5 +-- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua index 6f410660..9a5c7149 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua @@ -1,25 +1,29 @@ return { labels = { - { t = "Min Sats.", x = 3, y = 10, }, - { t = "Angle", x = 3, y = 20, }, - { t = "Initial Alt", x = 3, y = 30, }, - { t = "Descent Dst", x = 3, y = 40, }, - { t = "Ground Spd", x = 3, y = 50, }, - { t = "Snty.", x = 80, y = 10, }, - { t = "Throttle", x = 80, y = 20, }, - { t = "Min", x = 85, y = 30, }, - { t = "Hover", x = 80, y = 40, }, - { t = "Max", x = 85, y = 50, }, + { t = "Min Sats.", x = 3, y = 14, }, + { t = "Angle", x = 3, y = 24, }, + { t = "Initial Alt", x = 3, y = 34, }, + { t = "Descent Dst", x = 3, y = 44, }, + { t = "Ground Spd", x = 3, y = 54, }, + { t = "Arm w/o fix", x = 3, y = 64, }, + { t = "Snty.", x = 80, y = 14, }, + { t = "Throttle", x = 80, y = 24, }, + { t = "Min", x = 85, y = 34, }, + { t = "Hover", x = 80, y = 44, }, + { t = "Max", x = 85, y = 54, }, }, fieldLayout = { - { x = 58, y = 10, }, - { x = 58, y = 20, }, - { x = 58, y = 30, }, - { x = 58, y = 40, }, - { x = 58, y = 50, }, - { x = 105, y = 10, }, - { x = 105, y = 30, }, - { x = 105, y = 40, }, - { x = 105, y = 50, }, + { x = 58, y = 14, }, + { x = 58, y = 24, }, + { x = 58, y = 34, }, + { x = 58, y = 44, }, + { x = 58, y = 54, }, + { x = 58, y = 64, }, + { x = 105, y = 14, }, + { x = 105, y = 34, }, + { x = 105, y = 44, }, + { x = 105, y = 54, }, + { x = 105, y = 54, }, + }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua index 5b61bde7..155daacc 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua @@ -5,6 +5,7 @@ return { { t = "Initial Alt.", x = 18, y = 36, }, { t = "Descent Dist.", x = 10, y = 46, }, { t = "Ground Speed", x = 10, y = 56, }, + { t = "Arm w/o fix", x = 15, y = 66, }, { t = "Sanity Ch.", x = 125, y = 16, }, { t = "Throttle", x = 125, y = 26, }, { t = "Min", x = 128, y = 36, }, @@ -17,6 +18,7 @@ return { { x = 75, y = 36, }, { x = 75, y = 46, }, { x = 75, y = 56, }, + { x = 75, y = 66, }, { x = 180, y = 16, }, { x = 150, y = 36, }, { x = 150, y = 46, }, diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua index f020b756..d09658d7 100644 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua @@ -5,11 +5,12 @@ return { { t = "Initial Altitude", x = 10, y = 120 }, { t = "Descent Distance", x = 10, y = 160 }, { t = "Ground Speed", x = 10, y = 200 }, - { t = "Snty.", x = 10, y = 240 }, - { t = "Throttle", x = 10, y = 280 }, - { t = "Min", x = 10, y = 320 }, - { t = "Hover", x = 10, y = 360 }, - { t = "Max", x = 10, y = 400 }, + { t = "Arm w/o fix", x = 10, y = 240, }, + { t = "Snty.", x = 10, y = 260 }, + { t = "Throttle", x = 10, y = 320 }, + { t = "Min", x = 10, y = 360 }, + { t = "Hover", x = 10, y = 400 }, + { t = "Max", x = 10, y = 440 }, }, fieldLayout = { { x = 260, y = 40, }, @@ -21,5 +22,6 @@ return { { x = 260, y = 320, }, { x = 260, y = 360, }, { x = 260, y = 400, }, + { x = 260, y = 440, }, }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua index 140d2bbd..e79db748 100644 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua @@ -5,6 +5,7 @@ return { { t = "Initial Altitude", x = 60, y = 120, }, { t = "Descent Distance", x = 10, y = 160, }, { t = "Ground Speed", x = 50, y = 200, }, + { t = "Arm w/o fix", x = 10, y = 240, }, { t = "Snty.", x = 310, y = 40, }, { t = "Throttle", x = 350, y = 80, }, { t = "Min", x = 330, y = 120, }, @@ -17,6 +18,7 @@ return { { x = 260, y = 120, }, { x = 260, y = 160, }, { x = 260, y = 200, }, + { x = 260, y = 240, }, { x = 400, y = 40, }, { x = 400, y = 120, }, { x = 400, y = 160, }, diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index 7ea57cc7..ac0d2dcd 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -5,8 +5,8 @@ return { title = "GPS Rescue", reboot = false, eepromWrite = true, - minBytes = 16, - requiredVersion = 1.041, + minBytes = 21, + requiredVersion = 1.043, labels = display.labels, fieldLayout = display.fieldLayout, fields = { @@ -15,6 +15,7 @@ return { { min = 20, max = 100, vals = { 3,4 }, }, { min = 30, max = 500, vals = { 5,6 }, }, { min = 30, max = 3000, vals = { 7,8 }, }, + { min = 0, max = 1, vals = { 21 }, table = { [0]="OFF","ON"}, }, { min = 0, max = 2, vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"}, }, { min = 1000, max = 2000, vals = { 9,10 }, }, { min = 1000, max = 2000, vals = { 13,14 }, }, From 1734adea7bed62c82dd2101717b9bfa6abd0efd2 Mon Sep 17 00:00:00 2001 From: kaweksl Date: Tue, 22 Oct 2019 13:31:18 +0200 Subject: [PATCH 028/193] fixed backward compability --- src/SCRIPTS/BF/PAGES/rescue.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index ac0d2dcd..809693a7 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -5,8 +5,8 @@ return { title = "GPS Rescue", reboot = false, eepromWrite = true, - minBytes = 21, - requiredVersion = 1.043, + minBytes = 16, + requiredVersion = 1.041, labels = display.labels, fieldLayout = display.fieldLayout, fields = { From f42450a9111091d0ffcbd6bdff4923d61ce7f6ed Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Tue, 22 Oct 2019 21:39:53 +0100 Subject: [PATCH 029/193] Fix selected field not reset on page exit --- src/SCRIPTS/BF/ui.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 66a0c1fd..9fbc2769 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -444,8 +444,10 @@ function run_ui(event) end end if stopDisplay and (not isTelemetryScript) then + currentLine = 1 currentState = pageStatus.mainMenu stopDisplay = false + collectgarbage() end processMspReply(mspPollReply()) return 0 From 1c8484413ed4057c130ee0fb29fd40b7c713c24c Mon Sep 17 00:00:00 2001 From: kaweksl Date: Wed, 23 Oct 2019 10:23:29 +0200 Subject: [PATCH 030/193] position adjusment --- src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua | 44 ++++++++++++------------- src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua | 42 +++++++++++------------ 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua index 9a5c7149..5d6f6eaf 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua @@ -1,29 +1,29 @@ return { labels = { - { t = "Min Sats.", x = 3, y = 14, }, - { t = "Angle", x = 3, y = 24, }, - { t = "Initial Alt", x = 3, y = 34, }, - { t = "Descent Dst", x = 3, y = 44, }, - { t = "Ground Spd", x = 3, y = 54, }, - { t = "Arm w/o fix", x = 3, y = 64, }, - { t = "Snty.", x = 80, y = 14, }, - { t = "Throttle", x = 80, y = 24, }, - { t = "Min", x = 85, y = 34, }, - { t = "Hover", x = 80, y = 44, }, - { t = "Max", x = 85, y = 54, }, + { t = "Min Sats.", x = 3, y = 12, }, + { t = "Angle", x = 3, y = 22, }, + { t = "Initial Alt", x = 3, y = 32, }, + { t = "Descent Dst", x = 3, y = 42, }, + { t = "Ground Spd", x = 3, y = 52, }, + { t = "Arm w/o fix", x = 3, y = 62, }, + { t = "Snty.", x = 80, y = 12, }, + { t = "Throttle", x = 80, y = 22, }, + { t = "Min", x = 85, y = 32, }, + { t = "Hover", x = 80, y = 42, }, + { t = "Max", x = 85, y = 52, }, }, fieldLayout = { - { x = 58, y = 14, }, - { x = 58, y = 24, }, - { x = 58, y = 34, }, - { x = 58, y = 44, }, - { x = 58, y = 54, }, - { x = 58, y = 64, }, - { x = 105, y = 14, }, - { x = 105, y = 34, }, - { x = 105, y = 44, }, - { x = 105, y = 54, }, - { x = 105, y = 54, }, + { x = 58, y = 12, }, + { x = 58, y = 22, }, + { x = 58, y = 32, }, + { x = 58, y = 42, }, + { x = 58, y = 52, }, + { x = 58, y = 62, }, + { x = 105, y = 12, }, + { x = 105, y = 32, }, + { x = 105, y = 42, }, + { x = 105, y = 52, }, + { x = 105, y = 52, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua index 155daacc..4a337e22 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua @@ -1,27 +1,27 @@ return { labels = { - { t = "Min Sats.", x = 30, y = 16, }, - { t = "Angle", x = 45, y = 26, }, - { t = "Initial Alt.", x = 18, y = 36, }, - { t = "Descent Dist.", x = 10, y = 46, }, - { t = "Ground Speed", x = 10, y = 56, }, - { t = "Arm w/o fix", x = 15, y = 66, }, - { t = "Sanity Ch.", x = 125, y = 16, }, - { t = "Throttle", x = 125, y = 26, }, - { t = "Min", x = 128, y = 36, }, - { t = "Hover", x = 120, y = 46, }, - { t = "Max", x = 128, y = 56, }, + { t = "Min Sats.", x = 30, y = 12, }, + { t = "Angle", x = 45, y = 22, }, + { t = "Initial Alt.", x = 18, y = 32, }, + { t = "Descent Dist.", x = 10, y = 42, }, + { t = "Ground Speed", x = 10, y = 52, }, + { t = "Arm w/o fix", x = 15, y = 62, }, + { t = "Sanity Ch.", x = 125, y = 12, }, + { t = "Throttle", x = 125, y = 22, }, + { t = "Min", x = 128, y = 32, }, + { t = "Hover", x = 120, y = 42, }, + { t = "Max", x = 128, y = 52, }, }, fieldLayout = { - { x = 75, y = 16, }, - { x = 75, y = 26, }, - { x = 75, y = 36, }, - { x = 75, y = 46, }, - { x = 75, y = 56, }, - { x = 75, y = 66, }, - { x = 180, y = 16, }, - { x = 150, y = 36, }, - { x = 150, y = 46, }, - { x = 150, y = 56, }, + { x = 75, y = 12, }, + { x = 75, y = 22, }, + { x = 75, y = 32, }, + { x = 75, y = 42, }, + { x = 75, y = 52, }, + { x = 75, y = 62, }, + { x = 180, y = 12, }, + { x = 150, y = 32, }, + { x = 150, y = 42, }, + { x = 150, y = 52, }, }, } From 3a242b6f1f098b6ce31d8df8790eac6f71f37b6c Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Tue, 15 Oct 2019 20:50:53 +0100 Subject: [PATCH 031/193] use vtx_defaults.lua for loading vtx values --- src/BF/VTX/vtx_defaults.lua | 8 +++++ src/SCRIPTS/BF/PAGES/vtx.lua | 63 ++++++++++++++++++++++-------------- 2 files changed, 47 insertions(+), 24 deletions(-) create mode 100644 src/BF/VTX/vtx_defaults.lua diff --git a/src/BF/VTX/vtx_defaults.lua b/src/BF/VTX/vtx_defaults.lua new file mode 100644 index 00000000..731b4b8f --- /dev/null +++ b/src/BF/VTX/vtx_defaults.lua @@ -0,0 +1,8 @@ +frequencyTable = { + { 5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725 }, -- Boscam A + { 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 }, -- Boscam B + { 5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945 }, -- Boscam E + { 5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880 }, -- FatShark + { 5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 }, -- RaceBand +} +bandTable = { "U", "A", "B", "E", "F", "R" } \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index 35d4346d..5cf944e0 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -1,4 +1,20 @@ + + local display = assert(loadScript(radio.templateHome.."vtx.lua"))() +assert(loadScript("/BF/VTX/vtx_defaults.lua"))() +local md = model.getInfo(); +vtx_tables = loadScript("/BF/VTX/"..md.name..".lua") +if (vtx_tables ~= nil) then + vtx_tables() +end +-- Vals +-- 1 Device Type +-- 2 Band +-- 3 Channel +-- 4 Power +-- 5 Pit +-- 6 Freq + return { read = 88, -- MSP_VTX_CONFIG write = 89, -- MSP_VTX_SET_CONFIG @@ -21,13 +37,7 @@ return { { vals = { 1 }, write = false, ro = true, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, { min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, }, - freqLookup = { - { 5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725 }, -- Boscam A - { 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 }, -- Boscam B - { 5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945 }, -- Boscam E - { 5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880 }, -- FatShark - { 5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 }, -- RaceBand - }, + freqLookup = frequencyTable, postLoad = function (self) if (self.values[2] or 0) < 0 or (self.values[3] or 0) == 0 or (self.values[4] or 0) == 0 then self.values = {} @@ -171,23 +181,28 @@ return { end, updatePowerTable = function(self) if self.values and not self.fields[3].table then - if self.values[1] == 1 then -- RTC6705 - self.fields[3].table = { 25, 200 } - self.fields[3].max = 2 - self.fields[4].t = nil -- don't display Pit field - self.fields[4].table = { [0]="", "" } - elseif self.values[1] == 3 then -- SmartAudio - self.fields[3].table = { 25, 200, 500, 800 } - self.fields[3].max = 4 - elseif self.values[1] == 4 then -- Tramp - self.fields[3].table = { 25, 100, 200, 400, 600 } - self.fields[3].max = 5 - elseif self.values[1] == 255 then -- None/Unknown - self.fields[3].t = nil -- don't display Power field - self.fields[3].max = 1 - self.fields[3].table = { [1]="" } - self.fields[4].t = nil -- don't display Pit field - self.fields[4].table = { [0]="", "" } + if powerTable then + self.fields[3].table = powerTable + self.fields[3].max = #(powerTable) + else + if self.values[1] == 1 then -- RTC6705 + self.fields[3].table = { 25, 200 } + self.fields[3].max = 2 + self.fields[4].t = nil -- don't display Pit field + self.fields[4].table = { [0]="", "" } + elseif self.values[1] == 3 then -- SmartAudio + self.fields[3].table = { 25, 200, 500, 800 } + self.fields[3].max = 4 + elseif self.values[1] == 4 then -- Tramp + self.fields[3].table = { 25, 100, 200, 400, 600 } + self.fields[3].max = 5 + elseif self.values[1] == 255 then -- None/Unknown + self.fields[3].t = nil -- don't display Power field + self.fields[3].max = 1 + self.fields[3].table = { [1]="" } + self.fields[4].t = nil -- don't display Pit field + self.fields[4].table = { [0]="", "" } + end end end end, From bbc435d988167effd029c0591af1b47dc31407e4 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Tue, 15 Oct 2019 21:20:13 +0100 Subject: [PATCH 032/193] Move all tables to vtx_defaults.lua --- src/BF/VTX/vtx_defaults.lua | 5 ++++- src/SCRIPTS/BF/PAGES/vtx.lua | 25 ++++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/BF/VTX/vtx_defaults.lua b/src/BF/VTX/vtx_defaults.lua index 731b4b8f..dbd49f2d 100644 --- a/src/BF/VTX/vtx_defaults.lua +++ b/src/BF/VTX/vtx_defaults.lua @@ -5,4 +5,7 @@ frequencyTable = { { 5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880 }, -- FatShark { 5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 }, -- RaceBand } -bandTable = { "U", "A", "B", "E", "F", "R" } \ No newline at end of file +frequenciesPerBand = 8 +bandTable = { [0]="U", "A", "B", "E", "F", "R" } +deviceTable = { [1]="6705",[3]="SA",[4]="Tramp",[255]="None"} +pitModeTable = { [0]="OFF", "ON" } \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index 5cf944e0..fc3ff8ef 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -1,5 +1,3 @@ - - local display = assert(loadScript(radio.templateHome.."vtx.lua"))() assert(loadScript("/BF/VTX/vtx_defaults.lua"))() local md = model.getInfo(); @@ -7,13 +5,14 @@ vtx_tables = loadScript("/BF/VTX/"..md.name..".lua") if (vtx_tables ~= nil) then vtx_tables() end --- Vals --- 1 Device Type --- 2 Band --- 3 Channel --- 4 Power --- 5 Pit --- 6 Freq + +-- Vals Fields +-- 1 Device Type Band +-- 2 Band Channel +-- 3 Channel Power +-- 4 Power Pit +-- 5 Pit Device Type +-- 6 Freq Frequency return { read = 88, -- MSP_VTX_CONFIG @@ -30,11 +29,11 @@ return { labels = display.labels, fieldLayout = display.fieldLayout, fields = { - { min=0, max=5, vals = { 2 }, table = { [0]="U", "A", "B", "E", "F", "R" }, upd = function(self) self.handleBandChanUpdate(self) end }, - { min=1, max=8, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, + { min=0, max=#(bandTable), vals = { 2 }, table = bandTable, upd = function(self) self.handleBandChanUpdate(self) end }, + { min=1, max=frequenciesPerBand, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, { min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, - { min=0, max=1, vals = { 5 }, table = { [0]="OFF", "ON" } }, - { vals = { 1 }, write = false, ro = true, table = { [1]="RTC6705",[3]="SmartAudio",[4]="Tramp",[255]="None"} }, + { min=0, max=#(pitModeTable), vals = { 5 }, table = pitModeTable }, + { vals = { 1 }, write = false, ro = true, table = deviceTable }, { min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, }, freqLookup = frequencyTable, From 3030559787660a9b0a58222aab030979a498ad06 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Tue, 15 Oct 2019 22:26:31 +0100 Subject: [PATCH 033/193] update other vtx.lua files. --- src/BF/VTX/vtx_defaults.lua | 2 +- src/SCRIPTS/BF/PAGES/vtx.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BF/VTX/vtx_defaults.lua b/src/BF/VTX/vtx_defaults.lua index dbd49f2d..89465ac8 100644 --- a/src/BF/VTX/vtx_defaults.lua +++ b/src/BF/VTX/vtx_defaults.lua @@ -7,5 +7,5 @@ frequencyTable = { } frequenciesPerBand = 8 bandTable = { [0]="U", "A", "B", "E", "F", "R" } -deviceTable = { [1]="6705",[3]="SA",[4]="Tramp",[255]="None"} +deviceTable = { [1]="6705", [3]="SA", [4]="Tramp", [255]="None" } pitModeTable = { [0]="OFF", "ON" } \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index fc3ff8ef..173b950c 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -260,4 +260,4 @@ return { end end end -} \ No newline at end of file +} From ec9fdb7d8b9c7554431025b92dd586e7e67ed2cc Mon Sep 17 00:00:00 2001 From: Reinhard Date: Fri, 25 Oct 2019 17:13:40 +0200 Subject: [PATCH 034/193] remove killEvents() to fix EVT_VIRTUAL_DEC_RPT long press '-' key did not respond like long press '+' key when editing values. Code line was leftover from pre-virtual events stage... --- src/SCRIPTS/BF/ui.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 9fbc2769..b7675e92 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -368,7 +368,6 @@ function run_ui(event) incValue(1) elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then incValue(-1) - killEvents(event) end end local nextPage = currentPage From 64f1112d13de30047abb617a6d09b40beca6cd67 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Tue, 22 Oct 2019 21:49:35 +0100 Subject: [PATCH 035/193] Layout fixes after refactoring Whitespace fixes Layout fixes for 212x64 Fix high res layouts text size. --- src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua | 12 ++++---- src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua | 28 +++++++++--------- src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua | 12 ++++---- src/SCRIPTS/BF/LAYOUT/128x64/rates.lua | 36 ++++++++++++------------ src/SCRIPTS/BF/LAYOUT/128x64/rx.lua | 24 ++++++++-------- src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua | 12 ++++---- src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua | 30 ++++++++++---------- src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua | 6 ++-- src/SCRIPTS/BF/LAYOUT/212x64/rates.lua | 36 ++++++++++++------------ src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua | 12 ++++---- src/SCRIPTS/BF/LAYOUT/212x64/rx.lua | 24 ++++++++-------- src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua | 12 ++++---- src/SCRIPTS/BF/radios.lua | 4 +-- 13 files changed, 124 insertions(+), 124 deletions(-) diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua index 06abe9e5..64911d96 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua @@ -1,11 +1,11 @@ return { labels = { - { t = "P", x = 55, y = 14, }, - { t = "I", x = 83, y = 14, }, - { t = "D", x = 111, y = 14, }, - { t = "Throttle", x = 5, y = 26, }, - { t = "Velocity", x = 5, y = 36, }, - { t = "Yaw" , x = 5, y = 46, }, + { t = "P", x = 55, y = 14, }, + { t = "I", x = 83, y = 14, }, + { t = "D", x = 111, y = 14, }, + { t = "Throttle", x = 5, y = 26, }, + { t = "Velocity", x = 5, y = 36, }, + { t = "Yaw" , x = 5, y = 46, }, }, fieldLayout = { { x = 51, y = 26, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua index 2d01f0fe..82b5957c 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua @@ -1,12 +1,12 @@ return { labels = { - { t = "Feed", x = 45, y = 11, }, - { t = "forward", x = 37, y = 18, }, - { t = "D", x = 85, y = 11, }, - { t = "Min", x = 80, y = 18, }, - { t = "ROLL", x = 10, y = 26, }, - { t = "PITCH", x = 10, y = 36, }, - { t = "YAW", x = 10, y = 46, }, + { t = "Feed", x = 45, y = 12, }, + { t = "forward", x = 37, y = 20, }, + { t = "D", x = 85, y = 12, }, + { t = "Min", x = 80, y = 20, }, + { t = "ROLL", x = 10, y = 28, }, + { t = "PITCH", x = 10, y = 38, }, + { t = "YAW", x = 10, y = 48, }, { t = "Feedforward", x = 10, y = 60, }, { t = "Transition", x = 20, y = 68, }, { t = "D Min", x = 10, y = 76, }, @@ -14,14 +14,14 @@ return { { t = "Advance", x = 20, y = 92, }, }, fieldLayout = { - { x = 48, y = 26, }, - { x = 48, y = 36, }, - { x = 48, y = 46, }, - { x = 80, y = 26, }, - { x = 80, y = 36, }, - { x = 80, y = 46, }, + { x = 48, y = 28, }, + { x = 48, y = 38, }, + { x = 48, y = 48, }, + { x = 80, y = 28, }, + { x = 80, y = 38, }, + { x = 80, y = 48, }, { x = 80, y = 68, }, { x = 80, y = 84, }, { x = 80, y = 92, }, }, -} +} \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua index e5b098a9..d2cc1cc7 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua @@ -1,12 +1,12 @@ return { labels = { - { t = "32K", x = 10, y = 14, }, - { t = "Gyro", x = 10, y = 24, }, - { t = "PID", x = 10, y = 34, }, - { t = "Prot", x = 58, y = 14, }, + { t = "32K", x = 10, y = 14, }, + { t = "Gyro", x = 10, y = 24, }, + { t = "PID", x = 10, y = 34, }, + { t = "Prot", x = 58, y = 14, }, { t = "Unsync", x = 58, y = 24, }, - { t = "PWM", x = 58, y = 34, }, - { t = "Idle", x = 58, y = 44, } + { t = "PWM", x = 58, y = 34, }, + { t = "Idle", x = 58, y = 44, } }, fieldLayout = { { x = 32, y = 14, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua index 067f3320..1872ec9e 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua @@ -1,14 +1,14 @@ return { labels = { - { t = "RC", x = 43, y = 11, }, - { t = "Rate", x = 38, y = 18, }, - { t = "Super", x = 63, y = 11, }, - { t = "Rate", x = 66, y = 18, }, - { t = "RC", x = 99, y = 11, }, - { t = "Expo", x = 94, y = 18, }, - { t = "ROLL", x = 10, y = 26, }, - { t = "PITCH", x = 10, y = 36, }, - { t = "YAW", x = 10, y = 46, }, + { t = "RC", x = 43, y = 12, }, + { t = "Rate", x = 38, y = 20, }, + { t = "Super", x = 63, y = 12, }, + { t = "Rate", x = 66, y = 20, }, + { t = "RC", x = 99, y = 12, }, + { t = "Expo", x = 94, y = 20, }, + { t = "ROLL", x = 10, y = 28, }, + { t = "PITCH", x = 10, y = 38, }, + { t = "YAW", x = 10, y = 48, }, { t = "Throttle", x = 10, y = 60, }, { t = "Mid", x = 20, y = 68, }, { t = "Expo", x = 20, y = 76, }, @@ -19,15 +19,15 @@ return { { t = "Breakpoint", x = 20, y = 116, }, }, fieldLayout = { - { x = 39, y = 26, }, - { x = 39, y = 36, }, - { x = 39, y = 46, }, - { x = 66, y = 26, }, - { x = 66, y = 36, }, - { x = 66, y = 46, }, - { x = 94, y = 26, }, - { x = 94, y = 36, }, - { x = 94, y = 46, }, + { x = 39, y = 28, }, + { x = 39, y = 38, }, + { x = 39, y = 48, }, + { x = 66, y = 28, }, + { x = 66, y = 38, }, + { x = 66, y = 48, }, + { x = 94, y = 28, }, + { x = 94, y = 38, }, + { x = 94, y = 48, }, { x = 70, y = 68, }, { x = 70, y = 76, }, { x = 70, y = 84, }, diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua index 2f267174..de0baf03 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua @@ -1,18 +1,18 @@ return { labels = { - { t = "Stick Min", x = 10, y = 20 }, - { t = "Stick Mid", x = 10, y = 30 }, - { t = "Stick Max", x = 10, y = 40 }, - { t = "Cam Angle", x = 10, y = 50 }, - { t = "Interp", x = 10, y = 60 }, - { t = "Interp Int", x = 10, y = 70 }, + { t = "Stick Min", x = 10, y = 12 }, + { t = "Stick Mid", x = 10, y = 22 }, + { t = "Stick Max", x = 10, y = 32 }, + { t = "Cam Angle", x = 10, y = 42 }, + { t = "Interp", x = 10, y = 52 }, + { t = "Interp Int", x = 10, y = 62 }, }, fieldLayout = { - { x = 70, y = 20, }, - { x = 70, y = 30, }, - { x = 70, y = 40, }, - { x = 70, y = 50, }, - { x = 70, y = 60, }, - { x = 70, y = 70, } + { x = 70, y = 12, }, + { x = 70, y = 22, }, + { x = 70, y = 32, }, + { x = 70, y = 42, }, + { x = 70, y = 52, }, + { x = 70, y = 62, } }, } \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua index abecf4c0..355b9e4d 100644 --- a/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua @@ -1,11 +1,11 @@ return { labels = { - { t = "Band", x = 10, y = 14 }, - { t = "Channel", x = 10, y = 24 }, - { t = "Power", x = 10, y = 34 }, - { t = "Pit", x = 10, y = 44 }, - { t = "Proto", x = 70, y = 14 }, - { t = "Freq", x = 70, y = 24 }, + { t = "Band", x = 10, y = 14 }, + { t = "Chan", x = 10, y = 24 }, + { t = "Power", x = 10, y = 34 }, + { t = "Pit", x = 10, y = 44 }, + { t = "Proto", x = 70, y = 14 }, + { t = "Freq", x = 70, y = 24 }, }, fieldLayout = { { x = 40, y = 14, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua index 345e7362..d97819d8 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua @@ -1,27 +1,27 @@ return { labels = { - { t = "Feed", x = 46, y = 11, }, - { t = "forward", x = 38, y = 18, }, - { t = "D", x = 86, y = 11, }, - { t = "Min", x = 81, y = 18, }, - { t = "ROLL", x = 8, y = 26, }, - { t = "PITCH", x = 8, y = 36, }, - { t = "YAW", x = 8, y = 46, }, + { t = "Feed", x = 46, y = 12, }, + { t = "forward", x = 38, y = 20, }, + { t = "D", x = 86, y = 12, }, + { t = "Min", x = 81, y = 20, }, + { t = "ROLL", x = 8, y = 28, }, + { t = "PITCH", x = 8, y = 38, }, + { t = "YAW", x = 8, y = 48, }, { t = "Feedforward", x = 110, y = 14, }, { t = "Transition", x = 120, y = 22, }, { t = "D Min", x = 110, y = 30, }, { t = "Gain", x = 120, y = 38, }, - { t = "Advance", x = 120, y = 46, }, + { t = "Advance", x = 120, y = 48, }, }, fieldLayout = { - { x = 49, y = 26, }, - { x = 49, y = 36, }, - { x = 49, y = 46, }, - { x = 81, y = 26, }, - { x = 81, y = 36, }, - { x = 81, y = 46, }, + { x = 49, y = 28, }, + { x = 49, y = 38, }, + { x = 49, y = 48, }, + { x = 81, y = 28, }, + { x = 81, y = 38, }, + { x = 81, y = 48, }, { x = 180, y = 22, }, { x = 180, y = 38, }, - { x = 180, y = 46, }, + { x = 180, y = 48, }, }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua index 17254082..098d3835 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua @@ -9,9 +9,9 @@ return { { t = "Idle Offset", x = 94, y = 44, } }, fieldLayout = { - { x = 65, y = 14, }, - { x = 65, y = 24, }, - { x = 65, y = 34, }, + { x = 65, y = 14, }, + { x = 65, y = 24, }, + { x = 65, y = 34, }, { x = 148, y = 14, }, { x = 148, y = 24, }, { x = 148, y = 34, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua index e4198473..15ab72b3 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua @@ -1,14 +1,14 @@ return { labels = { - { t = "RC", x = 43, y = 11, }, - { t = "Rate", x = 38, y = 18, }, - { t = "Super", x = 63, y = 11, }, - { t = "Rate", x = 66, y = 18, }, - { t = "RC", x = 99, y = 11, }, - { t = "Expo", x = 94, y = 18, }, - { t = "ROLL", x = 8, y = 26, }, - { t = "PITCH", x = 8, y = 36, }, - { t = "YAW", x = 8, y = 46, }, + { t = "RC", x = 43, y = 12, }, + { t = "Rate", x = 38, y = 20, }, + { t = "Super", x = 63, y = 12, }, + { t = "Rate", x = 66, y = 20, }, + { t = "RC", x = 99, y = 12, }, + { t = "Expo", x = 94, y = 20, }, + { t = "ROLL", x = 8, y = 28, }, + { t = "PITCH", x = 8, y = 38, }, + { t = "YAW", x = 8, y = 48, }, { t = "Throttle", x = 120, y = 12, }, { t = "Mid", x = 130, y = 20, }, { t = "Expo", x = 130, y = 28, }, @@ -19,15 +19,15 @@ return { { t = "Breakpoint", x = 130, y = 68, }, }, fieldLayout = { - { x = 39, y = 26, }, - { x = 39, y = 36, }, - { x = 39, y = 46, }, - { x = 66, y = 26, }, - { x = 66, y = 36, }, - { x = 66, y = 46, }, - { x = 94, y = 26, }, - { x = 94, y = 36, }, - { x = 94, y = 46, }, + { x = 39, y = 28, }, + { x = 39, y = 38, }, + { x = 39, y = 48, }, + { x = 66, y = 28, }, + { x = 66, y = 38, }, + { x = 66, y = 48, }, + { x = 94, y = 28, }, + { x = 94, y = 38, }, + { x = 94, y = 48, }, { x = 180, y = 20, }, { x = 180, y = 28, }, { x = 180, y = 36, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua index 4a337e22..40ff9232 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua @@ -13,12 +13,12 @@ return { { t = "Max", x = 128, y = 52, }, }, fieldLayout = { - { x = 75, y = 12, }, - { x = 75, y = 22, }, - { x = 75, y = 32, }, - { x = 75, y = 42, }, - { x = 75, y = 52, }, - { x = 75, y = 62, }, + { x = 75, y = 12, }, + { x = 75, y = 22, }, + { x = 75, y = 32, }, + { x = 75, y = 42, }, + { x = 75, y = 52, }, + { x = 75, y = 62, }, { x = 180, y = 12, }, { x = 150, y = 32, }, { x = 150, y = 42, }, diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua index f539f9de..24c48664 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua @@ -1,18 +1,18 @@ return { labels = { - { t = "Stick Min", x = 30, y = 20 }, - { t = "Stick Mid", x = 30, y = 30 }, - { t = "Stick Max", x = 30, y = 40 }, - { t = "Cam Angle", x = 110, y = 20 }, - { t = "Interp", x = 110, y = 30 }, - { t = "Interp Int", x = 110, y = 40 }, + { t = "Stick Min", x = 30, y = 12 }, + { t = "Stick Mid", x = 30, y = 22 }, + { t = "Stick Max", x = 30, y = 32 }, + { t = "Cam Angle", x = 110, y = 12 }, + { t = "Interp", x = 110, y = 22 }, + { t = "Interp Int", x = 110, y = 32 }, }, fieldLayout = { - { x = 80, y = 20, }, - { x = 80, y = 30, }, - { x = 80, y = 40, }, - { x = 160, y = 20, }, - { x = 160, y = 30, }, - { x = 160, y = 40, } + { x = 80, y = 12, }, + { x = 80, y = 22, }, + { x = 80, y = 32, }, + { x = 160, y = 12, }, + { x = 160, y = 22, }, + { x = 160, y = 32, } }, } diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua index 3b770256..170aa41c 100644 --- a/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua +++ b/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua @@ -8,11 +8,11 @@ return { { t = "Freq", x = 100, y = 24 }, }, fieldLayout = { - { x = 75, y = 155, }, - { x = 75, y = 200, }, - { x = 75, y = 242, }, - { x = 75, y = 284, }, - { x = 150, y = 68, }, - { x = 150, y = 110, }, + { x = 75, y = 14, }, + { x = 75, y = 24, }, + { x = 75, y = 34, }, + { x = 75, y = 44, }, + { x = 150, y = 14, }, + { x = 150, y = 24, }, }, } diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index 651180f5..ccb8485f 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -35,7 +35,7 @@ local supportedRadios = MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, NoTelem = { 192, LCD_H - 28, "No Telemetry", BLINK }, - textSize = MIDSIZE, + textSize = 0, yMinLimit = 35, yMaxLimit = 215, }, @@ -46,7 +46,7 @@ local supportedRadios = MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", BLINK }, - textSize = MIDSIZE, + textSize = 0, yMinLimit = 35, yMaxLimit = 215, }, From 49ea3c7c0e305adb65cdc7d6d996478a9773761b Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 27 Oct 2019 21:38:33 +0100 Subject: [PATCH 036/193] Change yMinLimit for 128x64 Makes it the same as for 212x64 --- src/SCRIPTS/BF/radios.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index ccb8485f..dc272436 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -14,7 +14,7 @@ local supportedRadios = SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, NoTelem = { 30, 55, "No Telemetry", BLINK }, textSize = SMLSIZE, - yMinLimit = 11, + yMinLimit = 12, yMaxLimit = 52, }, ["212x64"] = From 466fce4ef93e2b3df78a7663011cb6d41ff00cbe Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 27 Oct 2019 21:50:24 +0100 Subject: [PATCH 037/193] Prevent drawScreen() from running when main menu is visible Prevents it from interfering with scrollPixelsY causing scrolling to not work properly on the main menu. No need for it to run when the main menu is visible either. --- src/SCRIPTS/BF/ui.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index b7675e92..f0a0fa68 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -389,7 +389,9 @@ function run_ui(event) if TEXT_BGCOLOR then lcd.drawFilledRectangle(0, 0, LCD_W, LCD_H, TEXT_BGCOLOR) end - drawScreen() + if currentState ~= pageStatus.mainMenu then + drawScreen() + end if protocol.rssi() == 0 then lcd.drawText(radio.NoTelem[1],radio.NoTelem[2],radio.NoTelem[3],radio.NoTelem[4]) end From cbc014e460192e7f8e79f3ffecdaef06ccce0692 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 27 Oct 2019 21:58:38 +0100 Subject: [PATCH 038/193] Main menu scroll fixes 1 should not be added to currentLineY. This places the text at the top of the screen outside yMinLim causing it to disappear. Also corrected an error where yMaxLim was used instead of yMinLim. --- src/SCRIPTS/BF/ui.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index f0a0fa68..a07df198 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -424,8 +424,8 @@ function run_ui(event) end for i=1, #PageFiles do if (not PageFiles[i].requiredVersion) or (apiVersion == 0) or (apiVersion > 0 and PageFiles[i].requiredVersion < apiVersion) then - local currentLineY = (menuLine-1)*lineSpacing + yMinLim + 1 - if currentLineY <= yMaxLim then + local currentLineY = (menuLine-1)*lineSpacing + yMinLim + if currentLineY <= yMinLim then scrollPixelsY = 0 elseif currentLineY - scrollPixelsY <= yMinLim then scrollPixelsY = currentLineY - yMinLim From af7171a34248aac78bdf0692c7d8977227b9c4e1 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Mon, 28 Oct 2019 21:03:43 +0000 Subject: [PATCH 039/193] Update Readme.txt --- README.md | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 8615bba9..66c8e015 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,50 @@ # betaflight-tx-lua-scripts -### Important: +**Important:** -Some changes in the recently released OpenTX 2.2.1 cause this version to have less RAM available for lua scripts than previous versions. This often leads to problems when using the Betaflight TX lua scripts on the Taranis X9D. A discussion of these problems can be found [here](https://github.com/betaflight/betaflight-tx-lua-scripts/issues/97). -A potential fix to increase the amount of RAM available has been identified: (https://github.com/opentx/opentx/pull/5579). -For now, the recommendation is for users wanting to update OpenTX from 2.2.0 to 2.2.1 on a Taranis X9D (and keep using the Betaflight TX lua scripts) to hold on and monitor the situation, in the hope that OpenTX will release a version with this bugfix in the near future. +*Some changes in OpenTX 2.2.1 cause this version to have less RAM available for lua scripts than previous versions. The recommendation is for users wanting to update OpenTX on a Taranis X9D (and keep using the Betaflight TX lua scripts) is to use 2.3.1 or higher.* -### How to download the scripts +## How to download the scripts -Please visit the [releases page](https://github.com/betaflight/betaflight-tx-lua-scripts/releases) to download a zip file containing latest version. +Please visit the [releases page](https://github.com/betaflight/Sbetaflight-tx-lua-scripts/releases) to download a zip file containing latest version. ## Firmware Considerations + - Betaflight - As a best practice, it is recommended to use the most recent stable release of Betaflight to obtain the best possible results. - Crossfire - v2.11 or greater - FrSky - While most receivers work fine, it's recommended to update the XSR family of receivers to their most recent firmware version to correct any known bugs in SmartPort telemetry. -## Building from source -- Be sure to have `LUA 5.2` installed in the path -- Run `./bin/build.sh` from the root folder -- Compiled files will be created a the `obj` in the root folder. Copy the files to your transmitter as instructed in the `Installing` section below as if you unzipped from a downloaded file. - ## Installing -!! IMPORTANT: DON'T COPY THE CONTENTS OF THIS REPOSITORY ONTO YOUR SDCARD !! +**!! IMPORTANT: DON'T COPY THE CONTENTS OF THIS REPOSITORY ONTO YOUR SDCARD !!** Unzip the files from the link above and drag the contents to your radio. If you do this correctly, the SCRIPTS directory will merge with your existing directories, placing the scripts in their appropriate paths. You will know if you did this correctly if the bf.lua file shows up in your /SCRIPTS/TELEMETRY directory. The src directory is not required for use and is only available for maintenance of the code. While it may work to use this directory, you may encounter memory issues on your transmitter. -How to install: +### How to install Bootloader Method + 1. Power off your transmitter and power it back on in boot loader mode. 2. Connect a USB cable and open the SD card drive on your computer. 3. Unzip the file and copy the scripts to the root of the SD card. 4. Unplug the USB cable and power cycle your transmitter. Manual method (varies, based on the model of your transmitter) + 1. Power off your transmitter. 2. Remove the SD card and plug it into a computer 3. Unzip the file and copy the scripts to the root of the SD card. 4. Reinsert your SD card into the transmitter 5. Power up your transmitter. -If you copied the files correctly, you can now go into the telemetry screen setup page and set up the script as telemetry page. +If you copied the files correctly, you can now go into the OpenTx Tools screen (Since OpenTx 2.3.0) and access the Betaflight Configuration tool, or you can use the telemetry screen setup page and set up the script as telemetry page. + +### Adding the script as a telemetry page -## Adding the script as a telemetry page Setting up the script as a telemetry page will enable access at the press of a button. (For now, this only applies to the Taranis X9D series). + 1. Hit the [MENU] button and select the model for which you would like to enable the script. 2. While on the [MODEL SELECTION] screen, long-press the [PAGE] button to navigate to the [DISPLAY] page. 3. Use the [-] button to move the cursor down to [Screen 1] and hit [ENT]. @@ -56,3 +54,13 @@ Setting up the script as a telemetry page will enable access at the press of a b 7. Long-press [EXIT] to return to your model screen. To invoke the script, simply long-press the [PAGE] button from the model screen. + +### Setting up VTX Tables + +If you are using a VTX that supports the SmartAudio or Tramp protocols then bands and channels etc. are managed using vtx tables since firmware version 4.1.0. The betaflight configurator will allow you to save your configuration to a _craftname_.lua file. Place this into the BF\VTX folder on the root of the SD card and rename it to match the model you use on your transmitter for this craft. The lua scrips will then use this information on the VTX configuration screen instead of the defaults. + +## Building from source + +- Be sure to have `LUA 5.2` installed in the path +- Run `./bin/build.sh` from the root folder +- Compiled files will be created a the `obj` in the root folder. Copy the files to your transmitter as instructed in the `Installing` section below as if you unzipped from a downloaded file. \ No newline at end of file From f464897c35fe3631c2be21e0b7a7603fb816e6f6 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Tue, 29 Oct 2019 09:06:40 +0000 Subject: [PATCH 040/193] Fix broken link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 66c8e015..28b4a950 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ## How to download the scripts -Please visit the [releases page](https://github.com/betaflight/Sbetaflight-tx-lua-scripts/releases) to download a zip file containing latest version. +Please visit the [releases page](https://github.com/betaflight/betaflight-tx-lua-scripts/releases) to download a zip file containing latest version. ## Firmware Considerations From 976cc3645390144702e8fb09a899cc198bebf3a6 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 29 Oct 2019 17:41:29 +0100 Subject: [PATCH 041/193] Reduce peak memory use --- src/SCRIPTS/BF/ui.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index b7675e92..1ea5bc3f 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -74,6 +74,7 @@ local function invalidatePages() Page = nil currentState = pageStatus.display saveTS = 0 + collectgarbage() end local function rebootFc() @@ -432,7 +433,7 @@ function run_ui(event) end local attr = (menuLine == i and INVERS or 0) if event == EVT_VIRTUAL_ENTER and attr == INVERS then - Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[i].script))() + invalidatePages() currentPage = i currentState = pageStatus.display end From 7060d56f4cea4029709488649e1dea5fd1bf473c Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 31 Oct 2019 20:48:04 +0100 Subject: [PATCH 042/193] Add scroll variable for main menu Added separate scroll variable for main menu to make. Renamed scrollPixelsY for consistency. --- src/SCRIPTS/BF/ui.lua | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 1307d824..3dd746e7 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -29,7 +29,8 @@ local popupMenuActive = false local lastRunTS = 0 local killEnterBreak = 0 local stopDisplay = true -local scrollPixelsY = 0 +local pageScrollY = 0 +local mainMenuScrollY = 0 local Page = nil @@ -197,17 +198,17 @@ local function drawScreen() local screen_title = Page.title drawScreenTitle("Betaflight / "..screen_title) if currentLineY <= Page.fieldLayout[1].y then - scrollPixelsY = 0 - elseif currentLineY - scrollPixelsY <= yMinLim then - scrollPixelsY = currentLineY - yMinLim - elseif currentLineY - scrollPixelsY >= yMaxLim then - scrollPixelsY = currentLineY - yMaxLim + pageScrollY = 0 + elseif currentLineY - pageScrollY <= yMinLim then + pageScrollY = currentLineY - yMinLim + elseif currentLineY - pageScrollY >= yMaxLim then + pageScrollY = currentLineY - yMaxLim end for i=1,#(Page.labels) do local f = Page.labels[i] local textOptions = radio.textSize + globalTextOptions - if (f.y - scrollPixelsY) >= yMinLim and (f.y - scrollPixelsY) <= yMaxLim then - lcd.drawText(f.x, f.y - scrollPixelsY, f.t, textOptions) + if (f.y - pageScrollY) >= yMinLim and (f.y - pageScrollY) <= yMaxLim then + lcd.drawText(f.x, f.y - pageScrollY, f.t, textOptions) end end local val = "---" @@ -232,8 +233,8 @@ local function drawScreen() val = f.table[f.value] end end - if (pos.y - scrollPixelsY) >= yMinLim and (pos.y - scrollPixelsY) <= yMaxLim then - lcd.drawText(pos.x, pos.y - scrollPixelsY, val, value_options) + if (pos.y - pageScrollY) >= yMinLim and (pos.y - pageScrollY) <= yMaxLim then + lcd.drawText(pos.x, pos.y - pageScrollY, val, value_options) end end end @@ -427,11 +428,11 @@ function run_ui(event) if (not PageFiles[i].requiredVersion) or (apiVersion == 0) or (apiVersion > 0 and PageFiles[i].requiredVersion < apiVersion) then local currentLineY = (menuLine-1)*lineSpacing + yMinLim if currentLineY <= yMinLim then - scrollPixelsY = 0 - elseif currentLineY - scrollPixelsY <= yMinLim then - scrollPixelsY = currentLineY - yMinLim - elseif currentLineY - scrollPixelsY >= yMaxLim then - scrollPixelsY = currentLineY - yMaxLim + mainMenuScrollY = 0 + elseif currentLineY - mainMenuScrollY <= yMinLim then + mainMenuScrollY = currentLineY - yMinLim + elseif currentLineY - mainMenuScrollY >= yMaxLim then + mainMenuScrollY = currentLineY - yMaxLim end local attr = (menuLine == i and INVERS or 0) if event == EVT_VIRTUAL_ENTER and attr == INVERS then @@ -439,8 +440,8 @@ function run_ui(event) currentPage = i currentState = pageStatus.display end - if ((i-1)*lineSpacing + yMinLim - scrollPixelsY) >= yMinLim and ((i-1)*lineSpacing + yMinLim - scrollPixelsY) <= yMaxLim then - lcd.drawText(6, (i-1)*lineSpacing + yMinLim - scrollPixelsY, PageFiles[i].title, attr) + if ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) >= yMinLim and ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) <= yMaxLim then + lcd.drawText(6, (i-1)*lineSpacing + yMinLim - mainMenuScrollY, PageFiles[i].title, attr) end end end From ea70f10c2aa0c6f32f518baba2c897f61d54eb59 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 31 Oct 2019 20:53:40 +0100 Subject: [PATCH 043/193] Sync menuLine with currentPage --- src/SCRIPTS/BF/ui.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 3dd746e7..47ace00d 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -159,6 +159,7 @@ local function incPage(inc) currentPage = incMax(currentPage, inc, #(PageFiles)) Page = nil currentLine = 1 + menuLine = currentPage collectgarbage() end From c72384603e053c8fe8edfd5e9ef6ec1b1bccf5cd Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 1 Nov 2019 22:00:37 +0100 Subject: [PATCH 044/193] Prevent Page access if nil --- src/SCRIPTS/BF/ui.lua | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 1307d824..4b92842b 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -105,6 +105,9 @@ local function processMspReply(cmd,rx_buf) if cmd == nil or rx_buf == nil then return end + if Page == nil then + return + end if cmd == Page.write then if Page.eepromWrite then eepromWrite() @@ -349,10 +352,12 @@ function run_ui(event) elseif event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then incLine(1) elseif event == EVT_VIRTUAL_ENTER then - local field = Page.fields[currentLine] - local idx = field.i or currentLine - if Page.values and Page.values[idx] and (field.ro ~= true) then - currentState = pageStatus.editing + if Page then + local field = Page.fields[currentLine] + local idx = field.i or currentLine + if Page.values and Page.values[idx] and (field.ro ~= true) then + currentState = pageStatus.editing + end end elseif event == EVT_VIRTUAL_EXIT then if isTelemetryScript then From 5a2087cd0f0eef14643dde90bd0a863fc387ca5d Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 10 Nov 2019 16:02:10 +0100 Subject: [PATCH 045/193] Remove unused variables and functions --- src/SCRIPTS/BF/ui.lua | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index f3fcf8b1..0891da1f 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -23,8 +23,6 @@ local saveTS = 0 local saveTimeout = 0 local saveRetries = 0 local saveMaxRetries = 0 -local pageRequested = false -local telemetryScreenActive = false local popupMenuActive = false local lastRunTS = 0 local killEnterBreak = 0 @@ -115,7 +113,6 @@ local function processMspReply(cmd,rx_buf) else invalidatePages() end - pageRequested = false return end if cmd == uiMsp.eepromWrite then @@ -220,7 +217,6 @@ local function drawScreen() local f = Page.fields[i] local pos = Page.fieldLayout[i] local text_options = radio.textSize + globalTextOptions - local heading_options = text_options local value_options = text_options if i == currentLine then value_options = text_options + INVERS @@ -252,10 +248,6 @@ function clipValue(val,min,max) return val end -local function getCurrentField() - return Page.fields[currentLine] -end - local function incValue(inc) local f = Page.fields[currentLine] local idx = f.i or currentLine From f2d46e313e9d7096dfe4da52c38a49bb738d2e3a Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 10 Nov 2019 22:53:17 +0100 Subject: [PATCH 046/193] VTX memory savings Have vtx_defaults return it's tables to vtx instead of loading them as globals. --- src/BF/VTX/vtx_defaults.lua | 20 ++++++++++---------- src/SCRIPTS/BF/PAGES/vtx.lua | 23 +++++++++++++---------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/BF/VTX/vtx_defaults.lua b/src/BF/VTX/vtx_defaults.lua index 89465ac8..3062297f 100644 --- a/src/BF/VTX/vtx_defaults.lua +++ b/src/BF/VTX/vtx_defaults.lua @@ -1,11 +1,11 @@ -frequencyTable = { - { 5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725 }, -- Boscam A - { 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 }, -- Boscam B - { 5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945 }, -- Boscam E - { 5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880 }, -- FatShark - { 5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 }, -- RaceBand +return { + frequencyTable = { + { 5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725 }, -- Boscam A + { 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 }, -- Boscam B + { 5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945 }, -- Boscam E + { 5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880 }, -- FatShark + { 5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 }, -- RaceBand + }, + frequenciesPerBand = 8, + bandTable = { [0]="U", "A", "B", "E", "F", "R" }, } -frequenciesPerBand = 8 -bandTable = { [0]="U", "A", "B", "E", "F", "R" } -deviceTable = { [1]="6705", [3]="SA", [4]="Tramp", [255]="None" } -pitModeTable = { [0]="OFF", "ON" } \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index 173b950c..afa8c8a7 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -1,10 +1,13 @@ local display = assert(loadScript(radio.templateHome.."vtx.lua"))() -assert(loadScript("/BF/VTX/vtx_defaults.lua"))() local md = model.getInfo(); -vtx_tables = loadScript("/BF/VTX/"..md.name..".lua") -if (vtx_tables ~= nil) then - vtx_tables() +local vtx_tables = loadScript("/BF/VTX/"..md.name..".lua") +if vtx_tables then + vtx_tables = vtx_tables() +else + vtx_tables = assert(loadScript("/BF/VTX/vtx_defaults.lua"))() end +local deviceTable = { [1]="6705", [3]="SA", [4]="Tramp", [255]="None" } +local pitModeTable = { [0]="OFF", "ON" } -- Vals Fields -- 1 Device Type Band @@ -29,14 +32,14 @@ return { labels = display.labels, fieldLayout = display.fieldLayout, fields = { - { min=0, max=#(bandTable), vals = { 2 }, table = bandTable, upd = function(self) self.handleBandChanUpdate(self) end }, - { min=1, max=frequenciesPerBand, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, + { min=0, max=#(vtx_tables.bandTable), vals = { 2 }, table = vtx_tables.bandTable, upd = function(self) self.handleBandChanUpdate(self) end }, + { min=1, max=vtx_tables.frequenciesPerBand, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, { min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, { min=0, max=#(pitModeTable), vals = { 5 }, table = pitModeTable }, { vals = { 1 }, write = false, ro = true, table = deviceTable }, { min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, }, - freqLookup = frequencyTable, + freqLookup = vtx_tables.frequencyTable, postLoad = function (self) if (self.values[2] or 0) < 0 or (self.values[3] or 0) == 0 or (self.values[4] or 0) == 0 then self.values = {} @@ -180,9 +183,9 @@ return { end, updatePowerTable = function(self) if self.values and not self.fields[3].table then - if powerTable then - self.fields[3].table = powerTable - self.fields[3].max = #(powerTable) + if vtx_tables.powerTable then + self.fields[3].table = vtx_tables.powerTable + self.fields[3].max = #(vtx_tables.powerTable) else if self.values[1] == 1 then -- RTC6705 self.fields[3].table = { 25, 200 } From 94e6dbc9f35657fdbe1c3cb0f5a3938325dabf2d Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 12 Nov 2019 21:47:52 +0100 Subject: [PATCH 047/193] More memory savings --- src/SCRIPTS/BF/MSP/common.lua | 7 ++----- src/SCRIPTS/BF/MSP/crsf.lua | 12 +++++------- src/SCRIPTS/BF/MSP/sp.lua | 11 +++++------ src/SCRIPTS/BF/protocols.lua | 2 +- src/SCRIPTS/BF/ui.lua | 2 +- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/SCRIPTS/BF/MSP/common.lua b/src/SCRIPTS/BF/MSP/common.lua index d50b3ba0..a18d5e3c 100644 --- a/src/SCRIPTS/BF/MSP/common.lua +++ b/src/SCRIPTS/BF/MSP/common.lua @@ -1,7 +1,6 @@ - -- Protocol version -MSP_VERSION = bit32.lshift(1,5) -MSP_STARTFLAG = bit32.lshift(1,4) +local MSP_VERSION = bit32.lshift(1,5) +local MSP_STARTFLAG = bit32.lshift(1,4) -- Sequence number for next MSP packet local mspSeq = 0 @@ -17,8 +16,6 @@ local mspTxIdx = 1 local mspTxCRC = 0 local mspTxPk = 0 -mspPendingRequest = false - function mspProcessTxQ() if (#(mspTxBuf) == 0) then return false diff --git a/src/SCRIPTS/BF/MSP/crsf.lua b/src/SCRIPTS/BF/MSP/crsf.lua index 4dccb563..700d4b87 100644 --- a/src/SCRIPTS/BF/MSP/crsf.lua +++ b/src/SCRIPTS/BF/MSP/crsf.lua @@ -1,14 +1,12 @@ - -- CRSF Devices -CRSF_ADDRESS_BETAFLIGHT = 0xC8 -CRSF_ADDRESS_RADIO_TRANSMITTER = 0xEA +local CRSF_ADDRESS_BETAFLIGHT = 0xC8 +local CRSF_ADDRESS_RADIO_TRANSMITTER = 0xEA -- CRSF Frame Types -CRSF_FRAMETYPE_MSP_REQ = 0x7A -- response request using msp sequence as command -CRSF_FRAMETYPE_MSP_RESP = 0x7B -- reply with 60 byte chunked binary -CRSF_FRAMETYPE_MSP_WRITE = 0x7C -- write with 60 byte chunked binary +local CRSF_FRAMETYPE_MSP_REQ = 0x7A -- response request using msp sequence as command +local CRSF_FRAMETYPE_MSP_RESP = 0x7B -- reply with 60 byte chunked binary +local CRSF_FRAMETYPE_MSP_WRITE = 0x7C -- write with 60 byte chunked binary crsfMspCmd = 0 -crsfMspHeader = {} protocol.mspSend = function(payload) local payloadOut = { CRSF_ADDRESS_BETAFLIGHT, CRSF_ADDRESS_RADIO_TRANSMITTER } diff --git a/src/SCRIPTS/BF/MSP/sp.lua b/src/SCRIPTS/BF/MSP/sp.lua index 5974ecd4..59d0d9c7 100644 --- a/src/SCRIPTS/BF/MSP/sp.lua +++ b/src/SCRIPTS/BF/MSP/sp.lua @@ -1,9 +1,8 @@ - -LOCAL_SENSOR_ID = 0x0D -SMARTPORT_REMOTE_SENSOR_ID = 0x1B -FPORT_REMOTE_SENSOR_ID = 0x00 -REQUEST_FRAME_ID = 0x30 -REPLY_FRAME_ID = 0x32 +local LOCAL_SENSOR_ID = 0x0D +local SMARTPORT_REMOTE_SENSOR_ID = 0x1B +local FPORT_REMOTE_SENSOR_ID = 0x00 +local REQUEST_FRAME_ID = 0x30 +local REPLY_FRAME_ID = 0x32 local lastSensorId, lastFrameId, lastDataId, lastValue diff --git a/src/SCRIPTS/BF/protocols.lua b/src/SCRIPTS/BF/protocols.lua index 01651cd4..85944515 100644 --- a/src/SCRIPTS/BF/protocols.lua +++ b/src/SCRIPTS/BF/protocols.lua @@ -26,7 +26,7 @@ local supportedProtocols = } } -function getProtocol() +local function getProtocol() if supportedProtocols.smartPort.push() then return supportedProtocols.smartPort elseif supportedProtocols.crsf.push() then diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 0891da1f..a929be54 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -48,10 +48,10 @@ end local function saveSettings(new) if Page.values then + local payload = {} if Page.preSave then payload = Page.preSave(Page) else - payload = {} for i=1,(Page.outputBytes or #Page.values) do payload[i] = Page.values[i] end From 9b0f34fbc0c5c343d4186c81f6916e810f23ace9 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 3 Nov 2019 22:20:27 +0100 Subject: [PATCH 048/193] Add ui states --- src/SCRIPTS/BF/ui.lua | 259 ++++++++++++++++++++++-------------------- 1 file changed, 134 insertions(+), 125 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index a929be54..5a0159fb 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -1,10 +1,15 @@ +local uiStatus = +{ + mainMenu = 1, + pages = 2, +} + local pageStatus = { display = 2, editing = 3, saving = 4, popupMenu = 5, - mainMenu = 6, } local uiMsp = @@ -15,7 +20,8 @@ local uiMsp = local menuLine = 1 local pageCount = 1 -local currentState = pageStatus.mainMenu +local uiState = uiStatus.mainMenu +local pageState = pageStatus.display local requestTimeout = 80 -- 800ms request timeout local currentPage = 1 local currentLine = 1 @@ -26,7 +32,7 @@ local saveMaxRetries = 0 local popupMenuActive = false local lastRunTS = 0 local killEnterBreak = 0 -local stopDisplay = true +local stopDisplay = false local pageScrollY = 0 local mainMenuScrollY = 0 @@ -58,10 +64,10 @@ local function saveSettings(new) end protocol.mspWrite(Page.write, payload) saveTS = getTime() - if currentState == pageStatus.saving then + if pageState == pageStatus.saving then saveRetries = saveRetries + 1 else - currentState = pageStatus.saving + pageState = pageStatus.saving saveRetries = 0 saveMaxRetries = protocol.saveMaxRetries or 2 -- default 2 saveTimeout = protocol.saveTimeout or 150 -- default 1.5s @@ -71,7 +77,7 @@ end local function invalidatePages() Page = nil - currentState = pageStatus.display + pageState = pageStatus.display saveTS = 0 collectgarbage() end @@ -220,7 +226,7 @@ local function drawScreen() local value_options = text_options if i == currentLine then value_options = text_options + INVERS - if currentState == pageStatus.editing then + if pageState == pageStatus.editing then value_options = value_options + BLINK end end @@ -285,128 +291,22 @@ local function drawPopupMenu() end function run_ui(event) - getPageCount() local now = getTime() -- if lastRunTS old than 500ms if lastRunTS + 50 < now then invalidatePages() if isTelemetryScript then - currentState = pageStatus.display + uiState = uiStatus.pages else - currentState = pageStatus.mainMenu + uiState = uiStatus.mainMenu end end lastRunTS = now - if (currentState == pageStatus.saving) then - if (saveTS + saveTimeout < now) then - if saveRetries < saveMaxRetries then - saveSettings() - else - -- max retries reached - currentState = pageStatus.display - invalidatePages() - end - end - end - -- process send queue - mspProcessTxQ() - -- navigation - if isTelemetryScript and event == EVT_VIRTUAL_MENU_LONG then -- telemetry script - popupMenuActive = 1 - currentState = pageStatus.popupMenu - elseif (not isTelemetryScript) and event == EVT_VIRTUAL_ENTER_LONG then -- standalone - popupMenuActive = 1 - killEnterBreak = 1 - currentState = pageStatus.popupMenu - -- menu is currently displayed - elseif currentState == pageStatus.popupMenu then - if event == EVT_VIRTUAL_EXIT then - currentState = pageStatus.display - elseif event == EVT_VIRTUAL_PREV then - incPopupMenu(-1) - elseif event == EVT_VIRTUAL_NEXT then - incPopupMenu(1) - elseif event == EVT_VIRTUAL_ENTER then - if killEnterBreak == 1 then - killEnterBreak = 0 - else - currentState = pageStatus.display - popupMenuList[popupMenuActive].f() - end - end - -- normal page viewing - elseif currentState <= pageStatus.display then - if not isTelemetryScript and event == EVT_VIRTUAL_PREV_PAGE then - incPage(-1) - killEvents(event) -- X10/T16 issue: pageUp is a long press - elseif (not isTelemetryScript and event == EVT_VIRTUAL_NEXT_PAGE) or (isTelemetryScript and event == EVT_VIRTUAL_MENU) then - incPage(1) - elseif event == EVT_VIRTUAL_PREV or event == EVT_VIRTUAL_PREV_REPT then - incLine(-1) - elseif event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then - incLine(1) - elseif event == EVT_VIRTUAL_ENTER then - if Page then - local field = Page.fields[currentLine] - local idx = field.i or currentLine - if Page.values and Page.values[idx] and (field.ro ~= true) then - currentState = pageStatus.editing - end - end - elseif event == EVT_VIRTUAL_EXIT then - if isTelemetryScript then - return protocol.exitFunc(); - else - stopDisplay = true - end - end - -- editing value - elseif currentState == pageStatus.editing then - if event == EVT_VIRTUAL_EXIT or event == EVT_VIRTUAL_ENTER then - currentState = pageStatus.display - elseif event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then - incValue(1) - elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then - incValue(-1) - end - end - local nextPage = currentPage - while Page == nil do - Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[currentPage].script))() - if Page.requiredVersion and apiVersion > 0 and Page.requiredVersion > apiVersion then - incPage(1) - if currentPage == nextPage then - lcd.clear() - lcd.drawText(radio.NoTelem[1], radio.NoTelem[2], "No Pages! API: " .. apiVersion, radio.NoTelem[4]) - return 1 - end - end - end - if not Page.values and currentState == pageStatus.display then - requestPage() - end - lcd.clear() - if TEXT_BGCOLOR then - lcd.drawFilledRectangle(0, 0, LCD_W, LCD_H, TEXT_BGCOLOR) - end - if currentState ~= pageStatus.mainMenu then - drawScreen() - end - if protocol.rssi() == 0 then - lcd.drawText(radio.NoTelem[1],radio.NoTelem[2],radio.NoTelem[3],radio.NoTelem[4]) + if isTelemetryScript then + uiState = uiStatus.pages end - if currentState == pageStatus.popupMenu then - drawPopupMenu() - elseif currentState == pageStatus.saving then - lcd.drawFilledRectangle(radio.SaveBox.x,radio.SaveBox.y,radio.SaveBox.w,radio.SaveBox.h,backgroundFill) - lcd.drawRectangle(radio.SaveBox.x,radio.SaveBox.y,radio.SaveBox.w,radio.SaveBox.h,SOLID) - if saveRetries <= 0 then - lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,"Saving...",DBLSIZE + BLINK + (globalTextOptions)) - else - lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,"Retrying",DBLSIZE + (globalTextOptions)) - end - end - if currentState == pageStatus.mainMenu and (not isTelemetryScript) then + if uiState == uiStatus.mainMenu then + getPageCount() if event == EVT_VIRTUAL_EXIT then return 2 elseif event == EVT_VIRTUAL_NEXT then @@ -436,19 +336,128 @@ function run_ui(event) if event == EVT_VIRTUAL_ENTER and attr == INVERS then invalidatePages() currentPage = i - currentState = pageStatus.display + pageState = pageStatus.display + uiState = uiStatus.pages end if ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) >= yMinLim and ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) <= yMaxLim then lcd.drawText(6, (i-1)*lineSpacing + yMinLim - mainMenuScrollY, PageFiles[i].title, attr) end end end + elseif uiState == uiStatus.pages then + if (pageState == pageStatus.saving) then + if (saveTS + saveTimeout < now) then + if saveRetries < saveMaxRetries then + saveSettings() + else + -- max retries reached + pageState = pageStatus.display + invalidatePages() + end + end + end + -- navigation + if isTelemetryScript and event == EVT_VIRTUAL_MENU_LONG then -- telemetry script + popupMenuActive = 1 + pageState = pageStatus.popupMenu + elseif (not isTelemetryScript) and event == EVT_VIRTUAL_ENTER_LONG then -- standalone + popupMenuActive = 1 + killEnterBreak = 1 + pageState = pageStatus.popupMenu + -- menu is currently displayed + elseif pageState == pageStatus.popupMenu then + if event == EVT_VIRTUAL_EXIT then + pageState = pageStatus.display + elseif event == EVT_VIRTUAL_PREV then + incPopupMenu(-1) + elseif event == EVT_VIRTUAL_NEXT then + incPopupMenu(1) + elseif event == EVT_VIRTUAL_ENTER then + if killEnterBreak == 1 then + killEnterBreak = 0 + else + pageState = pageStatus.display + popupMenuList[popupMenuActive].f() + end + end + -- normal page viewing + elseif pageState <= pageStatus.display then + if not isTelemetryScript and event == EVT_VIRTUAL_PREV_PAGE then + incPage(-1) + killEvents(event) -- X10/T16 issue: pageUp is a long press + elseif (not isTelemetryScript and event == EVT_VIRTUAL_NEXT_PAGE) or (isTelemetryScript and event == EVT_VIRTUAL_MENU) then + incPage(1) + elseif event == EVT_VIRTUAL_PREV or event == EVT_VIRTUAL_PREV_REPT then + incLine(-1) + elseif event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then + incLine(1) + elseif event == EVT_VIRTUAL_ENTER then + if Page then + local field = Page.fields[currentLine] + local idx = field.i or currentLine + if Page.values and Page.values[idx] and (field.ro ~= true) then + pageState = pageStatus.editing + end + end + elseif event == EVT_VIRTUAL_EXIT then + if isTelemetryScript then + return protocol.exitFunc(); + else + stopDisplay = true + end + end + -- editing value + elseif pageState == pageStatus.editing then + if event == EVT_VIRTUAL_EXIT or event == EVT_VIRTUAL_ENTER then + pageState = pageStatus.display + elseif event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then + incValue(1) + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then + incValue(-1) + end + end + local nextPage = currentPage + while Page == nil do + Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[currentPage].script))() + if Page.requiredVersion and apiVersion > 0 and Page.requiredVersion > apiVersion then + incPage(1) + if currentPage == nextPage then + lcd.clear() + lcd.drawText(radio.NoTelem[1], radio.NoTelem[2], "No Pages! API: " .. apiVersion, radio.NoTelem[4]) + return 1 + end + end + end + if not Page.values and pageState == pageStatus.display then + requestPage() + end + lcd.clear() + if TEXT_BGCOLOR then + lcd.drawFilledRectangle(0, 0, LCD_W, LCD_H, TEXT_BGCOLOR) + end + drawScreen() + if pageState == pageStatus.popupMenu then + drawPopupMenu() + elseif pageState == pageStatus.saving then + lcd.drawFilledRectangle(radio.SaveBox.x,radio.SaveBox.y,radio.SaveBox.w,radio.SaveBox.h,backgroundFill) + lcd.drawRectangle(radio.SaveBox.x,radio.SaveBox.y,radio.SaveBox.w,radio.SaveBox.h,SOLID) + if saveRetries <= 0 then + lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,"Saving...",DBLSIZE + BLINK + (globalTextOptions)) + else + lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,"Retrying",DBLSIZE + (globalTextOptions)) + end + end + if stopDisplay and (not isTelemetryScript) then + invalidatePages() + currentLine = 1 + uiState = uiStatus.mainMenu + stopDisplay = false + end end - if stopDisplay and (not isTelemetryScript) then - currentLine = 1 - currentState = pageStatus.mainMenu - stopDisplay = false - collectgarbage() + -- process send queue + mspProcessTxQ() + if protocol.rssi() == 0 then + lcd.drawText(radio.NoTelem[1],radio.NoTelem[2],radio.NoTelem[3],radio.NoTelem[4]) end processMspReply(mspPollReply()) return 0 From 3d5b716db8e79a7444ceeb5afb9a1a758b9b776f Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 21 Nov 2019 21:44:50 +0100 Subject: [PATCH 049/193] Add apiVersion detection for TOOLS script --- src/SCRIPTS/BF/ui.lua | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 5a0159fb..e39d84f2 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -1,7 +1,8 @@ local uiStatus = { - mainMenu = 1, + init = 1, pages = 2, + mainMenu = 3, } local pageStatus = @@ -20,7 +21,7 @@ local uiMsp = local menuLine = 1 local pageCount = 1 -local uiState = uiStatus.mainMenu +local uiState = uiStatus.init local pageState = pageStatus.display local requestTimeout = 80 -- 800ms request timeout local currentPage = 1 @@ -37,6 +38,7 @@ local pageScrollY = 0 local mainMenuScrollY = 0 local Page = nil +local background = nil local backgroundFill = TEXT_BGCOLOR or ERASE local foregroundColor = LINE_COLOR or SOLID @@ -298,14 +300,32 @@ function run_ui(event) if isTelemetryScript then uiState = uiStatus.pages else - uiState = uiStatus.mainMenu + uiState = uiStatus.init end end lastRunTS = now if isTelemetryScript then uiState = uiStatus.pages end - if uiState == uiStatus.mainMenu then + if uiState == uiStatus.init then + local yMinLim = radio.yMinLimit + lcd.clear() + drawScreenTitle("Betaflight Config", 0, 0) + lcd.drawText(6, yMinLim, "Initialising") + if apiVersion == 0 then + if not background then + background = assert(loadScript("/SCRIPTS/BF/background.lua"))() + background.init() + else + background.run_bg() + end + return 0 + else + background = nil + invalidatePages() + uiState = uiStatus.mainMenu + end + elseif uiState == uiStatus.mainMenu then getPageCount() if event == EVT_VIRTUAL_EXIT then return 2 From 401ba717b060c66572f009e5d25bd257bc1918fe Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 21 Nov 2019 21:51:16 +0100 Subject: [PATCH 050/193] Fix main menu api/requiredVersion check --- src/SCRIPTS/BF/ui.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index e39d84f2..d756d73f 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -48,7 +48,7 @@ local globalTextOptions = TEXT_COLOR or 0 local function getPageCount() pageCount = 0 for i=1,#(PageFiles) do - if (not PageFiles[i].requiredVersion) or (apiVersion == 0) or (apiVersion > 0 and PageFiles[i].requiredVersion < apiVersion) then + if (not PageFiles[i].requiredVersion) or (apiVersion == 0) or (apiVersion > 0 and PageFiles[i].requiredVersion <= apiVersion) then pageCount = pageCount + 1 end end @@ -343,7 +343,7 @@ function run_ui(event) lineSpacing = 25 end for i=1, #PageFiles do - if (not PageFiles[i].requiredVersion) or (apiVersion == 0) or (apiVersion > 0 and PageFiles[i].requiredVersion < apiVersion) then + if (not PageFiles[i].requiredVersion) or (apiVersion == 0) or (apiVersion > 0 and PageFiles[i].requiredVersion <= apiVersion) then local currentLineY = (menuLine-1)*lineSpacing + yMinLim if currentLineY <= yMinLim then mainMenuScrollY = 0 From e555ab49743b95571f429e9a7cbaf97e492fb542 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 21 Nov 2019 21:54:45 +0100 Subject: [PATCH 051/193] Rename currentLine to currentField Because that's what it actually is. --- src/SCRIPTS/BF/ui.lua | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index d756d73f..3671f917 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -25,7 +25,7 @@ local uiState = uiStatus.init local pageState = pageStatus.display local requestTimeout = 80 -- 800ms request timeout local currentPage = 1 -local currentLine = 1 +local currentField = 1 local saveTS = 0 local saveTimeout = 0 local saveRetries = 0 @@ -166,13 +166,13 @@ end local function incPage(inc) currentPage = incMax(currentPage, inc, #(PageFiles)) Page = nil - currentLine = 1 + currentField = 1 menuLine = currentPage collectgarbage() end local function incLine(inc) - currentLine = clipValue(currentLine + inc, 1, #(Page.fields)) + currentField = clipValue(currentField + inc, 1, #(Page.fields)) end local function incMainMenu(inc) @@ -203,15 +203,15 @@ end local function drawScreen() local yMinLim = radio.yMinLimit or 0 local yMaxLim = radio.yMaxLimit or LCD_H - local currentLineY = Page.fieldLayout[currentLine].y + local currentFieldY = Page.fieldLayout[currentField].y local screen_title = Page.title drawScreenTitle("Betaflight / "..screen_title) - if currentLineY <= Page.fieldLayout[1].y then + if currentFieldY <= Page.fieldLayout[1].y then pageScrollY = 0 - elseif currentLineY - pageScrollY <= yMinLim then - pageScrollY = currentLineY - yMinLim - elseif currentLineY - pageScrollY >= yMaxLim then - pageScrollY = currentLineY - yMaxLim + elseif currentFieldY - pageScrollY <= yMinLim then + pageScrollY = currentFieldY - yMinLim + elseif currentFieldY - pageScrollY >= yMaxLim then + pageScrollY = currentFieldY - yMaxLim end for i=1,#(Page.labels) do local f = Page.labels[i] @@ -226,7 +226,7 @@ local function drawScreen() local pos = Page.fieldLayout[i] local text_options = radio.textSize + globalTextOptions local value_options = text_options - if i == currentLine then + if i == currentField then value_options = text_options + INVERS if pageState == pageStatus.editing then value_options = value_options + BLINK @@ -257,8 +257,8 @@ function clipValue(val,min,max) end local function incValue(inc) - local f = Page.fields[currentLine] - local idx = f.i or currentLine + local f = Page.fields[currentField] + local idx = f.i or currentField local scale = (f.scale or 1) local mult = (f.mult or 1) f.value = clipValue(f.value + ((inc*mult)/scale), (f.min/scale) or 0, (f.max/scale) or 255) @@ -344,13 +344,13 @@ function run_ui(event) end for i=1, #PageFiles do if (not PageFiles[i].requiredVersion) or (apiVersion == 0) or (apiVersion > 0 and PageFiles[i].requiredVersion <= apiVersion) then - local currentLineY = (menuLine-1)*lineSpacing + yMinLim - if currentLineY <= yMinLim then + local currentFieldY = (menuLine-1)*lineSpacing + yMinLim + if currentFieldY <= yMinLim then mainMenuScrollY = 0 - elseif currentLineY - mainMenuScrollY <= yMinLim then - mainMenuScrollY = currentLineY - yMinLim - elseif currentLineY - mainMenuScrollY >= yMaxLim then - mainMenuScrollY = currentLineY - yMaxLim + elseif currentFieldY - mainMenuScrollY <= yMinLim then + mainMenuScrollY = currentFieldY - yMinLim + elseif currentFieldY - mainMenuScrollY >= yMaxLim then + mainMenuScrollY = currentFieldY - yMaxLim end local attr = (menuLine == i and INVERS or 0) if event == EVT_VIRTUAL_ENTER and attr == INVERS then @@ -413,8 +413,8 @@ function run_ui(event) incLine(1) elseif event == EVT_VIRTUAL_ENTER then if Page then - local field = Page.fields[currentLine] - local idx = field.i or currentLine + local field = Page.fields[currentField] + local idx = field.i or currentField if Page.values and Page.values[idx] and (field.ro ~= true) then pageState = pageStatus.editing end @@ -469,7 +469,7 @@ function run_ui(event) end if stopDisplay and (not isTelemetryScript) then invalidatePages() - currentLine = 1 + currentField = 1 uiState = uiStatus.mainMenu stopDisplay = false end From d9bc9fcdb816a0328d2ea927986987d2c039413f Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 22 Nov 2019 18:10:28 +0100 Subject: [PATCH 052/193] allow apiVersion detection in init state for TELEMETRY script --- src/SCRIPTS/BF/ui.lua | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 3671f917..8a6fd7e3 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -297,16 +297,9 @@ function run_ui(event) -- if lastRunTS old than 500ms if lastRunTS + 50 < now then invalidatePages() - if isTelemetryScript then - uiState = uiStatus.pages - else - uiState = uiStatus.init - end + uiState = uiStatus.init end lastRunTS = now - if isTelemetryScript then - uiState = uiStatus.pages - end if uiState == uiStatus.init then local yMinLim = radio.yMinLimit lcd.clear() @@ -323,7 +316,11 @@ function run_ui(event) else background = nil invalidatePages() - uiState = uiStatus.mainMenu + if isTelemetryScript then + uiState = uiStatus.pages + else + uiState = uiStatus.mainMenu + end end elseif uiState == uiStatus.mainMenu then getPageCount() From 5cc9a56a57fb2e0fef30d805010907c9da62ad88 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 28 Nov 2019 22:11:19 +0100 Subject: [PATCH 053/193] backward compatibility --- src/SCRIPTS/BF/LAYOUT/128x64/filters.lua | 58 ------- src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua | 19 --- src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua | 31 ---- src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua | 21 --- src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua | 27 --- src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua | 20 --- src/SCRIPTS/BF/LAYOUT/128x64/rates.lua | 38 ----- src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua | 29 ---- src/SCRIPTS/BF/LAYOUT/128x64/rx.lua | 18 -- src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua | 18 -- src/SCRIPTS/BF/LAYOUT/212x64/filters.lua | 58 ------- src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua | 19 --- src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua | 31 ---- src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua | 21 --- src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua | 27 --- src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua | 20 --- src/SCRIPTS/BF/LAYOUT/212x64/rates.lua | 38 ----- src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua | 27 --- src/SCRIPTS/BF/LAYOUT/212x64/rx.lua | 18 -- src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua | 18 -- src/SCRIPTS/BF/LAYOUT/320x480/filters.lua | 58 ------- src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua | 19 --- .../BF/LAYOUT/320x480/pid_advanced.lua | 31 ---- src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua | 21 --- src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua | 27 --- src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua | 20 --- src/SCRIPTS/BF/LAYOUT/320x480/rates.lua | 38 ----- src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua | 27 --- src/SCRIPTS/BF/LAYOUT/320x480/rx.lua | 18 -- src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua | 18 -- src/SCRIPTS/BF/LAYOUT/480x272/filters.lua | 58 ------- src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua | 19 --- .../BF/LAYOUT/480x272/pid_advanced.lua | 31 ---- src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua | 22 --- src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua | 27 --- src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua | 20 --- src/SCRIPTS/BF/LAYOUT/480x272/rates.lua | 38 ----- src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua | 27 --- src/SCRIPTS/BF/LAYOUT/480x272/rx.lua | 18 -- src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua | 18 -- src/SCRIPTS/BF/PAGES/filters.lua | 155 ++++++++++++++---- src/SCRIPTS/BF/PAGES/gpspids.lua | 78 ++++++--- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 98 ++++++++--- src/SCRIPTS/BF/PAGES/pids1.lua | 82 ++++++--- src/SCRIPTS/BF/PAGES/pids2.lua | 105 +++++++++--- src/SCRIPTS/BF/PAGES/pwm.lua | 92 ++++++++--- src/SCRIPTS/BF/PAGES/rates.lua | 124 +++++++++++--- src/SCRIPTS/BF/PAGES/rescue.lua | 76 ++++++--- src/SCRIPTS/BF/PAGES/rx.lua | 65 ++++++-- src/SCRIPTS/BF/PAGES/vtx.lua | 48 ++++-- .../BF/TEMPLATES/128x64/default_template.lua | 7 + .../BF/TEMPLATES/212x64/default_template.lua | 7 + .../BF/TEMPLATES/320x480/default_template.lua | 7 + .../BF/TEMPLATES/480x272/default_template.lua | 7 + src/SCRIPTS/BF/pages.lua | 56 +++++-- src/SCRIPTS/BF/radios.lua | 12 +- src/SCRIPTS/BF/ui.lua | 93 +++++------ 57 files changed, 821 insertions(+), 1402 deletions(-) delete mode 100644 src/SCRIPTS/BF/LAYOUT/128x64/filters.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/128x64/rates.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/128x64/rx.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/212x64/filters.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/212x64/rates.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/212x64/rx.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/320x480/filters.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/320x480/rates.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/320x480/rx.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/480x272/filters.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/480x272/rates.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/480x272/rx.lua delete mode 100644 src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua create mode 100644 src/SCRIPTS/BF/TEMPLATES/128x64/default_template.lua create mode 100644 src/SCRIPTS/BF/TEMPLATES/212x64/default_template.lua create mode 100644 src/SCRIPTS/BF/TEMPLATES/320x480/default_template.lua create mode 100644 src/SCRIPTS/BF/TEMPLATES/480x272/default_template.lua diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua deleted file mode 100644 index b76da948..00000000 --- a/src/SCRIPTS/BF/LAYOUT/128x64/filters.lua +++ /dev/null @@ -1,58 +0,0 @@ -return { - labels = { - { t = "Gyro Lowpass 1 Dynamic", x = 2, y = 12, }, - { t = "Min Cutoff", x = 12, y = 20, }, - { t = "Max Cutoff", x = 12, y = 28, }, - { t = "Filter Type", x = 12, y = 36, }, - { t = "Gyro Lowpass 1", x = 2, y = 44, }, - { t = "Cutoff", x = 12, y = 52, }, - { t = "Filter Type", x = 12, y = 60, }, - { t = "Gyro Lowpass 2", x = 2, y = 68, }, - { t = "Cutoff", x = 12, y = 76, }, - { t = "Filter Type", x = 12, y = 84, }, - { t = "Gyro Notch 1", x = 2, y = 92, }, - { t = "Center", x = 12, y = 100, }, - { t = "Cutoff", x = 12, y = 108, }, - { t = "Gyro Notch 2", x = 2, y = 116, }, - { t = "Center", x = 12, y = 124, }, - { t = "Cutoff", x = 12, y = 132, }, - { t = "D Term Lowpass 1 Dynamic", x = 2, y = 140, }, - { t = "Min Cutoff", x = 12, y = 148, }, - { t = "Max Cutoff", x = 12, y = 156, }, - { t = "Filter Type", x = 12, y = 164, }, - { t = "D Term Lowpass 1", x = 2, y = 172, }, - { t = "Cutoff", x = 12, y = 180, }, - { t = "Filter Type", x = 12, y = 188, }, - { t = "D Term Lowpass 2", x = 2, y = 196, }, - { t = "Cutoff", x = 12, y = 204, }, - { t = "Filter Type", x = 12, y = 212, }, - { t = "D Term Notch", x = 2, y = 220, }, - { t = "Center", x = 12, y = 228, }, - { t = "Cutoff", x = 12, y = 236, }, - { t = "Yaw Lowpass", x = 2, y = 244, }, - { t = "Cutoff", x = 12, y = 252, }, - }, - fieldLayout = { - { x = 87, y = 20, }, - { x = 87, y = 28, }, - { x = 87, y = 36, }, - { x = 87, y = 52, }, - { x = 87, y = 60, }, - { x = 87, y = 76, }, - { x = 87, y = 84, }, - { x = 87, y = 100, }, - { x = 87, y = 108, }, - { x = 87, y = 124, }, - { x = 87, y = 132, }, - { x = 87, y = 148, }, - { x = 87, y = 156, }, - { x = 87, y = 164, }, - { x = 87, y = 180, }, - { x = 87, y = 188, }, - { x = 87, y = 204, }, - { x = 87, y = 212, }, - { x = 87, y = 228, }, - { x = 87, y = 236, }, - { x = 87, y = 252, }, - } -} diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua deleted file mode 100644 index 64911d96..00000000 --- a/src/SCRIPTS/BF/LAYOUT/128x64/gpspids.lua +++ /dev/null @@ -1,19 +0,0 @@ -return { - labels = { - { t = "P", x = 55, y = 14, }, - { t = "I", x = 83, y = 14, }, - { t = "D", x = 111, y = 14, }, - { t = "Throttle", x = 5, y = 26, }, - { t = "Velocity", x = 5, y = 36, }, - { t = "Yaw" , x = 5, y = 46, }, - }, - fieldLayout = { - { x = 51, y = 26, }, - { x = 51, y = 36, }, - { x = 51, y = 46, }, - { x = 79, y = 26, }, - { x = 79, y = 36, }, - { x = 107, y = 26, }, - { x = 107, y = 36, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua deleted file mode 100644 index 37b6fdb3..00000000 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pid_advanced.lua +++ /dev/null @@ -1,31 +0,0 @@ -return { - labels = { - { t = "Acro Trainer", x = 2, y = 12, }, - { t = "Angle Limit", x = 12, y = 20, }, - { t = "Throttle Boost", x = 2, y = 28, }, - { t = "Absolute Control", x = 2, y = 36, }, - { t = "I Term Rotation", x = 2, y = 44, }, - { t = "VBAT Compensation", x = 2, y = 52, }, - { t = "I Term Relax", x = 2, y = 60, }, - { t = "Axes", x = 12, y = 68, }, - { t = "Type", x = 12, y = 76, }, - { t = "Integrated Yaw", x = 2, y = 84, }, - { t = "Anti Gravity", x = 2, y = 92, }, - { t = "Mode", x = 12, y = 100, }, - { t = "Gain", x = 12, y = 108, }, - { t = "Threshold", x = 12, y = 116, }, - }, - fieldLayout = { - { x = 87, y = 20, }, - { x = 87, y = 28, }, - { x = 87, y = 36, }, - { x = 87, y = 44, }, - { x = 87, y = 52, }, - { x = 87, y = 68, }, - { x = 87, y = 76, }, - { x = 87, y = 84, }, - { x = 87, y = 100, }, - { x = 87, y = 108, }, - { x = 87, y = 116, }, - } -} diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua deleted file mode 100644 index 1efeb2e7..00000000 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pids1.lua +++ /dev/null @@ -1,21 +0,0 @@ -return { - labels = { - { t = "P", x = 45, y = 14, }, - { t = "I", x = 73, y = 14, }, - { t = "D", x = 101, y = 14, }, - { t = "ROLL", x = 10, y = 26, }, - { t = "PITCH", x = 10, y = 36, }, - { t = "YAW", x = 10, y = 46, }, - }, - fieldLayout = { - { x = 41, y = 26, }, - { x = 41, y = 36, }, - { x = 41, y = 46, }, - { x = 69, y = 26, }, - { x = 69, y = 36, }, - { x = 69, y = 46, }, - { x = 97, y = 26, }, - { x = 97, y = 36, }, - { x = 97, y = 46, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua deleted file mode 100644 index 82b5957c..00000000 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pids2.lua +++ /dev/null @@ -1,27 +0,0 @@ -return { - labels = { - { t = "Feed", x = 45, y = 12, }, - { t = "forward", x = 37, y = 20, }, - { t = "D", x = 85, y = 12, }, - { t = "Min", x = 80, y = 20, }, - { t = "ROLL", x = 10, y = 28, }, - { t = "PITCH", x = 10, y = 38, }, - { t = "YAW", x = 10, y = 48, }, - { t = "Feedforward", x = 10, y = 60, }, - { t = "Transition", x = 20, y = 68, }, - { t = "D Min", x = 10, y = 76, }, - { t = "Gain", x = 20, y = 84, }, - { t = "Advance", x = 20, y = 92, }, - }, - fieldLayout = { - { x = 48, y = 28, }, - { x = 48, y = 38, }, - { x = 48, y = 48, }, - { x = 80, y = 28, }, - { x = 80, y = 38, }, - { x = 80, y = 48, }, - { x = 80, y = 68, }, - { x = 80, y = 84, }, - { x = 80, y = 92, }, - }, -} \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua deleted file mode 100644 index d2cc1cc7..00000000 --- a/src/SCRIPTS/BF/LAYOUT/128x64/pwm.lua +++ /dev/null @@ -1,20 +0,0 @@ -return { - labels = { - { t = "32K", x = 10, y = 14, }, - { t = "Gyro", x = 10, y = 24, }, - { t = "PID", x = 10, y = 34, }, - { t = "Prot", x = 58, y = 14, }, - { t = "Unsync", x = 58, y = 24, }, - { t = "PWM", x = 58, y = 34, }, - { t = "Idle", x = 58, y = 44, } - }, - fieldLayout = { - { x = 32, y = 14, }, - { x = 32, y = 24, }, - { x = 32, y = 34, }, - { x = 90, y = 14, }, - { x = 90, y = 24, }, - { x = 90, y = 34, }, - { x = 90, y = 44, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua deleted file mode 100644 index 1872ec9e..00000000 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rates.lua +++ /dev/null @@ -1,38 +0,0 @@ -return { - labels = { - { t = "RC", x = 43, y = 12, }, - { t = "Rate", x = 38, y = 20, }, - { t = "Super", x = 63, y = 12, }, - { t = "Rate", x = 66, y = 20, }, - { t = "RC", x = 99, y = 12, }, - { t = "Expo", x = 94, y = 20, }, - { t = "ROLL", x = 10, y = 28, }, - { t = "PITCH", x = 10, y = 38, }, - { t = "YAW", x = 10, y = 48, }, - { t = "Throttle", x = 10, y = 60, }, - { t = "Mid", x = 20, y = 68, }, - { t = "Expo", x = 20, y = 76, }, - { t = "Limit Type", x = 20, y = 84, }, - { t = "Limit %", x = 20, y = 92, }, - { t = "TPA", x = 10, y = 100, }, - { t = "Rate", x = 20, y = 108, }, - { t = "Breakpoint", x = 20, y = 116, }, - }, - fieldLayout = { - { x = 39, y = 28, }, - { x = 39, y = 38, }, - { x = 39, y = 48, }, - { x = 66, y = 28, }, - { x = 66, y = 38, }, - { x = 66, y = 48, }, - { x = 94, y = 28, }, - { x = 94, y = 38, }, - { x = 94, y = 48, }, - { x = 70, y = 68, }, - { x = 70, y = 76, }, - { x = 70, y = 84, }, - { x = 70, y = 92, }, - { x = 70, y = 108, }, - { x = 70, y = 116, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua deleted file mode 100644 index 5d6f6eaf..00000000 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rescue.lua +++ /dev/null @@ -1,29 +0,0 @@ -return { - labels = { - { t = "Min Sats.", x = 3, y = 12, }, - { t = "Angle", x = 3, y = 22, }, - { t = "Initial Alt", x = 3, y = 32, }, - { t = "Descent Dst", x = 3, y = 42, }, - { t = "Ground Spd", x = 3, y = 52, }, - { t = "Arm w/o fix", x = 3, y = 62, }, - { t = "Snty.", x = 80, y = 12, }, - { t = "Throttle", x = 80, y = 22, }, - { t = "Min", x = 85, y = 32, }, - { t = "Hover", x = 80, y = 42, }, - { t = "Max", x = 85, y = 52, }, - }, - fieldLayout = { - { x = 58, y = 12, }, - { x = 58, y = 22, }, - { x = 58, y = 32, }, - { x = 58, y = 42, }, - { x = 58, y = 52, }, - { x = 58, y = 62, }, - { x = 105, y = 12, }, - { x = 105, y = 32, }, - { x = 105, y = 42, }, - { x = 105, y = 52, }, - { x = 105, y = 52, }, - - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua deleted file mode 100644 index de0baf03..00000000 --- a/src/SCRIPTS/BF/LAYOUT/128x64/rx.lua +++ /dev/null @@ -1,18 +0,0 @@ -return { - labels = { - { t = "Stick Min", x = 10, y = 12 }, - { t = "Stick Mid", x = 10, y = 22 }, - { t = "Stick Max", x = 10, y = 32 }, - { t = "Cam Angle", x = 10, y = 42 }, - { t = "Interp", x = 10, y = 52 }, - { t = "Interp Int", x = 10, y = 62 }, - }, - fieldLayout = { - { x = 70, y = 12, }, - { x = 70, y = 22, }, - { x = 70, y = 32, }, - { x = 70, y = 42, }, - { x = 70, y = 52, }, - { x = 70, y = 62, } - }, - } \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua deleted file mode 100644 index 355b9e4d..00000000 --- a/src/SCRIPTS/BF/LAYOUT/128x64/vtx.lua +++ /dev/null @@ -1,18 +0,0 @@ -return { - labels = { - { t = "Band", x = 10, y = 14 }, - { t = "Chan", x = 10, y = 24 }, - { t = "Power", x = 10, y = 34 }, - { t = "Pit", x = 10, y = 44 }, - { t = "Proto", x = 70, y = 14 }, - { t = "Freq", x = 70, y = 24 }, - }, - fieldLayout = { - { x = 40, y = 14, }, - { x = 40, y = 24, }, - { x = 40, y = 34, }, - { x = 40, y = 44, }, - { x = 100, y = 14, }, - { x = 100, y = 24, }, - }, -} \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua b/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua deleted file mode 100644 index f5edfbb8..00000000 --- a/src/SCRIPTS/BF/LAYOUT/212x64/filters.lua +++ /dev/null @@ -1,58 +0,0 @@ -return { - labels = { - { t = "Gyro Lowpass 1 Dynamic", x = 2, y = 12, }, - { t = "Min Cutoff", x = 12, y = 20, }, - { t = "Max Cutoff", x = 12, y = 28, }, - { t = "Filter Type", x = 12, y = 36, }, - { t = "Gyro Lowpass 1", x = 2, y = 44, }, - { t = "Cutoff", x = 12, y = 52, }, - { t = "Filter Type", x = 12, y = 60, }, - { t = "Gyro Lowpass 2", x = 2, y = 68, }, - { t = "Cutoff", x = 12, y = 76, }, - { t = "Filter Type", x = 12, y = 84, }, - { t = "Gyro Notch 1", x = 2, y = 92, }, - { t = "Center", x = 12, y = 100, }, - { t = "Cutoff", x = 12, y = 108, }, - { t = "Gyro Notch 2", x = 2, y = 116, }, - { t = "Center", x = 12, y = 124, }, - { t = "Cutoff", x = 12, y = 132, }, - { t = "D Term Lowpass 1 Dynamic", x = 2, y = 140, }, - { t = "Min Cutoff", x = 12, y = 148, }, - { t = "Max Cutoff", x = 12, y = 156, }, - { t = "Filter Type", x = 12, y = 164, }, - { t = "D Term Lowpass 1", x = 2, y = 172, }, - { t = "Cutoff", x = 12, y = 180, }, - { t = "Filter Type", x = 12, y = 188, }, - { t = "D Term Lowpass 2", x = 2, y = 196, }, - { t = "Cutoff", x = 12, y = 204, }, - { t = "Filter Type", x = 12, y = 212, }, - { t = "D Term Notch", x = 2, y = 220, }, - { t = "Center", x = 12, y = 228, }, - { t = "Cutoff", x = 12, y = 236, }, - { t = "Yaw Lowpass", x = 2, y = 244, }, - { t = "Cutoff", x = 12, y = 252, }, - }, - fieldLayout = { - { x = 87, y = 20, }, - { x = 87, y = 28, }, - { x = 87, y = 36, }, - { x = 87, y = 52, }, - { x = 87, y = 60, }, - { x = 87, y = 76, }, - { x = 87, y = 84, }, - { x = 87, y = 100, }, - { x = 87, y = 108, }, - { x = 87, y = 124, }, - { x = 87, y = 132, }, - { x = 87, y = 148, }, - { x = 87, y = 156, }, - { x = 87, y = 164, }, - { x = 87, y = 180, }, - { x = 87, y = 188, }, - { x = 87, y = 204, }, - { x = 87, y = 212, }, - { x = 87, y = 228, }, - { x = 87, y = 236, }, - { x = 87, y = 252, }, - } -} diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua deleted file mode 100644 index 178b5232..00000000 --- a/src/SCRIPTS/BF/LAYOUT/212x64/gpspids.lua +++ /dev/null @@ -1,19 +0,0 @@ -return { - labels = { - { t = "P", x = 70, y = 14, }, - { t = "I", x = 98, y = 14, }, - { t = "D", x = 126, y = 14, }, - { t = "Throttle", x = 25, y = 26, }, - { t = "Velocity", x = 25, y = 36, }, - { t = "Yaw", x = 25, y = 46, }, - }, - fieldLayout = { - { x = 66, y = 26, }, - { x = 66, y = 36, }, - { x = 66, y = 46, }, - { x = 94, y = 26, }, - { x = 94, y = 36, }, - { x = 122, y = 26, }, - { x = 122, y = 36, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua deleted file mode 100644 index 37b6fdb3..00000000 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pid_advanced.lua +++ /dev/null @@ -1,31 +0,0 @@ -return { - labels = { - { t = "Acro Trainer", x = 2, y = 12, }, - { t = "Angle Limit", x = 12, y = 20, }, - { t = "Throttle Boost", x = 2, y = 28, }, - { t = "Absolute Control", x = 2, y = 36, }, - { t = "I Term Rotation", x = 2, y = 44, }, - { t = "VBAT Compensation", x = 2, y = 52, }, - { t = "I Term Relax", x = 2, y = 60, }, - { t = "Axes", x = 12, y = 68, }, - { t = "Type", x = 12, y = 76, }, - { t = "Integrated Yaw", x = 2, y = 84, }, - { t = "Anti Gravity", x = 2, y = 92, }, - { t = "Mode", x = 12, y = 100, }, - { t = "Gain", x = 12, y = 108, }, - { t = "Threshold", x = 12, y = 116, }, - }, - fieldLayout = { - { x = 87, y = 20, }, - { x = 87, y = 28, }, - { x = 87, y = 36, }, - { x = 87, y = 44, }, - { x = 87, y = 52, }, - { x = 87, y = 68, }, - { x = 87, y = 76, }, - { x = 87, y = 84, }, - { x = 87, y = 100, }, - { x = 87, y = 108, }, - { x = 87, y = 116, }, - } -} diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua deleted file mode 100644 index 66ccafb5..00000000 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pids1.lua +++ /dev/null @@ -1,21 +0,0 @@ -return { - labels = { - { t = "P", x = 70, y = 14, }, - { t = "I", x = 98, y = 14, }, - { t = "D", x = 126, y = 14, }, - { t = "ROLL", x = 25, y = 26, }, - { t = "PITCH", x = 25, y = 36, }, - { t = "YAW", x = 25, y = 46, }, - }, - fieldLayout = { - { x = 66, y = 26, }, - { x = 66, y = 36, }, - { x = 66, y = 46, }, - { x = 94, y = 26, }, - { x = 94, y = 36, }, - { x = 94, y = 46, }, - { x = 122, y = 26, }, - { x = 122, y = 36, }, - { x = 122, y = 46, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua deleted file mode 100644 index d97819d8..00000000 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pids2.lua +++ /dev/null @@ -1,27 +0,0 @@ -return { - labels = { - { t = "Feed", x = 46, y = 12, }, - { t = "forward", x = 38, y = 20, }, - { t = "D", x = 86, y = 12, }, - { t = "Min", x = 81, y = 20, }, - { t = "ROLL", x = 8, y = 28, }, - { t = "PITCH", x = 8, y = 38, }, - { t = "YAW", x = 8, y = 48, }, - { t = "Feedforward", x = 110, y = 14, }, - { t = "Transition", x = 120, y = 22, }, - { t = "D Min", x = 110, y = 30, }, - { t = "Gain", x = 120, y = 38, }, - { t = "Advance", x = 120, y = 48, }, - }, - fieldLayout = { - { x = 49, y = 28, }, - { x = 49, y = 38, }, - { x = 49, y = 48, }, - { x = 81, y = 28, }, - { x = 81, y = 38, }, - { x = 81, y = 48, }, - { x = 180, y = 22, }, - { x = 180, y = 38, }, - { x = 180, y = 48, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua b/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua deleted file mode 100644 index 098d3835..00000000 --- a/src/SCRIPTS/BF/LAYOUT/212x64/pwm.lua +++ /dev/null @@ -1,20 +0,0 @@ -return { - labels = { - { t = "32K", x = 48, y = 14, }, - { t = "Gyro Rt", x = 29, y = 24, }, - { t = "PID Rt", x = 35, y = 34, }, - { t = "Protocol", x = 107, y = 14, }, - { t = "Unsynced", x = 106, y = 24, }, - { t = "PWM Rate", x = 105, y = 34, }, - { t = "Idle Offset", x = 94, y = 44, } - }, - fieldLayout = { - { x = 65, y = 14, }, - { x = 65, y = 24, }, - { x = 65, y = 34, }, - { x = 148, y = 14, }, - { x = 148, y = 24, }, - { x = 148, y = 34, }, - { x = 148, y = 44, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua deleted file mode 100644 index 15ab72b3..00000000 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rates.lua +++ /dev/null @@ -1,38 +0,0 @@ -return { - labels = { - { t = "RC", x = 43, y = 12, }, - { t = "Rate", x = 38, y = 20, }, - { t = "Super", x = 63, y = 12, }, - { t = "Rate", x = 66, y = 20, }, - { t = "RC", x = 99, y = 12, }, - { t = "Expo", x = 94, y = 20, }, - { t = "ROLL", x = 8, y = 28, }, - { t = "PITCH", x = 8, y = 38, }, - { t = "YAW", x = 8, y = 48, }, - { t = "Throttle", x = 120, y = 12, }, - { t = "Mid", x = 130, y = 20, }, - { t = "Expo", x = 130, y = 28, }, - { t = "Limit Type", x = 130, y = 36, }, - { t = "Limit %", x = 130, y = 44, }, - { t = "TPA", x = 120, y = 52, }, - { t = "Rate", x = 130, y = 60, }, - { t = "Breakpoint", x = 130, y = 68, }, - }, - fieldLayout = { - { x = 39, y = 28, }, - { x = 39, y = 38, }, - { x = 39, y = 48, }, - { x = 66, y = 28, }, - { x = 66, y = 38, }, - { x = 66, y = 48, }, - { x = 94, y = 28, }, - { x = 94, y = 38, }, - { x = 94, y = 48, }, - { x = 180, y = 20, }, - { x = 180, y = 28, }, - { x = 180, y = 36, }, - { x = 180, y = 44, }, - { x = 180, y = 60, }, - { x = 180, y = 68, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua deleted file mode 100644 index 40ff9232..00000000 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rescue.lua +++ /dev/null @@ -1,27 +0,0 @@ -return { - labels = { - { t = "Min Sats.", x = 30, y = 12, }, - { t = "Angle", x = 45, y = 22, }, - { t = "Initial Alt.", x = 18, y = 32, }, - { t = "Descent Dist.", x = 10, y = 42, }, - { t = "Ground Speed", x = 10, y = 52, }, - { t = "Arm w/o fix", x = 15, y = 62, }, - { t = "Sanity Ch.", x = 125, y = 12, }, - { t = "Throttle", x = 125, y = 22, }, - { t = "Min", x = 128, y = 32, }, - { t = "Hover", x = 120, y = 42, }, - { t = "Max", x = 128, y = 52, }, - }, - fieldLayout = { - { x = 75, y = 12, }, - { x = 75, y = 22, }, - { x = 75, y = 32, }, - { x = 75, y = 42, }, - { x = 75, y = 52, }, - { x = 75, y = 62, }, - { x = 180, y = 12, }, - { x = 150, y = 32, }, - { x = 150, y = 42, }, - { x = 150, y = 52, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua deleted file mode 100644 index 24c48664..00000000 --- a/src/SCRIPTS/BF/LAYOUT/212x64/rx.lua +++ /dev/null @@ -1,18 +0,0 @@ -return { - labels = { - { t = "Stick Min", x = 30, y = 12 }, - { t = "Stick Mid", x = 30, y = 22 }, - { t = "Stick Max", x = 30, y = 32 }, - { t = "Cam Angle", x = 110, y = 12 }, - { t = "Interp", x = 110, y = 22 }, - { t = "Interp Int", x = 110, y = 32 }, - }, - fieldLayout = { - { x = 80, y = 12, }, - { x = 80, y = 22, }, - { x = 80, y = 32, }, - { x = 160, y = 12, }, - { x = 160, y = 22, }, - { x = 160, y = 32, } - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua b/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua deleted file mode 100644 index 170aa41c..00000000 --- a/src/SCRIPTS/BF/LAYOUT/212x64/vtx.lua +++ /dev/null @@ -1,18 +0,0 @@ -return { - labels = { - { t = "Band", x = 25, y = 14 }, - { t = "Channel", x = 25, y = 24 }, - { t = "Power", x = 25, y = 34 }, - { t = "Pit", x = 25, y = 44 }, - { t = "Proto", x = 100, y = 14 }, - { t = "Freq", x = 100, y = 24 }, - }, - fieldLayout = { - { x = 75, y = 14, }, - { x = 75, y = 24, }, - { x = 75, y = 34, }, - { x = 75, y = 44, }, - { x = 150, y = 14, }, - { x = 150, y = 24, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua b/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua deleted file mode 100644 index b75db021..00000000 --- a/src/SCRIPTS/BF/LAYOUT/320x480/filters.lua +++ /dev/null @@ -1,58 +0,0 @@ -return { - labels = { - { t = "Gyro Lowpass 1 Dynamic", x = 5, y = 35, }, - { t = "Min Cutoff", x = 35, y = 55, }, - { t = "Max Cutoff", x = 35, y = 75, }, - { t = "Filter Type", x = 35, y = 95, }, - { t = "Gyro Lowpass 1", x = 5, y = 115, }, - { t = "Cutoff", x = 35, y = 135, }, - { t = "Filter Type", x = 35, y = 155, }, - { t = "Gyro Lowpass 2", x = 5, y = 175, }, - { t = "Cutoff", x = 35, y = 195, }, - { t = "Filter Type", x = 35, y = 215, }, - { t = "Gyro Notch 1", x = 5, y = 235, }, - { t = "Center", x = 35, y = 255, }, - { t = "Cutoff", x = 35, y = 275, }, - { t = "Gyro Notch 2", x = 5, y = 295, }, - { t = "Center", x = 35, y = 315, }, - { t = "Cutoff", x = 35, y = 335, }, - { t = "D Term Lowpass 1 Dynamic", x = 5, y = 355, }, - { t = "Min Cutoff", x = 35, y = 375, }, - { t = "Max Cutoff", x = 35, y = 395, }, - { t = "Filter Type", x = 35, y = 415, }, - { t = "D Term Lowpass 1", x = 5, y = 435, }, - { t = "Cutoff", x = 35, y = 455, }, - { t = "Filter Type", x = 35, y = 475, }, - { t = "D Term Lowpass 2", x = 5, y = 495, }, - { t = "Cutoff", x = 35, y = 515, }, - { t = "Filter Type", x = 35, y = 535, }, - { t = "D Term Notch", x = 5, y = 555, }, - { t = "Center", x = 35, y = 575, }, - { t = "Cutoff", x = 35, y = 595, }, - { t = "Yaw Lowpass", x = 5, y = 615, }, - { t = "Cutoff", x = 35, y = 635, }, - }, - fieldLayout = { - { x = 200, y = 55, }, - { x = 200, y = 75, }, - { x = 200, y = 95, }, - { x = 200, y = 135, }, - { x = 200, y = 155, }, - { x = 200, y = 195, }, - { x = 200, y = 215, }, - { x = 200, y = 255, }, - { x = 200, y = 275, }, - { x = 200, y = 315, }, - { x = 200, y = 335, }, - { x = 200, y = 375, }, - { x = 200, y = 395, }, - { x = 200, y = 415, }, - { x = 200, y = 455, }, - { x = 200, y = 475, }, - { x = 200, y = 515, }, - { x = 200, y = 535, }, - { x = 200, y = 575, }, - { x = 200, y = 595, }, - { x = 200, y = 635, }, - } -} diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua deleted file mode 100644 index c7dd58c8..00000000 --- a/src/SCRIPTS/BF/LAYOUT/320x480/gpspids.lua +++ /dev/null @@ -1,19 +0,0 @@ -return { - labels = { - { t = "P", x = 100, y = 48, }, - { t = "I", x = 180, y = 48, }, - { t = "D", x = 260, y = 48, }, - { t = "Throttle", x = 10, y = 100, }, - { t = "Velocity", x = 10, y = 150, }, - { t = "Yaw" , x = 10, y = 200, }, - }, - fieldLayout = { - { x = 100, y = 100, }, - { x = 100, y = 150, }, - { x = 100, y = 200, }, - { x = 180, y = 100, }, - { x = 180, y = 150, }, - { x = 260, y = 100, }, - { x = 260, y = 150, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua deleted file mode 100644 index a35a9904..00000000 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pid_advanced.lua +++ /dev/null @@ -1,31 +0,0 @@ -return { - labels = { - { t = "Acro Trainer", x = 5, y = 35, }, - { t = "Angle Limit", x = 15, y = 55, }, - { t = "Throttle Boost", x = 5, y = 75, }, - { t = "Absolute Control", x = 5, y = 95, }, - { t = "I Term Rotation", x = 5, y = 115, }, - { t = "VBAT Compensation", x = 5, y = 135, }, - { t = "I Term Relax", x = 5, y = 155, }, - { t = "Axes", x = 15, y = 175, }, - { t = "Type", x = 15, y = 195, }, - { t = "Integrated Yaw", x = 5, y = 215, }, - { t = "Anti Gravity", x = 5, y = 235, }, - { t = "Mode", x = 15, y = 255, }, - { t = "Gain", x = 15, y = 275, }, - { t = "Threshold", x = 15, y = 295, }, - }, - fieldLayout = { - { x = 200, y = 55, }, - { x = 200, y = 75, }, - { x = 200, y = 95, }, - { x = 200, y = 115, }, - { x = 200, y = 135, }, - { x = 200, y = 175, }, - { x = 200, y = 195, }, - { x = 200, y = 215, }, - { x = 200, y = 255, }, - { x = 200, y = 275, }, - { x = 200, y = 295, }, - } -} diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua deleted file mode 100644 index 5ace790b..00000000 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pids1.lua +++ /dev/null @@ -1,21 +0,0 @@ -return { - labels = { - { t = "P", x = 100, y = 48, }, - { t = "I", x = 180, y = 48, }, - { t = "D", x = 260, y = 48, }, - { t = "ROLL", x = 10, y = 100, }, - { t = "PITCH", x = 10, y = 150, }, - { t = "YAW", x = 10, y = 200, }, - }, - fieldLayout = { - { x = 100, y = 100, }, - { x = 100, y = 150, }, - { x = 100, y = 200, }, - { x = 180, y = 100, }, - { x = 180, y = 150, }, - { x = 180, y = 200, }, - { x = 260, y = 100, }, - { x = 260, y = 150, }, - { x = 260, y = 200, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua deleted file mode 100644 index 730c81ac..00000000 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pids2.lua +++ /dev/null @@ -1,27 +0,0 @@ -return { - labels = { - { t = "Feed", x = 97, y = 52, }, - { t = "forward", x = 82, y = 70, }, - { t = "D", x = 207, y = 52, }, - { t = "Min", x = 202, y = 70, }, - { t = "ROLL", x = 28, y = 100, }, - { t = "PITCH", x = 28, y = 150, }, - { t = "YAW", x = 28, y = 200, }, - { t = "Feedforward", x = 28, y = 250, }, - { t = "Transition", x = 40, y = 270, }, - { t = "D Min", x = 28, y = 300, }, - { t = "Gain", x = 40, y = 320, }, - { t = "Advance", x = 40, y = 350, }, - }, - fieldLayout = { - { x = 102, y = 100, }, - { x = 102, y = 150, }, - { x = 102, y = 200, }, - { x = 202, y = 100, }, - { x = 202, y = 150, }, - { x = 202, y = 200, }, - { x = 150, y = 270, }, - { x = 150, y = 320, }, - { x = 150, y = 350, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua b/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua deleted file mode 100644 index a05535ca..00000000 --- a/src/SCRIPTS/BF/LAYOUT/320x480/pwm.lua +++ /dev/null @@ -1,20 +0,0 @@ -return { - labels = { - { t = "Protocol", x = 36, y = 68 }, - { t = "32K", x = 36, y = 110 }, - { t = "Gyro Rt", x = 36, y = 155 }, - { t = "PID Rt", x = 36, y = 200 }, - { t = "Unsynced", x = 36, y = 242 }, - { t = "PWM Rate", x = 36, y = 284 }, - { t = "Idle Offset", x = 36, y = 326 } - }, - fieldLayout = { - { x = 150, y = 68, }, - { x = 150, y = 110, }, - { x = 150, y = 155, }, - { x = 150, y = 200, }, - { x = 150, y = 242, }, - { x = 150, y = 284, }, - { x = 150, y = 326, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua deleted file mode 100644 index 95f3d156..00000000 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rates.lua +++ /dev/null @@ -1,38 +0,0 @@ -return { - labels = { - { t = "RC", x = 100, y = 52 }, - { t = "Rate", x = 94, y = 70 }, - { t = "Super", x = 148, y = 52 }, - { t = "Rate", x = 152, y = 70 }, - { t = "RC", x = 214, y = 52 }, - { t = "Expo", x = 207, y = 70 }, - { t = "ROLL", x = 28, y = 100 }, - { t = "PITCH", x = 28, y = 150 }, - { t = "YAW", x = 28, y = 200 }, - { t = "Throttle", x = 28, y = 250 }, - { t = "Mid", x = 40, y = 270, }, - { t = "Expo", x = 40, y = 290, }, - { t = "Limit Type", x = 40, y = 310, }, - { t = "Limit %", x = 40, y = 330, }, - { t = "TPA", x = 28, y = 350, }, - { t = "Rate", x = 40, y = 370, }, - { t = "Breakpoint", x = 40, y = 390, }, - }, - fieldLayout = { - { x = 102, y = 100, }, - { x = 102, y = 150, }, - { x = 102, y = 200, }, - { x = 158, y = 100, }, - { x = 158, y = 150, }, - { x = 158, y = 200, }, - { x = 216, y = 100, }, - { x = 216, y = 150, }, - { x = 216, y = 200, }, - { x = 150, y = 270, }, - { x = 150, y = 290, }, - { x = 150, y = 310, }, - { x = 150, y = 330, }, - { x = 150, y = 370, }, - { x = 150, y = 390, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua deleted file mode 100644 index d09658d7..00000000 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rescue.lua +++ /dev/null @@ -1,27 +0,0 @@ -return { - labels = { - { t = "Min Sats.", x = 10, y = 40 }, - { t = "Angle", x = 10, y = 80 }, - { t = "Initial Altitude", x = 10, y = 120 }, - { t = "Descent Distance", x = 10, y = 160 }, - { t = "Ground Speed", x = 10, y = 200 }, - { t = "Arm w/o fix", x = 10, y = 240, }, - { t = "Snty.", x = 10, y = 260 }, - { t = "Throttle", x = 10, y = 320 }, - { t = "Min", x = 10, y = 360 }, - { t = "Hover", x = 10, y = 400 }, - { t = "Max", x = 10, y = 440 }, - }, - fieldLayout = { - { x = 260, y = 40, }, - { x = 260, y = 80, }, - { x = 260, y = 120, }, - { x = 260, y = 160, }, - { x = 260, y = 200, }, - { x = 260, y = 240, }, - { x = 260, y = 320, }, - { x = 260, y = 360, }, - { x = 260, y = 400, }, - { x = 260, y = 440, }, - }, -} \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua b/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua deleted file mode 100644 index d9c5ae83..00000000 --- a/src/SCRIPTS/BF/LAYOUT/320x480/rx.lua +++ /dev/null @@ -1,18 +0,0 @@ -return { - labels = { - { t = "Stick Min", x = 36, y = 68 }, - { t = "Stick Mid", x = 36, y = 110 }, - { t = "Stick Max", x = 36, y = 155 }, - { t = "Cam Angle", x = 36, y = 200 }, - { t = "Interp", x = 36, y = 242 }, - { t = "Interp Int", x = 36, y = 284 } - }, - fieldLayout = { - { x = 150, y = 68, }, - { x = 150, y = 110, }, - { x = 150, y = 155, }, - { x = 150, y = 200, }, - { x = 150, y = 242, }, - { x = 150, y = 284, } - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua b/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua deleted file mode 100644 index fedff593..00000000 --- a/src/SCRIPTS/BF/LAYOUT/320x480/vtx.lua +++ /dev/null @@ -1,18 +0,0 @@ -return { - labels = { - { t = "Band", x = 36, y = 155 }, - { t = "Channel", x = 36, y = 200 }, - { t = "Power", x = 36, y = 242 }, - { t = "Pit", x = 36, y = 284 }, - { t = "Proto", x = 36, y = 68 }, - { t = "Freq", x = 36, y = 110 }, - }, - fieldLayout = { - { x = 150, y = 155, }, - { x = 150, y = 200, }, - { x = 150, y = 242, }, - { x = 150, y = 284, }, - { x = 150, y = 68, }, - { x = 150, y = 110, }, - }, -} \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua b/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua deleted file mode 100644 index 39267df6..00000000 --- a/src/SCRIPTS/BF/LAYOUT/480x272/filters.lua +++ /dev/null @@ -1,58 +0,0 @@ -return { - labels = { - { t = "Gyro Lowpass 1 Dynamic", x = 5, y = 35 }, - { t = "Min Cutoff", x = 35, y = 55, }, - { t = "Max Cutoff", x = 35, y = 75, }, - { t = "Filter Type", x = 35, y = 95, }, - { t = "Gyro Lowpass 1", x = 5, y = 115, }, - { t = "Cutoff", x = 35, y = 135, }, - { t = "Filter Type", x = 35, y = 155, }, - { t = "Gyro Lowpass 2", x = 5, y = 175, }, - { t = "Cutoff", x = 35, y = 195, }, - { t = "Filter Type", x = 35, y = 215, }, - { t = "Gyro Notch 1", x = 5, y = 235, }, - { t = "Center", x = 35, y = 255, }, - { t = "Cutoff", x = 35, y = 275, }, - { t = "Gyro Notch 2", x = 5, y = 295, }, - { t = "Center", x = 35, y = 315, }, - { t = "Cutoff", x = 35, y = 335, }, - { t = "D Term Lowpass 1 Dynamic", x = 5, y = 355, }, - { t = "Min Cutoff", x = 35, y = 375, }, - { t = "Max Cutoff", x = 35, y = 395, }, - { t = "Filter Type", x = 35, y = 415, }, - { t = "D Term Lowpass 1", x = 5, y = 435, }, - { t = "Cutoff", x = 35, y = 455, }, - { t = "Filter Type", x = 35, y = 475, }, - { t = "D Term Lowpass 2", x = 5, y = 495, }, - { t = "Cutoff", x = 35, y = 515, }, - { t = "Filter Type", x = 35, y = 535, }, - { t = "D Term Notch", x = 5, y = 555, }, - { t = "Center", x = 35, y = 575, }, - { t = "Cutoff", x = 35, y = 595, }, - { t = "Yaw Lowpass", x = 5, y = 615, }, - { t = "Cutoff", x = 35, y = 635, }, - }, - fieldLayout = { - { x = 200, y = 55, }, - { x = 200, y = 75, }, - { x = 200, y = 95, }, - { x = 200, y = 135, }, - { x = 200, y = 155, }, - { x = 200, y = 195, }, - { x = 200, y = 215, }, - { x = 200, y = 255, }, - { x = 200, y = 275, }, - { x = 200, y = 315, }, - { x = 200, y = 335, }, - { x = 200, y = 375, }, - { x = 200, y = 395, }, - { x = 200, y = 415, }, - { x = 200, y = 455, }, - { x = 200, y = 475, }, - { x = 200, y = 515, }, - { x = 200, y = 535, }, - { x = 200, y = 575, }, - { x = 200, y = 595, }, - { x = 200, y = 635, }, - } -} diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua b/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua deleted file mode 100644 index 42c82a6a..00000000 --- a/src/SCRIPTS/BF/LAYOUT/480x272/gpspids.lua +++ /dev/null @@ -1,19 +0,0 @@ -return { - labels = { - { t = "P", x = 142, y = 48, }, - { t = "I", x = 244, y = 48, }, - { t = "D", x = 342, y = 48, }, - { t = "Throttle", x = 28, y = 100, }, - { t = "Velocity", x = 28, y = 150, }, - { t = "Yaw" , x = 28, y = 200, }, - }, - fieldLayout = { - { x = 140, y = 100, }, - { x = 140, y = 150, }, - { x = 140, y = 200, }, - { x = 240, y = 100, }, - { x = 240, y = 150, }, - { x = 340, y = 100, }, - { x = 340, y = 150, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua deleted file mode 100644 index a35a9904..00000000 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pid_advanced.lua +++ /dev/null @@ -1,31 +0,0 @@ -return { - labels = { - { t = "Acro Trainer", x = 5, y = 35, }, - { t = "Angle Limit", x = 15, y = 55, }, - { t = "Throttle Boost", x = 5, y = 75, }, - { t = "Absolute Control", x = 5, y = 95, }, - { t = "I Term Rotation", x = 5, y = 115, }, - { t = "VBAT Compensation", x = 5, y = 135, }, - { t = "I Term Relax", x = 5, y = 155, }, - { t = "Axes", x = 15, y = 175, }, - { t = "Type", x = 15, y = 195, }, - { t = "Integrated Yaw", x = 5, y = 215, }, - { t = "Anti Gravity", x = 5, y = 235, }, - { t = "Mode", x = 15, y = 255, }, - { t = "Gain", x = 15, y = 275, }, - { t = "Threshold", x = 15, y = 295, }, - }, - fieldLayout = { - { x = 200, y = 55, }, - { x = 200, y = 75, }, - { x = 200, y = 95, }, - { x = 200, y = 115, }, - { x = 200, y = 135, }, - { x = 200, y = 175, }, - { x = 200, y = 195, }, - { x = 200, y = 215, }, - { x = 200, y = 255, }, - { x = 200, y = 275, }, - { x = 200, y = 295, }, - } -} diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua deleted file mode 100644 index 2896075d..00000000 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pids1.lua +++ /dev/null @@ -1,22 +0,0 @@ - -return { - labels = { - { t = "P", x = 142, y = 48, }, - { t = "I", x = 244, y = 48, }, - { t = "D", x = 342, y = 48, }, - { t = "ROLL", x = 28, y = 100, }, - { t = "PITCH", x = 28, y = 150, }, - { t = "YAW", x = 28, y = 200, }, - }, - fieldLayout = { - { x = 140, y = 100, }, - { x = 140, y = 150, }, - { x = 140, y = 200, }, - { x = 240, y = 100, }, - { x = 240, y = 150, }, - { x = 240, y = 200, }, - { x = 340, y = 100, }, - { x = 340, y = 150, }, - { x = 340, y = 200, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua deleted file mode 100644 index 8f4bc5da..00000000 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pids2.lua +++ /dev/null @@ -1,27 +0,0 @@ -return { - labels = { - { t = "Feed", x = 97, y = 52, }, - { t = "forward", x = 82, y = 70, }, - { t = "D", x = 207, y = 52, }, - { t = "Min", x = 202, y = 70, }, - { t = "ROLL", x = 28, y = 100, }, - { t = "PITCH", x = 28, y = 150, }, - { t = "YAW", x = 28, y = 200, }, - { t = "Feedforward", x = 290, y = 100, }, - { t = "Transition", x = 300, y = 120, }, - { t = "D Min", x = 290, y = 140, }, - { t = "Gain", x = 300, y = 160, }, - { t = "Advance", x = 300, y = 180, }, - }, - fieldLayout = { - { x = 102, y = 100, }, - { x = 102, y = 150, }, - { x = 102, y = 200, }, - { x = 202, y = 100, }, - { x = 202, y = 150, }, - { x = 202, y = 200, }, - { x = 390, y = 120, }, - { x = 390, y = 160, }, - { x = 390, y = 180, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua b/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua deleted file mode 100644 index 31dad642..00000000 --- a/src/SCRIPTS/BF/LAYOUT/480x272/pwm.lua +++ /dev/null @@ -1,20 +0,0 @@ -return { - labels = { - { t = "Protocol", x = 36, y = 68 }, - { t = "32K", x = 36, y = 110 }, - { t = "Gyro Rt", x = 36, y = 155 }, - { t = "PID Rt", x = 36, y = 200 }, - { t = "Unsynced", x = 232, y = 110 }, - { t = "PWM Rate", x = 232, y = 155 }, - { t = "Idle Offset", x = 232, y = 200 }, - }, - fieldLayout = { - { x = 130, y = 68, }, - { x = 130, y = 110, }, - { x = 130, y = 155, }, - { x = 130, y = 200, }, - { x = 350, y = 110, }, - { x = 350, y = 155, }, - { x = 350, y = 200, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua deleted file mode 100644 index 85425eb2..00000000 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rates.lua +++ /dev/null @@ -1,38 +0,0 @@ -return { - labels = { - { t = "RC", x = 100, y = 52, }, - { t = "Rate", x = 94, y = 70, }, - { t = "Super", x = 148, y = 52, }, - { t = "Rate", x = 152, y = 70, }, - { t = "RC", x = 214, y = 52, }, - { t = "Expo", x = 207, y = 70, }, - { t = "ROLL", x = 28, y = 100, }, - { t = "PITCH", x = 28, y = 150, }, - { t = "YAW", x = 28, y = 200, }, - { t = "Throttle", x = 290, y = 60, }, - { t = "Mid", x = 300, y = 80, }, - { t = "Expo", x = 300, y = 100, }, - { t = "Limit Type", x = 300, y = 120, }, - { t = "Limit %", x = 300, y = 140, }, - { t = "TPA", x = 290, y = 160, }, - { t = "Rate", x = 300, y = 180, }, - { t = "Breakpoint", x = 300, y = 200, }, - }, - fieldLayout = { - { x = 102, y = 100, }, - { x = 102, y = 150, }, - { x = 102, y = 200, }, - { x = 158, y = 100, }, - { x = 158, y = 150, }, - { x = 158, y = 200, }, - { x = 216, y = 100, }, - { x = 216, y = 150, }, - { x = 216, y = 200, }, - { x = 390, y = 80, }, - { x = 390, y = 100, }, - { x = 390, y = 120, }, - { x = 390, y = 140, }, - { x = 390, y = 180, }, - { x = 390, y = 200, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua deleted file mode 100644 index e79db748..00000000 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rescue.lua +++ /dev/null @@ -1,27 +0,0 @@ -return { - labels = { - { t = "Min Sats.", x =130, y = 40, }, - { t = "Angle", x =150, y = 80, }, - { t = "Initial Altitude", x = 60, y = 120, }, - { t = "Descent Distance", x = 10, y = 160, }, - { t = "Ground Speed", x = 50, y = 200, }, - { t = "Arm w/o fix", x = 10, y = 240, }, - { t = "Snty.", x = 310, y = 40, }, - { t = "Throttle", x = 350, y = 80, }, - { t = "Min", x = 330, y = 120, }, - { t = "Hover", x = 310, y = 160, }, - { t = "Max", x = 330, y = 200, }, - }, - fieldLayout = { - { x = 260, y = 40, }, - { x = 260, y = 80, }, - { x = 260, y = 120, }, - { x = 260, y = 160, }, - { x = 260, y = 200, }, - { x = 260, y = 240, }, - { x = 400, y = 40, }, - { x = 400, y = 120, }, - { x = 400, y = 160, }, - { x = 400, y = 200, }, - }, -} \ No newline at end of file diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua b/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua deleted file mode 100644 index 175e8bf2..00000000 --- a/src/SCRIPTS/BF/LAYOUT/480x272/rx.lua +++ /dev/null @@ -1,18 +0,0 @@ -return { - labels = { - { t = "Stick Min", x = 36, y = 68 }, - { t = "Stick Mid", x = 36, y = 110 }, - { t = "Stick Max", x = 36, y = 155 }, - { t = "Cam Angle", x = 232, y = 68 }, - { t = "Interp", x = 232, y = 110 }, - { t = "Interp Int", x = 232, y = 155 }, - }, - fieldLayout = { - { x = 130, y = 68, }, - { x = 130, y = 110, }, - { x = 130, y = 155, }, - { x = 350, y = 68, }, - { x = 350, y = 110, }, - { x = 350, y = 155, }, - }, -} diff --git a/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua b/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua deleted file mode 100644 index b844b488..00000000 --- a/src/SCRIPTS/BF/LAYOUT/480x272/vtx.lua +++ /dev/null @@ -1,18 +0,0 @@ -return { - labels = { - { t = "Band", x = 36, y = 110 }, - { t = "Channel", x = 36, y = 155 }, - { t = "Power", x = 232, y = 110 }, - { t = "Pit", x = 232, y = 155 }, - { t = "Proto", x = 36, y = 68 }, - { t = "Freq", x = 232, y = 68 }, - }, - fieldLayout = { - { x = 130, y = 110, }, - { x = 130, y = 155, }, - { x = 350, y = 110, }, - { x = 350, y = 155, }, - { x = 130, y = 68, }, - { x = 350, y = 68, }, - }, -} \ No newline at end of file diff --git a/src/SCRIPTS/BF/PAGES/filters.lua b/src/SCRIPTS/BF/PAGES/filters.lua index 8b4d53fe..d3a195c5 100644 --- a/src/SCRIPTS/BF/PAGES/filters.lua +++ b/src/SCRIPTS/BF/PAGES/filters.lua @@ -1,35 +1,122 @@ -local display = assert(loadScript(radio.templateHome.."filters.lua"))() +local template = loadScript(radio.templateHome.."filters.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +if apiVersion >= 1.041 then + labels[#labels + 1] = { t = "Gyro Lowpass 1 Dynamic", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1000, vals = { 30, 31 } } + labels[#labels + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1000, vals = { 32, 33 } } + labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } } +end + +if apiVersion >= 1.016 then + labels[#labels + 1] = { t = "Gyro Lowpass 1", x = x, y = inc.y(lineSpacing) } + if apiVersion >= 1.039 then + labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 21, 22 } } + labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + else + labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 255, vals = { 1 } } + end +end + +if apiVersion >= 1.039 then + labels[#labels + 1] = { t = "Gyro Lowpass 2", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 23, 24 } } + labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } } +end + +if apiVersion >= 1.020 then + labels[#labels + 1] = { t = "Gyro Notch 1", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 6, 7 } } + labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 8, 9 } } +end + +if apiVersion >= 1.021 then + labels[#labels + 1] = { t = "Gyro Notch 2", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 14, 15 } } + labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 16, 17 } } +end + +if apiVersion >= 1.041 then + labels[#labels + 1] = { t = "D Term Lowpass 1 Dynamic", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1000, vals = { 34, 35 } } + labels[#labels + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1000, vals = { 36, 37 } } + labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } } +end + +if apiVersion >= 1.016 then + labels[#labels + 1] = { t = "D Term Lowpass 1", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 2, 3 } } + if apiVersion >= 1.036 and apiVersion <= 1.038 then + labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 2, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD", [2] = "FIR" } } + elseif apiVersion >= 1.039 then + labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + end +end + +if apiVersion >= 1.039 then + labels[#labels + 1] = { t = "D Term Lowpass 2", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 27, 28 } } + if apiVersion >= 1.041 then + labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + end +end + +if apiVersion >= 1.020 then + labels[#labels + 1] = { t = "D Term Notch", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 10, 11 } } + labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 12, 13 } } +end + +if apiVersion >= 1.016 then + labels[#labels + 1] = { t = "Yaw Lowpass", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 500, vals = { 4, 5 } } +end + return { - read = 92, -- MSP_FILTER_CONFIG - write = 93, -- MSP_SET_FILTER_CONFIG - eepromWrite = true, - reboot = false, - title = "Filters", - minBytes = 37, - outputBytes = 37, - labels = display.labels, - fieldLayout = display.fieldLayout, - fields = { - { min = 0, max = 1000, vals = { 30, 31 } }, - { min = 0, max = 1000, vals = { 32, 33 } }, - { min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { min = 0, max = 16000, vals = { 21, 22 } }, - { min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { min = 0, max = 16000, vals = { 23, 24 } }, - { min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { min = 0, max = 16000, vals = { 6, 7 } }, - { min = 0, max = 16000, vals = { 8, 9 } }, - { min = 0, max = 16000, vals = { 14, 15 } }, - { min = 0, max = 16000, vals = { 16, 17 } }, - { min = 0, max = 1000, vals = { 34, 35 } }, - { min = 0, max = 1000, vals = { 36, 37 } }, - { min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { min = 0, max = 16000, vals = { 2, 3 } }, - { min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { min = 0, max = 16000, vals = { 27, 28 } }, - { min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } }, - { min = 0, max = 16000, vals = { 10, 11 } }, - { min = 0, max = 16000, vals = { 12, 13 } }, - { min = 0, max = 500, vals = { 4, 5 } }, - }, -} \ No newline at end of file + read = 92, -- MSP_FILTER_CONFIG + write = 93, -- MSP_SET_FILTER_CONFIG + eepromWrite = true, + reboot = false, + title = "Filters", + minBytes = 5, + labels = labels, + fields = fields, +} diff --git a/src/SCRIPTS/BF/PAGES/gpspids.lua b/src/SCRIPTS/BF/PAGES/gpspids.lua index 0fbfabe4..dd6af065 100644 --- a/src/SCRIPTS/BF/PAGES/gpspids.lua +++ b/src/SCRIPTS/BF/PAGES/gpspids.lua @@ -1,21 +1,59 @@ -local display = assert(loadScript(radio.templateHome.."gpspids.lua"))() +local template = loadScript(radio.templateHome.."gpspids.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +if apiVersion >= 1.041 then + x = margin + y = yMinLim - tableSpacing.header + labels[#labels + 1] = { t = "", x = x, y = inc.y(tableSpacing.header) } + labels[#labels + 1] = { t = "Throttle", x = x, y = inc.y(tableSpacing.row) } + labels[#labels + 1] = { t = "Velocity", x = x, y = inc.y(tableSpacing.row) } + labels[#labels + 1] = { t = "Yaw", x = x, y = inc.y(tableSpacing.row) } + + x = x + tableSpacing.col*1.3 + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "P", x = x, y = inc.y(tableSpacing.header) } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 1, 2 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 7, 8 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 500, vals = { 13, 14 } } + + x = x + tableSpacing.col + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "I", x = x, y = inc.y(tableSpacing.header) } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 3, 4 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 9, 10 } } + + x = x + tableSpacing.col + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "D", x = x, y = inc.y(tableSpacing.header) } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 5, 6 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 11, 12 } } +end + return { - read = 136, -- MSP_GPS_RESCUE_PIDS - write = 226, -- MSP_SET_GPS_RESCUE_PIDS - title = "GPS Rescue / PIDs", - reboot = false, - eepromWrite = true, - minBytes = 14, - requiredVersion = 1.041, - labels = display.labels, - fieldLayout = display.fieldLayout, - fields = { - { min = 0, max = 200, vals = { 1,2 }, }, - { min = 0, max = 200, vals = { 7,8 }, }, - { min = 0, max = 500, vals = { 13,14 }, }, - { min = 0, max = 200, vals = { 3,4 }, }, - { min = 0, max = 200, vals = { 9,10 }, }, - { min = 0, max = 200, vals = { 5,6 }, }, - { min = 0, max = 200, vals = { 11,12 }, }, - }, -} \ No newline at end of file + read = 136, -- MSP_GPS_RESCUE_PIDS + write = 226, -- MSP_SET_GPS_RESCUE_PIDS + title = "GPS Rescue / PIDs", + reboot = false, + eepromWrite = true, + minBytes = 14, + labels = labels, + fields = fields, +} diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index fb23a25a..1c6d5aa7 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -1,25 +1,75 @@ -local display = assert(loadScript(radio.templateHome.."pid_advanced.lua"))() +local template = loadScript(radio.templateHome.."pid_advanced.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +if apiVersion >= 1.040 then + labels[#labels + 1] = { t = "Acro Trainer", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Angle Limit", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 20, max = 80, vals = { 32 } } + labels[#labels + 1] = { t = "Throttle Boost", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 31 } } + labels[#labels + 1] = { t = "Absolute Control", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 20, vals = { 30 } } + labels[#labels + 1] = { t = "I Term Rotation", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } } +end + +if apiVersion >= 1.016 then + labels[#labels + 1] = { t = "VBAT Compensation", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } } +end + +if apiVersion >= 1.040 and apiVersion <= 1.041 then + labels[#labels + 1] = { t = "Smart Feedforward", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 27 }, table = { [0] = "OFF", "ON" } } +end + +if apiVersion >= 1.040 then + labels[#labels + 1] = { t = "I Term Relax", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Axes", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } } + labels[#labels + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } } +end + +if apiVersion >= 1.041 then + labels[#labels + 1] = { t = "Integrated Yaw", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } } +end + +if apiVersion >= 1.036 then + labels[#labels + 1] = { t = "Anti Gravity", x = x, y = inc.y(lineSpacing) } + if apiVersion >= 1.040 then + labels[#labels + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } } + end + labels[#labels + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } + labels[#labels + 1] = { t = "Threshold", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 20,max = 1000, vals = { 20, 21 } } +end + return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PID Advanced", - reboot = false, - eepromWrite = true, - minBytes = 46, - outputBytes = 46, - labels = display.labels, - fieldLayout = display.fieldLayout, - fields = { - { min = 20, max = 80, vals = { 32 } }, - { min = 0, max = 100, vals = { 31 } }, - { min = 0, max = 20, vals = { 30 } }, - { min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } }, - { min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } }, - { min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } }, - { min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } }, - { min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } }, - { min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } }, - { min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 }, - { min = 20, max = 1000, vals = { 20, 21 } }, - } -} \ No newline at end of file + read = 94, -- MSP_PID_ADVANCED + write = 95, -- MSP_SET_PID_ADVANCED + title = "PID Advanced", + reboot = false, + eepromWrite = true, + minBytes = 8, + labels = labels, + fields = fields, +} diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua index 6a5fd4ba..b3e9830f 100644 --- a/src/SCRIPTS/BF/PAGES/pids1.lua +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -1,22 +1,64 @@ -local display = assert(loadScript(radio.templateHome.."pids1.lua"))() +local template = loadScript(radio.templateHome.."pids1.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +if apiVersion >= 1.016 then + x = margin + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "", x = x, y = inc.y(tableSpacing.header) } + labels[#labels + 1] = { t = "ROLL", x = x, y = inc.y(tableSpacing.row) } + labels[#labels + 1] = { t = "PITCH", x = x, y = inc.y(tableSpacing.row) } + labels[#labels + 1] = { t = "YAW", x = x, y = inc.y(tableSpacing.row) } + + x = x + tableSpacing.col + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "P", x = x, y = inc.y(tableSpacing.header) } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 1 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 4 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 7 } } + + x = x + tableSpacing.col + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "I", x = x, y = inc.y(tableSpacing.header) } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 2 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 5 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 8 } } + + x = x + tableSpacing.col + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "D", x = x, y = inc.y(tableSpacing.header) } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 3 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 6 } } + if apiVersion >= 1.041 then + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 9 } } + end +end + return { - read = 112, -- MSP_PID - write = 202, -- MSP_SET_PID - title = "PIDs (1/2)", - reboot = false, - eepromWrite = true, - minBytes = 9, - labels = display.labels, - fieldLayout = display.fieldLayout, - fields = { - { min = 0, max = 200, vals = { 1 }, }, - { min = 0, max = 200, vals = { 4 }, }, - { min = 0, max = 200, vals = { 7 }, }, - { min = 0, max = 200, vals = { 2 }, }, - { min = 0, max = 200, vals = { 5 }, }, - { min = 0, max = 200, vals = { 8 }, }, - { min = 0, max = 200, vals = { 3 }, }, - { min = 0, max = 200, vals = { 6 }, }, - { min = 0, max = 200, vals = { 9 }, }, - }, + read = 112, -- MSP_PID + write = 202, -- MSP_SET_PID + title = "PIDs (1/2)", + reboot = false, + eepromWrite = true, + minBytes = 9, + labels = labels, + fields = fields, } diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index 248dfd09..46cf7e2b 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -1,22 +1,87 @@ -local display = assert(loadScript(radio.templateHome.."pids2.lua"))() +local template = loadScript(radio.templateHome.."pids2.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +if apiVersion >= 1.040 then + x = margin + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "", x = x, y = inc.y(tableSpacing.header) } + labels[#labels + 1] = { t = "ROLL", x = x, y = inc.y(tableSpacing.row) } + labels[#labels + 1] = { t = "PITCH", x = x, y = inc.y(tableSpacing.row) } + labels[#labels + 1] = { t = "YAW", x = x, y = inc.y(tableSpacing.row) } + + x = x + tableSpacing.col + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "FF", x = x, y = inc.y(tableSpacing.header) } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 2000, vals = { 33, 34 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 2000, vals = { 35, 36 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 2000, vals = { 37, 38 } } + + if apiVersion >= 1.041 then + x = x + tableSpacing.col + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "D Min", x = x, y = inc.y(tableSpacing.header) } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 40 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 41 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 42 } } + end + + x = margin + y = inc.y(lineSpacing*0.4) +end + + + +if apiVersion >= 1.040 then + labels[#labels + 1] = { t = "Feedforward", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Transition", x = indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 9 }, scale = 100 } +end + +if apiVersion >= 1.041 then + labels[#labels + 1] = { t = "D Min", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Gain", x = indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 43 } } + labels[#labels + 1] = { t = "Advance", x = indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 200, vals = { 44 } } +end + +if apiVersion >= 1.021 and apiVersion <= 1.039 then + labels[#labels + 1] = { t = "Dterm Setpoint", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Weight", x = indent, y = inc.y(lineSpacing) } + if apiVersion >= 1.021 and apiVersion <= 1.038 then + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 254, vals = { 10 }, scale = 100 } + else + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 254, vals = { 25 }, scale = 100 } + end + labels[#labels + 1] = { t = "Transition", x = indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 9 }, scale = 100 } +end + return { - read = 94, -- MSP_PID_ADVANCED - write = 95, -- MSP_SET_PID_ADVANCED - title = "PIDs (2/2)", - reboot = false, - eepromWrite = true, - minBytes = 44, - labels = display.labels, - fieldLayout = display.fieldLayout, - fields = { - { min = 0, max = 2000, vals = { 33, 34 }, }, - { min = 0, max = 2000, vals = { 35, 36 }, }, - { min = 0, max = 2000, vals = { 37, 38 }, }, - { min = 0, max = 100, vals = { 40 }, }, - { min = 0, max = 100, vals = { 41 }, }, - { min = 0, max = 100, vals = { 42 }, }, - { min = 0, max = 100, vals = { 9 }, scale = 100 }, - { min = 0, max = 100, vals = { 43 }, }, - { min = 0, max = 200, vals = { 44 }, }, - }, + read = 94, -- MSP_PID_ADVANCED + write = 95, -- MSP_SET_PID_ADVANCED + title = "PIDs (2/2)", + reboot = false, + eepromWrite = true, + minBytes = 17, + labels = labels, + fields = fields, } diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index 72dfd2b9..d861f9d6 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -1,35 +1,82 @@ -local display = assert(loadScript(radio.templateHome.."pwm.lua"))() +local template = loadScript(radio.templateHome.."pwm.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +if apiVersion >= 1.031 and apiVersion <= 1.040 then + labels[#labels + 1] = { t = "32kHz Sampling", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end } +end + +if apiVersion >= 1.016 then + labels[#labels + 1] = { t = "Gyro Update", x = x, y = inc.y(lineSpacing)} + fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 32, vals = { 1 }, upd = function(self) self.updatePidRateTable(self) end } + labels[#labels + 1] = { t = "PID Loop", x = x, y = inc.y(lineSpacing)} + fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 16, vals = { 2 }, } + labels[#labels + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 9, vals = { 4 }, table = { [0] = "OFF", "OS125", "OS42", "MSHOT","BRSH", "DS150", "DS300", "DS600","DS1200", "PS1000" } } + labels[#labels + 1] = { t = "Unsynced PWM", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 3 }, table = { [0] = "OFF", "ON" } } + labels[#labels + 1] = { t = "PWM Frequency", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 200, max = 32000, vals = { 5, 6 }, } +end + +if apiVersion >= 1.031 then + labels[#labels + 1] = { t = "Idle Throttle %", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 2000, vals = { 7, 8 }, scale = 100 } +end + return { - read = 90, -- MSP_ADVANCED_CONFIG - write = 91, -- MSP_SET_ADVANCED_CONFIG - reboot = true, - eepromWrite = true, - title = "PWM", - minBytes = 9, - labels = display.labels, - fieldLayout = display.fieldLayout, - fields = { - { vals = { 9 }, min = 0, max = 1, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end }, - { vals = { 1 }, min = 1, max = 32, upd = function(self) self.updatePidRateTable(self) end }, - { vals = { 2 }, min = 1, max = 16, }, - { vals = { 4 }, min = 0, max = 9, table = { [0] = "OFF", "OS125", "OS42", "MSHOT","BRSH", "DS150", "DS300", "DS600","DS1200", "PS1000" } }, - { vals = { 3 }, min = 0, max = 1, table = { [0] = "OFF", "ON" } }, - { vals = { 5, 6 }, min = 200, max = 32000, }, - { vals = { 7, 8 }, min = 0, max = 2000, scale = 100 }, - }, + read = 90, -- MSP_ADVANCED_CONFIG + write = 91, -- MSP_SET_ADVANCED_CONFIG + reboot = true, + eepromWrite = true, + title = "PWM", + minBytes = 6, + labels = labels, + fields = fields, + getGyroDenomFieldIndex = function(self) + for i=1,#self.fields do + if self.fields[i].vals[1] == 1 then + return i + end + end + end, + getPidDenomFieldIndex = function(self) + for i=1,#self.fields do + if self.fields[i].vals[1] == 2 then + return i + end + end + end, calculateGyroRates = function(self, baseRate) self.gyroRates = {} - self.fields[2].table = {} + local idx = self.getGyroDenomFieldIndex(self) + self.fields[idx].table = {} for i=1, 32 do self.gyroRates[i] = baseRate/i local fmt = nil - self.fields[2].table[i] = string.format("%.2f",baseRate/i) + self.fields[idx].table[i] = string.format("%.2f",baseRate/i) end end, calculatePidRates = function(self, baseRate) - self.fields[3].table = {} + local idx = self.getPidDenomFieldIndex(self) + self.fields[idx].table = {} for i=1, 16 do - self.fields[3].table[i] = string.format("%.2f",baseRate/i) + self.fields[idx].table[i] = string.format("%.2f",baseRate/i) end end, updateRateTables = function(self) @@ -42,6 +89,7 @@ return { end end, updatePidRateTable = function(self) + self.updateRateTables(self) local newRateIdx = self.values[1] local newRate = self.gyroRates[newRateIdx] self.calculatePidRates(self, newRate) diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua index 96fa2b4d..8d0f600d 100644 --- a/src/SCRIPTS/BF/PAGES/rates.lua +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -1,28 +1,100 @@ -local display = assert(loadScript(radio.templateHome.."rates.lua"))() +local template = loadScript(radio.templateHome.."rates.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +if apiVersion >= 1.016 then + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "", x = x, y = inc.y(tableSpacing.header) } + labels[#labels + 1] = { t = "", x = x, y = inc.y(tableSpacing.header) } + labels[#labels + 1] = { t = "ROLL", x = x, y = inc.y(tableSpacing.row) } + labels[#labels + 1] = { t = "PITCH", x = x, y = inc.y(tableSpacing.row) } + labels[#labels + 1] = { t = "YAW", x = x, y = inc.y(tableSpacing.row) } + + x = x + tableSpacing.col + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "RC", x = x, y = inc.y(tableSpacing.header) } + labels[#labels + 1] = { t = "Rate", x = x, y = inc.y(tableSpacing.header) } + if apiVersion >= 1.037 then + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 255, vals = { 1 }, scale = 100 } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 255, vals = { 13 }, scale = 100 } + else + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row*1.5), min = 0, max = 255, vals = { 1 }, scale = 100 } + inc.y(tableSpacing.row*0.5) + end + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 255, vals = { 12 }, scale = 100 } + + x = x + tableSpacing.col + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "Super", x = x, y = inc.y(tableSpacing.header) } + labels[#labels + 1] = { t = "Rate", x = x, y = inc.y(tableSpacing.header) } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 3 }, scale = 100 } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 4 }, scale = 100 } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 255, vals = { 5 }, scale = 100 } + + x = x + tableSpacing.col + y = yMinLim - tableSpacing.header + + labels[#labels + 1] = { t = "RC", x = x, y = inc.y(tableSpacing.header) } + labels[#labels + 1] = { t = "Expo", x = x, y = inc.y(tableSpacing.header) } + if apiVersion >= 1.037 then + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 2 }, scale = 100 } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 14 }, scale = 100 } + else + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row*1.5), min = 0, max = 100, vals = { 2 }, scale = 100 } + inc.y(tableSpacing.row*0.5) + end + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 11 }, scale = 100 } + + x = margin + inc.y(lineSpacing*0.4) +end + +if apiVersion >= 1.016 then + labels[#labels + 1] = { t = "Throttle", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Mid", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 7 }, scale = 100 } + labels[#labels + 1] = { t = "Expo", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 8 }, scale = 100 } + if apiVersion >= 1.041 then + labels[#labels + 1] = { t = "Limit Type", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 2, vals = { 15 }, table = { [0] = "OFF", "SCALE", "CLIP" } } + labels[#labels + 1] = { t = "Limit %", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 25, max = 100, vals = { 16 } } + end +end + +if apiVersion >= 1.016 then + labels[#labels + 1] = { t = "TPA", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Rate", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 6 } , scale = 100 } + labels[#labels + 1] = { t = "Breakpoint", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 9, 10 } } +end + return { - read = 111, -- MSP_RC_TUNING - write = 204, -- MSP_SET_RC_TUNING - title = "Rates", - reboot = false, - eepromWrite = true, - minBytes = 16, - labels = display.labels, - fieldLayout = display.fieldLayout, - fields = { - { vals = { 1 }, min = 0, max = 255, scale = 100, }, - { vals = { 13 }, min = 0, max = 255, scale = 100, }, - { vals = { 12 }, min = 0, max = 255, scale = 100, }, - { vals = { 3 }, min = 0, max = 100, scale = 100, }, - { vals = { 4 }, min = 0, max = 100, scale = 100, }, - { vals = { 5 }, min = 0, max = 255, scale = 100, }, - { vals = { 2 }, min = 0, max = 100, scale = 100, }, - { vals = { 14 }, min = 0, max = 100, scale = 100, }, - { vals = { 11 }, min = 0, max = 100, scale = 100, }, - { vals = { 7 }, min = 0, max = 100, scale = 100, }, - { vals = { 8 }, min = 0, max = 100, scale = 100, }, - { vals = { 15 }, min = 0, max = 2, table = { [0] = "OFF", "SCALE", "CLIP" } }, - { vals = { 16 }, min = 25, max = 100, }, - { vals = { 6 } , min = 0, max = 100, scale = 100, }, - { vals = { 9, 10 }, min = 1000, max = 2000, }, - }, + read = 111, -- MSP_RC_TUNING + write = 204, -- MSP_SET_RC_TUNING + title = "Rates", + reboot = false, + eepromWrite = true, + minBytes = 12, + labels = labels, + fields = fields, } diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index 809693a7..718c83ac 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -1,24 +1,56 @@ -local display = assert(loadScript(radio.templateHome.."rescue.lua"))() +local template = loadScript(radio.templateHome.."rescue.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +if apiVersion >= 1.041 then + labels[#labels + 1] = { t = "Min Sats.", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 50, vals = { 16 } } + labels[#labels + 1] = { t = "Angle", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 200, vals = { 1, 2 } } + labels[#labels + 1] = { t = "Initial Altitude", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 20, max = 100, vals = { 3, 4 } } + labels[#labels + 1] = { t = "Descent Distance", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 30, max = 500, vals = { 5, 6 } } + labels[#labels + 1] = { t = "Ground Speed", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 30, max = 3000, vals = { 7, 8 } } + + if apiVersion >= 1.043 then + labels[#labels + 1] = { t = "Arm w/o fix", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 21 }, table = { [0]="OFF","ON"} } + end + + labels[#labels + 1] = { t = "Sanity Check", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 2, vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"} } + labels[#labels + 1] = { t = "Throttle", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Min", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 9, 10 } } + labels[#labels + 1] = { t = "Hover", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 13, 14 } } + labels[#labels + 1] = { t = "Max", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 11, 12 } } +end + return { - read = 135, -- MSP_GPS_RESCUE - write = 225, -- MSP_SET_GPS_RESCUE - title = "GPS Rescue", - reboot = false, - eepromWrite = true, - minBytes = 16, - requiredVersion = 1.041, - labels = display.labels, - fieldLayout = display.fieldLayout, - fields = { - { min = 0, max = 50, vals = { 16 }, }, - { min = 0, max = 200, vals = { 1,2 }, }, - { min = 20, max = 100, vals = { 3,4 }, }, - { min = 30, max = 500, vals = { 5,6 }, }, - { min = 30, max = 3000, vals = { 7,8 }, }, - { min = 0, max = 1, vals = { 21 }, table = { [0]="OFF","ON"}, }, - { min = 0, max = 2, vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"}, }, - { min = 1000, max = 2000, vals = { 9,10 }, }, - { min = 1000, max = 2000, vals = { 13,14 }, }, - { min = 1000, max = 2000, vals = { 11,12 }, }, - }, + read = 135, -- MSP_GPS_RESCUE + write = 225, -- MSP_SET_GPS_RESCUE + title = "GPS Rescue", + reboot = false, + eepromWrite = true, + minBytes = 16, + labels = labels, + fields = fields, } diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index 6323f104..75286661 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -1,19 +1,50 @@ -local display = assert(loadScript(radio.templateHome.."rx.lua"))() +local template = loadScript(radio.templateHome.."rx.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +if apiVersion >= 1.016 then + labels[#labels + 1] = { t = "Stick", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Low", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 6, 7 } } + labels[#labels + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 4, 5 } } + labels[#labels + 1] = { t = "High", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 2, 3 } } +end + +if apiVersion >= 1.020 then + labels[#labels + 1] = { t = "Interp", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} } + labels[#labels + 1] = { t = "Interp Int", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 50, vals = { 14 } } +end + +if apiVersion >= 1.031 then + labels[#labels + 1] = { t = "Cam Angle", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 90, vals = { 23 } } +end + return { - read = 44, -- MSP_RX_CONFIG - write = 45, -- MSP_SET_RX_CONFIG - title = "RX", - reboot = false, - eepromWrite = true, - minBytes = 23, - labels = display.labels, - fieldLayout = display.fieldLayout, - fields = { - { min = 1000, max = 2000, vals = { 6, 7 }, }, - { min = 1000, max = 2000, vals = { 4, 5 }, }, - { min = 1000, max = 2000, vals = { 2, 3 }, }, - { min = 0, max = 90, vals = { 23 }, }, - { min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} }, - { min = 1, max = 50, vals = { 14 }, } - }, + read = 44, -- MSP_RX_CONFIG + write = 45, -- MSP_SET_RX_CONFIG + title = "RX", + reboot = false, + eepromWrite = true, + minBytes = 12, + labels = labels, + fields = fields, } diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index afa8c8a7..1f2d8da0 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -1,4 +1,3 @@ -local display = assert(loadScript(radio.templateHome.."vtx.lua"))() local md = model.getInfo(); local vtx_tables = loadScript("/BF/VTX/"..md.name..".lua") if vtx_tables then @@ -8,6 +7,41 @@ else end local deviceTable = { [1]="6705", [3]="SA", [4]="Tramp", [255]="None" } local pitModeTable = { [0]="OFF", "ON" } +local template = loadScript(radio.templateHome.."vtx.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +if apiVersion >= 1.036 then + labels[#labels + 1] = { t = "Band", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min=0, max=#(vtx_tables.bandTable), vals = { 2 }, table = vtx_tables.bandTable, upd = function(self) self.handleBandChanUpdate(self) end } + labels[#labels + 1] = { t = "Channel", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min=1, max=vtx_tables.frequenciesPerBand, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end } + labels[#labels + 1] = { t = "Power", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end } + labels[#labels + 1] = { t = "Pit Mode", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min=0, max=#(pitModeTable), vals = { 5 }, table = pitModeTable } + labels[#labels + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, vals = { 1 }, write = false, ro = true, table = deviceTable } +end + +if apiVersion >= 1.037 then + labels[#labels + 1] = { t = "Frequency", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end } +end -- Vals Fields -- 1 Device Type Band @@ -29,16 +63,8 @@ return { prevFreqVal = 0, lastFreqUpdTS = 0, freqModCounter = 0, - labels = display.labels, - fieldLayout = display.fieldLayout, - fields = { - { min=0, max=#(vtx_tables.bandTable), vals = { 2 }, table = vtx_tables.bandTable, upd = function(self) self.handleBandChanUpdate(self) end }, - { min=1, max=vtx_tables.frequenciesPerBand, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end }, - { min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end }, - { min=0, max=#(pitModeTable), vals = { 5 }, table = pitModeTable }, - { vals = { 1 }, write = false, ro = true, table = deviceTable }, - { min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end }, - }, + labels = labels, + fields = fields, freqLookup = vtx_tables.frequencyTable, postLoad = function (self) if (self.values[2] or 0) < 0 or (self.values[3] or 0) == 0 or (self.values[4] or 0) == 0 then diff --git a/src/SCRIPTS/BF/TEMPLATES/128x64/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/128x64/default_template.lua new file mode 100644 index 00000000..76e110f0 --- /dev/null +++ b/src/SCRIPTS/BF/TEMPLATES/128x64/default_template.lua @@ -0,0 +1,7 @@ +return { + margin = 2, + indent = 6, + lineSpacing = 8, + listSpacing = { line = 8, field = 88 }, + tableSpacing = { row = 10, col = 30, header = 8 }, +} diff --git a/src/SCRIPTS/BF/TEMPLATES/212x64/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/212x64/default_template.lua new file mode 100644 index 00000000..76e110f0 --- /dev/null +++ b/src/SCRIPTS/BF/TEMPLATES/212x64/default_template.lua @@ -0,0 +1,7 @@ +return { + margin = 2, + indent = 6, + lineSpacing = 8, + listSpacing = { line = 8, field = 88 }, + tableSpacing = { row = 10, col = 30, header = 8 }, +} diff --git a/src/SCRIPTS/BF/TEMPLATES/320x480/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/320x480/default_template.lua new file mode 100644 index 00000000..74213779 --- /dev/null +++ b/src/SCRIPTS/BF/TEMPLATES/320x480/default_template.lua @@ -0,0 +1,7 @@ +return { + margin = 5, + indent = 15, + lineSpacing = 20, + listSpacing = { line = 20, field = 170 }, + tableSpacing = { row = 25, col = 60, header = 20 }, +} diff --git a/src/SCRIPTS/BF/TEMPLATES/480x272/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/480x272/default_template.lua new file mode 100644 index 00000000..74213779 --- /dev/null +++ b/src/SCRIPTS/BF/TEMPLATES/480x272/default_template.lua @@ -0,0 +1,7 @@ +return { + margin = 5, + indent = 15, + lineSpacing = 20, + listSpacing = { line = 20, field = 170 }, + tableSpacing = { row = 25, col = 60, header = 20 }, +} diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index ef003801..fe266b03 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -1,13 +1,43 @@ -PageFiles = -{ - { title = "VTX Settings", script = "vtx.lua" }, - { title = "PIDs 1", script = "pids1.lua" }, - { title = "PIDs 2", script = "pids2.lua" }, - { title = "Rates", script = "rates.lua" }, - { title = "Advanced PIDs", script = "pid_advanced.lua" }, - { title = "Filters", script = "filters.lua" }, - { title = "Gyro / Motor", script = "pwm.lua" }, - { title = "Receiver", script = "rx.lua" }, - { title = "GPS Rescue", script = "rescue.lua", requiredVersion = 1.041 }, - { title = "GPS PIDs", script = "gpspids.lua", requiredVersion = 1.041 }, -} \ No newline at end of file +local PageFiles = {} + +if apiVersion >= 1.036 then + PageFiles[#PageFiles + 1] = { title = "VTX Settings", script = "vtx.lua" } +end + +if apiVersion >= 1.016 then + PageFiles[#PageFiles + 1] = { title = "PIDs 1", script = "pids1.lua" } +end + +if apiVersion >= 1.021 then + PageFiles[#PageFiles + 1] = { title = "PIDs 2", script = "pids2.lua" } +end + +if apiVersion >= 1.016 then + PageFiles[#PageFiles + 1] = { title = "Rates", script = "rates.lua" } +end + +if apiVersion >= 1.016 then + PageFiles[#PageFiles + 1] = { title = "Advanced PIDs", script = "pid_advanced.lua" } +end + +if apiVersion >= 1.016 then + PageFiles[#PageFiles + 1] = { title = "Filters", script = "filters.lua" } +end + +if apiVersion >= 1.016 then + PageFiles[#PageFiles + 1] = { title = "Gyro / Motor", script = "pwm.lua" } +end + +if apiVersion >= 1.016 then + PageFiles[#PageFiles + 1] = { title = "Receiver", script = "rx.lua" } +end + +if apiVersion >= 1.041 then + PageFiles[#PageFiles + 1] = { title = "GPS Rescue", script = "rescue.lua" } +end + +if apiVersion >= 1.041 then + PageFiles[#PageFiles + 1] = { title = "GPS PIDs", script = "gpspids.lua" } +end + +return PageFiles diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index dc272436..e571a853 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -8,7 +8,7 @@ local supportedRadios = { ["128x64"] = { - templateHome = SCRIPT_HOME.."/LAYOUT/128x64/", + templateHome = SCRIPT_HOME.."/TEMPLATES/128x64/", resolution = lcdResolution.low, MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, @@ -19,7 +19,7 @@ local supportedRadios = }, ["212x64"] = { - templateHome = SCRIPT_HOME.."/LAYOUT/212x64/", + templateHome = SCRIPT_HOME.."/TEMPLATES/212x64/", resolution = lcdResolution.low, MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 }, SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, @@ -30,25 +30,25 @@ local supportedRadios = }, ["480x272"] = { - templateHome = SCRIPT_HOME.."/LAYOUT/480x272/", + templateHome = SCRIPT_HOME.."/TEMPLATES/480x272/", resolution = lcdResolution.high, MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, NoTelem = { 192, LCD_H - 28, "No Telemetry", BLINK }, textSize = 0, yMinLimit = 35, - yMaxLimit = 215, + yMaxLimit = 235, }, ["320x480"] = { - templateHome = SCRIPT_HOME.."/LAYOUT/320x480/", + templateHome = SCRIPT_HOME.."/TEMPLATES/320x480/", resolution = lcdResolution.high, MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", BLINK }, textSize = 0, yMinLimit = 35, - yMaxLimit = 215, + yMaxLimit = 235, }, } diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 8a6fd7e3..0567af01 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -19,8 +19,6 @@ local uiMsp = eepromWrite = 250 } -local menuLine = 1 -local pageCount = 1 local uiState = uiStatus.init local pageState = pageStatus.display local requestTimeout = 80 -- 800ms request timeout @@ -36,7 +34,7 @@ local killEnterBreak = 0 local stopDisplay = false local pageScrollY = 0 local mainMenuScrollY = 0 - +local PageFiles = nil local Page = nil local background = nil @@ -45,15 +43,6 @@ local foregroundColor = LINE_COLOR or SOLID local globalTextOptions = TEXT_COLOR or 0 -local function getPageCount() - pageCount = 0 - for i=1,#(PageFiles) do - if (not PageFiles[i].requiredVersion) or (apiVersion == 0) or (apiVersion > 0 and PageFiles[i].requiredVersion <= apiVersion) then - pageCount = pageCount + 1 - end - end -end - local function saveSettings(new) if Page.values then local payload = {} @@ -167,7 +156,6 @@ local function incPage(inc) currentPage = incMax(currentPage, inc, #(PageFiles)) Page = nil currentField = 1 - menuLine = currentPage collectgarbage() end @@ -176,7 +164,7 @@ local function incLine(inc) end local function incMainMenu(inc) - menuLine = clipValue(menuLine + inc, 1, pageCount) + currentPage = clipValue(currentPage + inc, 1, #PageFiles) end local function incPopupMenu(inc) @@ -203,10 +191,11 @@ end local function drawScreen() local yMinLim = radio.yMinLimit or 0 local yMaxLim = radio.yMaxLimit or LCD_H - local currentFieldY = Page.fieldLayout[currentField].y - local screen_title = Page.title - drawScreenTitle("Betaflight / "..screen_title) - if currentFieldY <= Page.fieldLayout[1].y then + local currentFieldY = Page.fields[currentField].y + local screenTitle = Page.title + local textOptions = radio.textSize + globalTextOptions + drawScreenTitle("Betaflight / "..screenTitle) + if currentFieldY <= Page.fields[1].y then pageScrollY = 0 elseif currentFieldY - pageScrollY <= yMinLim then pageScrollY = currentFieldY - yMinLim @@ -215,7 +204,6 @@ local function drawScreen() end for i=1,#(Page.labels) do local f = Page.labels[i] - local textOptions = radio.textSize + globalTextOptions if (f.y - pageScrollY) >= yMinLim and (f.y - pageScrollY) <= yMaxLim then lcd.drawText(f.x, f.y - pageScrollY, f.t, textOptions) end @@ -223,13 +211,11 @@ local function drawScreen() local val = "---" for i=1,#(Page.fields) do local f = Page.fields[i] - local pos = Page.fieldLayout[i] - local text_options = radio.textSize + globalTextOptions - local value_options = text_options + local valueOptions = textOptions if i == currentField then - value_options = text_options + INVERS + valueOptions = valueOptions + INVERS if pageState == pageStatus.editing then - value_options = value_options + BLINK + valueOptions = valueOptions + BLINK end end if f.value then @@ -241,8 +227,8 @@ local function drawScreen() val = f.table[f.value] end end - if (pos.y - pageScrollY) >= yMinLim and (pos.y - pageScrollY) <= yMaxLim then - lcd.drawText(pos.x, pos.y - pageScrollY, val, value_options) + if (f.y - pageScrollY) >= yMinLim and (f.y - pageScrollY) <= yMaxLim then + lcd.drawText(f.x, f.y - pageScrollY, val, valueOptions) end end end @@ -315,6 +301,7 @@ function run_ui(event) return 0 else background = nil + PageFiles = assert(loadScript("/SCRIPTS/BF/pages.lua"))() invalidatePages() if isTelemetryScript then uiState = uiStatus.pages @@ -323,7 +310,6 @@ function run_ui(event) end end elseif uiState == uiStatus.mainMenu then - getPageCount() if event == EVT_VIRTUAL_EXIT then return 2 elseif event == EVT_VIRTUAL_NEXT then @@ -340,25 +326,23 @@ function run_ui(event) lineSpacing = 25 end for i=1, #PageFiles do - if (not PageFiles[i].requiredVersion) or (apiVersion == 0) or (apiVersion > 0 and PageFiles[i].requiredVersion <= apiVersion) then - local currentFieldY = (menuLine-1)*lineSpacing + yMinLim - if currentFieldY <= yMinLim then - mainMenuScrollY = 0 - elseif currentFieldY - mainMenuScrollY <= yMinLim then - mainMenuScrollY = currentFieldY - yMinLim - elseif currentFieldY - mainMenuScrollY >= yMaxLim then - mainMenuScrollY = currentFieldY - yMaxLim - end - local attr = (menuLine == i and INVERS or 0) - if event == EVT_VIRTUAL_ENTER and attr == INVERS then - invalidatePages() - currentPage = i - pageState = pageStatus.display - uiState = uiStatus.pages - end - if ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) >= yMinLim and ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) <= yMaxLim then - lcd.drawText(6, (i-1)*lineSpacing + yMinLim - mainMenuScrollY, PageFiles[i].title, attr) - end + local currentFieldY = (currentPage-1)*lineSpacing + yMinLim + if currentFieldY <= yMinLim then + mainMenuScrollY = 0 + elseif currentFieldY - mainMenuScrollY <= yMinLim then + mainMenuScrollY = currentFieldY - yMinLim + elseif currentFieldY - mainMenuScrollY >= yMaxLim then + mainMenuScrollY = currentFieldY - yMaxLim + end + local attr = (currentPage == i and INVERS or 0) + if event == EVT_VIRTUAL_ENTER and attr == INVERS then + invalidatePages() + currentPage = i + pageState = pageStatus.display + uiState = uiStatus.pages + end + if ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) >= yMinLim and ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) <= yMaxLim then + lcd.drawText(6, (i-1)*lineSpacing + yMinLim - mainMenuScrollY, PageFiles[i].title, attr) end end elseif uiState == uiStatus.pages then @@ -433,17 +417,14 @@ function run_ui(event) incValue(-1) end end - local nextPage = currentPage - while Page == nil do - Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[currentPage].script))() - if Page.requiredVersion and apiVersion > 0 and Page.requiredVersion > apiVersion then - incPage(1) - if currentPage == nextPage then - lcd.clear() - lcd.drawText(radio.NoTelem[1], radio.NoTelem[2], "No Pages! API: " .. apiVersion, radio.NoTelem[4]) - return 1 - end + if Page == nil then + if #PageFiles == 0 then + lcd.clear() + lcd.drawText(radio.NoTelem[1], radio.NoTelem[2], "No Pages! API: " .. apiVersion, radio.NoTelem[4]) + return 1 end + Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[currentPage].script))() + collectgarbage() end if not Page.values and pageState == pageStatus.display then requestPage() From 860093783dd677384ad8a81947f316918f999e50 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 28 Nov 2019 23:22:29 +0100 Subject: [PATCH 054/193] Make PWM page functions more efficient --- src/SCRIPTS/BF/PAGES/pwm.lua | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index d861f9d6..3a025fb0 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -23,9 +23,9 @@ end if apiVersion >= 1.016 then labels[#labels + 1] = { t = "Gyro Update", x = x, y = inc.y(lineSpacing)} - fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 32, vals = { 1 }, upd = function(self) self.updatePidRateTable(self) end } + fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end } labels[#labels + 1] = { t = "PID Loop", x = x, y = inc.y(lineSpacing)} - fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 16, vals = { 2 }, } + fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 16, vals = { 2 }, table = {} } labels[#labels + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 9, vals = { 4 }, table = { [0] = "OFF", "OS125", "OS42", "MSHOT","BRSH", "DS150", "DS300", "DS600","DS1200", "PS1000" } } labels[#labels + 1] = { t = "Unsynced PWM", x = x, y = inc.y(lineSpacing) } @@ -48,6 +48,7 @@ return { minBytes = 6, labels = labels, fields = fields, + gyroRates = {}, getGyroDenomFieldIndex = function(self) for i=1,#self.fields do if self.fields[i].vals[1] == 1 then @@ -63,18 +64,14 @@ return { end end, calculateGyroRates = function(self, baseRate) - self.gyroRates = {} local idx = self.getGyroDenomFieldIndex(self) - self.fields[idx].table = {} for i=1, 32 do self.gyroRates[i] = baseRate/i - local fmt = nil self.fields[idx].table[i] = string.format("%.2f",baseRate/i) end end, calculatePidRates = function(self, baseRate) local idx = self.getPidDenomFieldIndex(self) - self.fields[idx].table = {} for i=1, 16 do self.fields[idx].table[i] = string.format("%.2f",baseRate/i) end From 1090cd53289e1b001db78cd10a93a02bfd18f95b Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 29 Nov 2019 21:17:31 +0100 Subject: [PATCH 055/193] Add RPM filter and dynamic notch --- .../BF/PAGES/{filters.lua => filters1.lua} | 4 +- src/SCRIPTS/BF/PAGES/filters2.lua | 45 +++++++++++++++++++ src/SCRIPTS/BF/pages.lua | 6 ++- 3 files changed, 52 insertions(+), 3 deletions(-) rename src/SCRIPTS/BF/PAGES/{filters.lua => filters1.lua} (98%) create mode 100644 src/SCRIPTS/BF/PAGES/filters2.lua diff --git a/src/SCRIPTS/BF/PAGES/filters.lua b/src/SCRIPTS/BF/PAGES/filters1.lua similarity index 98% rename from src/SCRIPTS/BF/PAGES/filters.lua rename to src/SCRIPTS/BF/PAGES/filters1.lua index d3a195c5..8b8a9adc 100644 --- a/src/SCRIPTS/BF/PAGES/filters.lua +++ b/src/SCRIPTS/BF/PAGES/filters1.lua @@ -1,4 +1,4 @@ -local template = loadScript(radio.templateHome.."filters.lua") +local template = loadScript(radio.templateHome.."filters1.lua") if template then template = template() else @@ -115,7 +115,7 @@ return { write = 93, -- MSP_SET_FILTER_CONFIG eepromWrite = true, reboot = false, - title = "Filters", + title = "Filters (1/2)", minBytes = 5, labels = labels, fields = fields, diff --git a/src/SCRIPTS/BF/PAGES/filters2.lua b/src/SCRIPTS/BF/PAGES/filters2.lua new file mode 100644 index 00000000..bc67b75a --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/filters2.lua @@ -0,0 +1,45 @@ +local template = loadScript(radio.templateHome.."filters2.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +if apiVersion >= 1.042 then + labels[#labels + 1] = { t = "Gyro RPM Filter", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Harmonics", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 3, vals = { 44 } } + labels[#labels + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 50, max = 200, vals = { 45 } } + labels[#labels + 1] = { t = "Dynamic Notch Filter", x = x, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Range", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 3, vals = { 38 }, table = { [0]="HIGH", "MEDIUM", "LOW", "AUTO" } } + labels[#labels + 1] = { t = "Width %", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 20, vals = { 39 } } + labels[#labels + 1] = { t = "Q", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 1000, vals = { 40, 41 } } + labels[#labels + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 60, max = 1000, vals = { 42, 43 } } +end + +return { + read = 92, -- MSP_FILTER_CONFIG + write = 93, -- MSP_SET_FILTER_CONFIG + eepromWrite = true, + reboot = false, + title = "Filters (2/2)", + minBytes = 5, + labels = labels, + fields = fields, +} diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index fe266b03..2fcdf6f8 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -21,7 +21,11 @@ if apiVersion >= 1.016 then end if apiVersion >= 1.016 then - PageFiles[#PageFiles + 1] = { title = "Filters", script = "filters.lua" } + PageFiles[#PageFiles + 1] = { title = "Filters 1", script = "filters1.lua" } +end + +if apiVersion >= 1.042 then + PageFiles[#PageFiles + 1] = { title = "Filters 2", script = "filters2.lua" } end if apiVersion >= 1.016 then From a2a61527e2301184e207f389bfdd18ed6685c1fe Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 29 Nov 2019 21:19:23 +0100 Subject: [PATCH 056/193] Add I Term Relax cutoff --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 1c6d5aa7..471062ba 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -44,6 +44,10 @@ if apiVersion >= 1.040 then fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } } labels[#labels + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing) } fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } } + if apiVersion >= 1.042 then + labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 100, vals = { 47 } } + end end if apiVersion >= 1.041 then From 5fff82b637269de0021df72b108ad66c3634ca28 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 3 Dec 2019 21:44:38 +0100 Subject: [PATCH 057/193] Allow text for fields --- src/SCRIPTS/BF/PAGES/filters1.lua | 69 +++++++++------------------ src/SCRIPTS/BF/PAGES/filters2.lua | 18 +++---- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 39 +++++---------- src/SCRIPTS/BF/PAGES/pids2.lua | 23 ++++----- src/SCRIPTS/BF/PAGES/pwm.lua | 21 +++----- src/SCRIPTS/BF/PAGES/rates.lua | 18 +++---- src/SCRIPTS/BF/PAGES/rescue.lua | 30 ++++-------- src/SCRIPTS/BF/PAGES/rx.lua | 18 +++---- src/SCRIPTS/BF/PAGES/vtx.lua | 18 +++---- src/SCRIPTS/BF/ui.lua | 5 +- 10 files changed, 90 insertions(+), 169 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/filters1.lua b/src/SCRIPTS/BF/PAGES/filters1.lua index 8b8a9adc..d7eb5937 100644 --- a/src/SCRIPTS/BF/PAGES/filters1.lua +++ b/src/SCRIPTS/BF/PAGES/filters1.lua @@ -18,96 +18,73 @@ local fields = {} if apiVersion >= 1.041 then labels[#labels + 1] = { t = "Gyro Lowpass 1 Dynamic", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1000, vals = { 30, 31 } } - labels[#labels + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1000, vals = { 32, 33 } } - labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 30, 31 } } + fields[#fields + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 32, 33 } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } } end if apiVersion >= 1.016 then labels[#labels + 1] = { t = "Gyro Lowpass 1", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.039 then - labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 21, 22 } } - labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 21, 22 } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } } else - labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 255, vals = { 1 } } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 1 } } end end if apiVersion >= 1.039 then labels[#labels + 1] = { t = "Gyro Lowpass 2", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 23, 24 } } - labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 23, 24 } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } } end if apiVersion >= 1.020 then labels[#labels + 1] = { t = "Gyro Notch 1", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 6, 7 } } - labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 8, 9 } } + fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 6, 7 } } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 8, 9 } } end if apiVersion >= 1.021 then labels[#labels + 1] = { t = "Gyro Notch 2", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 14, 15 } } - labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 16, 17 } } + fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 14, 15 } } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 16, 17 } } end if apiVersion >= 1.041 then labels[#labels + 1] = { t = "D Term Lowpass 1 Dynamic", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1000, vals = { 34, 35 } } - labels[#labels + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1000, vals = { 36, 37 } } - labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 34, 35 } } + fields[#fields + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 36, 37 } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } } end if apiVersion >= 1.016 then labels[#labels + 1] = { t = "D Term Lowpass 1", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 2, 3 } } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 2, 3 } } if apiVersion >= 1.036 and apiVersion <= 1.038 then - labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 2, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD", [2] = "FIR" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD", [2] = "FIR" } } elseif apiVersion >= 1.039 then - labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } } end end if apiVersion >= 1.039 then labels[#labels + 1] = { t = "D Term Lowpass 2", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 27, 28 } } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 27, 28 } } if apiVersion >= 1.041 then - labels[#labels + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } } end end if apiVersion >= 1.020 then labels[#labels + 1] = { t = "D Term Notch", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 10, 11 } } - labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 16000, vals = { 12, 13 } } + fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 10, 11 } } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 12, 13 } } end if apiVersion >= 1.016 then labels[#labels + 1] = { t = "Yaw Lowpass", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 500, vals = { 4, 5 } } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 4, 5 } } end return { diff --git a/src/SCRIPTS/BF/PAGES/filters2.lua b/src/SCRIPTS/BF/PAGES/filters2.lua index bc67b75a..20042605 100644 --- a/src/SCRIPTS/BF/PAGES/filters2.lua +++ b/src/SCRIPTS/BF/PAGES/filters2.lua @@ -18,19 +18,13 @@ local fields = {} if apiVersion >= 1.042 then labels[#labels + 1] = { t = "Gyro RPM Filter", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Harmonics", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 3, vals = { 44 } } - labels[#labels + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 50, max = 200, vals = { 45 } } + fields[#fields + 1] = { t = "Harmonics", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 44 } } + fields[#fields + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 45 } } labels[#labels + 1] = { t = "Dynamic Notch Filter", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Range", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 3, vals = { 38 }, table = { [0]="HIGH", "MEDIUM", "LOW", "AUTO" } } - labels[#labels + 1] = { t = "Width %", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 20, vals = { 39 } } - labels[#labels + 1] = { t = "Q", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 1000, vals = { 40, 41 } } - labels[#labels + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 60, max = 1000, vals = { 42, 43 } } + fields[#fields + 1] = { t = "Range", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 38 }, table = { [0]="HIGH", "MEDIUM", "LOW", "AUTO" } } + fields[#fields + 1] = { t = "Width %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 39 } } + fields[#fields + 1] = { t = "Q", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 1000, vals = { 40, 41 } } + fields[#fields + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 60, max = 1000, vals = { 42, 43 } } end return { diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 471062ba..0bc820eb 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -18,53 +18,40 @@ local fields = {} if apiVersion >= 1.040 then labels[#labels + 1] = { t = "Acro Trainer", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Angle Limit", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 20, max = 80, vals = { 32 } } - labels[#labels + 1] = { t = "Throttle Boost", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 31 } } - labels[#labels + 1] = { t = "Absolute Control", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 20, vals = { 30 } } - labels[#labels + 1] = { t = "I Term Rotation", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } } + fields[#fields + 1] = { t = "Angle Limit", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 80, vals = { 32 } } + fields[#fields + 1] = { t = "Throttle Boost", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 31 } } + fields[#fields + 1] = { t = "Absolute Control", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 30 } } + fields[#fields + 1] = { t = "I Term Rotation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } } end if apiVersion >= 1.016 then - labels[#labels + 1] = { t = "VBAT Compensation", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } } + fields[#fields + 1] = { t = "VBAT Compensation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } } end if apiVersion >= 1.040 and apiVersion <= 1.041 then - labels[#labels + 1] = { t = "Smart Feedforward", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 27 }, table = { [0] = "OFF", "ON" } } + fields[#fields + 1] = { t = "Smart Feedforward", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 27 }, table = { [0] = "OFF", "ON" } } end if apiVersion >= 1.040 then labels[#labels + 1] = { t = "I Term Relax", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Axes", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } } - labels[#labels + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } } + fields[#fields + 1] = { t = "Axes", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } } + fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } } if apiVersion >= 1.042 then - labels[#labels + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 100, vals = { 47 } } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 100, vals = { 47 } } end end if apiVersion >= 1.041 then - labels[#labels + 1] = { t = "Integrated Yaw", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } } + fields[#fields + 1] = { t = "Integrated Yaw", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } } end if apiVersion >= 1.036 then labels[#labels + 1] = { t = "Anti Gravity", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.040 then - labels[#labels + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } } + fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } } end - labels[#labels + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } - labels[#labels + 1] = { t = "Threshold", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 20,max = 1000, vals = { 20, 21 } } + fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } + fields[#fields + 1] = { t = "Threshold", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 20,max = 1000, vals = { 20, 21 } } end return { diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index 46cf7e2b..b4c3a68d 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -50,29 +50,24 @@ end if apiVersion >= 1.040 then - labels[#labels + 1] = { t = "Feedforward", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Transition", x = indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 9 }, scale = 100 } + labels[#labels + 1] = { t = "Feedforward", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Transition", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 9 }, scale = 100 } end if apiVersion >= 1.041 then - labels[#labels + 1] = { t = "D Min", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Gain", x = indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 43 } } - labels[#labels + 1] = { t = "Advance", x = indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 200, vals = { 44 } } + labels[#labels + 1] = { t = "D Min", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 43 } } + fields[#fields + 1] = { t = "Advance", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 44 } } end if apiVersion >= 1.021 and apiVersion <= 1.039 then - labels[#labels + 1] = { t = "Dterm Setpoint", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Weight", x = indent, y = inc.y(lineSpacing) } + labels[#labels + 1] = { t = "Dterm Setpoint", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.021 and apiVersion <= 1.038 then - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 254, vals = { 10 }, scale = 100 } + fields[#fields + 1] = { t = "Weight", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 254, vals = { 10 }, scale = 100 } else - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 254, vals = { 25 }, scale = 100 } + fields[#fields + 1] = { t = "Weight", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 254, vals = { 25 }, scale = 100 } end - labels[#labels + 1] = { t = "Transition", x = indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 9 }, scale = 100 } + fields[#fields + 1] = { t = "Transition", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 9 }, scale = 100 } end return { diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index 3a025fb0..b3ee5c67 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -17,26 +17,19 @@ local labels = {} local fields = {} if apiVersion >= 1.031 and apiVersion <= 1.040 then - labels[#labels + 1] = { t = "32kHz Sampling", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end } + fields[#fields + 1] = { t = "32kHz Sampling", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end } end if apiVersion >= 1.016 then - labels[#labels + 1] = { t = "Gyro Update", x = x, y = inc.y(lineSpacing)} - fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end } - labels[#labels + 1] = { t = "PID Loop", x = x, y = inc.y(lineSpacing)} - fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 16, vals = { 2 }, table = {} } - labels[#labels + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 9, vals = { 4 }, table = { [0] = "OFF", "OS125", "OS42", "MSHOT","BRSH", "DS150", "DS300", "DS600","DS1200", "PS1000" } } - labels[#labels + 1] = { t = "Unsynced PWM", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 3 }, table = { [0] = "OFF", "ON" } } - labels[#labels + 1] = { t = "PWM Frequency", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 200, max = 32000, vals = { 5, 6 }, } + fields[#fields + 1] = { t = "Gyro Update", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end } + fields[#fields + 1] = { t = "PID Loop", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {} } + fields[#fields + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 9, vals = { 4 }, table = { [0] = "OFF", "OS125", "OS42", "MSHOT","BRSH", "DS150", "DS300", "DS600","DS1200", "PS1000" } } + fields[#fields + 1] = { t = "Unsynced PWM", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 3 }, table = { [0] = "OFF", "ON" } } + fields[#fields + 1] = { t = "PWM Frequency", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 200, max = 32000, vals = { 5, 6 }, } end if apiVersion >= 1.031 then - labels[#labels + 1] = { t = "Idle Throttle %", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 2000, vals = { 7, 8 }, scale = 100 } + fields[#fields + 1] = { t = "Idle Throttle %", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2000, vals = { 7, 8 }, scale = 100 } end return { diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua index 8d0f600d..6f348e6b 100644 --- a/src/SCRIPTS/BF/PAGES/rates.lua +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -68,24 +68,18 @@ end if apiVersion >= 1.016 then labels[#labels + 1] = { t = "Throttle", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Mid", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 7 }, scale = 100 } - labels[#labels + 1] = { t = "Expo", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 8 }, scale = 100 } + fields[#fields + 1] = { t = "Mid", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 7 }, scale = 100 } + fields[#fields + 1] = { t = "Expo", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 8 }, scale = 100 } if apiVersion >= 1.041 then - labels[#labels + 1] = { t = "Limit Type", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 2, vals = { 15 }, table = { [0] = "OFF", "SCALE", "CLIP" } } - labels[#labels + 1] = { t = "Limit %", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 25, max = 100, vals = { 16 } } + fields[#fields + 1] = { t = "Limit Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 15 }, table = { [0] = "OFF", "SCALE", "CLIP" } } + fields[#fields + 1] = { t = "Limit %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 25, max = 100, vals = { 16 } } end end if apiVersion >= 1.016 then labels[#labels + 1] = { t = "TPA", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Rate", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 100, vals = { 6 } , scale = 100 } - labels[#labels + 1] = { t = "Breakpoint", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 9, 10 } } + fields[#fields + 1] = { t = "Rate", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 6 } , scale = 100 } + fields[#fields + 1] = { t = "Breakpoint", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 9, 10 } } end return { diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index 718c83ac..ecc9785a 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -17,31 +17,21 @@ local labels = {} local fields = {} if apiVersion >= 1.041 then - labels[#labels + 1] = { t = "Min Sats.", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 50, vals = { 16 } } - labels[#labels + 1] = { t = "Angle", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 200, vals = { 1, 2 } } - labels[#labels + 1] = { t = "Initial Altitude", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 20, max = 100, vals = { 3, 4 } } - labels[#labels + 1] = { t = "Descent Distance", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 30, max = 500, vals = { 5, 6 } } - labels[#labels + 1] = { t = "Ground Speed", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 30, max = 3000, vals = { 7, 8 } } + fields[#fields + 1] = { t = "Min Sats.", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 16 } } + fields[#fields + 1] = { t = "Angle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 1, 2 } } + fields[#fields + 1] = { t = "Initial Altitude", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 100, vals = { 3, 4 } } + fields[#fields + 1] = { t = "Descent Distance", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 30, max = 500, vals = { 5, 6 } } + fields[#fields + 1] = { t = "Ground Speed", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 30, max = 3000, vals = { 7, 8 } } if apiVersion >= 1.043 then - labels[#labels + 1] = { t = "Arm w/o fix", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 1, vals = { 21 }, table = { [0]="OFF","ON"} } + fields[#fields + 1] = { t = "Arm w/o fix", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 21 }, table = { [0]="OFF","ON"} } end - labels[#labels + 1] = { t = "Sanity Check", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 2, vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"} } + fields[#fields + 1] = { t = "Sanity Check", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"} } labels[#labels + 1] = { t = "Throttle", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Min", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 9, 10 } } - labels[#labels + 1] = { t = "Hover", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 13, 14 } } - labels[#labels + 1] = { t = "Max", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 11, 12 } } + fields[#fields + 1] = { t = "Min", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 9, 10 } } + fields[#fields + 1] = { t = "Hover", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 13, 14 } } + fields[#fields + 1] = { t = "Max", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 11, 12 } } end return { diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index 75286661..f9939b5e 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -18,24 +18,18 @@ local fields = {} if apiVersion >= 1.016 then labels[#labels + 1] = { t = "Stick", x = x, y = inc.y(lineSpacing) } - labels[#labels + 1] = { t = "Low", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 6, 7 } } - labels[#labels + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 4, 5 } } - labels[#labels + 1] = { t = "High", x = x + indent, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 1000, max = 2000, vals = { 2, 3 } } + fields[#fields + 1] = { t = "Low", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 6, 7 } } + fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 4, 5 } } + fields[#fields + 1] = { t = "High", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 2, 3 } } end if apiVersion >= 1.020 then - labels[#labels + 1] = { t = "Interp", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} } - labels[#labels + 1] = { t = "Interp Int", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 1, max = 50, vals = { 14 } } + fields[#fields + 1] = { t = "Interp", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} } + fields[#fields + 1] = { t = "Interp Int", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 50, vals = { 14 } } end if apiVersion >= 1.031 then - labels[#labels + 1] = { t = "Cam Angle", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 0, max = 90, vals = { 23 } } + fields[#fields + 1] = { t = "Cam Angle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 90, vals = { 23 } } end return { diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index 1f2d8da0..bccdedab 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -26,21 +26,15 @@ local labels = {} local fields = {} if apiVersion >= 1.036 then - labels[#labels + 1] = { t = "Band", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min=0, max=#(vtx_tables.bandTable), vals = { 2 }, table = vtx_tables.bandTable, upd = function(self) self.handleBandChanUpdate(self) end } - labels[#labels + 1] = { t = "Channel", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min=1, max=vtx_tables.frequenciesPerBand, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end } - labels[#labels + 1] = { t = "Power", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end } - labels[#labels + 1] = { t = "Pit Mode", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min=0, max=#(pitModeTable), vals = { 5 }, table = pitModeTable } - labels[#labels + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, vals = { 1 }, write = false, ro = true, table = deviceTable } + fields[#fields + 1] = { t = "Band", x = x, y = inc.y(lineSpacing), sp = x + sp, min=0, max=#(vtx_tables.bandTable), vals = { 2 }, table = vtx_tables.bandTable, upd = function(self) self.handleBandChanUpdate(self) end } + fields[#fields + 1] = { t = "Channel", x = x, y = inc.y(lineSpacing), sp = x + sp, min=1, max=vtx_tables.frequenciesPerBand, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end } + fields[#fields + 1] = { t = "Power", x = x, y = inc.y(lineSpacing), sp = x + sp, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end } + fields[#fields + 1] = { t = "Pit Mode", x = x, y = inc.y(lineSpacing), sp = x + sp, min=0, max=#(pitModeTable), vals = { 5 }, table = pitModeTable } + fields[#fields + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing), sp = x + sp, vals = { 1 }, write = false, ro = true, table = deviceTable } end if apiVersion >= 1.037 then - labels[#labels + 1] = { t = "Frequency", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { x = x + sp, y = y, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end } + fields[#fields + 1] = { t = "Frequency", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end } end -- Vals Fields diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 0567af01..0cdc3d9c 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -228,7 +228,10 @@ local function drawScreen() end end if (f.y - pageScrollY) >= yMinLim and (f.y - pageScrollY) <= yMaxLim then - lcd.drawText(f.x, f.y - pageScrollY, val, valueOptions) + if f.t then + lcd.drawText(f.x, f.y - pageScrollY, f.t, textOptions) + end + lcd.drawText(f.sp or f.x, f.y - pageScrollY, val, valueOptions) end end end From d354232adbe19b354d7a6b87eff1db4fa79d7615 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 5 Dec 2019 22:36:54 +0100 Subject: [PATCH 058/193] Unload background when not used + other minor changes Unloads background when ui is visible. It's prevented from running anyway. Removed optional init function. + some minor simplifications. Saves around 2KB for telemetry script. Reference tables instead of copying No need to make actual copies of these tables. Saves a little bit of memory and some cpu cycles. Separate main menu event handling from draw code Rename incLine to incField incValue fix Avoid potential nil divided by scale if for some reason min/max doesn't exist. Make ui.lua functions local They're only used in this file --- src/SCRIPTS/BF/background.lua | 12 ++---- src/SCRIPTS/BF/data_init.lua | 7 +--- src/SCRIPTS/BF/ui.lua | 71 ++++++++++++++--------------------- src/SCRIPTS/TELEMETRY/bf.lua | 24 ++++++++---- 4 files changed, 51 insertions(+), 63 deletions(-) diff --git a/src/SCRIPTS/BF/background.lua b/src/SCRIPTS/BF/background.lua index a060f9dc..b0e361e0 100644 --- a/src/SCRIPTS/BF/background.lua +++ b/src/SCRIPTS/BF/background.lua @@ -2,7 +2,7 @@ local INTERVAL = 50 -- in 1/100th seconds local MSP_TX_INFO = 186 -local lastRunTS +local lastRunTS = 0 local sensorId = -1 local dataInitialised = false local data_init = nil @@ -21,10 +21,6 @@ local function modelActive(sensorValue) return type(sensorValue) == "number" and sensorValue > 0 end -local function init() - lastRunTS = 0 -end - local function run_bg() -- run in intervals if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then @@ -37,7 +33,7 @@ local function run_bg() data_init = assert(loadScript(SCRIPT_HOME .. "/data_init.lua"))() end - dataInitialised = data_init.init(); + dataInitialised = data_init(); if dataInitialised then data_init = nil @@ -52,7 +48,7 @@ local function run_bg() rssi = 255 end - values = {} + local values = {} values[1] = rssi protocol.mspWrite(MSP_TX_INFO, values) @@ -68,4 +64,4 @@ local function run_bg() mspProcessTxQ() end -return { init=init, run_bg=run_bg } +return run_bg diff --git a/src/SCRIPTS/BF/data_init.lua b/src/SCRIPTS/BF/data_init.lua index dc4c9013..cf97d824 100644 --- a/src/SCRIPTS/BF/data_init.lua +++ b/src/SCRIPTS/BF/data_init.lua @@ -23,13 +23,11 @@ local function init() elseif apiVersionReceived and not timeIsSet then -- only send datetime one time after telemetry connection became available -- or when connection is restored after e.g. lipo refresh - + local values = {} if apiVersion >= 1.041 then -- format: seconds after the epoch (32) / milliseconds (16) local now = getRtcTime() - values = {} - for i = 1, 4 do values[i] = bit32.band(now, 0xFF) now = bit32.rshift(now, 8) @@ -42,7 +40,6 @@ local function init() local now = getDateTime() local year = now.year; - values = {} values[1] = bit32.band(year, 0xFF) year = bit32.rshift(year, 8) values[2] = bit32.band(year, 0xFF) @@ -61,4 +58,4 @@ local function init() return apiVersionReceived and timeIsSet end -return { init=init } +return init diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 0cdc3d9c..316524ec 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -45,13 +45,9 @@ local globalTextOptions = TEXT_COLOR or 0 local function saveSettings(new) if Page.values then - local payload = {} + local payload = Page.values if Page.preSave then payload = Page.preSave(Page) - else - for i=1,(Page.outputBytes or #Page.values) do - payload[i] = Page.values[i] - end end protocol.mspWrite(Page.write, payload) saveTS = getTime() @@ -123,11 +119,7 @@ local function processMspReply(cmd,rx_buf) return end if #(rx_buf) > 0 then - Page.values = {} - for i=1,#(rx_buf) do - Page.values[i] = rx_buf[i] - end - + Page.values = rx_buf for i=1,#(Page.fields) do if (#(Page.values) or 0) >= Page.minBytes then local f = Page.fields[i] @@ -152,6 +144,15 @@ local function incMax(val, inc, base) return ((val + inc + base - 1) % base) + 1 end +local function clipValue(val,min,max) + if val < min then + val = min + elseif val > max then + val = max + end + return val +end + local function incPage(inc) currentPage = incMax(currentPage, inc, #(PageFiles)) Page = nil @@ -159,7 +160,7 @@ local function incPage(inc) collectgarbage() end -local function incLine(inc) +local function incField(inc) currentField = clipValue(currentField + inc, 1, #(Page.fields)) end @@ -178,7 +179,7 @@ local function requestPage() end end -function drawScreenTitle(screen_title) +local function drawScreenTitle(screen_title) if radio.resolution == lcdResolution.low then lcd.drawFilledRectangle(0, 0, LCD_W, 10) lcd.drawText(1,1,screen_title,INVERS) @@ -236,21 +237,12 @@ local function drawScreen() end end -function clipValue(val,min,max) - if val < min then - val = min - elseif val > max then - val = max - end - return val -end - local function incValue(inc) local f = Page.fields[currentField] local idx = f.i or currentField local scale = (f.scale or 1) local mult = (f.mult or 1) - f.value = clipValue(f.value + ((inc*mult)/scale), (f.min/scale) or 0, (f.max/scale) or 255) + f.value = clipValue(f.value + ((inc*mult)/scale), ((f.min or 0)/scale), ((f.max or 255)/scale)) f.value = math.floor((f.value*scale)/mult + 0.5)/(scale/mult) for idx=1, #(f.vals) do Page.values[f.vals[idx]] = bit32.rshift(math.floor(f.value*scale + 0.5), (idx-1)*8) @@ -281,7 +273,7 @@ local function drawPopupMenu() end end -function run_ui(event) +local function run_ui(event) local now = getTime() -- if lastRunTS old than 500ms if lastRunTS + 50 < now then @@ -297,10 +289,8 @@ function run_ui(event) if apiVersion == 0 then if not background then background = assert(loadScript("/SCRIPTS/BF/background.lua"))() - background.init() - else - background.run_bg() end + background() return 0 else background = nil @@ -319,6 +309,9 @@ function run_ui(event) incMainMenu(1) elseif event == EVT_VIRTUAL_PREV then incMainMenu(-1) + elseif event == EVT_VIRTUAL_ENTER then + pageState = pageStatus.display + uiState = uiStatus.pages end lcd.clear() drawScreenTitle("Betaflight Config", 0, 0) @@ -328,22 +321,16 @@ function run_ui(event) if radio.resolution == lcdResolution.high then lineSpacing = 25 end + local currentFieldY = (currentPage-1)*lineSpacing + yMinLim + if currentFieldY <= yMinLim then + mainMenuScrollY = 0 + elseif currentFieldY - mainMenuScrollY <= yMinLim then + mainMenuScrollY = currentFieldY - yMinLim + elseif currentFieldY - mainMenuScrollY >= yMaxLim then + mainMenuScrollY = currentFieldY - yMaxLim + end for i=1, #PageFiles do - local currentFieldY = (currentPage-1)*lineSpacing + yMinLim - if currentFieldY <= yMinLim then - mainMenuScrollY = 0 - elseif currentFieldY - mainMenuScrollY <= yMinLim then - mainMenuScrollY = currentFieldY - yMinLim - elseif currentFieldY - mainMenuScrollY >= yMaxLim then - mainMenuScrollY = currentFieldY - yMaxLim - end local attr = (currentPage == i and INVERS or 0) - if event == EVT_VIRTUAL_ENTER and attr == INVERS then - invalidatePages() - currentPage = i - pageState = pageStatus.display - uiState = uiStatus.pages - end if ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) >= yMinLim and ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) <= yMaxLim then lcd.drawText(6, (i-1)*lineSpacing + yMinLim - mainMenuScrollY, PageFiles[i].title, attr) end @@ -392,9 +379,9 @@ function run_ui(event) elseif (not isTelemetryScript and event == EVT_VIRTUAL_NEXT_PAGE) or (isTelemetryScript and event == EVT_VIRTUAL_MENU) then incPage(1) elseif event == EVT_VIRTUAL_PREV or event == EVT_VIRTUAL_PREV_REPT then - incLine(-1) + incField(-1) elseif event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then - incLine(1) + incField(1) elseif event == EVT_VIRTUAL_ENTER then if Page then local field = Page.fields[currentField] diff --git a/src/SCRIPTS/TELEMETRY/bf.lua b/src/SCRIPTS/TELEMETRY/bf.lua index 92434f5a..48254f30 100644 --- a/src/SCRIPTS/TELEMETRY/bf.lua +++ b/src/SCRIPTS/TELEMETRY/bf.lua @@ -17,15 +17,23 @@ local MENU_TIMESLICE = 100 local lastMenuEvent = 0 -function run(event) - lastMenuEvent = getTime() - run_ui(event) +local function run(event) + if background then + background = nil + collectgarbage() + end + lastMenuEvent = getTime() + run_ui(event) end -function run_bg() - if lastMenuEvent + MENU_TIMESLICE < getTime() then - background.run_bg() - end +local function run_bg() + if lastMenuEvent + MENU_TIMESLICE < getTime() then + if not background then + background = assert(loadScript(SCRIPT_HOME.."/background.lua"))() + collectgarbage() + end + background() + end end -return { init=background.init, run=run, background=run_bg } +return { run=run, background=run_bg } From c497498b7cbfdae884f5a0b528e4309b9dcf0ef2 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 10 Dec 2019 15:11:08 +0100 Subject: [PATCH 059/193] Fix no telemetry blink for high res LCDs Seems like BLINK on it's own doesn't work for the high resolution screens. Changed it back to what it used to be. Works in the simulator. Extended yMaxLimit for 320x480. --- src/SCRIPTS/BF/radios.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index e571a853..6853e9c6 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -34,7 +34,7 @@ local supportedRadios = resolution = lcdResolution.high, MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, - NoTelem = { 192, LCD_H - 28, "No Telemetry", BLINK }, + NoTelem = { 192, LCD_H - 28, "No Telemetry", TEXT_COLOR + INVERS + BLINK }, textSize = 0, yMinLimit = 35, yMaxLimit = 235, @@ -45,10 +45,10 @@ local supportedRadios = resolution = lcdResolution.high, MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, - NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", BLINK }, + NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", TEXT_COLOR + INVERS + BLINK }, textSize = 0, yMinLimit = 35, - yMaxLimit = 235, + yMaxLimit = 435, }, } From fada4f7da497129a34e58dd7c803937df3fd3ed0 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 13 Dec 2019 00:23:49 +0100 Subject: [PATCH 060/193] Fix TEXT_COLOR bug TEXT_COLOR is not a thing on the radios with low resolution screen. --- src/SCRIPTS/BF/radios.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index 6853e9c6..a511937b 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -34,7 +34,7 @@ local supportedRadios = resolution = lcdResolution.high, MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, - NoTelem = { 192, LCD_H - 28, "No Telemetry", TEXT_COLOR + INVERS + BLINK }, + NoTelem = { 192, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, textSize = 0, yMinLimit = 35, yMaxLimit = 235, @@ -45,7 +45,7 @@ local supportedRadios = resolution = lcdResolution.high, MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, - NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", TEXT_COLOR + INVERS + BLINK }, + NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, textSize = 0, yMinLimit = 35, yMaxLimit = 435, From 7a29e5f8552153c7ff60bad2e976676640da5ddc Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 13 Dec 2019 00:35:19 +0100 Subject: [PATCH 061/193] Esc protocol backwards compatibility Create the esc protocol table based on apiVersion. It's done just like in the configurator. Also fixes a bug that prevents the rate tables from being updated if there is no self.values[9] --- src/SCRIPTS/BF/PAGES/pwm.lua | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index b3ee5c67..2dce2102 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -16,6 +16,23 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +local escProtocols = { [0] = "PWM", "OS125", "OS42", "MSHOT" } + +if apiVersion >= 1.020 then + escProtocols[#escProtocols + 1] = "BRSH" +end +if apiVersion >= 1.031 then + escProtocols[#escProtocols + 1] = "DS150" + escProtocols[#escProtocols + 1] = "DS300" + escProtocols[#escProtocols + 1] = "DS600" + if apiVersion < 1.042 then + escProtocols[#escProtocols + 1] = "DS1200" + end + if apiVersion >= 1.036 then + escProtocols[#escProtocols + 1] = "PS1000" + end +end + if apiVersion >= 1.031 and apiVersion <= 1.040 then fields[#fields + 1] = { t = "32kHz Sampling", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end } end @@ -23,7 +40,7 @@ end if apiVersion >= 1.016 then fields[#fields + 1] = { t = "Gyro Update", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end } fields[#fields + 1] = { t = "PID Loop", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {} } - fields[#fields + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 9, vals = { 4 }, table = { [0] = "OFF", "OS125", "OS42", "MSHOT","BRSH", "DS150", "DS300", "DS600","DS1200", "PS1000" } } + fields[#fields + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #escProtocols, vals = { 4 }, table = escProtocols } fields[#fields + 1] = { t = "Unsynced PWM", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 3 }, table = { [0] = "OFF", "ON" } } fields[#fields + 1] = { t = "PWM Frequency", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 200, max = 32000, vals = { 5, 6 }, } end @@ -70,7 +87,7 @@ return { end end, updateRateTables = function(self) - if self.values[9] == 0 then + if (self.values[9] or 0) == 0 then self.calculateGyroRates(self, 8) self.calculatePidRates(self, 8) elseif self.values[9] == 1 then From 9a73ac45971fceee8906654965a0cfdbcbe5689d Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 17 Dec 2019 20:23:37 +0100 Subject: [PATCH 062/193] Make clipValue global again Needed by vtx page --- src/SCRIPTS/BF/ui.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 316524ec..75784df5 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -144,7 +144,7 @@ local function incMax(val, inc, base) return ((val + inc + base - 1) % base) + 1 end -local function clipValue(val,min,max) +function clipValue(val,min,max) if val < min then val = min elseif val > max then From 8e2f496887a1751914bc87f5b1159750e4fc99a6 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 17 Dec 2019 21:15:02 +0100 Subject: [PATCH 063/193] Fix Page.values check before editing This is old code. i is not used anymore and currentField is not the index for the values we want to edit. --- src/SCRIPTS/BF/ui.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 75784df5..17aff567 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -239,7 +239,6 @@ end local function incValue(inc) local f = Page.fields[currentField] - local idx = f.i or currentField local scale = (f.scale or 1) local mult = (f.mult or 1) f.value = clipValue(f.value + ((inc*mult)/scale), ((f.min or 0)/scale), ((f.max or 255)/scale)) @@ -384,9 +383,8 @@ local function run_ui(event) incField(1) elseif event == EVT_VIRTUAL_ENTER then if Page then - local field = Page.fields[currentField] - local idx = field.i or currentField - if Page.values and Page.values[idx] and (field.ro ~= true) then + local f = Page.fields[currentField] + if Page.values and Page.values[f.vals[#f.vals]] and not f.ro then pageState = pageStatus.editing end end From 4a50fbeb54f16a22fb5030db6434a2a460b068cd Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 22 Dec 2019 10:53:19 +1300 Subject: [PATCH 064/193] Added FUNDING.yml. --- .github/FUNDING.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..86e8d583 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +custom: https://paypal.me/betaflight +patreon: betaflight From 33d0dbaf764ba6ee01858b505fa58ee946b62a2e Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 23 Dec 2019 14:27:01 +0100 Subject: [PATCH 065/193] Improve protocol detection From OpenTX 2.3.4 sport/crossfireTelemetryPush behaviour is changed. These functions will now return nil if incorrect telemetry protocol is detected. --- src/SCRIPTS/BF/protocols.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/protocols.lua b/src/SCRIPTS/BF/protocols.lua index 85944515..270d4ce1 100644 --- a/src/SCRIPTS/BF/protocols.lua +++ b/src/SCRIPTS/BF/protocols.lua @@ -27,9 +27,9 @@ local supportedProtocols = } local function getProtocol() - if supportedProtocols.smartPort.push() then + if supportedProtocols.smartPort.push() ~= nil then return supportedProtocols.smartPort - elseif supportedProtocols.crsf.push() then + elseif supportedProtocols.crsf.push() ~= nil then return supportedProtocols.crsf end end From 1ba3027570804deb782b198c188b387e8d61f758 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 23 Dec 2019 20:27:10 +0100 Subject: [PATCH 066/193] RSSI function script background.lua as a function script. --- src/SCRIPTS/FUNCTIONS/rssi.lua | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/SCRIPTS/FUNCTIONS/rssi.lua diff --git a/src/SCRIPTS/FUNCTIONS/rssi.lua b/src/SCRIPTS/FUNCTIONS/rssi.lua new file mode 100644 index 00000000..8c43106d --- /dev/null +++ b/src/SCRIPTS/FUNCTIONS/rssi.lua @@ -0,0 +1,8 @@ +SCRIPT_HOME = "/SCRIPTS/BF" +apiVersion = 0 +protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() +assert(loadScript(protocol.transport))() +assert(loadScript(SCRIPT_HOME.."/MSP/common.lua"))() +local background = assert(loadScript(SCRIPT_HOME.."/background.lua"))() + +return { run=background } From 9eeb8f38cc9b5c884e47d6a63efbed6c316d5578 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sat, 25 Jan 2020 22:23:15 +0100 Subject: [PATCH 067/193] Remove TELEMETRY script Removes the telemetry version of the script. bf.lua still exists but only displays a message telling the user to use the TOOLS version instead. bf.lua should be removed from the TELEMETRY folder at a later time. --- src/SCRIPTS/BF/protocols.lua | 2 -- src/SCRIPTS/BF/ui.lua | 41 ++++++++---------------------------- src/SCRIPTS/TELEMETRY/bf.lua | 39 +++------------------------------- src/SCRIPTS/TOOLS/bf.lua | 2 -- 4 files changed, 12 insertions(+), 72 deletions(-) diff --git a/src/SCRIPTS/BF/protocols.lua b/src/SCRIPTS/BF/protocols.lua index 270d4ce1..4c409bed 100644 --- a/src/SCRIPTS/BF/protocols.lua +++ b/src/SCRIPTS/BF/protocols.lua @@ -4,7 +4,6 @@ local supportedProtocols = { transport = SCRIPT_HOME.."/MSP/sp.lua", rssi = function() return getValue("RSSI") end, - exitFunc = function() return 0 end, stateSensor = "Tmp1", push = sportTelemetryPush, maxTxBufferSize = 6, @@ -16,7 +15,6 @@ local supportedProtocols = { transport = SCRIPT_HOME.."/MSP/crsf.lua", rssi = function() return getValue("TQly") end, - exitFunc = function() return "/CROSSFIRE/crossfire.lua" end, stateSensor = "1RSS", push = crossfireTelemetryPush, maxTxBufferSize = 8, diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 17aff567..8ec04c9e 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -29,9 +29,7 @@ local saveTimeout = 0 local saveRetries = 0 local saveMaxRetries = 0 local popupMenuActive = false -local lastRunTS = 0 local killEnterBreak = 0 -local stopDisplay = false local pageScrollY = 0 local mainMenuScrollY = 0 local PageFiles = nil @@ -273,13 +271,6 @@ local function drawPopupMenu() end local function run_ui(event) - local now = getTime() - -- if lastRunTS old than 500ms - if lastRunTS + 50 < now then - invalidatePages() - uiState = uiStatus.init - end - lastRunTS = now if uiState == uiStatus.init then local yMinLim = radio.yMinLimit lcd.clear() @@ -295,11 +286,7 @@ local function run_ui(event) background = nil PageFiles = assert(loadScript("/SCRIPTS/BF/pages.lua"))() invalidatePages() - if isTelemetryScript then - uiState = uiStatus.pages - else - uiState = uiStatus.mainMenu - end + uiState = uiStatus.mainMenu end elseif uiState == uiStatus.mainMenu then if event == EVT_VIRTUAL_EXIT then @@ -336,7 +323,7 @@ local function run_ui(event) end elseif uiState == uiStatus.pages then if (pageState == pageStatus.saving) then - if (saveTS + saveTimeout < now) then + if (saveTS + saveTimeout < getTime()) then if saveRetries < saveMaxRetries then saveSettings() else @@ -347,10 +334,7 @@ local function run_ui(event) end end -- navigation - if isTelemetryScript and event == EVT_VIRTUAL_MENU_LONG then -- telemetry script - popupMenuActive = 1 - pageState = pageStatus.popupMenu - elseif (not isTelemetryScript) and event == EVT_VIRTUAL_ENTER_LONG then -- standalone + if event == EVT_VIRTUAL_ENTER_LONG then popupMenuActive = 1 killEnterBreak = 1 pageState = pageStatus.popupMenu @@ -372,10 +356,10 @@ local function run_ui(event) end -- normal page viewing elseif pageState <= pageStatus.display then - if not isTelemetryScript and event == EVT_VIRTUAL_PREV_PAGE then + if event == EVT_VIRTUAL_PREV_PAGE then incPage(-1) killEvents(event) -- X10/T16 issue: pageUp is a long press - elseif (not isTelemetryScript and event == EVT_VIRTUAL_NEXT_PAGE) or (isTelemetryScript and event == EVT_VIRTUAL_MENU) then + elseif event == EVT_VIRTUAL_NEXT_PAGE then incPage(1) elseif event == EVT_VIRTUAL_PREV or event == EVT_VIRTUAL_PREV_REPT then incField(-1) @@ -389,11 +373,10 @@ local function run_ui(event) end end elseif event == EVT_VIRTUAL_EXIT then - if isTelemetryScript then - return protocol.exitFunc(); - else - stopDisplay = true - end + invalidatePages() + currentField = 1 + uiState = uiStatus.mainMenu + return 0 end -- editing value elseif pageState == pageStatus.editing then @@ -433,12 +416,6 @@ local function run_ui(event) lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,"Retrying",DBLSIZE + (globalTextOptions)) end end - if stopDisplay and (not isTelemetryScript) then - invalidatePages() - currentField = 1 - uiState = uiStatus.mainMenu - stopDisplay = false - end end -- process send queue mspProcessTxQ() diff --git a/src/SCRIPTS/TELEMETRY/bf.lua b/src/SCRIPTS/TELEMETRY/bf.lua index 48254f30..3b931cfd 100644 --- a/src/SCRIPTS/TELEMETRY/bf.lua +++ b/src/SCRIPTS/TELEMETRY/bf.lua @@ -1,39 +1,6 @@ -SCRIPT_HOME = "/SCRIPTS/BF" - -apiVersion = 0 -isTelemetryScript = true - -protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() -radio = assert(loadScript(SCRIPT_HOME.."/radios.lua"))() - -assert(loadScript(SCRIPT_HOME.."/pages.lua"))() -assert(loadScript(protocol.transport))() -assert(loadScript(SCRIPT_HOME.."/MSP/common.lua"))() - -local run_ui = assert(loadScript(SCRIPT_HOME.."/ui.lua"))() -local background = assert(loadScript(SCRIPT_HOME.."/background.lua"))() - -local MENU_TIMESLICE = 100 - -local lastMenuEvent = 0 - local function run(event) - if background then - background = nil - collectgarbage() - end - lastMenuEvent = getTime() - run_ui(event) -end - -local function run_bg() - if lastMenuEvent + MENU_TIMESLICE < getTime() then - if not background then - background = assert(loadScript(SCRIPT_HOME.."/background.lua"))() - collectgarbage() - end - background() - end + lcd.clear() + lcd.drawText(2, 2, "Use TOOLS menu instead of this") end -return { run=run, background=run_bg } +return { run=run } diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index fdbdd054..c6f4d57d 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -2,12 +2,10 @@ local toolName = "TNS|Betaflight setup|TNE" SCRIPT_HOME = "/SCRIPTS/BF" apiVersion = 0 -isTelemetryScript = false protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() radio = assert(loadScript(SCRIPT_HOME.."/radios.lua"))() -assert(loadScript(SCRIPT_HOME.."/pages.lua"))() assert(loadScript(protocol.transport))() assert(loadScript(SCRIPT_HOME.."/MSP/common.lua"))() From 8b3c16e333e14f3f1fdfe1f81ae2e5e78144540c Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 2 Feb 2020 15:52:23 +0100 Subject: [PATCH 068/193] Background function improvements Improved RTC synchronisation by periodically sending the time to the FC until we get the response confirming that the data was received and OK. Improved rssi functionality by detecting the rssi source set in the FC. Only sends rssi if source is NONE or MSP. Rssi also broken out into it's own file. Unloaded when not needed. Changed rssi scaling. It is now 0 - 99 to 0 - 255. Chose to do it like this because it doesn't need changes in the firmware and it's backwards compatible with earlier versions. No need for the user to adjust scaling/offset etc. The INTERVAL is now separate for data_init and rssi. This gives better control over what parts of the code to run at that interval. Previously the buffer was polled at the same interval as the commands were sent. Now it's polled every lua cycle. This speeds up apiVersion detection by up to 0.5 seconds. Same for RTC sync. Renamed rssi.lua function script to bfbkgd.lua(sorry. 6 char limit). Used "bf" to show where the script comes from to avoid confusion as people might have scripts from different sources in the FUNCTION folder. --- src/SCRIPTS/BF/background.lua | 69 ++++++++-------- src/SCRIPTS/BF/data_init.lua | 79 ++++++++++--------- src/SCRIPTS/BF/rssi.lua | 46 +++++++++++ src/SCRIPTS/BF/ui.lua | 12 +-- .../FUNCTIONS/{rssi.lua => bfbkgd.lua} | 0 5 files changed, 126 insertions(+), 80 deletions(-) create mode 100644 src/SCRIPTS/BF/rssi.lua rename src/SCRIPTS/FUNCTIONS/{rssi.lua => bfbkgd.lua} (100%) diff --git a/src/SCRIPTS/BF/background.lua b/src/SCRIPTS/BF/background.lua index b0e361e0..bd3ba355 100644 --- a/src/SCRIPTS/BF/background.lua +++ b/src/SCRIPTS/BF/background.lua @@ -1,11 +1,8 @@ -local INTERVAL = 50 -- in 1/100th seconds - -local MSP_TX_INFO = 186 - -local lastRunTS = 0 local sensorId = -1 local dataInitialised = false local data_init = nil +local rssiEnabled = true +local rssiTask = nil local function getSensorValue() if sensorId == -1 then @@ -22,46 +19,44 @@ local function modelActive(sensorValue) end local function run_bg() - -- run in intervals - if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then - local sensorValue = getSensorValue() - if modelActive(sensorValue) then - -- Send data when the telemetry connection is available - -- assuming when sensor value higher than 0 there is an telemetry connection - if not dataInitialised then - if data_init == nil then - data_init = assert(loadScript(SCRIPT_HOME .. "/data_init.lua"))() - end + local sensorValue = getSensorValue() + if modelActive(sensorValue) then + -- Send data when the telemetry connection is available + -- assuming when sensor value higher than 0 there is an telemetry connection + if not dataInitialised then + if not data_init then + data_init = assert(loadScript(SCRIPT_HOME .. "/data_init.lua"))() + end - dataInitialised = data_init(); + dataInitialised = data_init() - if dataInitialised then - data_init = nil + if dataInitialised then + data_init = nil - collectgarbage() - end - else - local rssi, alarm_low, alarm_crit = getRSSI() - -- Scale the [0, 85] (empirical) RSSI values to [0, 255] - rssi = rssi * 3 - if rssi > 255 then - rssi = 255 - end + collectgarbage() + end + elseif rssiEnabled and apiVersion >= 1.037 then + if not rssiTask then + rssiTask = assert(loadScript(SCRIPT_HOME.."/rssi.lua"))() + end - local values = {} - values[1] = rssi + rssiEnabled = rssiTask() - protocol.mspWrite(MSP_TX_INFO, values) + if not rssiEnabled then + rssiTask = nil + + collectgarbage() end - else - dataInitialised = false end - - lastRunTS = getTime() + else + dataInitialised = false + rssiEnabled = true + if data_init or rssiTask then + data_init = nil + rssiTask = nil + collectgarbage() + end end - - -- process queue - mspProcessTxQ() end return run_bg diff --git a/src/SCRIPTS/BF/data_init.lua b/src/SCRIPTS/BF/data_init.lua index cf97d824..ae4da07f 100644 --- a/src/SCRIPTS/BF/data_init.lua +++ b/src/SCRIPTS/BF/data_init.lua @@ -3,57 +3,62 @@ local MSP_SET_RTC = 246 local apiVersionReceived = false local timeIsSet = false +local lastRunTS = 0 +local INTERVAL = 50 local function processMspReply(cmd,rx_buf) - if cmd == nil or rx_buf == nil then - return - end - if cmd == MSP_API_VERSION and #(rx_buf) >= 3 then + if cmd == MSP_API_VERSION and #rx_buf >= 3 then apiVersion = rx_buf[2] + rx_buf[3] / 1000 apiVersionReceived = true end + if cmd == MSP_SET_RTC then + timeIsSet = true + end end local function init() - if not apiVersionReceived then - protocol.mspRead(MSP_API_VERSION) - - processMspReply(mspPollReply()) - elseif apiVersionReceived and not timeIsSet then - -- only send datetime one time after telemetry connection became available - -- or when connection is restored after e.g. lipo refresh - local values = {} - if apiVersion >= 1.041 then - -- format: seconds after the epoch (32) / milliseconds (16) - local now = getRtcTime() - - for i = 1, 4 do - values[i] = bit32.band(now, 0xFF) - now = bit32.rshift(now, 8) + if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then + if not apiVersionReceived then + protocol.mspRead(MSP_API_VERSION) + elseif apiVersionReceived and not timeIsSet then + -- only send datetime one time after telemetry connection became available + -- or when connection is restored after e.g. lipo refresh + local values = {} + if apiVersion >= 1.041 then + -- format: seconds after the epoch (32) / milliseconds (16) + local now = getRtcTime() + + for i = 1, 4 do + values[i] = bit32.band(now, 0xFF) + now = bit32.rshift(now, 8) + end + + values[5] = 0 -- we don't have milliseconds + values[6] = 0 + else + -- format: year (16) / month (8) / day (8) / hour (8) / min (8) / sec (8) + local now = getDateTime() + local year = now.year + + values[1] = bit32.band(year, 0xFF) + year = bit32.rshift(year, 8) + values[2] = bit32.band(year, 0xFF) + values[3] = now.mon + values[4] = now.day + values[5] = now.hour + values[6] = now.min + values[7] = now.sec end - values[5] = 0 -- we don't have milliseconds - values[6] = 0 - else - -- format: year (16) / month (8) / day (8) / hour (8) / min (8) / sec (8) - local now = getDateTime() - local year = now.year; - - values[1] = bit32.band(year, 0xFF) - year = bit32.rshift(year, 8) - values[2] = bit32.band(year, 0xFF) - values[3] = now.mon - values[4] = now.day - values[5] = now.hour - values[6] = now.min - values[7] = now.sec + protocol.mspWrite(MSP_SET_RTC, values) end + lastRunTS = getTime() + end - protocol.mspWrite(MSP_SET_RTC, values) + mspProcessTxQ() - timeIsSet = true - end + processMspReply(mspPollReply()) return apiVersionReceived and timeIsSet end diff --git a/src/SCRIPTS/BF/rssi.lua b/src/SCRIPTS/BF/rssi.lua new file mode 100644 index 00000000..401e7103 --- /dev/null +++ b/src/SCRIPTS/BF/rssi.lua @@ -0,0 +1,46 @@ +local MSP_SET_TX_INFO = 186 +local MSP_TX_INFO = 187 + +local RSSI_SOURCE_NONE = 0 +local RSSI_SOURCE_MSP = 4 + +local rssiSourceReceived = false +local rssiSource = RSSI_SOURCE_NONE +local lastRunTS = 0 +local INTERVAL = 50 + +local function processMspReply(cmd,rx_buf) + if cmd == MSP_TX_INFO and #rx_buf >= 1 then + rssiSource = rx_buf[1] + rssiSourceReceived = true + end +end + +local function rssiTask() + if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then + if not rssiSourceReceived then + protocol.mspRead(MSP_TX_INFO) + elseif rssiSource == RSSI_SOURCE_NONE or rssiSource == RSSI_SOURCE_MSP then + local rssi, alarm_low, alarm_crit = getRSSI() + -- Scale the [0, 99] RSSI values to [0, 255] + rssi = rssi * 255 / 99 + if rssi > 255 then + rssi = 255 + end + + local values = {} + values[1] = rssi + + protocol.mspWrite(MSP_SET_TX_INFO, values) + end + lastRunTS = getTime() + end + + mspProcessTxQ() + + processMspReply(mspPollReply()) + + return rssiSource == RSSI_SOURCE_NONE or rssiSource == RSSI_SOURCE_MSP +end + +return rssiTask diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 8ec04c9e..183b2ec3 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -34,7 +34,7 @@ local pageScrollY = 0 local mainMenuScrollY = 0 local PageFiles = nil local Page = nil -local background = nil +local init = nil local backgroundFill = TEXT_BGCOLOR or ERASE local foregroundColor = LINE_COLOR or SOLID @@ -277,14 +277,14 @@ local function run_ui(event) drawScreenTitle("Betaflight Config", 0, 0) lcd.drawText(6, yMinLim, "Initialising") if apiVersion == 0 then - if not background then - background = assert(loadScript("/SCRIPTS/BF/background.lua"))() + if not init then + init = assert(loadScript(SCRIPT_HOME.."/data_init.lua"))() end - background() + init() return 0 else - background = nil - PageFiles = assert(loadScript("/SCRIPTS/BF/pages.lua"))() + init = nil + PageFiles = assert(loadScript(SCRIPT_HOME.."/pages.lua"))() invalidatePages() uiState = uiStatus.mainMenu end diff --git a/src/SCRIPTS/FUNCTIONS/rssi.lua b/src/SCRIPTS/FUNCTIONS/bfbkgd.lua similarity index 100% rename from src/SCRIPTS/FUNCTIONS/rssi.lua rename to src/SCRIPTS/FUNCTIONS/bfbkgd.lua From 0838cc5a9506d84cad32fa95d4fb79e69ebaf5d3 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 6 Feb 2020 22:46:46 +0100 Subject: [PATCH 069/193] Dynamic notch max frequency Adds the new dynamic notch max frequency. Min frequency range adjusted to 60-250Hz. --- src/SCRIPTS/BF/PAGES/filters2.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/filters2.lua b/src/SCRIPTS/BF/PAGES/filters2.lua index 20042605..5b1fe917 100644 --- a/src/SCRIPTS/BF/PAGES/filters2.lua +++ b/src/SCRIPTS/BF/PAGES/filters2.lua @@ -21,10 +21,17 @@ if apiVersion >= 1.042 then fields[#fields + 1] = { t = "Harmonics", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 44 } } fields[#fields + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 45 } } labels[#labels + 1] = { t = "Dynamic Notch Filter", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Range", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 38 }, table = { [0]="HIGH", "MEDIUM", "LOW", "AUTO" } } + if apiVersion < 1.043 then + fields[#fields + 1] = { t = "Range", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 38 }, table = { [0]="HIGH", "MEDIUM", "LOW", "AUTO" } } + end fields[#fields + 1] = { t = "Width %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 39 } } fields[#fields + 1] = { t = "Q", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 1000, vals = { 40, 41 } } - fields[#fields + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 60, max = 1000, vals = { 42, 43 } } + if apiVersion >= 1.043 then + fields[#fields + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 60, max = 250, vals = { 42, 43 } } + fields[#fields + 1] = { t = "Max Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 200, max = 1000, vals = { 46, 47 } } + else + fields[#fields + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 60, max = 1000, vals = { 42, 43 } } + end end return { From edd84df28b7c14dc0136fc401e26992032143b3b Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 10 Feb 2020 12:52:31 +0100 Subject: [PATCH 070/193] Memory saving + ui.lua size reduction A number of small savings that add up to 1-1.5KB. lcdResolution/radio.resolution removed. Use highRes bool for high resolution LCDs instead. SCRIPT_HOME removed. Use chdir("/SCRIPTS/BF") instead. Removed some unused/unnecessary code/variables. Made some changes to reduce the size of ui.lua. Removed unnecessary paranthesis, newlines, indents. Also removed comments where they aren't really needed. Reducing the size of a file helps with on device compilation. ui.lua size reduced by approximately 1.5KB. --- src/SCRIPTS/BF/MSP/common.lua | 28 ++--- src/SCRIPTS/BF/MSP/crsf.lua | 2 +- src/SCRIPTS/BF/MSP/sp.lua | 17 ++- src/SCRIPTS/BF/background.lua | 4 +- src/SCRIPTS/BF/protocols.lua | 4 +- src/SCRIPTS/BF/radios.lua | 21 +--- src/SCRIPTS/BF/ui.lua | 186 ++++++++++++------------------- src/SCRIPTS/FUNCTIONS/bfbkgd.lua | 8 +- src/SCRIPTS/FUNCTIONS/pids.lua | 4 +- src/SCRIPTS/TOOLS/bf.lua | 10 +- 10 files changed, 109 insertions(+), 175 deletions(-) diff --git a/src/SCRIPTS/BF/MSP/common.lua b/src/SCRIPTS/BF/MSP/common.lua index a18d5e3c..46648991 100644 --- a/src/SCRIPTS/BF/MSP/common.lua +++ b/src/SCRIPTS/BF/MSP/common.lua @@ -6,7 +6,6 @@ local MSP_STARTFLAG = bit32.lshift(1,4) local mspSeq = 0 local mspRemoteSeq = 0 local mspRxBuf = {} -local mspRxIdx = 1 local mspRxCRC = 0 local mspRxReq = 0 local mspStarted = false @@ -14,7 +13,6 @@ local mspLastReq = 0 local mspTxBuf = {} local mspTxIdx = 1 local mspTxCRC = 0 -local mspTxPk = 0 function mspProcessTxQ() if (#(mspTxBuf) == 0) then @@ -31,10 +29,7 @@ function mspProcessTxQ() payload[1] = payload[1] + MSP_STARTFLAG end local i = 2 - while (i <= protocol.maxTxBufferSize) do - if mspTxIdx > #(mspTxBuf) then - break - end + while (i <= protocol.maxTxBufferSize) and mspTxIdx <= #mspTxBuf do payload[i] = mspTxBuf[mspTxIdx] mspTxIdx = mspTxIdx + 1 mspTxCRC = bit32.bxor(mspTxCRC,payload[i]) @@ -48,17 +43,13 @@ function mspProcessTxQ() payload[i] = 0 i = i + 1 end - if protocol.mspSend(payload) then - mspTxPk = mspTxPk + 1 - end + protocol.mspSend(payload) mspTxBuf = {} mspTxIdx = 1 - mspTxCRC = 0 + mspTxCRC = 0 return false end - if protocol.mspSend(payload) then - mspTxPk = mspTxPk + 1 - end + protocol.mspSend(payload) return true end @@ -90,7 +81,6 @@ function mspReceivedReply(payload) local seq = bit32.band(head,0x0F) if start then -- start flag set - mspRxIdx = 1 mspRxBuf = {} mspRxSize = payload[idx] mspRxCRC = bit32.bxor(mspRxSize,mspLastReq) @@ -103,28 +93,26 @@ function mspReceivedReply(payload) mspStarted = false return nil end - while (idx <= protocol.maxRxBufferSize) and (mspRxIdx <= mspRxSize) do - mspRxBuf[mspRxIdx] = payload[idx] + while (idx <= protocol.maxRxBufferSize) and (#mspRxBuf < mspRxSize) do + mspRxBuf[#mspRxBuf + 1] = payload[idx] mspRxCRC = bit32.bxor(mspRxCRC,payload[idx]) - mspRxIdx = mspRxIdx + 1 idx = idx + 1 end if idx > protocol.maxRxBufferSize then mspRemoteSeq = seq return true end + mspStarted = false -- check CRC if mspRxCRC ~= payload[idx] then - mspStarted = false return nil end - mspStarted = false return mspRxBuf end function mspPollReply() while true do - ret = protocol.mspPoll() + local ret = protocol.mspPoll() if type(ret) == "table" then mspLastReq = 0 return mspRxReq, ret diff --git a/src/SCRIPTS/BF/MSP/crsf.lua b/src/SCRIPTS/BF/MSP/crsf.lua index 700d4b87..63c92006 100644 --- a/src/SCRIPTS/BF/MSP/crsf.lua +++ b/src/SCRIPTS/BF/MSP/crsf.lua @@ -13,7 +13,7 @@ protocol.mspSend = function(payload) for i=1, #(payload) do payloadOut[i+2] = payload[i] end - return crossfireTelemetryPush(crsfMspCmd, payloadOut) + return protocol.push(crsfMspCmd, payloadOut) end protocol.mspRead = function(cmd) diff --git a/src/SCRIPTS/BF/MSP/sp.lua b/src/SCRIPTS/BF/MSP/sp.lua index 59d0d9c7..eaabe8cd 100644 --- a/src/SCRIPTS/BF/MSP/sp.lua +++ b/src/SCRIPTS/BF/MSP/sp.lua @@ -7,12 +7,10 @@ local REPLY_FRAME_ID = 0x32 local lastSensorId, lastFrameId, lastDataId, lastValue protocol.mspSend = function(payload) - local dataId = 0 - dataId = payload[1] + bit32.lshift(payload[2],8) - local value = 0 - value = payload[3] + bit32.lshift(payload[4],8) + local dataId = payload[1] + bit32.lshift(payload[2],8) + local value = payload[3] + bit32.lshift(payload[4],8) + bit32.lshift(payload[5],16) + bit32.lshift(payload[6],24) - return sportTelemetryPush(LOCAL_SENSOR_ID, REQUEST_FRAME_ID, dataId, value) + return protocol.push(LOCAL_SENSOR_ID, REQUEST_FRAME_ID, dataId, value) end protocol.mspRead = function(cmd) @@ -23,15 +21,14 @@ protocol.mspWrite = function(cmd, payload) return mspSendRequest(cmd, payload) end ---Discards duplicate data from lua input buffer +-- Discards duplicate data from lua input buffer local function smartPortTelemetryPop() - local sensorId, frameId, dataId, value while true do - sensorId, frameId, dataId, value = sportTelemetryPop() - if sensorId == nil then + local sensorId, frameId, dataId, value = sportTelemetryPop() + if not sensorId then return nil elseif (lastSensorId == sensorId) and (lastFrameId == frameId) and (lastDataId == dataId) and (lastValue == value) then - --Keep checking + -- Keep checking else lastSensorId = sensorId lastFrameId = frameId diff --git a/src/SCRIPTS/BF/background.lua b/src/SCRIPTS/BF/background.lua index bd3ba355..203be3e7 100644 --- a/src/SCRIPTS/BF/background.lua +++ b/src/SCRIPTS/BF/background.lua @@ -25,7 +25,7 @@ local function run_bg() -- assuming when sensor value higher than 0 there is an telemetry connection if not dataInitialised then if not data_init then - data_init = assert(loadScript(SCRIPT_HOME .. "/data_init.lua"))() + data_init = assert(loadScript("data_init.lua"))() end dataInitialised = data_init() @@ -37,7 +37,7 @@ local function run_bg() end elseif rssiEnabled and apiVersion >= 1.037 then if not rssiTask then - rssiTask = assert(loadScript(SCRIPT_HOME.."/rssi.lua"))() + rssiTask = assert(loadScript("rssi.lua"))() end rssiEnabled = rssiTask() diff --git a/src/SCRIPTS/BF/protocols.lua b/src/SCRIPTS/BF/protocols.lua index 4c409bed..de50da10 100644 --- a/src/SCRIPTS/BF/protocols.lua +++ b/src/SCRIPTS/BF/protocols.lua @@ -2,7 +2,7 @@ local supportedProtocols = { smartPort = { - transport = SCRIPT_HOME.."/MSP/sp.lua", + transport = "MSP/sp.lua", rssi = function() return getValue("RSSI") end, stateSensor = "Tmp1", push = sportTelemetryPush, @@ -13,7 +13,7 @@ local supportedProtocols = }, crsf = { - transport = SCRIPT_HOME.."/MSP/crsf.lua", + transport = "MSP/crsf.lua", rssi = function() return getValue("TQly") end, stateSensor = "1RSS", push = crossfireTelemetryPush, diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index a511937b..f42f4ddc 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -1,15 +1,8 @@ -lcdResolution = -{ - low = 0, - high = 1 -} - local supportedRadios = { ["128x64"] = { - templateHome = SCRIPT_HOME.."/TEMPLATES/128x64/", - resolution = lcdResolution.low, + templateHome = "TEMPLATES/128x64/", MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, NoTelem = { 30, 55, "No Telemetry", BLINK }, @@ -19,8 +12,7 @@ local supportedRadios = }, ["212x64"] = { - templateHome = SCRIPT_HOME.."/TEMPLATES/212x64/", - resolution = lcdResolution.low, + templateHome = "TEMPLATES/212x64/", MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 }, SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, NoTelem = { 70, 55, "No Telemetry", BLINK }, @@ -30,8 +22,8 @@ local supportedRadios = }, ["480x272"] = { - templateHome = SCRIPT_HOME.."/TEMPLATES/480x272/", - resolution = lcdResolution.high, + templateHome = "TEMPLATES/480x272/", + highRes = true, MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, NoTelem = { 192, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, @@ -41,8 +33,8 @@ local supportedRadios = }, ["320x480"] = { - templateHome = SCRIPT_HOME.."/TEMPLATES/320x480/", - resolution = lcdResolution.high, + templateHome = "TEMPLATES/320x480/", + highRes = true, MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, @@ -52,7 +44,6 @@ local supportedRadios = }, } -local ver, rad, maj, min, rev = getVersion() local radio = supportedRadios[tostring(LCD_W) .. "x" .. tostring(LCD_H)] if not radio then diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 183b2ec3..f5a52518 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -21,27 +21,25 @@ local uiMsp = local uiState = uiStatus.init local pageState = pageStatus.display -local requestTimeout = 80 -- 800ms request timeout +local requestTimeout = 80 local currentPage = 1 local currentField = 1 local saveTS = 0 -local saveTimeout = 0 +local saveTimeout = protocol.saveTimeout local saveRetries = 0 -local saveMaxRetries = 0 -local popupMenuActive = false +local saveMaxRetries = protocol.saveMaxRetries +local popupMenuActive = 1 local killEnterBreak = 0 local pageScrollY = 0 local mainMenuScrollY = 0 -local PageFiles = nil -local Page = nil -local init = nil +local PageFiles, Page, init local backgroundFill = TEXT_BGCOLOR or ERASE local foregroundColor = LINE_COLOR or SOLID local globalTextOptions = TEXT_COLOR or 0 -local function saveSettings(new) +local function saveSettings() if Page.values then local payload = Page.values if Page.preSave then @@ -54,8 +52,6 @@ local function saveSettings(new) else pageState = pageStatus.saving saveRetries = 0 - saveMaxRetries = protocol.saveMaxRetries or 2 -- default 2 - saveTimeout = protocol.saveTimeout or 150 -- default 1.5s end end end @@ -77,54 +73,33 @@ local function eepromWrite() end local popupMenuList = { - { - t = "save page", - f = saveSettings - }, - { - t = "reload", - f = invalidatePages - }, - { - t = "reboot", - f = rebootFc - } + { t = "save page", f = saveSettings }, + { t = "reload", f = invalidatePages }, + { t = "reboot", f = rebootFc }, } local function processMspReply(cmd,rx_buf) - if cmd == nil or rx_buf == nil then - return - end - if Page == nil then - return - end - if cmd == Page.write then + if not Page or not rx_buf then + elseif cmd == Page.write then if Page.eepromWrite then eepromWrite() else invalidatePages() end - return - end - if cmd == uiMsp.eepromWrite then + elseif cmd == uiMsp.eepromWrite then if Page.reboot then rebootFc() end invalidatePages() - return - end - if cmd ~= Page.read then - return - end - if #(rx_buf) > 0 then + elseif cmd == Page.read and #rx_buf > 0 then Page.values = rx_buf - for i=1,#(Page.fields) do - if (#(Page.values) or 0) >= Page.minBytes then + for i=1,#Page.fields do + if #Page.values >= Page.minBytes then local f = Page.fields[i] if f.vals then - f.value = 0; - for idx=1, #(f.vals) do - local raw_val = (Page.values[f.vals[idx]] or 0) + f.value = 0 + for idx=1, #f.vals do + local raw_val = Page.values[f.vals[idx]] or 0 raw_val = bit32.lshift(raw_val, (idx-1)*8) f.value = bit32.bor(f.value, raw_val) end @@ -152,14 +127,13 @@ function clipValue(val,min,max) end local function incPage(inc) - currentPage = incMax(currentPage, inc, #(PageFiles)) - Page = nil + currentPage = incMax(currentPage, inc, #PageFiles) currentField = 1 - collectgarbage() + invalidatePages() end local function incField(inc) - currentField = clipValue(currentField + inc, 1, #(Page.fields)) + currentField = clipValue(currentField + inc, 1, #Page.fields) end local function incMainMenu(inc) @@ -167,33 +141,32 @@ local function incMainMenu(inc) end local function incPopupMenu(inc) - popupMenuActive = clipValue(popupMenuActive + inc, 1, #(popupMenuList)) + popupMenuActive = clipValue(popupMenuActive + inc, 1, #popupMenuList) end local function requestPage() - if Page.read and ((Page.reqTS == nil) or (Page.reqTS + requestTimeout <= getTime())) then + if Page.read and ((not Page.reqTS) or (Page.reqTS + requestTimeout <= getTime())) then Page.reqTS = getTime() protocol.mspRead(Page.read) end end -local function drawScreenTitle(screen_title) - if radio.resolution == lcdResolution.low then - lcd.drawFilledRectangle(0, 0, LCD_W, 10) - lcd.drawText(1,1,screen_title,INVERS) - else +local function drawScreenTitle(screenTitle) + if radio.highRes then lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR) - lcd.drawText(5,5,screen_title, MENU_TITLE_COLOR) + lcd.drawText(5,5,screenTitle, MENU_TITLE_COLOR) + else + lcd.drawFilledRectangle(0, 0, LCD_W, 10) + lcd.drawText(1,1,screenTitle,INVERS) end end local function drawScreen() - local yMinLim = radio.yMinLimit or 0 - local yMaxLim = radio.yMaxLimit or LCD_H + local yMinLim = radio.yMinLimit + local yMaxLim = radio.yMaxLimit local currentFieldY = Page.fields[currentField].y - local screenTitle = Page.title local textOptions = radio.textSize + globalTextOptions - drawScreenTitle("Betaflight / "..screenTitle) + drawScreenTitle("Betaflight / "..Page.title) if currentFieldY <= Page.fields[1].y then pageScrollY = 0 elseif currentFieldY - pageScrollY <= yMinLim then @@ -201,14 +174,15 @@ local function drawScreen() elseif currentFieldY - pageScrollY >= yMaxLim then pageScrollY = currentFieldY - yMaxLim end - for i=1,#(Page.labels) do + for i=1,#Page.labels do local f = Page.labels[i] - if (f.y - pageScrollY) >= yMinLim and (f.y - pageScrollY) <= yMaxLim then - lcd.drawText(f.x, f.y - pageScrollY, f.t, textOptions) + local y = f.y - pageScrollY + if y >= yMinLim and y <= yMaxLim then + lcd.drawText(f.x, y, f.t, textOptions) end end local val = "---" - for i=1,#(Page.fields) do + for i=1,#Page.fields do local f = Page.fields[i] local valueOptions = textOptions if i == currentField then @@ -226,22 +200,23 @@ local function drawScreen() val = f.table[f.value] end end - if (f.y - pageScrollY) >= yMinLim and (f.y - pageScrollY) <= yMaxLim then + local y = f.y - pageScrollY + if y >= yMinLim and y <= yMaxLim then if f.t then - lcd.drawText(f.x, f.y - pageScrollY, f.t, textOptions) + lcd.drawText(f.x, y, f.t, textOptions) end - lcd.drawText(f.sp or f.x, f.y - pageScrollY, val, valueOptions) + lcd.drawText(f.sp or f.x, y, val, valueOptions) end end end local function incValue(inc) local f = Page.fields[currentField] - local scale = (f.scale or 1) - local mult = (f.mult or 1) - f.value = clipValue(f.value + ((inc*mult)/scale), ((f.min or 0)/scale), ((f.max or 255)/scale)) - f.value = math.floor((f.value*scale)/mult + 0.5)/(scale/mult) - for idx=1, #(f.vals) do + local scale = f.scale or 1 + local mult = f.mult or 1 + f.value = clipValue(f.value + inc*mult/scale, (f.min or 0)/scale, (f.max or 255)/scale) + f.value = math.floor(f.value*scale/mult + 0.5)*mult/scale + for idx=1, #f.vals do Page.values[f.vals[idx]] = bit32.rshift(math.floor(f.value*scale + 0.5), (idx-1)*8) end if f.upd and Page.values then @@ -255,18 +230,18 @@ local function drawPopupMenu() local w = radio.MenuBox.w local h_line = radio.MenuBox.h_line local h_offset = radio.MenuBox.h_offset - local h = #(popupMenuList) * h_line + h_offset*2 + local h = #popupMenuList * h_line + h_offset*2 lcd.drawFilledRectangle(x,y,w,h,backgroundFill) lcd.drawRectangle(x,y,w-1,h-1,foregroundColor) lcd.drawText(x+h_line/2,y+h_offset,"Menu:",globalTextOptions) for i,e in ipairs(popupMenuList) do - local text_options = globalTextOptions + local textOptions = globalTextOptions if popupMenuActive == i then - text_options = text_options + INVERS + textOptions = textOptions + INVERS end - lcd.drawText(x+radio.MenuBox.x_offset,y+(i-1)*h_line+h_offset,e.t,text_options) + lcd.drawText(x+radio.MenuBox.x_offset,y+(i-1)*h_line+h_offset,e.t,textOptions) end end @@ -274,20 +249,17 @@ local function run_ui(event) if uiState == uiStatus.init then local yMinLim = radio.yMinLimit lcd.clear() - drawScreenTitle("Betaflight Config", 0, 0) + drawScreenTitle("Betaflight Config") lcd.drawText(6, yMinLim, "Initialising") if apiVersion == 0 then - if not init then - init = assert(loadScript(SCRIPT_HOME.."/data_init.lua"))() - end + init = init or assert(loadScript("data_init.lua"))() init() return 0 - else - init = nil - PageFiles = assert(loadScript(SCRIPT_HOME.."/pages.lua"))() - invalidatePages() - uiState = uiStatus.mainMenu end + init = nil + PageFiles = assert(loadScript("pages.lua"))() + invalidatePages() + uiState = uiStatus.mainMenu elseif uiState == uiStatus.mainMenu then if event == EVT_VIRTUAL_EXIT then return 2 @@ -296,15 +268,14 @@ local function run_ui(event) elseif event == EVT_VIRTUAL_PREV then incMainMenu(-1) elseif event == EVT_VIRTUAL_ENTER then - pageState = pageStatus.display uiState = uiStatus.pages end lcd.clear() - drawScreenTitle("Betaflight Config", 0, 0) + drawScreenTitle("Betaflight Config") local yMinLim = radio.yMinLimit local yMaxLim = radio.yMaxLimit local lineSpacing = 10 - if radio.resolution == lcdResolution.high then + if radio.highRes then lineSpacing = 25 end local currentFieldY = (currentPage-1)*lineSpacing + yMinLim @@ -316,29 +287,27 @@ local function run_ui(event) mainMenuScrollY = currentFieldY - yMaxLim end for i=1, #PageFiles do - local attr = (currentPage == i and INVERS or 0) - if ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) >= yMinLim and ((i-1)*lineSpacing + yMinLim - mainMenuScrollY) <= yMaxLim then - lcd.drawText(6, (i-1)*lineSpacing + yMinLim - mainMenuScrollY, PageFiles[i].title, attr) + local attr = currentPage == i and INVERS or 0 + local y = (i-1)*lineSpacing + yMinLim - mainMenuScrollY + if y >= yMinLim and y <= yMaxLim then + lcd.drawText(6, y, PageFiles[i].title, attr) end end elseif uiState == uiStatus.pages then - if (pageState == pageStatus.saving) then - if (saveTS + saveTimeout < getTime()) then + if pageState == pageStatus.saving then + if saveTS + saveTimeout < getTime() then if saveRetries < saveMaxRetries then saveSettings() else - -- max retries reached pageState = pageStatus.display invalidatePages() end end end - -- navigation if event == EVT_VIRTUAL_ENTER_LONG then popupMenuActive = 1 killEnterBreak = 1 pageState = pageStatus.popupMenu - -- menu is currently displayed elseif pageState == pageStatus.popupMenu then if event == EVT_VIRTUAL_EXIT then pageState = pageStatus.display @@ -354,7 +323,6 @@ local function run_ui(event) popupMenuList[popupMenuActive].f() end end - -- normal page viewing elseif pageState <= pageStatus.display then if event == EVT_VIRTUAL_PREV_PAGE then incPage(-1) @@ -378,7 +346,6 @@ local function run_ui(event) uiState = uiStatus.mainMenu return 0 end - -- editing value elseif pageState == pageStatus.editing then if event == EVT_VIRTUAL_EXIT or event == EVT_VIRTUAL_ENTER then pageState = pageStatus.display @@ -388,40 +355,31 @@ local function run_ui(event) incValue(-1) end end - if Page == nil then - if #PageFiles == 0 then - lcd.clear() - lcd.drawText(radio.NoTelem[1], radio.NoTelem[2], "No Pages! API: " .. apiVersion, radio.NoTelem[4]) - return 1 - end - Page = assert(loadScript(SCRIPT_HOME.."/Pages/"..PageFiles[currentPage].script))() + if not Page then + Page = assert(loadScript("Pages/"..PageFiles[currentPage].script))() collectgarbage() end if not Page.values and pageState == pageStatus.display then requestPage() end lcd.clear() - if TEXT_BGCOLOR then - lcd.drawFilledRectangle(0, 0, LCD_W, LCD_H, TEXT_BGCOLOR) - end drawScreen() if pageState == pageStatus.popupMenu then drawPopupMenu() elseif pageState == pageStatus.saving then + local saveMsg = "Saving..." + if saveRetries > 0 then + saveMsg = "Retrying" + end lcd.drawFilledRectangle(radio.SaveBox.x,radio.SaveBox.y,radio.SaveBox.w,radio.SaveBox.h,backgroundFill) lcd.drawRectangle(radio.SaveBox.x,radio.SaveBox.y,radio.SaveBox.w,radio.SaveBox.h,SOLID) - if saveRetries <= 0 then - lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,"Saving...",DBLSIZE + BLINK + (globalTextOptions)) - else - lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,"Retrying",DBLSIZE + (globalTextOptions)) - end + lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,saveMsg,DBLSIZE + globalTextOptions) end end - -- process send queue - mspProcessTxQ() if protocol.rssi() == 0 then lcd.drawText(radio.NoTelem[1],radio.NoTelem[2],radio.NoTelem[3],radio.NoTelem[4]) end + mspProcessTxQ() processMspReply(mspPollReply()) return 0 end diff --git a/src/SCRIPTS/FUNCTIONS/bfbkgd.lua b/src/SCRIPTS/FUNCTIONS/bfbkgd.lua index 8c43106d..fcaec519 100644 --- a/src/SCRIPTS/FUNCTIONS/bfbkgd.lua +++ b/src/SCRIPTS/FUNCTIONS/bfbkgd.lua @@ -1,8 +1,8 @@ -SCRIPT_HOME = "/SCRIPTS/BF" +chdir("/SCRIPTS/BF") apiVersion = 0 -protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() +protocol = assert(loadScript("protocols.lua"))() assert(loadScript(protocol.transport))() -assert(loadScript(SCRIPT_HOME.."/MSP/common.lua"))() -local background = assert(loadScript(SCRIPT_HOME.."/background.lua"))() +assert(loadScript("MSP/common.lua"))() +local background = assert(loadScript("background.lua"))() return { run=background } diff --git a/src/SCRIPTS/FUNCTIONS/pids.lua b/src/SCRIPTS/FUNCTIONS/pids.lua index 2b207643..c2041e22 100644 --- a/src/SCRIPTS/FUNCTIONS/pids.lua +++ b/src/SCRIPTS/FUNCTIONS/pids.lua @@ -1,6 +1,6 @@ -SCRIPT_HOME = "/SCRIPTS/BF" +chdir("/SCRIPTS/BF") -assert(loadScript(SCRIPT_HOME.."/MSP/messages.lua"))() +assert(loadScript("MSP/messages.lua"))() local msg_p = { intro = "p.wav", diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index c6f4d57d..07c0082a 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -1,14 +1,14 @@ local toolName = "TNS|Betaflight setup|TNE" -SCRIPT_HOME = "/SCRIPTS/BF" +chdir("/SCRIPTS/BF") apiVersion = 0 -protocol = assert(loadScript(SCRIPT_HOME.."/protocols.lua"))() -radio = assert(loadScript(SCRIPT_HOME.."/radios.lua"))() +protocol = assert(loadScript("protocols.lua"))() +radio = assert(loadScript("radios.lua"))() assert(loadScript(protocol.transport))() -assert(loadScript(SCRIPT_HOME.."/MSP/common.lua"))() +assert(loadScript("MSP/common.lua"))() -local run_ui = assert(loadScript(SCRIPT_HOME.."/ui.lua"))() +local run_ui = assert(loadScript("ui.lua"))() return { run=run_ui } From f17ea5dcba285df0ef3c4c9df87aacfbd5aea1ee Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 12 Feb 2020 17:43:30 +0100 Subject: [PATCH 071/193] Compile script Adds a script that compiles all Betaflight lua files the first time bf.lua is executed. build.sh has been repurposed to create a file containing a table with the files to be compiled. The .lua files are tested for errors using luac -p. No .luac files are created. --- bin/build.sh | 21 ++++++++++++++++----- src/SCRIPTS/BF/COMPILE/compile.lua | 21 +++++++++++++++++++++ src/SCRIPTS/BF/COMPILE/scripts_compiled.lua | 1 + src/SCRIPTS/TOOLS/bf.lua | 19 ++++++++++++------- 4 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 src/SCRIPTS/BF/COMPILE/compile.lua create mode 100644 src/SCRIPTS/BF/COMPILE/scripts_compiled.lua diff --git a/bin/build.sh b/bin/build.sh index ff6dbdf0..a58209fa 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -16,20 +16,31 @@ if [ ${#MANIFEST[@]} -eq 0 ]; then exit 1 fi +SCRIPTS_LUA=obj/SCRIPTS/BF/COMPILE/scripts.lua + +echo 'local scripts = {' >> $SCRIPTS_LUA +for f in ${MANIFEST[@]}; +do + echo ' ''"'${f/\obj/}'",' >> $SCRIPTS_LUA +done +echo '}' >> $SCRIPTS_LUA +echo 'return scripts[...]' >> $SCRIPTS_LUA + +MANIFEST+=($SCRIPTS_LUA); + for f in ${MANIFEST[@]}; do SRC_NAME=$f - OBJ_NAME=$(dirname ${f})/$(basename ${f} .lua).luac - echo -e "Compiling file \e[1m${SRC_NAME}\e[21m..." - luac -s -o ${OBJ_NAME} ${SRC_NAME} + echo -e "Testing file \e[1m${SRC_NAME}\e[21m..." + luac -p ${SRC_NAME} _fail=$? if [[ $_fail -ne 0 ]]; then LAST_FAILURE=$_fail - echo -e "\e[1m\e[39m[\e[31mBUILD FAILED\e[39m]\e[21m Compilation error in file ${SRC_NAME}\e[1m" + echo -e "\e[1m\e[39m[\e[31mBUILD FAILED\e[39m]\e[21m Error in file ${SRC_NAME}\e[1m" fi done if [[ $LAST_FAILURE -eq 0 ]]; then - echo -e "\e[1m\e[39m[\e[32mTEST SUCCESSFUL\e[39m]\e[21m All lua files built successfully!" + echo -e "\e[1m\e[39m[\e[32mTEST SUCCESSFUL\e[39m]\e[21m" fi exit $LAST_FAILURE diff --git a/src/SCRIPTS/BF/COMPILE/compile.lua b/src/SCRIPTS/BF/COMPILE/compile.lua new file mode 100644 index 00000000..d2bbc0d0 --- /dev/null +++ b/src/SCRIPTS/BF/COMPILE/compile.lua @@ -0,0 +1,21 @@ +local i = 1 + +local function compile() + local script = assert(loadScript("COMPILE/scripts.lua"))(i) + collectgarbage() + i = i + 1 + if script then + lcd.clear() + lcd.drawText(2, 2, "Compiling...", SMLSIZE) + lcd.drawText(2, 22, script, SMLSIZE) + assert(loadScript(script, 'c')) + collectgarbage() + return 0 + end + local file = io.open("COMPILE/scripts_compiled.lua", 'w') + io.write(file, "return true") + io.close(file) + return 1 +end + +return compile diff --git a/src/SCRIPTS/BF/COMPILE/scripts_compiled.lua b/src/SCRIPTS/BF/COMPILE/scripts_compiled.lua new file mode 100644 index 00000000..585a20e0 --- /dev/null +++ b/src/SCRIPTS/BF/COMPILE/scripts_compiled.lua @@ -0,0 +1 @@ +return false diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index 07c0082a..af3d420b 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -3,12 +3,17 @@ chdir("/SCRIPTS/BF") apiVersion = 0 -protocol = assert(loadScript("protocols.lua"))() -radio = assert(loadScript("radios.lua"))() +local run = nil +local scriptsCompiled = assert(loadScript("COMPILE/scripts_compiled.lua"))() -assert(loadScript(protocol.transport))() -assert(loadScript("MSP/common.lua"))() +if scriptsCompiled then + protocol = assert(loadScript("protocols.lua"))() + radio = assert(loadScript("radios.lua"))() + assert(loadScript(protocol.transport))() + assert(loadScript("MSP/common.lua"))() + run = assert(loadScript("ui.lua"))() +else + run = assert(loadScript("COMPILE/compile.lua"))() +end -local run_ui = assert(loadScript("ui.lua"))() - -return { run=run_ui } +return { run=run } From 94a5b63d457b7787157064334e99c326d947bdc3 Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 16 Feb 2020 19:49:24 +1300 Subject: [PATCH 072/193] Added 'clean' task to Makefile. --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b654b915..a220bac2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,10 @@ all: bin/build.sh -release: all +clean: + rm -rf obj/* + +release: clean all FILE_NAME="betaflight-tx-lua-scripts_$$(git describe --abbrev=0 --tags).zip"; \ rm -f $${FILE_NAME}; \ zip -r $${FILE_NAME} obj/ From 518ca36cfbbde73526cc12028e13db787ecc8f3f Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 17 Feb 2020 21:17:13 +0100 Subject: [PATCH 073/193] Move event handler for EVT_VIRTUAL_ENTER_LONG to a more appropriate place. It now lives in the display state. --- src/SCRIPTS/BF/ui.lua | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index f5a52518..f6d03fca 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -303,11 +303,6 @@ local function run_ui(event) invalidatePages() end end - end - if event == EVT_VIRTUAL_ENTER_LONG then - popupMenuActive = 1 - killEnterBreak = 1 - pageState = pageStatus.popupMenu elseif pageState == pageStatus.popupMenu then if event == EVT_VIRTUAL_EXIT then pageState = pageStatus.display @@ -323,7 +318,7 @@ local function run_ui(event) popupMenuList[popupMenuActive].f() end end - elseif pageState <= pageStatus.display then + elseif pageState == pageStatus.display then if event == EVT_VIRTUAL_PREV_PAGE then incPage(-1) killEvents(event) -- X10/T16 issue: pageUp is a long press @@ -340,6 +335,10 @@ local function run_ui(event) pageState = pageStatus.editing end end + elseif event == EVT_VIRTUAL_ENTER_LONG then + popupMenuActive = 1 + killEnterBreak = 1 + pageState = pageStatus.popupMenu elseif event == EVT_VIRTUAL_EXIT then invalidatePages() currentField = 1 From 300fdb3a8b4167100eba2f049805bcd44d2aa7e2 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 18 Feb 2020 22:59:50 +0100 Subject: [PATCH 074/193] Prevent double compile Forces a recompile of scripts_compiled.lua after writing to it. This ensures that the .lua and .luac are the same and prevents a potential recompile the next time bf.lua is launched. --- src/SCRIPTS/BF/COMPILE/compile.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SCRIPTS/BF/COMPILE/compile.lua b/src/SCRIPTS/BF/COMPILE/compile.lua index d2bbc0d0..b6f8fd22 100644 --- a/src/SCRIPTS/BF/COMPILE/compile.lua +++ b/src/SCRIPTS/BF/COMPILE/compile.lua @@ -15,6 +15,7 @@ local function compile() local file = io.open("COMPILE/scripts_compiled.lua", 'w') io.write(file, "return true") io.close(file) + assert(loadScript("COMPILE/scripts_compiled.lua", 'c')) return 1 end From ac9d186b24deffc134fa2df18afb508c46dedf41 Mon Sep 17 00:00:00 2001 From: Michael Keller Date: Fri, 21 Feb 2020 20:33:29 +1300 Subject: [PATCH 075/193] Added azure build. --- Makefile | 18 ++++++++----- azure-pipelines.yml | 65 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 azure-pipelines.yml diff --git a/Makefile b/Makefile index a220bac2..f1a618d9 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,16 @@ -all: - bin/build.sh +DIR := ${CURDIR} + +all: files + +files: + @bin/build.sh clean: - rm -rf obj/* + @rm -rf obj/* -release: clean all +release: clean files + @RELEASE_DIR=release; \ FILE_NAME="betaflight-tx-lua-scripts_$$(git describe --abbrev=0 --tags).zip"; \ - rm -f $${FILE_NAME}; \ - zip -r $${FILE_NAME} obj/ + mkdir -p $${RELEASE_DIR}; \ + rm -f $${RELEASE_DIR}/$${FILE_NAME}; \ + zip -q -r $${RELEASE_DIR}/$${FILE_NAME} obj/ diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 00000000..04198bdb --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,65 @@ +# Builds the Betaflight TX lua scripts. +# +# After building, artifacts are released to a seperate repository. +# +# Azure Pipelines requires the following extensions to be installed: +# - GitHub Tool: https://marketplace.visualstudio.com/items?itemName=marcelo-formentao.github-tools +# +# You'll also need to setup the follwing pipeline variables: +# "releaseNotes" - This is used to add the release notes in the windows job in the build stage so they can be published as part of the github release in the release stage +# "endpoint" - The name of the github endpoint link setup in AzDo - setup when linking AzDo and GitHub +# "owner" - The owner of the repository to release to e.g. betaflight +# "repoName" - The name of the repository to release to e.g. betaflight-configurator-nightly + +name: $(Date:yyyyMMdd).$(BuildID) +trigger: + batch: true + branches: + include: + - master +pr: none + +stages: +- stage: Build + jobs: + - job: 'Linux' + pool: + vmImage: 'ubuntu-16.04' + steps: + - script: sudo apt-get -y install lua5.2 + displayName: 'Install lua compiler.' + - script: make release -C $(System.DefaultWorkingDirectory) + displayName: 'Test and build the release.' + - powershell: Set-Content -Path '$(System.DefaultWorkingDirectory)/release/log.txt' -Value $env:BUILD_SOURCEVERSIONMESSAGE + - task: PublishPipelineArtifact@1 + displayName: 'Publish release' + inputs: + artifactName: betaflight-tx-lua-scripts + targetPath: '$(System.DefaultWorkingDirectory)/release' + +- stage: Release + jobs: + - job: Release + steps: + - task: DownloadPipelineArtifact@2 + inputs: + buildType: 'current' + targetPath: '$(Pipeline.Workspace)' + - powershell: Write-Output ("##vso[task.setvariable variable=releaseNotes;]$(gc $(Pipeline.Workspace)/betaflight-tx-lua-scripts/log.txt)") + - task: GitHubReleasePublish@1 + inputs: + githubEndpoint: '$(endpoint)' + manuallySetRepository: true + githubOwner: '$(owner)' + githubRepositoryName: '$(repoName)' + githubReleaseNotes: '$(releaseNotes)' + githubReleaseDraft: false + githubReleasePrerelease: false + githubIgnoreAssets: false + githubReleaseAsset: | + $(Pipeline.Workspace)/betaflight-tx-lua-scripts/** + githubReuseRelease: true + githubReuseDraftOnly: true + githubSkipDuplicatedAssets: false + githubEditRelease: false + githubDeleteEmptyTag: false From b2f05bfa814fa8f9becaa754117da4b58fb5fa8e Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 23 Feb 2020 15:59:14 +0100 Subject: [PATCH 076/193] VTX Table download Downloads vtx tables if supported and available. This is done as part of ui.lua's init state. The vtx tables are saved as /BF/VTX/modelname.lua where "modelname" is the name of the currently selected model. Delete this file if the vtx tables need to be updated for some reason. The script will download them again. --- src/SCRIPTS/BF/ui.lua | 7 +- src/SCRIPTS/BF/ui_init.lua | 28 ++++++++ src/SCRIPTS/BF/vtx_tables.lua | 119 ++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 5 deletions(-) create mode 100644 src/SCRIPTS/BF/ui_init.lua create mode 100644 src/SCRIPTS/BF/vtx_tables.lua diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index f6d03fca..77dd57e1 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -247,13 +247,10 @@ end local function run_ui(event) if uiState == uiStatus.init then - local yMinLim = radio.yMinLimit lcd.clear() drawScreenTitle("Betaflight Config") - lcd.drawText(6, yMinLim, "Initialising") - if apiVersion == 0 then - init = init or assert(loadScript("data_init.lua"))() - init() + init = init or assert(loadScript("ui_init.lua"))() + if not init() then return 0 end init = nil diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua new file mode 100644 index 00000000..e31e9dac --- /dev/null +++ b/src/SCRIPTS/BF/ui_init.lua @@ -0,0 +1,28 @@ +local apiVersionReceived = false +local vtxTablesReceived = loadScript("/BF/VTX/"..model.getInfo().name..".lua") +local data_init, getVtxTables + +local function init() + if apiVersion == 0 then + lcd.drawText(6, radio.yMinLimit, "Initialising") + data_init = data_init or assert(loadScript("data_init.lua"))() + data_init() + elseif apiVersion > 0 and not apiVersionReceived then + data_init = nil + apiVersionReceived = true + collectgarbage() + elseif apiVersion >= 1.042 and not vtxTablesReceived then + lcd.drawText(6, radio.yMinLimit, "Downloading VTX Tables") + getVtxTables = getVtxTables or assert(loadScript("vtx_tables.lua"))() + vtxTablesReceived = getVtxTables() + if vtxTablesReceived then + getVtxTables = nil + collectgarbage() + end + else + return true + end + return apiVersionReceived and vtxTablesReceived +end + +return init diff --git a/src/SCRIPTS/BF/vtx_tables.lua b/src/SCRIPTS/BF/vtx_tables.lua new file mode 100644 index 00000000..83ca15ea --- /dev/null +++ b/src/SCRIPTS/BF/vtx_tables.lua @@ -0,0 +1,119 @@ +local MSP_VTX_CONFIG = 88 +local MSP_VTXTABLE_BAND = 137 +local MSP_VTXTABLE_POWERLEVEL = 138 + +local vtxTableAvailable = false +local vtxConfigReceived = false +local vtxFrequencyTableReceived = false +local vtxPowerTableReceived = false +local vtxTablesReceived = false +local requestedBand = 1 +local requestedPowerLevel = 1 +local vtxTableConfig = {} +local frequencyTable = {} +local frequenciesPerBand = 0 +local bandTable = {} +local powerTable = {} + +local lastRunTS = 0 +local INTERVAL = 100 + +local function processMspReply(cmd, payload) + if cmd == MSP_VTX_CONFIG then + vtxConfigReceived = true + vtxTableAvailable = payload[12] ~= 0 + vtxTableConfig.bands = payload[13] + vtxTableConfig.channels = payload[14] + vtxTableConfig.powerLevels = payload[15] + end + if cmd == MSP_VTXTABLE_BAND and payload[1] == requestedBand then + local i = 1 + local receivedBand = payload[i] + i = i + 1 + local bandNameLength = payload[i] + i = i + bandNameLength + 1 + bandTable[receivedBand] = string.char(payload[i]) + i = i + 2 + local channels = payload[i] + i = i + 1 + frequencyTable[receivedBand] = {} + for channel = 1, channels do + local frequency = 0 + for idx=1, 2 do + local raw_val = payload[i] + raw_val = bit32.lshift(raw_val, (idx-1)*8) + frequency = bit32.bor(frequency, raw_val) + i = i + 1 + end + frequencyTable[receivedBand][channel] = frequency + end + requestedBand = requestedBand + 1 + vtxFrequencyTableReceived = requestedBand > vtxTableConfig.bands + end + if cmd == MSP_VTXTABLE_POWERLEVEL and payload[1] == requestedPowerLevel then + local i = 1 + local powerLevel = payload[i] + i = i + 3 + local powerLabelLength = payload[i] + i = i + 1 + powerTable[powerLevel] = '' + for c = 1, powerLabelLength do + powerTable[powerLevel] = powerTable[powerLevel]..string.char(payload[i]) + i = i + 1 + end + requestedPowerLevel = requestedPowerLevel + 1 + vtxPowerTableReceived = requestedPowerLevel > vtxTableConfig.powerLevels + end +end + +local function getVtxTables() + if lastRunTS + INTERVAL < getTime() then + lastRunTS = getTime() + if not vtxConfigReceived then + protocol.mspRead(MSP_VTX_CONFIG) + elseif vtxConfigReceived and not vtxTableAvailable then + return true + elseif not vtxFrequencyTableReceived then + protocol.mspWrite(MSP_VTXTABLE_BAND, { requestedBand }) + elseif not vtxPowerTableReceived then + protocol.mspWrite(MSP_VTXTABLE_POWERLEVEL, { requestedPowerLevel }) + else + vtxTablesReceived = true + end + end + if vtxTablesReceived then + local f = io.open("/BF/VTX/"..model.getInfo().name..".lua", 'w') + io.write(f, "return {", "\n") + io.write(f, " frequencyTable = {", "\n") + for i = 1, #frequencyTable do + local frequencyString = " { " + for k = 1, #frequencyTable[i] do + frequencyString = frequencyString..tostring(frequencyTable[i][k])..", " + end + frequencyString = frequencyString.."}," + io.write(f, frequencyString, "\n") + end + io.write(f, " },", "\n") + io.write(f, " frequenciesPerBand = "..tostring(vtxTableConfig.channels)..",", "\n") + local bandString = " bandTable = { [0]=\"U\", " + for i = 1, #bandTable do + bandString = bandString.."\""..bandTable[i].."\", " + end + bandString = bandString.."}," + io.write(f, bandString, "\n") + local powerString = " powerTable = { " + for i = 1, #powerTable do + powerString = powerString.."\""..powerTable[i].."\", " + end + powerString = powerString.."}," + io.write(f, powerString, "\n") + io.write(f, "}", "\n") + io.close(f) + assert(loadScript("/BF/VTX/"..model.getInfo().name..".lua", 'c')) + end + mspProcessTxQ() + processMspReply(mspPollReply()) + return vtxTablesReceived +end + +return getVtxTables From 16a01fdb926f82f73de1509923a64a6980dc8f93 Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 1 Mar 2020 16:53:45 +1300 Subject: [PATCH 077/193] Updated README.md. --- README.md | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 28b4a950..a55ad2d7 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,21 @@ # betaflight-tx-lua-scripts -**Important:** - -*Some changes in OpenTX 2.2.1 cause this version to have less RAM available for lua scripts than previous versions. The recommendation is for users wanting to update OpenTX on a Taranis X9D (and keep using the Betaflight TX lua scripts) is to use 2.3.1 or higher.* - ## How to download the scripts Please visit the [releases page](https://github.com/betaflight/betaflight-tx-lua-scripts/releases) to download a zip file containing latest version. ## Firmware Considerations -- Betaflight - As a best practice, it is recommended to use the most recent stable release of Betaflight to obtain the best possible results. -- Crossfire - v2.11 or greater -- FrSky - While most receivers work fine, it's recommended to update the XSR family of receivers to their most recent firmware version to correct any known bugs in SmartPort telemetry. +- Betaflight - 4.1.0 or newer. As a best practice, it is recommended to use the most recent stable release of Betaflight to obtain the best possible results; +- OpenTX - 2.3.4 or newer; +- Crossfire TX / RX - v2.11 or newer; +- FrSky TX / RX - While most receivers work fine, it's recommended to update the XSR family of receivers to their most recent firmware version to correct any known bugs in SmartPort telemetry. ## Installing **!! IMPORTANT: DON'T COPY THE CONTENTS OF THIS REPOSITORY ONTO YOUR SDCARD !!** -Unzip the files from the link above and drag the contents to your radio. If you do this correctly, the SCRIPTS directory will merge with your existing directories, placing the scripts in their appropriate paths. You will know if you did this correctly if the bf.lua file shows up in your /SCRIPTS/TELEMETRY directory. +Unzip the files from the link above and drag the contents to your radio. If you do this correctly, the SCRIPTS directory will merge with your existing directories, placing the scripts in their appropriate paths. You will know if you did this correctly if the `bf.lua` file shows up in your `/SCRIPTS/TOOLS` directory. The src directory is not required for use and is only available for maintenance of the code. While it may work to use this directory, you may encounter memory issues on your transmitter. @@ -39,28 +36,18 @@ Manual method (varies, based on the model of your transmitter) 4. Reinsert your SD card into the transmitter 5. Power up your transmitter. -If you copied the files correctly, you can now go into the OpenTx Tools screen (Since OpenTx 2.3.0) and access the Betaflight Configuration tool, or you can use the telemetry screen setup page and set up the script as telemetry page. - -### Adding the script as a telemetry page - -Setting up the script as a telemetry page will enable access at the press of a button. (For now, this only applies to the Taranis X9D series). +If you copied the files correctly, you can now go into the OpenTx Tools screen from the main menu and access the Betaflight Configuration tool. The first time you run the script, a message 'Compiling...' will appear in the display before the script is started - this is normal, and is done to minimise the RAM usage of the script. -1. Hit the [MENU] button and select the model for which you would like to enable the script. -2. While on the [MODEL SELECTION] screen, long-press the [PAGE] button to navigate to the [DISPLAY] page. -3. Use the [-] button to move the cursor down to [Screen 1] and hit [ENT]. -4. Use the [+] or [-] buttons to select the [Script] option and press [ENT]. -5. Press [-] to move the cursor to the script selection field and hit [ENT]. -6. Select 'bf' and hit [ENT]. -7. Long-press [EXIT] to return to your model screen. +### Running the script as a telemetry page -To invoke the script, simply long-press the [PAGE] button from the model screen. +Due to issues with input mapping and memory overruns, running the script as a telemetry page **is no longer supported**. The only way to run the script is through the Tools screen in the OpenTX main menu. ### Setting up VTX Tables -If you are using a VTX that supports the SmartAudio or Tramp protocols then bands and channels etc. are managed using vtx tables since firmware version 4.1.0. The betaflight configurator will allow you to save your configuration to a _craftname_.lua file. Place this into the BF\VTX folder on the root of the SD card and rename it to match the model you use on your transmitter for this craft. The lua scrips will then use this information on the VTX configuration screen instead of the defaults. +If you are using a VTX that supports the SmartAudio or Tramp protocols then bands and channels etc. are managed using VTX tables since Betaflight version 4.1.0. The script will be downloading and storing the current VTX table for every model the first time the model is connected and the script is run. If you change the VTX table, you have to re-load the updated VTX table in the script, by choosing the 'vtx tables' option in the function menu. ## Building from source -- Be sure to have `LUA 5.2` installed in the path -- Run `./bin/build.sh` from the root folder -- Compiled files will be created a the `obj` in the root folder. Copy the files to your transmitter as instructed in the `Installing` section below as if you unzipped from a downloaded file. \ No newline at end of file +- Be sure to have `make` and `luac` in version 5.2 installed in the path +- Run `make` from the root folder +- The installation files will be created a the `obj` in the root folder. Copy the files to your transmitter as instructed in the '[Installing](#installing)' section below as if you unzipped from a downloaded file. From 405926484ebdd8ebc27e1f6354bf0baddca7a4eb Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sat, 29 Feb 2020 12:08:08 +0100 Subject: [PATCH 078/193] Add vtx tables download to popup menu Deletes the contents of the .lua file containing vtx tables for the selected model and downloads them again. The menu item is only available for firmwares supporting vtx tables. --- src/SCRIPTS/BF/ui.lua | 28 +++++++++++++++++++++------- src/SCRIPTS/BF/ui_init.lua | 9 ++++++++- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 77dd57e1..04d59058 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -32,7 +32,7 @@ local popupMenuActive = 1 local killEnterBreak = 0 local pageScrollY = 0 local mainMenuScrollY = 0 -local PageFiles, Page, init +local PageFiles, Page, init, popupMenuList local backgroundFill = TEXT_BGCOLOR or ERASE local foregroundColor = LINE_COLOR or SOLID @@ -72,11 +72,24 @@ local function eepromWrite() protocol.mspRead(uiMsp.eepromWrite) end -local popupMenuList = { - { t = "save page", f = saveSettings }, - { t = "reload", f = invalidatePages }, - { t = "reboot", f = rebootFc }, -} +local function getVtxTables() + uiState = uiStatus.init + PageFiles = nil + invalidatePages() + io.close(io.open("/BF/VTX/"..model.getInfo().name..".lua", 'w')) + return 0 +end + +local function createPopupMenu() + popupMenuList = { + { t = "save page", f = saveSettings }, + { t = "reload", f = invalidatePages }, + { t = "reboot", f = rebootFc }, + } + if apiVersion >= 1.042 then + popupMenuList[#popupMenuList + 1] = { t = "vtx tables", f = getVtxTables } + end +end local function processMspReply(cmd,rx_buf) if not Page or not rx_buf then @@ -254,6 +267,7 @@ local function run_ui(event) return 0 end init = nil + createPopupMenu() PageFiles = assert(loadScript("pages.lua"))() invalidatePages() uiState = uiStatus.mainMenu @@ -312,7 +326,7 @@ local function run_ui(event) killEnterBreak = 0 else pageState = pageStatus.display - popupMenuList[popupMenuActive].f() + return popupMenuList[popupMenuActive].f() or 0 end end elseif pageState == pageStatus.display then diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index e31e9dac..8686b5dc 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -1,6 +1,13 @@ local apiVersionReceived = false -local vtxTablesReceived = loadScript("/BF/VTX/"..model.getInfo().name..".lua") +local vtxTablesReceived = false local data_init, getVtxTables +local vtxTables = loadScript("/BF/VTX/"..model.getInfo().name..".lua") + +if vtxTables and vtxTables() then + vtxTablesReceived = true + vtxTables = nil + collectgarbage() +end local function init() if apiVersion == 0 then From 6aa590db9377a00a9fddf9734246f129ff7ea1b2 Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 8 Mar 2020 14:37:28 +1300 Subject: [PATCH 079/193] Updated documentation from template repository. --- .github/issue_template.md | 12 +++++++++ .github/pull_request_template.md | 19 +++++++++++++ CODE_OF_CONDUCT.md | 46 ++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 13 +++++++++ LICENSE | 14 +++++----- 5 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 .github/issue_template.md create mode 100644 .github/pull_request_template.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 00000000..5c797982 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,12 @@ +# If your issue looks like a hardware fault or a configuration problem please don't raise an issue here. + +## Please consider using other user support options such as asking the manufacturer of the hardware you are using, RCGroups: https://rcgroups.com/forums/showthread.php?t=2464844, or Slack (registration at https://slack.betaflight.com/) or other user support forums & groups (e.g. Facebook). + +## If you believe there is an issue with the firmware itself please follow these steps: +1. Describe your problem; +2. Include ways to reproduce the problem; +3. Provide as much information as possible about your hardware and software, including: +- what hardware / software you are using; +- the version of all the software used; +- how things are connected / wired up. +4. Remove this Text :). diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..c6c4eb30 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,19 @@ +## Important considerations when opening a pull request: + +1. Make sure you do not make the changes you want to open a pull request for on the `master` branch of your fork, or open the pull request from the `master` branch of your fork. Some of our integrations will fail if you do this, resulting in your pull request not being accepted. If this is your first pull request, it is probably a good idea to first read up on how opening pull requests work (https://opensource.com/article/19/7/create-pull-request-github is a good introduction); + +2. Pull requests will only be accepted if they are opened against the `master` branch of our repository. Pull requests opened against other branches without prior consent from the maintainers will be closed; + +3. Please follow the coding style guidelines: https://github.com/cleanflight/cleanflight/blob/master/docs/development/CodingStyle.md + +4. Keep your pull requests as small and concise as possible. One pull request should only ever add / update one feature. If the change that you are proposing has a wider scope, consider splitting it over multiple pull requests. In particular, pull requests that combine changes to features and one or more new targets are not acceptable. + +5. Ideally, a pull request should contain only one commit, with a descriptive message. If your changes use more than one commit, rebase / squash them into one commit before submitting a pull request. If you need to amend your pull request, make sure that the additional commit has a descriptive message, or - even better - use `git commit --amend` to amend your original commit. + +6. All pull requests are reviewed. Be ready to receive constructive criticism, and to learn and improve your coding style. Also, be ready to clarify anything that isn't already sufficiently explained in the code and text of the pull request, and to defend your ideas. + +7. We use continuous integration (CI) with [Travis](https://travis-ci.com/betaflight) to build all targets and run the test suite for every pull request. Pull requests that fail any of the builds or fail tests will most likely not be reviewed before they are fixed to build successfully and pass the tests. In order to get a quick idea if there are things that need fixing **before** opening a pull request or pushing an update into an existing pull request, run `make pre-push` to run a representative subset of the CI build. _Note: This is not an exhaustive test(which will take hours to run on any desktop type system), so even if this passes the CI build might still fail._ + +8. If your pull request is a fix for one or more issues that are open in GitHub, add a comment to your pull request, and add the issue numbers of the issues that are fixed in the form `Fixes #`. This will cause the issues to be closed when the pull request is merged; + +9. Remove this Text :). diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..f858f60d --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at conduct-violations@betaflight.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..bad6bbd9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Issues and Support. + +Please remember the issue tracker on github is _not_ for user support. Please also do not email developers directly for support. Instead please use IRC or the forums first, then if the problem is confirmed create an issue that details how to repeat the problem so it can be investigated. + +Issues created without steps to repeat are likely to be closed. E-mail requests for support will go un-answered; All support needs to be public so that other people can read the problems and solutions. + +Remember that issues that are due to mis-configuration, wiring or failure to read documentation just takes time away from the developers and can often be solved without developer interaction by other users. + +Please search for existing issues *before* creating new ones. + +# Developers + +Please refer to the development section in the [this folder](https://github.com/betaflight/betaflight/tree/master/docs/development). diff --git a/LICENSE b/LICENSE index 9cecc1d4..f288702d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - {one line to give the program's name and a brief idea of what it does.} - Copyright (C) {year} {name of author} + + Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -645,14 +645,14 @@ the "copyright" line and a pointer to where the full notice is found. GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: - {project} Copyright (C) {year} {fullname} + Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see -. +. The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read -. +. From 909687cb7c277659c507ed110c42c6a81730c4ab Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 9 Mar 2020 15:04:47 +0100 Subject: [PATCH 080/193] Fix "Radio not supported" message --- src/SCRIPTS/BF/protocols.lua | 6 +----- src/SCRIPTS/BF/radios.lua | 7 ++----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/SCRIPTS/BF/protocols.lua b/src/SCRIPTS/BF/protocols.lua index de50da10..d0c1951d 100644 --- a/src/SCRIPTS/BF/protocols.lua +++ b/src/SCRIPTS/BF/protocols.lua @@ -32,10 +32,6 @@ local function getProtocol() end end -local protocol = getProtocol() - -if not protocol then - error("Telemetry protocol not supported!") -end +local protocol = assert(getProtocol(), "Telemetry protocol not supported!") return protocol diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index f42f4ddc..6f200e4c 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -44,10 +44,7 @@ local supportedRadios = }, } -local radio = supportedRadios[tostring(LCD_W) .. "x" .. tostring(LCD_H)] - -if not radio then - error("Radio not supported: "..rad) -end +local resolution = LCD_W.."x"..LCD_H +local radio = assert(supportedRadios[resolution], resolution.." not supported") return radio From a72f907d7523f82239f40a9a26aa0f5921c02c3c Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 12 Mar 2020 21:30:17 +0100 Subject: [PATCH 081/193] Fix vtx frequency backward compatibility --- src/SCRIPTS/BF/PAGES/vtx.lua | 2 ++ src/SCRIPTS/BF/ui.lua | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index bccdedab..dc2168d5 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -35,6 +35,8 @@ end if apiVersion >= 1.037 then fields[#fields + 1] = { t = "Frequency", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end } +elseif apiVersion >= 1.036 then + fields[#fields + 1] = { t = "Frequency", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 5000, max = 5999, ro = true } end -- Vals Fields diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 04d59058..c65dfd09 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -342,7 +342,7 @@ local function run_ui(event) elseif event == EVT_VIRTUAL_ENTER then if Page then local f = Page.fields[currentField] - if Page.values and Page.values[f.vals[#f.vals]] and not f.ro then + if Page.values and f.vals and Page.values[f.vals[#f.vals]] and not f.ro then pageState = pageStatus.editing end end From 04b0dd2293121a8369d5377db4cd0b8342de849c Mon Sep 17 00:00:00 2001 From: mikeller Date: Sat, 21 Mar 2020 17:20:26 +1300 Subject: [PATCH 082/193] Moved non-azure-dependent build settings into YAML variables. --- azure-pipelines.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 04198bdb..3cd7f376 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -11,6 +11,11 @@ # "owner" - The owner of the repository to release to e.g. betaflight # "repoName" - The name of the repository to release to e.g. betaflight-configurator-nightly +variables: + owner: betaflight + repoName: betaflight-tx-lua-scripts-nightlies + releaseNotes: This is a nightly build off the tip of 'master'. It may be unstable and result in corrupted configurations or data loss. **Use only for testing.** + name: $(Date:yyyyMMdd).$(BuildID) trigger: batch: true From 256ef17f4dd57c4c4f85474ec2c49e8bb3411128 Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 22 Mar 2020 20:02:03 +1300 Subject: [PATCH 083/193] Improved the Azure build. --- azure-pipelines.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 3cd7f376..66f7f867 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -35,7 +35,6 @@ stages: displayName: 'Install lua compiler.' - script: make release -C $(System.DefaultWorkingDirectory) displayName: 'Test and build the release.' - - powershell: Set-Content -Path '$(System.DefaultWorkingDirectory)/release/log.txt' -Value $env:BUILD_SOURCEVERSIONMESSAGE - task: PublishPipelineArtifact@1 displayName: 'Publish release' inputs: @@ -50,14 +49,17 @@ stages: inputs: buildType: 'current' targetPath: '$(Pipeline.Workspace)' - - powershell: Write-Output ("##vso[task.setvariable variable=releaseNotes;]$(gc $(Pipeline.Workspace)/betaflight-tx-lua-scripts/log.txt)") - task: GitHubReleasePublish@1 inputs: githubEndpoint: '$(endpoint)' manuallySetRepository: true githubOwner: '$(owner)' githubRepositoryName: '$(repoName)' - githubReleaseNotes: '$(releaseNotes)' + githubReleaseNotes: |+ + $(releaseNotes) + + ### Changes: + $(Build.SourceVersionMessage) githubReleaseDraft: false githubReleasePrerelease: false githubIgnoreAssets: false From 46328a608e4554fd6ee419559570ac37c705a029 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 31 Mar 2020 18:10:39 +0200 Subject: [PATCH 084/193] Update I Term Relax Cutoff max Max is changed from 100 to 50 for MSP version 1.43 --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 0bc820eb..a922cb8d 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -36,7 +36,9 @@ if apiVersion >= 1.040 then labels[#labels + 1] = { t = "I Term Relax", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Axes", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } } fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } } - if apiVersion >= 1.042 then + if apiVersion >= 1.043 then + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 50, vals = { 47 } } + elseif apiVersion >= 1.042 then fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 100, vals = { 47 } } end end @@ -51,7 +53,7 @@ if apiVersion >= 1.036 then fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } } end fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } - fields[#fields + 1] = { t = "Threshold", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 20,max = 1000, vals = { 20, 21 } } + fields[#fields + 1] = { t = "Threshold", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 1000, vals = { 20, 21 } } end return { From 0272cbc6ff626f46203cc1eb4ec656a7b524d3ea Mon Sep 17 00:00:00 2001 From: mikeller Date: Sat, 18 Apr 2020 19:02:57 +1200 Subject: [PATCH 085/193] Fixed pull request template. --- .github/pull_request_template.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c6c4eb30..a509065d 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -4,7 +4,7 @@ 2. Pull requests will only be accepted if they are opened against the `master` branch of our repository. Pull requests opened against other branches without prior consent from the maintainers will be closed; -3. Please follow the coding style guidelines: https://github.com/cleanflight/cleanflight/blob/master/docs/development/CodingStyle.md +3. Please follow the coding style guidelines: https://github.com/betaflight/betaflight/blob/master/docs/development/CodingStyle.md 4. Keep your pull requests as small and concise as possible. One pull request should only ever add / update one feature. If the change that you are proposing has a wider scope, consider splitting it over multiple pull requests. In particular, pull requests that combine changes to features and one or more new targets are not acceptable. @@ -12,7 +12,7 @@ 6. All pull requests are reviewed. Be ready to receive constructive criticism, and to learn and improve your coding style. Also, be ready to clarify anything that isn't already sufficiently explained in the code and text of the pull request, and to defend your ideas. -7. We use continuous integration (CI) with [Travis](https://travis-ci.com/betaflight) to build all targets and run the test suite for every pull request. Pull requests that fail any of the builds or fail tests will most likely not be reviewed before they are fixed to build successfully and pass the tests. In order to get a quick idea if there are things that need fixing **before** opening a pull request or pushing an update into an existing pull request, run `make pre-push` to run a representative subset of the CI build. _Note: This is not an exhaustive test(which will take hours to run on any desktop type system), so even if this passes the CI build might still fail._ +7. We use continuous integration (CI) with [Travis](https://travis-ci.com/betaflight) to build all targets and run the test suite for every pull request. Pull requests that fail any of the builds or fail tests will most likely not be reviewed before they are fixed to build successfully and pass the tests. In order to get a quick idea if there are things that need fixing **before** opening a pull request or pushing an update into an existing pull request, run `make pre-push` to run a representative subset of the CI build. _Note: This is not an exhaustive test (which will take hours to run on any desktop type system), so even if this passes the CI build might still fail._ 8. If your pull request is a fix for one or more issues that are open in GitHub, add a comment to your pull request, and add the issue numbers of the issues that are fixed in the form `Fixes #`. This will cause the issues to be closed when the pull request is merged; From 9a29f3a850380784aff89d5eb6a5dafff6bddec5 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sat, 18 Apr 2020 23:21:57 +0200 Subject: [PATCH 086/193] Add Dynamic Idle Added Dynamic Idle to PID Advanced page. --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index a922cb8d..739fdf46 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -24,6 +24,10 @@ if apiVersion >= 1.040 then fields[#fields + 1] = { t = "I Term Rotation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } } end +if apiVersion >= 1.043 then + fields[#fields + 1] = { t = "Dynamic Idle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 50 } } +end + if apiVersion >= 1.016 then fields[#fields + 1] = { t = "VBAT Compensation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } } end From c40bc60783a52ffe346ea5df5d0837e65846edb5 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 27 Apr 2020 22:20:27 +0200 Subject: [PATCH 087/193] Dynamic idle and rpm harmonics reboot This commit adds a reboot after changing the dynamic idle value and after disabling the rpm filter by setting harmonics to 0. Rpm filter has to be enabled for dynamic idle to work. Disabling the rpm filter will also disable dynamic idle. Reboot needed for dynamic idle change to take effect. --- src/SCRIPTS/BF/PAGES/filters2.lua | 7 +++++++ src/SCRIPTS/BF/PAGES/pid_advanced.lua | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/SCRIPTS/BF/PAGES/filters2.lua b/src/SCRIPTS/BF/PAGES/filters2.lua index 5b1fe917..5984a61c 100644 --- a/src/SCRIPTS/BF/PAGES/filters2.lua +++ b/src/SCRIPTS/BF/PAGES/filters2.lua @@ -43,4 +43,11 @@ return { minBytes = 5, labels = labels, fields = fields, + postLoad = function(self) + self.rpmHarmonics = self.values[44] + end, + preSave = function(self) + self.reboot = self.values[44] == 0 and self.rpmHarmonics ~= 0 + return self.values + end, } diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 739fdf46..f9250841 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -69,4 +69,11 @@ return { minBytes = 8, labels = labels, fields = fields, + postLoad = function(self) + self.dynamicIdle = self.values[50] + end, + preSave = function(self) + self.reboot = self.values[50] ~= self.dynamicIdle + return self.values + end, } From 6235663a3e8fa4c6b6a37808f003deef2ce4433d Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 3 May 2020 13:47:22 +0200 Subject: [PATCH 088/193] Add motor protocol DISABLED --- src/SCRIPTS/BF/PAGES/pwm.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index 2dce2102..9e681611 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -33,6 +33,10 @@ if apiVersion >= 1.031 then end end +if apiVersion >= 1.043 then + escProtocols[#escProtocols + 1] = "DISABLED" +end + if apiVersion >= 1.031 and apiVersion <= 1.040 then fields[#fields + 1] = { t = "32kHz Sampling", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end } end From 6e2d35278c80e2c6679b39c83dcea4cd024b090c Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 3 May 2020 23:11:00 +0200 Subject: [PATCH 089/193] Remove Gyro/PID loop --- src/SCRIPTS/BF/PAGES/pwm.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index 2dce2102..c87d0845 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -38,8 +38,10 @@ if apiVersion >= 1.031 and apiVersion <= 1.040 then end if apiVersion >= 1.016 then - fields[#fields + 1] = { t = "Gyro Update", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end } - fields[#fields + 1] = { t = "PID Loop", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {} } + if apiVersion <= 1.042 then + fields[#fields + 1] = { t = "Gyro Update", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end } + fields[#fields + 1] = { t = "PID Loop", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {} } + end fields[#fields + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #escProtocols, vals = { 4 }, table = escProtocols } fields[#fields + 1] = { t = "Unsynced PWM", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 3 }, table = { [0] = "OFF", "ON" } } fields[#fields + 1] = { t = "PWM Frequency", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 200, max = 32000, vals = { 5, 6 }, } From 829c1cb8ddcff74dffe6f552288a5e41ce5cb31b Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sat, 9 May 2020 18:20:34 +0200 Subject: [PATCH 090/193] Update readme Added instructions for background script. Removed 4.1.0 requirement. Merged "How to download the scripts" into "Installing" section. some minor changes. --- README.md | 20 ++++++++++-------- .../assets/images/background_script_setup.png | Bin 0 -> 1353 bytes 2 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 docs/assets/images/background_script_setup.png diff --git a/README.md b/README.md index a55ad2d7..eb175806 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,8 @@ -# betaflight-tx-lua-scripts - -## How to download the scripts - -Please visit the [releases page](https://github.com/betaflight/betaflight-tx-lua-scripts/releases) to download a zip file containing latest version. +# Betaflight TX Lua Scripts ## Firmware Considerations -- Betaflight - 4.1.0 or newer. As a best practice, it is recommended to use the most recent stable release of Betaflight to obtain the best possible results; +- Betaflight - As a best practice, it is recommended to use the most recent stable release of Betaflight to obtain the best possible results; - OpenTX - 2.3.4 or newer; - Crossfire TX / RX - v2.11 or newer; - FrSky TX / RX - While most receivers work fine, it's recommended to update the XSR family of receivers to their most recent firmware version to correct any known bugs in SmartPort telemetry. @@ -15,9 +11,9 @@ Please visit the [releases page](https://github.com/betaflight/betaflight-tx-lua **!! IMPORTANT: DON'T COPY THE CONTENTS OF THIS REPOSITORY ONTO YOUR SDCARD !!** -Unzip the files from the link above and drag the contents to your radio. If you do this correctly, the SCRIPTS directory will merge with your existing directories, placing the scripts in their appropriate paths. You will know if you did this correctly if the `bf.lua` file shows up in your `/SCRIPTS/TOOLS` directory. +Download a zip file containing the latest version from the [releases page](https://github.com/betaflight/betaflight-tx-lua-scripts/releases). -The src directory is not required for use and is only available for maintenance of the code. While it may work to use this directory, you may encounter memory issues on your transmitter. +Unzip the files from the link above and drag the contents of the `obj` folder to your radios SD card. If you do this correctly, the `SCRIPTS` directory will merge with your existing directories, placing the scripts in their appropriate paths. You will know if you did this correctly if the `bf.lua` file shows up in your `/SCRIPTS/TOOLS` directory. ### How to install @@ -46,8 +42,14 @@ Due to issues with input mapping and memory overruns, running the script as a te If you are using a VTX that supports the SmartAudio or Tramp protocols then bands and channels etc. are managed using VTX tables since Betaflight version 4.1.0. The script will be downloading and storing the current VTX table for every model the first time the model is connected and the script is run. If you change the VTX table, you have to re-load the updated VTX table in the script, by choosing the 'vtx tables' option in the function menu. +### Background script +The optional background script offers RTC synchronization and RSSI through MSP. It can be setup as a special or global function in OpenTX. The image below shows how to run the background script as a special function. + +![Background script setup](docs/assets/images/background_script_setup.png) + + ## Building from source - Be sure to have `make` and `luac` in version 5.2 installed in the path - Run `make` from the root folder -- The installation files will be created a the `obj` in the root folder. Copy the files to your transmitter as instructed in the '[Installing](#installing)' section below as if you unzipped from a downloaded file. +- The installation files will be created in the `obj` folder. Copy the files to your transmitter as instructed in the '[Installing](#installing)' section as if you unzipped from a downloaded file. diff --git a/docs/assets/images/background_script_setup.png b/docs/assets/images/background_script_setup.png new file mode 100644 index 0000000000000000000000000000000000000000..fabb458ecd7154d1279477624c35060fab60cb52 GIT binary patch literal 1353 zcmX|>e^8Ql9LFCeXR=bePOS`Rxye;?S1UA=&^A5u=O}HcrM6}1XxbDpHFeUuHMik2 zGb=U0hQB(<$Dy4eg5Avk(<1UYx(mtDm+XHN)PVG9f17n^%^ zW_;g;F<(~)W)$1`NqW{t#)5Umf@>+&UdMODY^i4kRi%8%j_PX9Dsf$zshZ09>A!sW zct-o!jJ9j3V_}%0FIuu{(Sf-u8qGtI6_JDt(W}ji7R{Bpc`vL)>ndY}4!>$i9$AZ&PF^bK~IFjL-|;1U(;N1&V)b#CBfP5Nj1N^q)qR0 zOJ1;z7CSRKba*i>)vuXK(Dy1lzF%ll-TH8S@*7zNU7SB|8oWDyWcn$xWVk!v)?Xyr zY&OU@SP;%}d@91JPegJXx+RFOupU~n9M&JUUg@q9kj>S;w(6@6$u)*v22d(2`l$D0T6@O$d469D zV|Za3MtWnpJA5dThGDKq5?Xkh!}5L=_(3TS=ws^kwPh6roaVFZ)Izyv=Ghr>JVH-W z2*gr#Yj;m%XEXpEvzg}~aZ`K2LOQ_}h?-h{X03yvo}5?YVzw2S<^@YNU8yUaE|OmLs&PmQCsXd1;v{_*V{i8z zlfHzSAE1P)d4uVOkhuHuE^OAP*4vG8zke5OoL^fD>7JSFq7p}SeCox-%{p;bc$do@K0G{$o>UM!$tv%kVjn1%;m_qvU zQJG2BQJ8#SbP>ED;V~1)`rQY8oMLgMn>%1_O<_V;DkhcCE?em+KX{Sbzg$XWAVc=73^?{8= xDH%7wXL}307xmOTybreqNX3Bi&@$}>0&h0*(^b(Sa`112!a|~ho4+`E_J5>*x^(~m literal 0 HcmV?d00001 From d344996c6382c5127a8d89d7589a593e4ccd20f2 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 11 May 2020 19:13:33 +0200 Subject: [PATCH 091/193] Change init message from "Initialising" to "Waiting for connection" to let people know that a connection to the FC is needed for it to work. Changed telemetry version message to "Use TOOLS menu" to fit the smaller screens. --- src/SCRIPTS/BF/ui_init.lua | 2 +- src/SCRIPTS/TELEMETRY/bf.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 8686b5dc..ddc453c9 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -11,7 +11,7 @@ end local function init() if apiVersion == 0 then - lcd.drawText(6, radio.yMinLimit, "Initialising") + lcd.drawText(6, radio.yMinLimit, "Waiting for connection") data_init = data_init or assert(loadScript("data_init.lua"))() data_init() elseif apiVersion > 0 and not apiVersionReceived then diff --git a/src/SCRIPTS/TELEMETRY/bf.lua b/src/SCRIPTS/TELEMETRY/bf.lua index 3b931cfd..e1e7a693 100644 --- a/src/SCRIPTS/TELEMETRY/bf.lua +++ b/src/SCRIPTS/TELEMETRY/bf.lua @@ -1,6 +1,6 @@ local function run(event) lcd.clear() - lcd.drawText(2, 2, "Use TOOLS menu instead of this") + lcd.drawText(2, 2, "Use TOOLS menu") end return { run=run } From b5ae160455cc42d8fd4ceba82651641a1cecf0e2 Mon Sep 17 00:00:00 2001 From: mikeller Date: Thu, 14 May 2020 01:35:44 +1200 Subject: [PATCH 092/193] Added requirement for SmartPort to README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb175806..596a84e2 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ - Betaflight - As a best practice, it is recommended to use the most recent stable release of Betaflight to obtain the best possible results; - OpenTX - 2.3.4 or newer; - Crossfire TX / RX - v2.11 or newer; -- FrSky TX / RX - While most receivers work fine, it's recommended to update the XSR family of receivers to their most recent firmware version to correct any known bugs in SmartPort telemetry. +- FrSky TX / RX with support for SmartPort - While most receivers with SmartPort support work fine, it is recommended to update the receiver to the most recent firmware version to correct any known bugs in telemetry. ## Installing From 36966e1630747b142f25e12cea46f2ff14affea6 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 17 May 2020 21:36:37 +0200 Subject: [PATCH 093/193] Change gyro/pid rate increment direction Incrementing the denominators means decrementing the rate shown on screen. Reversed it by multiplying by -1. --- src/SCRIPTS/BF/PAGES/pwm.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index 7cb40a4e..a6531c5e 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -43,8 +43,8 @@ end if apiVersion >= 1.016 then if apiVersion <= 1.042 then - fields[#fields + 1] = { t = "Gyro Update", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end } - fields[#fields + 1] = { t = "PID Loop", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {} } + fields[#fields + 1] = { t = "Gyro Update", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end, mult = -1 } + fields[#fields + 1] = { t = "PID Loop", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {}, mult = -1 } end fields[#fields + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #escProtocols, vals = { 4 }, table = escProtocols } fields[#fields + 1] = { t = "Unsynced PWM", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 3 }, table = { [0] = "OFF", "ON" } } From 0719752fbf99cbb6c4b6fe35886f08058aeb25fa Mon Sep 17 00:00:00 2001 From: Curtis Bangert Date: Sat, 9 May 2020 21:55:33 -0400 Subject: [PATCH 094/193] Added CMS framework (CRSF Only) --- src/SCRIPTS/BF/CMS/common.lua | 120 +++++++++++++++++++++++++++++++ src/SCRIPTS/BF/CMS/crsf.lua | 64 +++++++++++++++++ src/SCRIPTS/BF/cms.lua | 23 ++++++ src/SCRIPTS/BF/protocols.lua | 11 +-- src/SCRIPTS/BF/radios.lua | 114 +++++++++++++++++++++-------- src/SCRIPTS/FUNCTIONS/bfbkgd.lua | 2 +- src/SCRIPTS/TOOLS/bf.lua | 4 +- src/SCRIPTS/TOOLS/bfCms.lua | 20 ++++++ 8 files changed, 321 insertions(+), 37 deletions(-) create mode 100644 src/SCRIPTS/BF/CMS/common.lua create mode 100644 src/SCRIPTS/BF/CMS/crsf.lua create mode 100644 src/SCRIPTS/BF/cms.lua create mode 100644 src/SCRIPTS/TOOLS/bfCms.lua diff --git a/src/SCRIPTS/BF/CMS/common.lua b/src/SCRIPTS/BF/CMS/common.lua new file mode 100644 index 00000000..bfb1b11a --- /dev/null +++ b/src/SCRIPTS/BF/CMS/common.lua @@ -0,0 +1,120 @@ +local CONST = { + bitmask = { + firstChunk = 0x80, + lastChunk = 0x40, + batchId = 0x3F, + rleCharValueMask = 0x7F, + rleCharRepeatedMask = 0x80 + }, + offset = { + meta = 1, + sequence = 2, + data = 3 + } +} + +local function cRleDecode(buf) + local dest = {} + local rpt = false + local c = nil + for i = 1, #buf do + if (rpt == false) then + c = bit32.band(buf[i], CONST.bitmask.rleCharValueMask) + if (bit32.band(buf[i], CONST.bitmask.rleCharRepeatedMask) > 0) then + rpt = true + else + dest[#dest + 1] = c + end + else + for j = 1, buf[i] do + dest[#dest + 1] = c + end + rpt = false + end + end + return dest +end + +screen = { + config = nil, + buffer = {}, + data = {}, + batchId = 0, + sequence = 0, + reset = function() + screen.buffer = {} + screen.data = {} + screen.batchId = 0 + screen.sequence = 0 + end, + draw = function() + if (screen.buffer ~= nil and screen.config ~= nil and #screen.buffer > 0) then + lcd.clear() + for char = 1, #screen.buffer do + if (screen.buffer[char] ~= 32) then -- skip spaces to avoid CPU spikes + c = string.char(screen.buffer[char]) + row = math.ceil(char / screen.config.cols) + col = char - ((row - 1) * screen.config.cols) + xPos = ((col - 1) * screen.config.pixelsPerChar) + screen.config.xIndent + 1 + yPos = ((row - 1) * screen.config.pixelsPerRow) + screen.config.yOffset + 1 + lcd.drawText(xPos, yPos, c, screen.config.textSize) + end + end + lcd.drawText(screen.config.refresh.left, screen.config.refresh.top, screen.config.refresh.text, screen.config.textSize) + end + end +} + +cms = { + menuOpen = false, + init = function(cmsConfig) + screen.config = assert(cmsConfig, "Resolution not supported") + screen.reset() + protocol.cms.close() + cms.menuOpen = false + end, + open = function() + protocol.cms.open(screen.config.rows, screen.config.cols) + end, + refresh = function() + protocol.cms.refresh() + end, + close = function() + protocol.cms.close() + cms.menuOpen = false + end, + update = function() + local command, data = protocol.cms.poll() + if (command == "update") then + local firstChunk = bit32.band(data[CONST.offset.meta], CONST.bitmask.firstChunk) + local lastChunk = bit32.band(data[CONST.offset.meta], CONST.bitmask.lastChunk) + local batchId = bit32.band(data[CONST.offset.meta], CONST.bitmask.batchId) + local sequence = data[CONST.offset.sequence] + local frameData = {} + for i = CONST.offset.data, #data do + frameData[#frameData + 1] = data[i] + end + if (firstChunk ~= 0) then + screen.reset() + screen.batchId = batchId + screen.sequence = 0 + end + if (screen.batchId == batchId) and (screen.sequence == sequence) then + screen.sequence = sequence + 1 + for i = 1, #frameData do + screen.data[#screen.data + 1] = frameData[i] + end + if (lastChunk ~= 0) then + screen.buffer = cRleDecode(screen.data) + screen.draw() + screen.reset() + end + else + protocol.cms.refresh() + end + cms.menuOpen = true + elseif (command == "clear") then + screen.reset() + end + end +} diff --git a/src/SCRIPTS/BF/CMS/crsf.lua b/src/SCRIPTS/BF/CMS/crsf.lua new file mode 100644 index 00000000..83c17337 --- /dev/null +++ b/src/SCRIPTS/BF/CMS/crsf.lua @@ -0,0 +1,64 @@ +local CONST = { + frame = { + destination = 1, + source = 2, + command = 3, + content = 4 + }, + address = { + transmitter = 0xEA, + betaflight = 0xC8 + }, + frameType = { + displayPort = 0x7D + }, + command = { + update = 0x01, + clear = 0x02, + open = 0x03, + close = 0x04, + refresh = 0x05 + } +} + +local function crsfDisplayPortCmd(cmd, data) + local payloadOut = { CONST.address.betaflight, CONST.address.transmitter, cmd } + if data ~= nil then + for i = 1, #(data) do + payloadOut[3 + i] = data[i] + end + end + return crossfireTelemetryPush(CONST.frameType.displayPort, payloadOut) +end + +protocol.cms.poll = function() + local command = nil + local dataOut = {} + local frameType, data = crossfireTelemetryPop() + if (data ~= nil) and (#data > 2) then + if (frameType == CONST.frameType.displayPort) and (data[CONST.frame.destination] == CONST.address.transmitter) and (data[CONST.frame.source] == CONST.address.betaflight) then + for k,v in pairs(CONST.command) do + if (v == data[CONST.frame.command]) then + command = k + end + end + for i = CONST.frame.content, #data do + dataOut[#dataOut + 1] = data[i] + end + end + end + return command, dataOut +end + +protocol.cms.open = function(rows, cols) + return crsfDisplayPortCmd(CONST.command.open, { rows, cols }) +end + +protocol.cms.close = function() + return crsfDisplayPortCmd(CONST.command.close, nil) +end + +protocol.cms.refresh = function() + return crsfDisplayPortCmd(CONST.command.refresh, nil) +end + diff --git a/src/SCRIPTS/BF/cms.lua b/src/SCRIPTS/BF/cms.lua new file mode 100644 index 00000000..15ca3395 --- /dev/null +++ b/src/SCRIPTS/BF/cms.lua @@ -0,0 +1,23 @@ +lastMenuEventTime = 0 + +local function init() + cms.init(radio) +end + +local function run(event) + lastMenuEventTime = getTime() + cms.update() + if (cms.menuOpen == false) then + cms.open() + end + if (event == radio.refresh.event) then + cms.refresh() + end + if (event == EVT_VIRTUAL_EXIT) then + cms.close() + return 1 + end + return 0 +end + +return { init=init, run=run } diff --git a/src/SCRIPTS/BF/protocols.lua b/src/SCRIPTS/BF/protocols.lua index d0c1951d..89f55de2 100644 --- a/src/SCRIPTS/BF/protocols.lua +++ b/src/SCRIPTS/BF/protocols.lua @@ -2,25 +2,28 @@ local supportedProtocols = { smartPort = { - transport = "MSP/sp.lua", + mspTransport = "MSP/sp.lua", rssi = function() return getValue("RSSI") end, stateSensor = "Tmp1", push = sportTelemetryPush, maxTxBufferSize = 6, maxRxBufferSize = 6, saveMaxRetries = 2, - saveTimeout = 500 + saveTimeout = 500, + cms = {}, }, crsf = { - transport = "MSP/crsf.lua", + mspTransport = "MSP/crsf.lua", + cmsTransport = "CMS/crsf.lua", rssi = function() return getValue("TQly") end, stateSensor = "1RSS", push = crossfireTelemetryPush, maxTxBufferSize = 8, maxRxBufferSize = 58, saveMaxRetries = 2, - saveTimeout = 150 + saveTimeout = 150, + cms = {}, } } diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index 6f200e4c..b41f9fcb 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -2,45 +2,99 @@ local supportedRadios = { ["128x64"] = { - templateHome = "TEMPLATES/128x64/", - MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, - SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, - NoTelem = { 30, 55, "No Telemetry", BLINK }, - textSize = SMLSIZE, - yMinLimit = 12, - yMaxLimit = 52, + msp = { + templateHome = "TEMPLATES/128x64/", + MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, + SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, + NoTelem = { 30, 55, "No Telemetry", BLINK }, + textSize = SMLSIZE, + yMinLimit = 12, + yMaxLimit = 52, + }, + cms = { + rows = 8, + cols = 26, + pixelsPerRow = 8, + pixelsPerChar = 5, + xIndent = 0, + yOffset = 0, + textSize = SMLSIZE, + refresh = { + event = EVT_VIRTUAL_ENTER, + text = "Refresh: [ENT]", + top = 1, + left = 64, + }, + }, }, ["212x64"] = { - templateHome = "TEMPLATES/212x64/", - MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 }, - SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, - NoTelem = { 70, 55, "No Telemetry", BLINK }, - textSize = SMLSIZE, - yMinLimit = 12, - yMaxLimit = 52, + msp = { + templateHome = "TEMPLATES/212x64/", + MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 }, + SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, + NoTelem = { 70, 55, "No Telemetry", BLINK }, + textSize = SMLSIZE, + yMinLimit = 12, + yMaxLimit = 52, + }, + cms = { + rows = 8, + cols = 32, + pixelsPerRow = 8, + pixelsPerChar = 6, + xIndent = 0, + yOffset = 0, + textSize = SMLSIZE, + refresh = { + event = EVT_VIRTUAL_INC, + text = "Refresh: [+]", + top = 1, + left = 156, + } + }, }, ["480x272"] = { - templateHome = "TEMPLATES/480x272/", - highRes = true, - MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, - SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, - NoTelem = { 192, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, - textSize = 0, - yMinLimit = 35, - yMaxLimit = 235, + msp = { + templateHome = "TEMPLATES/480x272/", + highRes = true, + MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, + SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, + NoTelem = { 192, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, + textSize = 0, + yMinLimit = 35, + yMaxLimit = 235, + }, + cms = { + rows = 9, + cols = 32, + pixelsPerRow = 24, + pixelsPerChar = 14, + xIndent = 14, + yOffset = 32, + textSize = MIDSIZE, + refresh = { + event = EVT_VIRTUAL_ENTER, + text = "Refresh: [ENT]", + top = 1, + left = 300, + } + }, }, ["320x480"] = { - templateHome = "TEMPLATES/320x480/", - highRes = true, - MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, - SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, - NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, - textSize = 0, - yMinLimit = 35, - yMaxLimit = 435, + msp = { + templateHome = "TEMPLATES/320x480/", + highRes = true, + MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, + SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, + NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, + textSize = 0, + yMinLimit = 35, + yMaxLimit = 435, + }, + cms = nil, }, } diff --git a/src/SCRIPTS/FUNCTIONS/bfbkgd.lua b/src/SCRIPTS/FUNCTIONS/bfbkgd.lua index fcaec519..137000ba 100644 --- a/src/SCRIPTS/FUNCTIONS/bfbkgd.lua +++ b/src/SCRIPTS/FUNCTIONS/bfbkgd.lua @@ -1,7 +1,7 @@ chdir("/SCRIPTS/BF") apiVersion = 0 protocol = assert(loadScript("protocols.lua"))() -assert(loadScript(protocol.transport))() +assert(loadScript(protocol.mspTransport))() assert(loadScript("MSP/common.lua"))() local background = assert(loadScript("background.lua"))() diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index af3d420b..cc2b70b6 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -8,8 +8,8 @@ local scriptsCompiled = assert(loadScript("COMPILE/scripts_compiled.lua"))() if scriptsCompiled then protocol = assert(loadScript("protocols.lua"))() - radio = assert(loadScript("radios.lua"))() - assert(loadScript(protocol.transport))() + radio = assert(loadScript("radios.lua"))().msp + assert(loadScript(protocol.mspTransport))() assert(loadScript("MSP/common.lua"))() run = assert(loadScript("ui.lua"))() else diff --git a/src/SCRIPTS/TOOLS/bfCms.lua b/src/SCRIPTS/TOOLS/bfCms.lua new file mode 100644 index 00000000..d9a8b0ab --- /dev/null +++ b/src/SCRIPTS/TOOLS/bfCms.lua @@ -0,0 +1,20 @@ +local toolName = "TNS|Betaflight CMS|TNE" +chdir("/SCRIPTS/BF") + +apiVersion = 0 + +local cms = { run = nil, init = nil } +local scriptsCompiled = assert(loadScript("COMPILE/scripts_compiled.lua"))() + +if scriptsCompiled then + protocol = assert(loadScript("protocols.lua"))() + local cmsTransport = assert(protocol.cmsTransport, "Telemetry protocol not supported!") + radio = assert(loadScript("radios.lua"))().cms + assert(loadScript(cmsTransport))() + assert(loadScript("CMS/common.lua"))() + cms = assert(loadScript("cms.lua"))() +else + cms = { run = assert(loadScript("COMPILE/compile.lua"))() } +end + +return cms From 60322c2e2078fcfbf6acf5eddfb394ba47375223 Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Fri, 19 Jun 2020 11:34:09 +0200 Subject: [PATCH 095/193] Update readme with link to nightly versions --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 596a84e2..7fd54e79 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Betaflight TX Lua Scripts + [![Build Status](https://api.travis-ci.com/betaflight/betaflight-tx-lua-scripts.svg?branch=master)](https://travis-ci.com/betaflight/betaflight-tx-lua-scripts) [![Build Status](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_apis/build/status/betaflight.betaflight-tx-lua-scripts?branchName=master)](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_build/latest?definitionId=1&branchName=master) + ## Firmware Considerations - Betaflight - As a best practice, it is recommended to use the most recent stable release of Betaflight to obtain the best possible results; @@ -48,6 +50,11 @@ The optional background script offers RTC synchronization and RSSI through MSP. ![Background script setup](docs/assets/images/background_script_setup.png) +## Unstable Testing Versions +Unstable testing versions of the latest builds of the Lua Script can be downloaded from [here](https://github.com/betaflight/betaflight-tx-lua-scripts-nightlies/releases). + +Be aware that these versions are intended for testing / feedback only, and may be buggy or broken. Caution is advised when using these versions. + ## Building from source - Be sure to have `make` and `luac` in version 5.2 installed in the path From 568595d5f732bcce585ff43ce721656977cbd568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Bjarni=20Gu=C3=B0mundsson?= Date: Tue, 8 Sep 2020 00:10:19 +0000 Subject: [PATCH 096/193] MCU id for vtx tables Reads MCU id from MSP and uses that unique id to store the vtx tables. This should solve the problem of using an incorrect vtx table when there are different crafts with different vtx hardware under the same model name. --- src/SCRIPTS/BF/PAGES/vtx.lua | 7 +++---- src/SCRIPTS/BF/mcu_id.lua | 37 +++++++++++++++++++++++++++++++++++ src/SCRIPTS/BF/ui.lua | 2 +- src/SCRIPTS/BF/ui_init.lua | 23 +++++++++++++--------- src/SCRIPTS/BF/vtx_tables.lua | 4 ++-- src/SCRIPTS/TOOLS/bf.lua | 1 + 6 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 src/SCRIPTS/BF/mcu_id.lua diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index dc2168d5..6b4bca9d 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -1,7 +1,6 @@ -local md = model.getInfo(); -local vtx_tables = loadScript("/BF/VTX/"..md.name..".lua") -if vtx_tables then - vtx_tables = vtx_tables() +local vtx_tables +if apiVersion >= 1.042 then + vtx_tables = assert(loadScript("/BF/VTX/"..mcuId..".lua"))() else vtx_tables = assert(loadScript("/BF/VTX/vtx_defaults.lua"))() end diff --git a/src/SCRIPTS/BF/mcu_id.lua b/src/SCRIPTS/BF/mcu_id.lua new file mode 100644 index 00000000..6ed9d8a4 --- /dev/null +++ b/src/SCRIPTS/BF/mcu_id.lua @@ -0,0 +1,37 @@ +local MSP_UID = 160 + +local MCUIdReceived = false + +local lastRunTS = 0 +local INTERVAL = 100 + +local function processMspReply(cmd, payload) + if cmd == MSP_UID then + local i = 1 + local id = "" + for j = 1, 3 do + local s = "" + for k = 1, 4 do + s = string.format("%02x", payload[i])..s + i = i + 1 + end + id = id..s + end + mcuId = id + MCUIdReceived = true + end +end + +local function getMCUId() + if lastRunTS + INTERVAL < getTime() then + lastRunTS = getTime() + if not MCUIdReceived then + protocol.mspRead(MSP_UID) + end + end + mspProcessTxQ() + processMspReply(mspPollReply()) + return MCUIdReceived +end + +return getMCUId diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index c65dfd09..2011f1cd 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -76,7 +76,7 @@ local function getVtxTables() uiState = uiStatus.init PageFiles = nil invalidatePages() - io.close(io.open("/BF/VTX/"..model.getInfo().name..".lua", 'w')) + io.close(io.open("/BF/VTX/"..mcuId..".lua", 'w')) return 0 end diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index ddc453c9..7ad770bd 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -1,13 +1,6 @@ local apiVersionReceived = false local vtxTablesReceived = false -local data_init, getVtxTables -local vtxTables = loadScript("/BF/VTX/"..model.getInfo().name..".lua") - -if vtxTables and vtxTables() then - vtxTablesReceived = true - vtxTables = nil - collectgarbage() -end +local data_init, getVtxTables, getMCUId local function init() if apiVersion == 0 then @@ -18,6 +11,18 @@ local function init() data_init = nil apiVersionReceived = true collectgarbage() + elseif apiVersion >= 1.042 and not mcuId then + lcd.drawText(6, radio.yMinLimit, "Waiting for device ID") + getMCUId = getMCUId or assert(loadScript("mcu_id.lua"))() + if getMCUId() then + getMCUId = nil + local vtxTables = loadScript("/BF/VTX/"..mcuId..".lua") + if vtxTables and vtxTables() then + vtxTablesReceived = true + vtxTables = nil + end + collectgarbage() + end elseif apiVersion >= 1.042 and not vtxTablesReceived then lcd.drawText(6, radio.yMinLimit, "Downloading VTX Tables") getVtxTables = getVtxTables or assert(loadScript("vtx_tables.lua"))() @@ -29,7 +34,7 @@ local function init() else return true end - return apiVersionReceived and vtxTablesReceived + return apiVersionReceived and vtxTablesReceived and mcuId end return init diff --git a/src/SCRIPTS/BF/vtx_tables.lua b/src/SCRIPTS/BF/vtx_tables.lua index 83ca15ea..01fa377f 100644 --- a/src/SCRIPTS/BF/vtx_tables.lua +++ b/src/SCRIPTS/BF/vtx_tables.lua @@ -82,7 +82,7 @@ local function getVtxTables() end end if vtxTablesReceived then - local f = io.open("/BF/VTX/"..model.getInfo().name..".lua", 'w') + local f = io.open("/BF/VTX/"..mcuId..".lua", 'w') io.write(f, "return {", "\n") io.write(f, " frequencyTable = {", "\n") for i = 1, #frequencyTable do @@ -109,7 +109,7 @@ local function getVtxTables() io.write(f, powerString, "\n") io.write(f, "}", "\n") io.close(f) - assert(loadScript("/BF/VTX/"..model.getInfo().name..".lua", 'c')) + assert(loadScript("/BF/VTX/"..mcuId..".lua", 'c')) end mspProcessTxQ() processMspReply(mspPollReply()) diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index cc2b70b6..3c4ee8b1 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -2,6 +2,7 @@ local toolName = "TNS|Betaflight setup|TNE" chdir("/SCRIPTS/BF") apiVersion = 0 +mcuId = nil local run = nil local scriptsCompiled = assert(loadScript("COMPILE/scripts_compiled.lua"))() From 37d091a13af7321bf6d616735f4beed52f6985dc Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 22 Sep 2020 12:03:36 +0200 Subject: [PATCH 097/193] 128x96 support Adds support for radios using a 128x96 resolution display. --- .../BF/TEMPLATES/128x96/default_template.lua | 7 +++++ src/SCRIPTS/BF/radios.lua | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/SCRIPTS/BF/TEMPLATES/128x96/default_template.lua diff --git a/src/SCRIPTS/BF/TEMPLATES/128x96/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/128x96/default_template.lua new file mode 100644 index 00000000..76e110f0 --- /dev/null +++ b/src/SCRIPTS/BF/TEMPLATES/128x96/default_template.lua @@ -0,0 +1,7 @@ +return { + margin = 2, + indent = 6, + lineSpacing = 8, + listSpacing = { line = 8, field = 88 }, + tableSpacing = { row = 10, col = 30, header = 8 }, +} diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index b41f9fcb..eccc21c2 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -27,6 +27,33 @@ local supportedRadios = }, }, }, + ["128x96"] = + { + msp = { + templateHome = "TEMPLATES/128x96/", + MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, + SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, + NoTelem = { 30, 87, "No Telemetry", BLINK }, + textSize = SMLSIZE, + yMinLimit = 12, + yMaxLimit = 84, + }, + cms = { + rows = 12, + cols = 26, + pixelsPerRow = 8, + pixelsPerChar = 5, + xIndent = 0, + yOffset = 0, + textSize = SMLSIZE, + refresh = { + event = EVT_VIRTUAL_ENTER, + text = "Refresh: [ENT]", + top = 1, + left = 64, + }, + }, + }, ["212x64"] = { msp = { From 0361f4605944e3535a1e1a9f47084fcb3da3fa46 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 2 Oct 2020 21:46:08 +0200 Subject: [PATCH 098/193] Allow drawing on whole display Allow drawing from 0 to LCD_H instead of using the scroll limits. --- src/SCRIPTS/BF/ui.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 2011f1cd..d70f2886 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -169,7 +169,7 @@ local function drawScreenTitle(screenTitle) lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR) lcd.drawText(5,5,screenTitle, MENU_TITLE_COLOR) else - lcd.drawFilledRectangle(0, 0, LCD_W, 10) + lcd.drawFilledRectangle(0, 0, LCD_W, 10, FORCE) lcd.drawText(1,1,screenTitle,INVERS) end end @@ -179,7 +179,6 @@ local function drawScreen() local yMaxLim = radio.yMaxLimit local currentFieldY = Page.fields[currentField].y local textOptions = radio.textSize + globalTextOptions - drawScreenTitle("Betaflight / "..Page.title) if currentFieldY <= Page.fields[1].y then pageScrollY = 0 elseif currentFieldY - pageScrollY <= yMinLim then @@ -190,7 +189,7 @@ local function drawScreen() for i=1,#Page.labels do local f = Page.labels[i] local y = f.y - pageScrollY - if y >= yMinLim and y <= yMaxLim then + if y >= 0 and y <= LCD_H then lcd.drawText(f.x, y, f.t, textOptions) end end @@ -214,13 +213,14 @@ local function drawScreen() end end local y = f.y - pageScrollY - if y >= yMinLim and y <= yMaxLim then + if y >= 0 and y <= LCD_H then if f.t then lcd.drawText(f.x, y, f.t, textOptions) end lcd.drawText(f.sp or f.x, y, val, valueOptions) end end + drawScreenTitle("Betaflight / "..Page.title) end local function incValue(inc) @@ -282,7 +282,6 @@ local function run_ui(event) uiState = uiStatus.pages end lcd.clear() - drawScreenTitle("Betaflight Config") local yMinLim = radio.yMinLimit local yMaxLim = radio.yMaxLimit local lineSpacing = 10 @@ -300,10 +299,11 @@ local function run_ui(event) for i=1, #PageFiles do local attr = currentPage == i and INVERS or 0 local y = (i-1)*lineSpacing + yMinLim - mainMenuScrollY - if y >= yMinLim and y <= yMaxLim then + if y >= 0 and y <= LCD_H then lcd.drawText(6, y, PageFiles[i].title, attr) end end + drawScreenTitle("Betaflight Config") elseif uiState == uiStatus.pages then if pageState == pageStatus.saving then if saveTS + saveTimeout < getTime() then From 2226d39bad37211143021f94e0756fea951d17a1 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 2 Oct 2020 22:03:52 +0200 Subject: [PATCH 099/193] Rename pids.lua to bfpids.lua to show where it comes from. --- src/SCRIPTS/FUNCTIONS/{pids.lua => bfpids.lua} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/SCRIPTS/FUNCTIONS/{pids.lua => bfpids.lua} (100%) diff --git a/src/SCRIPTS/FUNCTIONS/pids.lua b/src/SCRIPTS/FUNCTIONS/bfpids.lua similarity index 100% rename from src/SCRIPTS/FUNCTIONS/pids.lua rename to src/SCRIPTS/FUNCTIONS/bfpids.lua From 0cae62f87a202c33c45b02b0ff224753da65ee8a Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 7 Oct 2020 18:14:00 +0200 Subject: [PATCH 100/193] Add FF Interpolate Adds FF Interpolate to pids2 page. --- src/SCRIPTS/BF/PAGES/pids2.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index b4c3a68d..2e56efdf 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -47,13 +47,18 @@ if apiVersion >= 1.040 then y = inc.y(lineSpacing*0.4) end - - if apiVersion >= 1.040 then labels[#labels + 1] = { t = "Feedforward", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Transition", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 9 }, scale = 100 } end +if apiVersion >= 1.044 then + labels[#labels + 1] = { t = "FF Interpolate", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 51 }, table = { [0] = "OFF", "ON", "AVG_2", "AVG_3", "AVG_4" } } + fields[#fields + 1] = { t = "Smoothness", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 75, vals = { 52 } } + fields[#fields + 1] = { t = "Boost", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 53 } } +end + if apiVersion >= 1.041 then labels[#labels + 1] = { t = "D Min", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 43 } } From 68c4dbb240bd180e10d837ce9f30c69ea714ba4e Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 7 Oct 2020 18:29:13 +0200 Subject: [PATCH 101/193] Add Vbat Sag Compensation Adds VBat Sag Compensation to PID Advanced page. Removes VBAT compensation for apiVersion > 1.043. Moved Integrated Yaw a little bit. --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index f9250841..0a52ceba 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -28,14 +28,22 @@ if apiVersion >= 1.043 then fields[#fields + 1] = { t = "Dynamic Idle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 50 } } end -if apiVersion >= 1.016 then +if apiVersion >= 1.016 and apiVersion <= 1.043 then fields[#fields + 1] = { t = "VBAT Compensation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } } end +if apiVersion >= 1.044 then + fields[#fields + 1] = { t = "Vbat Sag Comp", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 54 } } +end + if apiVersion >= 1.040 and apiVersion <= 1.041 then fields[#fields + 1] = { t = "Smart Feedforward", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 27 }, table = { [0] = "OFF", "ON" } } end +if apiVersion >= 1.041 then + fields[#fields + 1] = { t = "Integrated Yaw", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } } +end + if apiVersion >= 1.040 then labels[#labels + 1] = { t = "I Term Relax", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Axes", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } } @@ -47,10 +55,6 @@ if apiVersion >= 1.040 then end end -if apiVersion >= 1.041 then - fields[#fields + 1] = { t = "Integrated Yaw", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } } -end - if apiVersion >= 1.036 then labels[#labels + 1] = { t = "Anti Gravity", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.040 then From 4974c94ee009c323b27cfe4b2e4be5955e82bfbb Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 7 Oct 2020 12:40:45 +0200 Subject: [PATCH 102/193] Rates type support Adds support for changing rates type. --- src/SCRIPTS/BF/PAGES/rates.lua | 49 ++++++++++++++++++++++++++++ src/SCRIPTS/BF/RATETABLES/ACTUAL.lua | 15 +++++++++ src/SCRIPTS/BF/RATETABLES/BF.lua | 15 +++++++++ src/SCRIPTS/BF/RATETABLES/KISS.lua | 15 +++++++++ src/SCRIPTS/BF/RATETABLES/QUICK.lua | 15 +++++++++ src/SCRIPTS/BF/RATETABLES/RF.lua | 15 +++++++++ src/SCRIPTS/BF/ui.lua | 3 ++ 7 files changed, 127 insertions(+) create mode 100644 src/SCRIPTS/BF/RATETABLES/ACTUAL.lua create mode 100644 src/SCRIPTS/BF/RATETABLES/BF.lua create mode 100644 src/SCRIPTS/BF/RATETABLES/KISS.lua create mode 100644 src/SCRIPTS/BF/RATETABLES/QUICK.lua create mode 100644 src/SCRIPTS/BF/RATETABLES/RF.lua diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua index 6f348e6b..927b74aa 100644 --- a/src/SCRIPTS/BF/PAGES/rates.lua +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -66,6 +66,10 @@ if apiVersion >= 1.016 then inc.y(lineSpacing*0.4) end +if apiVersion >= 1.043 then + fields[#fields + 1] = { t = "Rates Type", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 23 }, table = { [0] = "BF", "RF", "KISS", "ACTUAL", "QUICK"}, postEdit = function(self) self.updateRatesType(self, true) end } +end + if apiVersion >= 1.016 then labels[#labels + 1] = { t = "Throttle", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Mid", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 7 }, scale = 100 } @@ -91,4 +95,49 @@ return { minBytes = 12, labels = labels, fields = fields, + ratesType, + getRatesType = function(self) + for i = 1, #self.fields do + if self.fields[i].vals and self.fields[i].vals[1] == 23 then + return self.fields[i].table[self.fields[i].value] + end + end + end, + updateRatesType = function(self, applyDefaults) + local ratesTable = assert(loadScript("RATETABLES/"..self.getRatesType(self)..".lua"))() + for i = 1, #ratesTable.labels do + self.labels[i].t = ratesTable.labels[i] + end + for i = 1, #ratesTable.fields do + for k, v in pairs(ratesTable.fields[i]) do + self.fields[i][k] = v + end + end + if applyDefaults and self.ratesType ~= self.getRatesType(self) then + for i = 1, #ratesTable.defaults do + local f = self.fields[i] + f.value = ratesTable.defaults[i] + for idx=1, #f.vals do + self.values[f.vals[idx]] = bit32.rshift(math.floor(f.value*(f.scale or 1) + 0.5), (idx-1)*8) + end + end + else + for i = 1, 9 do + local f = self.fields[i] + f.value = 0 + for idx=1, #f.vals do + local raw_val = self.values[f.vals[idx]] or 0 + raw_val = bit32.lshift(raw_val, (idx-1)*8) + f.value = bit32.bor(f.value, raw_val) + end + f.value = f.value/(f.scale or 1) + end + end + self.ratesType = self.getRatesType(self) + end, + postLoad = function(self) + if apiVersion >= 1.043 then + self.updateRatesType(self) + end + end, } diff --git a/src/SCRIPTS/BF/RATETABLES/ACTUAL.lua b/src/SCRIPTS/BF/RATETABLES/ACTUAL.lua new file mode 100644 index 00000000..42bf533d --- /dev/null +++ b/src/SCRIPTS/BF/RATETABLES/ACTUAL.lua @@ -0,0 +1,15 @@ +return { + labels = { "", "", "ROLL", "PITCH", "YAW", "Cntr", "Sens", "Max", "Rate", "", "Expo" }, + fields = { + { min = 1, max = 200, scale = 0.1 }, + { min = 1, max = 200, scale = 0.1 }, + { min = 1, max = 200, scale = 0.1 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 } + }, + defaults = { 200, 200, 200, 670, 670, 670, 0.54, 0.54, 0.54 } +} diff --git a/src/SCRIPTS/BF/RATETABLES/BF.lua b/src/SCRIPTS/BF/RATETABLES/BF.lua new file mode 100644 index 00000000..343d6df3 --- /dev/null +++ b/src/SCRIPTS/BF/RATETABLES/BF.lua @@ -0,0 +1,15 @@ +return { + labels = { "", "", "ROLL", "PITCH", "YAW", "RC", "Rate", "Super", "Rate", "RC", "Expo" }, + fields = { + { min = 0, max = 255, scale = 100 }, + { min = 0, max = 255, scale = 100 }, + { min = 0, max = 255, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 255, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 } + }, + defaults = { 1.0, 1.0, 1.0, 0.7, 0.7, 0.7, 0.0, 0.0, 0.0 } +} diff --git a/src/SCRIPTS/BF/RATETABLES/KISS.lua b/src/SCRIPTS/BF/RATETABLES/KISS.lua new file mode 100644 index 00000000..f365f270 --- /dev/null +++ b/src/SCRIPTS/BF/RATETABLES/KISS.lua @@ -0,0 +1,15 @@ +return { + labels = { "", "", "ROLL", "PITCH", "YAW", "RC", "Rate", "", "Rate", "RC", "Curve" }, + fields = { + { min = 1, max = 255, scale = 100 }, + { min = 1, max = 255, scale = 100 }, + { min = 1, max = 255, scale = 100 }, + { min = 0, max = 99, scale = 100 }, + { min = 0, max = 99, scale = 100 }, + { min = 0, max = 99, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 } + }, + defaults = { 1.0, 1.0, 1.0, 0.7, 0.7, 0.7, 0.0, 0.0, 0.0 } +} diff --git a/src/SCRIPTS/BF/RATETABLES/QUICK.lua b/src/SCRIPTS/BF/RATETABLES/QUICK.lua new file mode 100644 index 00000000..367eeef0 --- /dev/null +++ b/src/SCRIPTS/BF/RATETABLES/QUICK.lua @@ -0,0 +1,15 @@ +return { + labels = { "", "", "ROLL", "PITCH", "YAW", "RC", "Rate", "Max", "Rate", "", "Expo" }, + fields = { + { min = 1, max = 255, scale = 100 }, + { min = 1, max = 255, scale = 100 }, + { min = 1, max = 255, scale = 100 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 200, scale = 0.1 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 }, + { min = 0, max = 100, scale = 100 } + }, + defaults = { 1.0, 1.0, 1.0, 670, 670, 670, 0.0, 0.0, 0.0 } +} diff --git a/src/SCRIPTS/BF/RATETABLES/RF.lua b/src/SCRIPTS/BF/RATETABLES/RF.lua new file mode 100644 index 00000000..12f74f36 --- /dev/null +++ b/src/SCRIPTS/BF/RATETABLES/RF.lua @@ -0,0 +1,15 @@ +return { + labels = { "", "", "ROLL", "PITCH", "YAW", "", "Rate", "", "Acro+", "", "Expo" }, + fields = { + { min = 1, max = 200, scale = 0.1 }, + { min = 1, max = 200, scale = 0.1 }, + { min = 1, max = 200, scale = 0.1 }, + { min = 0, max = 100, scale = 1 }, + { min = 0, max = 100, scale = 1 }, + { min = 0, max = 100, scale = 1 }, + { min = 0, max = 100, scale = 1 }, + { min = 0, max = 100, scale = 1 }, + { min = 0, max = 100, scale = 1 } + }, + defaults = { 370, 370, 370, 80, 80, 80, 50, 50, 50 } +} diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index d70f2886..630c3d8e 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -358,6 +358,9 @@ local function run_ui(event) end elseif pageState == pageStatus.editing then if event == EVT_VIRTUAL_EXIT or event == EVT_VIRTUAL_ENTER then + if Page.fields[currentField].postEdit then + Page.fields[currentField].postEdit(Page) + end pageState = pageStatus.display elseif event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then incValue(1) From 6fb00afc5480bcb1d951f92a0d465368ce58500a Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 11 Oct 2020 21:38:44 +0200 Subject: [PATCH 103/193] Add Thrust Linearization Adds Thrust Linearization to PID Advanced page. --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 0a52ceba..a5812ba4 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -34,6 +34,7 @@ end if apiVersion >= 1.044 then fields[#fields + 1] = { t = "Vbat Sag Comp", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 54 } } + fields[#fields + 1] = { t = "Thrust Linear", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 55 } } end if apiVersion >= 1.040 and apiVersion <= 1.041 then From 53bb56172e69e5b95d525275611e21c40dc7d464 Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Mon, 19 Oct 2020 15:29:11 +0200 Subject: [PATCH 104/193] Add version and release badges to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7fd54e79..1ae45f13 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Betaflight TX Lua Scripts - [![Build Status](https://api.travis-ci.com/betaflight/betaflight-tx-lua-scripts.svg?branch=master)](https://travis-ci.com/betaflight/betaflight-tx-lua-scripts) [![Build Status](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_apis/build/status/betaflight.betaflight-tx-lua-scripts?branchName=master)](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_build/latest?definitionId=1&branchName=master) + [![Latest version](https://img.shields.io/github/v/release/betaflight/betaflight-tx-lua-scripts)](https://github.com/betaflight/betaflight-tx-lua-scripts/releases) [![Build Status](https://api.travis-ci.com/betaflight/betaflight-tx-lua-scripts.svg?branch=master)](https://travis-ci.com/betaflight/betaflight-tx-lua-scripts) [![Build Status](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_apis/build/status/betaflight.betaflight-tx-lua-scripts?branchName=master)](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_build/latest?definitionId=1&branchName=master) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) ## Firmware Considerations From 5e624c83ed84f6ecf8a181b869dfff90c2ea0b3f Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 20 Oct 2020 17:01:04 +0200 Subject: [PATCH 105/193] Allow 0 anti gravity gain Changes anti gravity gain min from 1000 to 0. --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index a5812ba4..fd596d5f 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -61,7 +61,11 @@ if apiVersion >= 1.036 then if apiVersion >= 1.040 then fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } } end - fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } + if apiVersion >= 1.044 then + fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } + else + fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } + end fields[#fields + 1] = { t = "Threshold", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 1000, vals = { 20, 21 } } end From 75494ffd44dd1d1ca0ebd87ac43a45fcde7376d8 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 18 Dec 2020 19:11:00 +0100 Subject: [PATCH 106/193] Add RC Smoothing FIlter parameters --- src/SCRIPTS/BF/PAGES/rx.lua | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index f9939b5e..9fa40d2e 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -17,19 +17,39 @@ local labels = {} local fields = {} if apiVersion >= 1.016 then - labels[#labels + 1] = { t = "Stick", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Low", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 6, 7 } } - fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 4, 5 } } - fields[#fields + 1] = { t = "High", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 2, 3 } } + labels[#labels + 1] = { t = "Stick", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Low", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 6, 7 } } + fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 4, 5 } } + fields[#fields + 1] = { t = "High", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 2, 3 } } +end + +if apiVersion >= 1.040 then + labels[#labels + 1] = { t = "RC Smoothing", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "Interpolation", "Filter" } } + fields[#fields + 1] = { t = "Channels", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 24 }, table = { [0] = "RP", "RPY", "RPYT", "T", "RT" } } end if apiVersion >= 1.020 then - fields[#fields + 1] = { t = "Interp", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} } - fields[#fields + 1] = { t = "Interp Int", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 50, vals = { 14 } } + fields[#fields + 1] = { t = "Interpolation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} } + fields[#fields + 1] = { t = "Interval", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 50, vals = { 14 } } + +end + +if apiVersion >= 1.040 then + labels[#labels + 1] = { t = "Input Filter", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 26 }, table = { [0] = "Auto" } } + fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 28 }, table = { [0] = "PT1", "BIQUAD"} } + labels[#labels + 1] = { t = "Derivative Filter", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 27 }, table = { [0] = "Auto" } } + fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 29 }, table = { [0] = "Off", "PT1", "BIQUAD", "Auto"} } +end + +if apiVersion >= 1.042 then + fields[#fields + 1] = { t = "Auto Smoothness", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 31 } } end if apiVersion >= 1.031 then - fields[#fields + 1] = { t = "Cam Angle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 90, vals = { 23 } } + fields[#fields + 1] = { t = "Cam Angle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 90, vals = { 23 } } end return { From 2c570a9fadb7f08c4b2bfffa91589064b51beafa Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 18 Dec 2020 19:32:47 +0100 Subject: [PATCH 107/193] Accelerometer calibration Adds a function to the menu that sends MSP_ACC_CALIBRATION to the FC. --- src/SCRIPTS/BF/PAGES/accelerometer.lua | 36 ++++++++++++++++++++++++++ src/SCRIPTS/BF/ui.lua | 13 +++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/SCRIPTS/BF/PAGES/accelerometer.lua diff --git a/src/SCRIPTS/BF/PAGES/accelerometer.lua b/src/SCRIPTS/BF/PAGES/accelerometer.lua new file mode 100644 index 00000000..f6c934bc --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/accelerometer.lua @@ -0,0 +1,36 @@ +local template = loadScript(radio.templateHome.."accelerometer.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +labels[#labels + 1] = { t = "Make sure the craft is level", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "and stable, then press", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "[ENTER] to calibrate, or", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "[EXIT] to cancel.", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { x = x, y = inc.y(lineSpacing), value = "", ro = true, onClick = function(self) self.accCal(self) end } + +return { + write = 205, -- MSP_ACC_CALIBRATION + title = "Accelerometer", + reboot = false, + eepromWrite = false, + minBytes = 0, + labels = labels, + fields = fields, + accCal = function(self) + protocol.mspRead(self.write) + end, +} diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 630c3d8e..552c8220 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -16,7 +16,7 @@ local pageStatus = local uiMsp = { reboot = 68, - eepromWrite = 250 + eepromWrite = 250, } local uiState = uiStatus.init @@ -72,6 +72,13 @@ local function eepromWrite() protocol.mspRead(uiMsp.eepromWrite) end +local function accCal() + invalidatePages() + currentField = 1 + Page = assert(loadScript("Pages/accelerometer.lua"))() + collectgarbage() +end + local function getVtxTables() uiState = uiStatus.init PageFiles = nil @@ -85,6 +92,7 @@ local function createPopupMenu() { t = "save page", f = saveSettings }, { t = "reload", f = invalidatePages }, { t = "reboot", f = rebootFc }, + { t = "acc cal", f = accCal }, } if apiVersion >= 1.042 then popupMenuList[#popupMenuList + 1] = { t = "vtx tables", f = getVtxTables } @@ -342,6 +350,9 @@ local function run_ui(event) elseif event == EVT_VIRTUAL_ENTER then if Page then local f = Page.fields[currentField] + if f.onClick then + f.onClick(Page) + end if Page.values and f.vals and Page.values[f.vals[#f.vals]] and not f.ro then pageState = pageStatus.editing end From 7ef9dd90e0f3a4eab66b23f58bea96b96504d208 Mon Sep 17 00:00:00 2001 From: Michael Keller Date: Sat, 16 Jan 2021 22:48:49 +1300 Subject: [PATCH 108/193] Changed stale request handling to use a GitHub action. --- .github/stale.yml | 55 ------------------------------------ .github/workflows/stale.yaml | 31 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 55 deletions(-) delete mode 100644 .github/stale.yml create mode 100644 .github/workflows/stale.yaml diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 74406576..00000000 --- a/.github/stale.yml +++ /dev/null @@ -1,55 +0,0 @@ -# Configuration for probot-stale - https://github.com/probot/stale - -# Number of days of inactivity before an Issue or Pull Request becomes stale -daysUntilStale: 30 - -# Number of days of inactivity before a stale Issue or Pull Request is closed. -# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. -daysUntilClose: 7 - -# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable -exemptLabels: - - BUG - - Feature Request - - Pinned - -# Set to true to ignore issues in a project (defaults to false) -exemptProjects: false - -# Set to true to ignore issues in a milestone (defaults to false) -exemptMilestones: true - -# Label to use when marking as stale -staleLabel: Inactive - -# Comment to post when marking as stale. Set to `false` to disable -markComment: > - This issue / pull request has been automatically marked as stale because it - has not had recent activity. It will be closed if no further activity occurs - within a week. - -# Comment to post when removing the stale label. -# unmarkComment: > -# Your comment here. - -# Comment to post when closing a stale Issue or Pull Request. -closeComment: > - Automatically closing as inactive. - -# Limit the number of actions per hour, from 1-30. Default is 30 -limitPerRun: 30 - -# Limit to only `issues` or `pulls` -# only: issues - -# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': -# pulls: -# daysUntilStale: 30 -# markComment: > -# This pull request has been automatically marked as stale because it has not had -# recent activity. It will be closed if no further activity occurs. Thank you -# for your contributions. - -# issues: -# exemptLabels: -# - confirmed diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml new file mode 100644 index 00000000..3f3811a0 --- /dev/null +++ b/.github/workflows/stale.yaml @@ -0,0 +1,31 @@ +name: 'Close stale issues' + +on: + schedule: + - cron: "30 4 * * *" + +jobs: + stale: + name: 'Check and close stale issues' + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + operations-per-run: 30 + days-before-stale: 30 + days-before-close: 7 + stale-issue-message: > + This issue has been automatically marked as stale because it + has not had recent activity. It will be closed if no further activity occurs + within a week. + close-issue-message: 'Issue closed automatically as inactive.' + exempt-issue-labels: 'BUG,Feature Request,Pinned,Has Milestone' + stale-issue-label: 'Inactive' + stale-pr-message: > + This pull request has been automatically marked as stale because it + has not had recent activity. It will be closed if no further activity occurs + within a week. + close-pr-message: 'Pull request closed automatically as inactive.' + exempt-pr-labels: 'Pinned,Has Milestone' + stale-pr-label: 'Inactive' From b8e4a1c83449771ad6a82c01b540f773b83627d3 Mon Sep 17 00:00:00 2001 From: mikeller Date: Tue, 9 Feb 2021 00:26:49 +1300 Subject: [PATCH 109/193] Exempt issues and pull requests with a milestone from going stale. --- .github/workflows/stale.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 3f3811a0..74c4c2cd 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -20,12 +20,13 @@ jobs: has not had recent activity. It will be closed if no further activity occurs within a week. close-issue-message: 'Issue closed automatically as inactive.' - exempt-issue-labels: 'BUG,Feature Request,Pinned,Has Milestone' + exempt-issue-labels: 'BUG,Feature Request,Pinned' stale-issue-label: 'Inactive' stale-pr-message: > This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs within a week. close-pr-message: 'Pull request closed automatically as inactive.' - exempt-pr-labels: 'Pinned,Has Milestone' + exempt-pr-labels: 'Pinned' stale-pr-label: 'Inactive' + exempt-all-milestones: true From fe68db8a686008468b1c1dc1ecb7ff25f9f8deb4 Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 28 Mar 2021 17:06:50 +1300 Subject: [PATCH 110/193] Enabled pull request builds in Azure. --- azure-pipelines.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 66f7f867..5a151a50 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -17,12 +17,19 @@ variables: releaseNotes: This is a nightly build off the tip of 'master'. It may be unstable and result in corrupted configurations or data loss. **Use only for testing.** name: $(Date:yyyyMMdd).$(BuildID) + trigger: batch: true branches: include: - master -pr: none + +pr: + drafts: false + branches: + include: + - master + - "*-maintenance" stages: - stage: Build From 7e36579ff629c8def25cb35ef42da4b75b2cb923 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 11 Apr 2021 16:06:58 +0200 Subject: [PATCH 111/193] Add min dth to GPS rescue page --- src/SCRIPTS/BF/PAGES/rescue.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index ecc9785a..f72ba094 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -32,6 +32,10 @@ if apiVersion >= 1.041 then fields[#fields + 1] = { t = "Min", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 9, 10 } } fields[#fields + 1] = { t = "Hover", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 13, 14 } } fields[#fields + 1] = { t = "Max", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 11, 12 } } + + if apiVersion >= 1.044 then + fields[#fields + 1] = { t = "Min Dth", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 1000, vals = { 23, 24 } } + end end return { From ef8cf943649c90dd026d75ab8911f6435b0224d4 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 11 Apr 2021 20:52:38 +0200 Subject: [PATCH 112/193] Add ascend/descend rate and altitude mode --- src/SCRIPTS/BF/PAGES/rescue.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index f72ba094..a409add9 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -24,7 +24,10 @@ if apiVersion >= 1.041 then fields[#fields + 1] = { t = "Ground Speed", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 30, max = 3000, vals = { 7, 8 } } if apiVersion >= 1.043 then + fields[#fields + 1] = { t = "Ascend Rate", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 100, max = 2500, vals = { 17, 18 }, scale = 100 } + fields[#fields + 1] = { t = "Descend Rate", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 100, max = 500, vals = { 19, 20 }, scale = 100 } fields[#fields + 1] = { t = "Arm w/o fix", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 21 }, table = { [0]="OFF","ON"} } + fields[#fields + 1] = { t = "Altitude Mode",x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 22 }, table = { [0]="Maximum", "Fixed", "Current"} } end fields[#fields + 1] = { t = "Sanity Check", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 15 }, table = { [0]="OFF","ON","FS_ONLY"} } From d00b921669a5aea0f9525e705bf01bde176bf811 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 2 May 2021 21:49:01 +0200 Subject: [PATCH 113/193] Popup improvements --- .../accelerometer.lua => CONFIRM/acc_cal.lua} | 18 +-- src/SCRIPTS/BF/CONFIRM/vtx_tables.lua | 29 +++++ src/SCRIPTS/BF/acc_cal.lua | 24 ++++ src/SCRIPTS/BF/background.lua | 20 +-- src/SCRIPTS/BF/data_init.lua | 2 +- src/SCRIPTS/BF/mcu_id.lua | 2 +- src/SCRIPTS/BF/ui.lua | 118 ++++++++++-------- src/SCRIPTS/BF/ui_init.lua | 25 ++-- src/SCRIPTS/BF/vtx_tables.lua | 2 +- 9 files changed, 146 insertions(+), 94 deletions(-) rename src/SCRIPTS/BF/{PAGES/accelerometer.lua => CONFIRM/acc_cal.lua} (70%) create mode 100644 src/SCRIPTS/BF/CONFIRM/vtx_tables.lua create mode 100644 src/SCRIPTS/BF/acc_cal.lua diff --git a/src/SCRIPTS/BF/PAGES/accelerometer.lua b/src/SCRIPTS/BF/CONFIRM/acc_cal.lua similarity index 70% rename from src/SCRIPTS/BF/PAGES/accelerometer.lua rename to src/SCRIPTS/BF/CONFIRM/acc_cal.lua index f6c934bc..1294e5c0 100644 --- a/src/SCRIPTS/BF/PAGES/accelerometer.lua +++ b/src/SCRIPTS/BF/CONFIRM/acc_cal.lua @@ -1,4 +1,4 @@ -local template = loadScript(radio.templateHome.."accelerometer.lua") +local template = loadScript(radio.templateHome.."acc_cal.lua") if template then template = template() else @@ -20,17 +20,11 @@ labels[#labels + 1] = { t = "Make sure the craft is level", x = x, y = inc.y(lin labels[#labels + 1] = { t = "and stable, then press", x = x, y = inc.y(lineSpacing) } labels[#labels + 1] = { t = "[ENTER] to calibrate, or", x = x, y = inc.y(lineSpacing) } labels[#labels + 1] = { t = "[EXIT] to cancel.", x = x, y = inc.y(lineSpacing) } -fields[#fields + 1] = { x = x, y = inc.y(lineSpacing), value = "", ro = true, onClick = function(self) self.accCal(self) end } +fields[#fields + 1] = { x = x, y = inc.y(lineSpacing), value = "", ro = true } return { - write = 205, -- MSP_ACC_CALIBRATION - title = "Accelerometer", - reboot = false, - eepromWrite = false, - minBytes = 0, - labels = labels, - fields = fields, - accCal = function(self) - protocol.mspRead(self.write) - end, + title = "Accelerometer", + labels = labels, + fields = fields, + init = assert(loadScript("acc_cal.lua"))(), } diff --git a/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua b/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua new file mode 100644 index 00000000..33d98dc5 --- /dev/null +++ b/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua @@ -0,0 +1,29 @@ +local template = loadScript(radio.templateHome.."vtx_tables.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +labels[#labels + 1] = { t = "Download VTX tables? Press", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "[ENTER] to download, or", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "[EXIT] to cancel.", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { x = x, y = inc.y(lineSpacing), value = "", ro = true } + +return { + title = "VTX Tables", + labels = labels, + fields = fields, + init = assert(loadScript("vtx_tables.lua"))(), +} diff --git a/src/SCRIPTS/BF/acc_cal.lua b/src/SCRIPTS/BF/acc_cal.lua new file mode 100644 index 00000000..582d459c --- /dev/null +++ b/src/SCRIPTS/BF/acc_cal.lua @@ -0,0 +1,24 @@ +local MSP_ACC_CALIBRATION = 205 +local accCalibrated = false +local lastRunTS = 0 +local INTERVAL = 500 + +local function processMspReply(cmd,rx_buf) + if cmd == MSP_ACC_CALIBRATION then + accCalibrated = true + end +end + +local function accCal() + if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then + lastRunTS = getTime() + if not accCalibrated then + protocol.mspRead(MSP_ACC_CALIBRATION) + end + end + mspProcessTxQ() + processMspReply(mspPollReply()) + return accCalibrated +end + +return { f = accCal, t = "Calibrating Accelerometer" } diff --git a/src/SCRIPTS/BF/background.lua b/src/SCRIPTS/BF/background.lua index 203be3e7..788d44c6 100644 --- a/src/SCRIPTS/BF/background.lua +++ b/src/SCRIPTS/BF/background.lua @@ -1,26 +1,14 @@ -local sensorId = -1 local dataInitialised = false local data_init = nil local rssiEnabled = true local rssiTask = nil -local function getSensorValue() - if sensorId == -1 then - local sensor = getFieldInfo(protocol.stateSensor) - if type(sensor) == "table" then - sensorId = sensor['id'] or -1 - end - end - return getValue(sensorId) -end - -local function modelActive(sensorValue) - return type(sensorValue) == "number" and sensorValue > 0 +local function modelActive() + return getValue(protocol.stateSensor) > 0 end local function run_bg() - local sensorValue = getSensorValue() - if modelActive(sensorValue) then + if modelActive() then -- Send data when the telemetry connection is available -- assuming when sensor value higher than 0 there is an telemetry connection if not dataInitialised then @@ -28,7 +16,7 @@ local function run_bg() data_init = assert(loadScript("data_init.lua"))() end - dataInitialised = data_init() + dataInitialised = data_init.f() if dataInitialised then data_init = nil diff --git a/src/SCRIPTS/BF/data_init.lua b/src/SCRIPTS/BF/data_init.lua index ae4da07f..5db438ef 100644 --- a/src/SCRIPTS/BF/data_init.lua +++ b/src/SCRIPTS/BF/data_init.lua @@ -63,4 +63,4 @@ local function init() return apiVersionReceived and timeIsSet end -return init +return { f = init, t = "Waiting for API version" } diff --git a/src/SCRIPTS/BF/mcu_id.lua b/src/SCRIPTS/BF/mcu_id.lua index 6ed9d8a4..26d1e2ba 100644 --- a/src/SCRIPTS/BF/mcu_id.lua +++ b/src/SCRIPTS/BF/mcu_id.lua @@ -34,4 +34,4 @@ local function getMCUId() return MCUIdReceived end -return getMCUId +return { f = getMCUId, t = "Waiting for device ID" } diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 552c8220..a3839c92 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -1,16 +1,16 @@ local uiStatus = { init = 1, - pages = 2, - mainMenu = 3, + mainMenu = 2, + pages = 3, + confirm = 4, } local pageStatus = { - display = 2, - editing = 3, - saving = 4, - popupMenu = 5, + display = 1, + editing = 2, + saving = 3, } local uiMsp = @@ -20,6 +20,7 @@ local uiMsp = } local uiState = uiStatus.init +local prevUiState local pageState = pageStatus.display local requestTimeout = 80 local currentPage = 1 @@ -32,7 +33,7 @@ local popupMenuActive = 1 local killEnterBreak = 0 local pageScrollY = 0 local mainMenuScrollY = 0 -local PageFiles, Page, init, popupMenuList +local PageFiles, Page, init, popupMenu local backgroundFill = TEXT_BGCOLOR or ERASE local foregroundColor = LINE_COLOR or SOLID @@ -72,30 +73,26 @@ local function eepromWrite() protocol.mspRead(uiMsp.eepromWrite) end -local function accCal() +local function confirm(page) + prevUiState = uiState + uiState = uiStatus.confirm invalidatePages() currentField = 1 - Page = assert(loadScript("Pages/accelerometer.lua"))() + Page = assert(loadScript(page))() collectgarbage() end -local function getVtxTables() - uiState = uiStatus.init - PageFiles = nil - invalidatePages() - io.close(io.open("/BF/VTX/"..mcuId..".lua", 'w')) - return 0 -end - local function createPopupMenu() - popupMenuList = { - { t = "save page", f = saveSettings }, - { t = "reload", f = invalidatePages }, - { t = "reboot", f = rebootFc }, - { t = "acc cal", f = accCal }, - } + popupMenuActive = 1 + popupMenu = {} + if uiState == uiStatus.pages then + popupMenu[#popupMenu + 1] = { t = "save page", f = saveSettings } + popupMenu[#popupMenu + 1] = { t = "reload", f = invalidatePages } + end + popupMenu[#popupMenu + 1] = { t = "reboot", f = rebootFc } + popupMenu[#popupMenu + 1] = { t = "acc cal", f = function() confirm("CONFIRM/acc_cal.lua") end } if apiVersion >= 1.042 then - popupMenuList[#popupMenuList + 1] = { t = "vtx tables", f = getVtxTables } + popupMenu[#popupMenu + 1] = { t = "vtx tables", f = function() confirm("CONFIRM/vtx_tables.lua") end } end end @@ -162,7 +159,7 @@ local function incMainMenu(inc) end local function incPopupMenu(inc) - popupMenuActive = clipValue(popupMenuActive + inc, 1, #popupMenuList) + popupMenuActive = clipValue(popupMenuActive + inc, 1, #popupMenu) end local function requestPage() @@ -251,13 +248,13 @@ local function drawPopupMenu() local w = radio.MenuBox.w local h_line = radio.MenuBox.h_line local h_offset = radio.MenuBox.h_offset - local h = #popupMenuList * h_line + h_offset*2 + local h = #popupMenu * h_line + h_offset*2 lcd.drawFilledRectangle(x,y,w,h,backgroundFill) lcd.drawRectangle(x,y,w-1,h-1,foregroundColor) lcd.drawText(x+h_line/2,y+h_offset,"Menu:",globalTextOptions) - for i,e in ipairs(popupMenuList) do + for i,e in ipairs(popupMenu) do local textOptions = globalTextOptions if popupMenuActive == i then textOptions = textOptions + INVERS @@ -267,18 +264,35 @@ local function drawPopupMenu() end local function run_ui(event) - if uiState == uiStatus.init then + if popupMenu then + drawPopupMenu() + if event == EVT_VIRTUAL_EXIT then + popupMenu = nil + elseif event == EVT_VIRTUAL_PREV then + incPopupMenu(-1) + elseif event == EVT_VIRTUAL_NEXT then + incPopupMenu(1) + elseif event == EVT_VIRTUAL_ENTER then + if killEnterBreak == 1 then + killEnterBreak = 0 + else + popupMenu[popupMenuActive].f() + popupMenu = nil + end + end + elseif uiState == uiStatus.init then lcd.clear() drawScreenTitle("Betaflight Config") init = init or assert(loadScript("ui_init.lua"))() - if not init() then + lcd.drawText(6, radio.yMinLimit, init.t) + if not init.f() then return 0 end init = nil - createPopupMenu() PageFiles = assert(loadScript("pages.lua"))() invalidatePages() - uiState = uiStatus.mainMenu + uiState = prevUiState or uiStatus.mainMenu + prevUiState = nil elseif uiState == uiStatus.mainMenu then if event == EVT_VIRTUAL_EXIT then return 2 @@ -288,6 +302,9 @@ local function run_ui(event) incMainMenu(-1) elseif event == EVT_VIRTUAL_ENTER then uiState = uiStatus.pages + elseif event == EVT_VIRTUAL_ENTER_LONG then + killEnterBreak = 1 + createPopupMenu() end lcd.clear() local yMinLim = radio.yMinLimit @@ -322,21 +339,6 @@ local function run_ui(event) invalidatePages() end end - elseif pageState == pageStatus.popupMenu then - if event == EVT_VIRTUAL_EXIT then - pageState = pageStatus.display - elseif event == EVT_VIRTUAL_PREV then - incPopupMenu(-1) - elseif event == EVT_VIRTUAL_NEXT then - incPopupMenu(1) - elseif event == EVT_VIRTUAL_ENTER then - if killEnterBreak == 1 then - killEnterBreak = 0 - else - pageState = pageStatus.display - return popupMenuList[popupMenuActive].f() or 0 - end - end elseif pageState == pageStatus.display then if event == EVT_VIRTUAL_PREV_PAGE then incPage(-1) @@ -350,17 +352,13 @@ local function run_ui(event) elseif event == EVT_VIRTUAL_ENTER then if Page then local f = Page.fields[currentField] - if f.onClick then - f.onClick(Page) - end if Page.values and f.vals and Page.values[f.vals[#f.vals]] and not f.ro then pageState = pageStatus.editing end end elseif event == EVT_VIRTUAL_ENTER_LONG then - popupMenuActive = 1 killEnterBreak = 1 - pageState = pageStatus.popupMenu + createPopupMenu() elseif event == EVT_VIRTUAL_EXIT then invalidatePages() currentField = 1 @@ -380,7 +378,7 @@ local function run_ui(event) end end if not Page then - Page = assert(loadScript("Pages/"..PageFiles[currentPage].script))() + Page = assert(loadScript("PAGES/"..PageFiles[currentPage].script))() collectgarbage() end if not Page.values and pageState == pageStatus.display then @@ -388,9 +386,7 @@ local function run_ui(event) end lcd.clear() drawScreen() - if pageState == pageStatus.popupMenu then - drawPopupMenu() - elseif pageState == pageStatus.saving then + if pageState == pageStatus.saving then local saveMsg = "Saving..." if saveRetries > 0 then saveMsg = "Retrying" @@ -399,6 +395,18 @@ local function run_ui(event) lcd.drawRectangle(radio.SaveBox.x,radio.SaveBox.y,radio.SaveBox.w,radio.SaveBox.h,SOLID) lcd.drawText(radio.SaveBox.x+radio.SaveBox.x_offset,radio.SaveBox.y+radio.SaveBox.h_offset,saveMsg,DBLSIZE + globalTextOptions) end + elseif uiState == uiStatus.confirm then + lcd.clear() + drawScreen() + if event == EVT_VIRTUAL_ENTER then + uiState = uiStatus.init + init = Page.init + invalidatePages() + elseif event == EVT_VIRTUAL_EXIT then + invalidatePages() + uiState = prevUiState + prevUiState = nil + end end if protocol.rssi() == 0 then lcd.drawText(radio.NoTelem[1],radio.NoTelem[2],radio.NoTelem[3],radio.NoTelem[4]) diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 7ad770bd..0f18cad0 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -1,20 +1,27 @@ local apiVersionReceived = false local vtxTablesReceived = false local data_init, getVtxTables, getMCUId +local returnTable = { f = nil, t = "" } + +local function modelActive() + return getValue(protocol.stateSensor) > 0 +end local function init() - if apiVersion == 0 then - lcd.drawText(6, radio.yMinLimit, "Waiting for connection") + if not modelActive() then + returnTable.t = "Waiting for connection" + elseif apiVersion == 0 then data_init = data_init or assert(loadScript("data_init.lua"))() - data_init() + returnTable.t = data_init.t + data_init.f() elseif apiVersion > 0 and not apiVersionReceived then data_init = nil apiVersionReceived = true collectgarbage() elseif apiVersion >= 1.042 and not mcuId then - lcd.drawText(6, radio.yMinLimit, "Waiting for device ID") getMCUId = getMCUId or assert(loadScript("mcu_id.lua"))() - if getMCUId() then + returnTable.t = getMCUId.t + if getMCUId.f() then getMCUId = nil local vtxTables = loadScript("/BF/VTX/"..mcuId..".lua") if vtxTables and vtxTables() then @@ -24,9 +31,9 @@ local function init() collectgarbage() end elseif apiVersion >= 1.042 and not vtxTablesReceived then - lcd.drawText(6, radio.yMinLimit, "Downloading VTX Tables") getVtxTables = getVtxTables or assert(loadScript("vtx_tables.lua"))() - vtxTablesReceived = getVtxTables() + returnTable.t = getVtxTables.t + vtxTablesReceived = getVtxTables.f() if vtxTablesReceived then getVtxTables = nil collectgarbage() @@ -37,4 +44,6 @@ local function init() return apiVersionReceived and vtxTablesReceived and mcuId end -return init +returnTable.f = init + +return returnTable diff --git a/src/SCRIPTS/BF/vtx_tables.lua b/src/SCRIPTS/BF/vtx_tables.lua index 01fa377f..91175588 100644 --- a/src/SCRIPTS/BF/vtx_tables.lua +++ b/src/SCRIPTS/BF/vtx_tables.lua @@ -116,4 +116,4 @@ local function getVtxTables() return vtxTablesReceived end -return getVtxTables +return { f = getVtxTables, t = "Downloading VTX Tables" } From 32f7ba51077578610f977dd3cad2df99d13388f1 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 13 May 2021 21:37:33 +0200 Subject: [PATCH 114/193] Add failsafe page --- src/SCRIPTS/BF/PAGES/failsafe.lua | 50 +++++++++++++++++++++++++++++++ src/SCRIPTS/BF/pages.lua | 4 +++ 2 files changed, 54 insertions(+) create mode 100644 src/SCRIPTS/BF/PAGES/failsafe.lua diff --git a/src/SCRIPTS/BF/PAGES/failsafe.lua b/src/SCRIPTS/BF/PAGES/failsafe.lua new file mode 100644 index 00000000..39298c37 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/failsafe.lua @@ -0,0 +1,50 @@ +local template = loadScript(radio.templateHome.."failsafe.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +local procedure = { [0] = "Land", "Drop" } + +if apiVersion >= 1.039 then + procedure[#procedure + 1] = "Rescue" +end + +if apiVersion >= 1.039 then + labels[#labels + 1] = { t = "Failsafe Switch", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Action", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 5 }, table = { [0] = "Stage 1", "Kill", "Stage 2" } } +else + fields[#fields + 1] = { t = "Kill switch", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 5 }, table = { [0] = "OFF", "ON" } } +end + +labels[#labels + 1] = { t = "Stage 2 Settings" , x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Procedure", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #procedure, vals = { 8 }, table = procedure } +fields[#fields + 1] = { t = "Guard Time", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 1 }, scale = 10 } +fields[#fields + 1] = { t = "Thrl Low Delay", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 300, vals = { 6, 7 }, scale = 10 } + +labels[#labels + 1] = { t = "Stage 2 Land Settings", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Thrl Land Value", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 750, max = 2250, vals = { 3, 4 } } +fields[#fields + 1] = { t = "Motor Off Delay", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 2 }, scale = 10 } + +return { + read = 75, -- MSP_FAILSAFE_CONFIG + write = 76, -- MSP_SET_FAILSAFE_CONFIG + title = "Failsafe", + reboot = true, + eepromWrite = true, + minBytes = 8, + labels = labels, + fields = fields, +} diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index 2fcdf6f8..d6151caa 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -36,6 +36,10 @@ if apiVersion >= 1.016 then PageFiles[#PageFiles + 1] = { title = "Receiver", script = "rx.lua" } end +if apiVersion >= 1.016 then + PageFiles[#PageFiles + 1] = { title = "Failsafe", script = "failsafe.lua" } +end + if apiVersion >= 1.041 then PageFiles[#PageFiles + 1] = { title = "GPS Rescue", script = "rescue.lua" } end From 9143addf0123bf0f0a1edab08253e2c11f6ffb7f Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 13 May 2021 22:42:04 +0200 Subject: [PATCH 115/193] Add simplified tuning page Simplified pid and filter tuning. --- src/SCRIPTS/BF/PAGES/simplified_tuning.lua | 44 ++++++++++++++++++++++ src/SCRIPTS/BF/pages.lua | 4 ++ 2 files changed, 48 insertions(+) create mode 100644 src/SCRIPTS/BF/PAGES/simplified_tuning.lua diff --git a/src/SCRIPTS/BF/PAGES/simplified_tuning.lua b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua new file mode 100644 index 00000000..49c31303 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua @@ -0,0 +1,44 @@ +local template = loadScript(radio.templateHome.."simplified_pids.lua") +if template then + template = template() +else + template = assert(loadScript(radio.templateHome.."default_template.lua"))() +end +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +labels[#labels + 1] = { t = "Simplified Pid", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Pid Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 1 }, table = { [0] = "OFF", "RP", "RPY" } } +fields[#fields + 1] = { t = "Master Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 2 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "R/P Ratio", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 3 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "I Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 4 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "P/D Ratio", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 5 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "PD Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 6 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Dmin Ratio", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 7 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "FF Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 8 }, scale = 100, mult = 5 } + +labels[#labels + 1] = { t = "Simplified Filter", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Gyro Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { t = "Gyro Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 10 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "D Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 11 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { t = "D Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 12 }, scale = 100, mult = 5 } + +return { + read = 140, -- MSP_SIMPLIFIED_TUNING + write = 141, -- MSP_SET_SIMPLIFIED_TUNING + title = "Simplified Tuning", + reboot = false, + eepromWrite = true, + minBytes = 12, + labels = labels, + fields = fields, +} diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index 2fcdf6f8..9d98d053 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -20,6 +20,10 @@ if apiVersion >= 1.016 then PageFiles[#PageFiles + 1] = { title = "Advanced PIDs", script = "pid_advanced.lua" } end +if apiVersion >= 1.044 then + PageFiles[#PageFiles + 1] = { title = "Simplified Tuning", script = "simplified_tuning.lua" } +end + if apiVersion >= 1.016 then PageFiles[#PageFiles + 1] = { title = "Filters 1", script = "filters1.lua" } end From 0452542b1d24d419862552562989a9945037cf88 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 17 May 2021 21:25:08 +0200 Subject: [PATCH 116/193] Add PT2 and PT3 filter options Adds PT2 and PT3 lowpass options to filter 1 page. --- src/SCRIPTS/BF/PAGES/filters1.lua | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/filters1.lua b/src/SCRIPTS/BF/PAGES/filters1.lua index d7eb5937..430d566d 100644 --- a/src/SCRIPTS/BF/PAGES/filters1.lua +++ b/src/SCRIPTS/BF/PAGES/filters1.lua @@ -16,18 +16,33 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +local gyroFilterType = { [0] = "PT1", "BIQUAD" } + +if apiVersion >= 1.044 then + gyroFilterType[#gyroFilterType + 1] = "PT2" + gyroFilterType[#gyroFilterType + 1] = "PT3" +end + +local dtermFilterType = gyroFilterType + +if apiVersion >= 1.036 and apiVersion <= 1.038 then + dtermFilterType = { [0] = "PT1", "BIQUAD", "FIR" } +end + +local dtermFilterType2 = gyroFilterType + if apiVersion >= 1.041 then labels[#labels + 1] = { t = "Gyro Lowpass 1 Dynamic", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 30, 31 } } fields[#fields + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 32, 33 } } - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #gyroFilterType, vals = { 25 }, table = gyroFilterType } end if apiVersion >= 1.016 then labels[#labels + 1] = { t = "Gyro Lowpass 1", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.039 then fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 21, 22 } } - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #gyroFilterType, vals = { 25 }, table = gyroFilterType } else fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 1 } } end @@ -36,7 +51,7 @@ end if apiVersion >= 1.039 then labels[#labels + 1] = { t = "Gyro Lowpass 2", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 23, 24 } } - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 26 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #gyroFilterType, vals = { 26 }, table = gyroFilterType } end if apiVersion >= 1.020 then @@ -55,16 +70,14 @@ if apiVersion >= 1.041 then labels[#labels + 1] = { t = "D Term Lowpass 1 Dynamic", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 34, 35 } } fields[#fields + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 36, 37 } } - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #dtermFilterType, vals = { 18 }, table = dtermFilterType } end if apiVersion >= 1.016 then labels[#labels + 1] = { t = "D Term Lowpass 1", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 2, 3 } } - if apiVersion >= 1.036 and apiVersion <= 1.038 then - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD", [2] = "FIR" } } - elseif apiVersion >= 1.039 then - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 18 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + if apiVersion >= 1.036 then + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #dtermFilterType, vals = { 18 }, table = dtermFilterType } end end @@ -72,7 +85,7 @@ if apiVersion >= 1.039 then labels[#labels + 1] = { t = "D Term Lowpass 2", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 27, 28 } } if apiVersion >= 1.041 then - fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 29 }, table = { [0] = "PT1", [1] = "BIQUAD" } } + fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #dtermFilterType2, vals = { 29 }, table = dtermFilterType2 } end end From b2c24ce1016ee0f0f6072a2bd9d816bc570d184c Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sat, 15 May 2021 21:14:03 +0200 Subject: [PATCH 117/193] Split data_init.lua --- src/SCRIPTS/BF/api_version.lua | 26 ++++++++++++++ src/SCRIPTS/BF/background.lua | 41 +++++++++++---------- src/SCRIPTS/BF/data_init.lua | 66 ---------------------------------- src/SCRIPTS/BF/rtc.lua | 54 ++++++++++++++++++++++++++++ src/SCRIPTS/BF/ui_init.lua | 26 +++++++------- 5 files changed, 114 insertions(+), 99 deletions(-) create mode 100644 src/SCRIPTS/BF/api_version.lua delete mode 100644 src/SCRIPTS/BF/data_init.lua create mode 100644 src/SCRIPTS/BF/rtc.lua diff --git a/src/SCRIPTS/BF/api_version.lua b/src/SCRIPTS/BF/api_version.lua new file mode 100644 index 00000000..366fa500 --- /dev/null +++ b/src/SCRIPTS/BF/api_version.lua @@ -0,0 +1,26 @@ +local MSP_API_VERSION = 1 + +local apiVersionReceived = false +local lastRunTS = 0 +local INTERVAL = 50 + +local function processMspReply(cmd,rx_buf) + if cmd == MSP_API_VERSION and #rx_buf >= 3 then + apiVersion = rx_buf[2] + rx_buf[3] / 1000 + apiVersionReceived = true + end +end + +local function getApiVersion() + if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then + protocol.mspRead(MSP_API_VERSION) + lastRunTS = getTime() + end + + mspProcessTxQ() + processMspReply(mspPollReply()) + + return apiVersionReceived +end + +return { f = getApiVersion, t = "Waiting for API version" } diff --git a/src/SCRIPTS/BF/background.lua b/src/SCRIPTS/BF/background.lua index 788d44c6..176198e5 100644 --- a/src/SCRIPTS/BF/background.lua +++ b/src/SCRIPTS/BF/background.lua @@ -1,7 +1,7 @@ -local dataInitialised = false -local data_init = nil +local apiVersionReceived = false +local timeIsSet = false +local getApiVersion, setRtc, rssiTask local rssiEnabled = true -local rssiTask = nil local function modelActive() return getValue(protocol.stateSensor) > 0 @@ -11,36 +11,35 @@ local function run_bg() if modelActive() then -- Send data when the telemetry connection is available -- assuming when sensor value higher than 0 there is an telemetry connection - if not dataInitialised then - if not data_init then - data_init = assert(loadScript("data_init.lua"))() + if not apiVersionReceived then + getApiVersion = getApiVersion or assert(loadScript("api_version.lua"))() + apiVersionReceived = getApiVersion.f() + if apiVersionReceived then + getApiVersion = nil + collectgarbage() end - - dataInitialised = data_init.f() - - if dataInitialised then - data_init = nil - + elseif not timeIsSet then + setRtc = setRtc or assert(loadScript("rtc.lua"))() + timeIsSet = setRtc.f() + if timeIsSet then + setRtc = nil collectgarbage() end elseif rssiEnabled and apiVersion >= 1.037 then - if not rssiTask then - rssiTask = assert(loadScript("rssi.lua"))() - end - + rssiTask = rssiTask or assert(loadScript("rssi.lua"))() rssiEnabled = rssiTask() - if not rssiEnabled then rssiTask = nil - collectgarbage() end end else - dataInitialised = false + apiVersionReceived = false + timeIsSet = false rssiEnabled = true - if data_init or rssiTask then - data_init = nil + if getApiVersion or setRtc or rssiTask then + getApiVersion = nil + setRtc = nil rssiTask = nil collectgarbage() end diff --git a/src/SCRIPTS/BF/data_init.lua b/src/SCRIPTS/BF/data_init.lua deleted file mode 100644 index 5db438ef..00000000 --- a/src/SCRIPTS/BF/data_init.lua +++ /dev/null @@ -1,66 +0,0 @@ -local MSP_API_VERSION = 1 -local MSP_SET_RTC = 246 - -local apiVersionReceived = false -local timeIsSet = false -local lastRunTS = 0 -local INTERVAL = 50 - -local function processMspReply(cmd,rx_buf) - if cmd == MSP_API_VERSION and #rx_buf >= 3 then - apiVersion = rx_buf[2] + rx_buf[3] / 1000 - - apiVersionReceived = true - end - if cmd == MSP_SET_RTC then - timeIsSet = true - end -end - -local function init() - if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then - if not apiVersionReceived then - protocol.mspRead(MSP_API_VERSION) - elseif apiVersionReceived and not timeIsSet then - -- only send datetime one time after telemetry connection became available - -- or when connection is restored after e.g. lipo refresh - local values = {} - if apiVersion >= 1.041 then - -- format: seconds after the epoch (32) / milliseconds (16) - local now = getRtcTime() - - for i = 1, 4 do - values[i] = bit32.band(now, 0xFF) - now = bit32.rshift(now, 8) - end - - values[5] = 0 -- we don't have milliseconds - values[6] = 0 - else - -- format: year (16) / month (8) / day (8) / hour (8) / min (8) / sec (8) - local now = getDateTime() - local year = now.year - - values[1] = bit32.band(year, 0xFF) - year = bit32.rshift(year, 8) - values[2] = bit32.band(year, 0xFF) - values[3] = now.mon - values[4] = now.day - values[5] = now.hour - values[6] = now.min - values[7] = now.sec - end - - protocol.mspWrite(MSP_SET_RTC, values) - end - lastRunTS = getTime() - end - - mspProcessTxQ() - - processMspReply(mspPollReply()) - - return apiVersionReceived and timeIsSet -end - -return { f = init, t = "Waiting for API version" } diff --git a/src/SCRIPTS/BF/rtc.lua b/src/SCRIPTS/BF/rtc.lua new file mode 100644 index 00000000..955c91e9 --- /dev/null +++ b/src/SCRIPTS/BF/rtc.lua @@ -0,0 +1,54 @@ +local MSP_SET_RTC = 246 + +local timeIsSet = false +local lastRunTS = 0 +local INTERVAL = 50 + +local function processMspReply(cmd,rx_buf) + if cmd == MSP_SET_RTC then + timeIsSet = true + end +end + +local function setRtc() + if lastRunTS == 0 or lastRunTS + INTERVAL < getTime() then + -- only send datetime one time after telemetry connection became available + -- or when connection is restored after e.g. lipo refresh + local values = {} + if apiVersion >= 1.041 then + -- format: seconds after the epoch (32) / milliseconds (16) + local now = getRtcTime() + + for i = 1, 4 do + values[i] = bit32.band(now, 0xFF) + now = bit32.rshift(now, 8) + end + + values[5] = 0 -- we don't have milliseconds + values[6] = 0 + else + -- format: year (16) / month (8) / day (8) / hour (8) / min (8) / sec (8) + local now = getDateTime() + local year = now.year + + values[1] = bit32.band(year, 0xFF) + year = bit32.rshift(year, 8) + values[2] = bit32.band(year, 0xFF) + values[3] = now.mon + values[4] = now.day + values[5] = now.hour + values[6] = now.min + values[7] = now.sec + end + + protocol.mspWrite(MSP_SET_RTC, values) + lastRunTS = getTime() + end + + mspProcessTxQ() + processMspReply(mspPollReply()) + + return timeIsSet +end + +return { f = setRtc, t = "" } diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 0f18cad0..f535e8b4 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -1,6 +1,7 @@ local apiVersionReceived = false local vtxTablesReceived = false -local data_init, getVtxTables, getMCUId +local mcuIdReceived = false +local getApiVersion, getVtxTables, getMCUId local returnTable = { f = nil, t = "" } local function modelActive() @@ -10,18 +11,19 @@ end local function init() if not modelActive() then returnTable.t = "Waiting for connection" - elseif apiVersion == 0 then - data_init = data_init or assert(loadScript("data_init.lua"))() - returnTable.t = data_init.t - data_init.f() - elseif apiVersion > 0 and not apiVersionReceived then - data_init = nil - apiVersionReceived = true - collectgarbage() - elseif apiVersion >= 1.042 and not mcuId then + elseif not apiVersionReceived then + getApiVersion = getApiVersion or assert(loadScript("api_version.lua"))() + returnTable.t = getApiVersion.t + apiVersionReceived = getApiVersion.f() + if apiVersionReceived then + getApiVersion = nil + collectgarbage() + end + elseif not mcuIdReceived and apiVersion >= 1.042 then getMCUId = getMCUId or assert(loadScript("mcu_id.lua"))() returnTable.t = getMCUId.t - if getMCUId.f() then + mcuIdReceived = getMCUId.f() + if mcuIdReceived then getMCUId = nil local vtxTables = loadScript("/BF/VTX/"..mcuId..".lua") if vtxTables and vtxTables() then @@ -30,7 +32,7 @@ local function init() end collectgarbage() end - elseif apiVersion >= 1.042 and not vtxTablesReceived then + elseif not vtxTablesReceived and apiVersion >= 1.042 then getVtxTables = getVtxTables or assert(loadScript("vtx_tables.lua"))() returnTable.t = getVtxTables.t vtxTablesReceived = getVtxTables.f() From cf5647cafcaa2c714db36ad4cf026eba392479d1 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 24 May 2021 22:07:29 +0200 Subject: [PATCH 118/193] Feedforward update --- src/SCRIPTS/BF/PAGES/pids2.lua | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index 2e56efdf..efa26efe 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -48,15 +48,13 @@ if apiVersion >= 1.040 then end if apiVersion >= 1.040 then - labels[#labels + 1] = { t = "Feedforward", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Transition", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 9 }, scale = 100 } -end - -if apiVersion >= 1.044 then - labels[#labels + 1] = { t = "FF Interpolate", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 51 }, table = { [0] = "OFF", "ON", "AVG_2", "AVG_3", "AVG_4" } } - fields[#fields + 1] = { t = "Smoothness", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 75, vals = { 52 } } - fields[#fields + 1] = { t = "Boost", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 53 } } + labels[#labels + 1] = { t = "Feedforward", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Transition", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 9 }, scale = 100 } + if apiVersion >= 1.044 then + fields[#fields + 1] = { t = "Averaging", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 51 }, table = { [0] = "OFF", "2_POINT", "3_POINT", "4_POINT" } } + fields[#fields + 1] = { t = "Smoothness", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 75, vals = { 52 } } + fields[#fields + 1] = { t = "Boost", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 53 } } + end end if apiVersion >= 1.041 then From 025686d900c429b43415963e9e5de73447d78b3b Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 24 May 2021 22:58:59 +0200 Subject: [PATCH 119/193] RC smoothing update --- src/SCRIPTS/BF/PAGES/rx.lua | 48 +++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index 9fa40d2e..408bc563 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -23,29 +23,35 @@ if apiVersion >= 1.016 then fields[#fields + 1] = { t = "High", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 2, 3 } } end -if apiVersion >= 1.040 then - labels[#labels + 1] = { t = "RC Smoothing", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "Interpolation", "Filter" } } - fields[#fields + 1] = { t = "Channels", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 24 }, table = { [0] = "RP", "RPY", "RPYT", "T", "RT" } } -end - -if apiVersion >= 1.020 then - fields[#fields + 1] = { t = "Interpolation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} } - fields[#fields + 1] = { t = "Interval", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 50, vals = { 14 } } - -end +if apiVersion >= 1.044 then + labels[#labels + 1] = { t = "RC Smoothing", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "ON", "OFF" } } + labels[#labels + 1] = { t = "Cutoffs", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Setpoint", x = x + indent*2, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 26 }, table = { [0] = "Auto" } } + fields[#fields + 1] = { t = "Feedforward", x = x + indent*2, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 27 }, table = { [0] = "Auto" } } + labels[#labels + 1] = { t = "Auto Smoothness", x = x + indent, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Setpoint", x = x + indent*2, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 250, vals = { 31 } } +else + if apiVersion >= 1.040 then + labels[#labels + 1] = { t = "RC Smoothing", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "Interpolation", "Filter" } } + fields[#fields + 1] = { t = "Channels", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 24 }, table = { [0] = "RP", "RPY", "RPYT", "T", "RT" } } + labels[#labels + 1] = { t = "Input Filter", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 26 }, table = { [0] = "Auto" } } + fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 28 }, table = { [0] = "PT1", "BIQUAD"} } + labels[#labels + 1] = { t = "Derivative Filter", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 27 }, table = { [0] = "Auto" } } + fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 29 }, table = { [0] = "Off", "PT1", "BIQUAD", "Auto"} } + end -if apiVersion >= 1.040 then - labels[#labels + 1] = { t = "Input Filter", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 26 }, table = { [0] = "Auto" } } - fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 28 }, table = { [0] = "PT1", "BIQUAD"} } - labels[#labels + 1] = { t = "Derivative Filter", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 255, vals = { 27 }, table = { [0] = "Auto" } } - fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 29 }, table = { [0] = "Off", "PT1", "BIQUAD", "Auto"} } -end + if apiVersion >= 1.020 then + fields[#fields + 1] = { t = "Interpolation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} } + fields[#fields + 1] = { t = "Interval", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 50, vals = { 14 } } + end -if apiVersion >= 1.042 then - fields[#fields + 1] = { t = "Auto Smoothness", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 31 } } + if apiVersion >= 1.042 then + fields[#fields + 1] = { t = "Auto Smoothness", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 31 } } + end end if apiVersion >= 1.031 then From d07d2b8a5adc690837a1db53ed1f6e8f4375aabe Mon Sep 17 00:00:00 2001 From: Asizon <43983086+Asizon@users.noreply.github.com> Date: Sun, 22 Aug 2021 13:38:34 +0200 Subject: [PATCH 120/193] Updated Azure used Ubuntu version --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5a151a50..7b94edce 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -36,7 +36,7 @@ stages: jobs: - job: 'Linux' pool: - vmImage: 'ubuntu-16.04' + vmImage: 'ubuntu-20.04' steps: - script: sudo apt-get -y install lua5.2 displayName: 'Install lua compiler.' From 34cdb94204cd3aa3adc8b687188ac0e55bbb1f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Daleck=C3=BD?= Date: Sat, 23 Oct 2021 18:57:19 +0200 Subject: [PATCH 121/193] Fix azure pipelines --- azure-pipelines.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7b94edce..837910b3 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -15,6 +15,7 @@ variables: owner: betaflight repoName: betaflight-tx-lua-scripts-nightlies releaseNotes: This is a nightly build off the tip of 'master'. It may be unstable and result in corrupted configurations or data loss. **Use only for testing.** + vmImage: 'ubuntu-20.04' name: $(Date:yyyyMMdd).$(BuildID) @@ -36,7 +37,7 @@ stages: jobs: - job: 'Linux' pool: - vmImage: 'ubuntu-20.04' + vmImage: '$(vmImage)' steps: - script: sudo apt-get -y install lua5.2 displayName: 'Install lua compiler.' @@ -51,6 +52,8 @@ stages: - stage: Release jobs: - job: Release + pool: + vmImage: '$(vmImage)' steps: - task: DownloadPipelineArtifact@2 inputs: From 8406e145ea8569fed359ec5ba02f8e779445381c Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sat, 27 Mar 2021 17:01:32 +0100 Subject: [PATCH 122/193] Update dynamic notch For the new multi dynamic notch in Betaflight 4.3. Replaced "Width"/"Q" with "Count"/"Bandwidth". https://github.com/betaflight/betaflight/pull/10554 --- src/SCRIPTS/BF/PAGES/filters2.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/PAGES/filters2.lua b/src/SCRIPTS/BF/PAGES/filters2.lua index 5984a61c..b97db3e5 100644 --- a/src/SCRIPTS/BF/PAGES/filters2.lua +++ b/src/SCRIPTS/BF/PAGES/filters2.lua @@ -24,7 +24,11 @@ if apiVersion >= 1.042 then if apiVersion < 1.043 then fields[#fields + 1] = { t = "Range", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 38 }, table = { [0]="HIGH", "MEDIUM", "LOW", "AUTO" } } end - fields[#fields + 1] = { t = "Width %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 39 } } + if apiVersion >= 1.044 then + fields[#fields + 1] = { t = "Count", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 5, vals = { 49 } } + else + fields[#fields + 1] = { t = "Width %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 39 } } + end fields[#fields + 1] = { t = "Q", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 1000, vals = { 40, 41 } } if apiVersion >= 1.043 then fields[#fields + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 60, max = 250, vals = { 42, 43 } } From 9eba4cc764bb57f364711c56eef370a311daae74 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 25 Oct 2021 21:33:39 +0200 Subject: [PATCH 123/193] Remove custom page template support --- src/SCRIPTS/BF/CONFIRM/acc_cal.lua | 7 +- src/SCRIPTS/BF/CONFIRM/vtx_tables.lua | 7 +- src/SCRIPTS/BF/PAGES/failsafe.lua | 7 +- src/SCRIPTS/BF/PAGES/filters1.lua | 7 +- src/SCRIPTS/BF/PAGES/filters2.lua | 7 +- src/SCRIPTS/BF/PAGES/gpspids.lua | 7 +- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 7 +- src/SCRIPTS/BF/PAGES/pids1.lua | 7 +- src/SCRIPTS/BF/PAGES/pids2.lua | 7 +- src/SCRIPTS/BF/PAGES/pwm.lua | 7 +- src/SCRIPTS/BF/PAGES/rates.lua | 7 +- src/SCRIPTS/BF/PAGES/rescue.lua | 7 +- src/SCRIPTS/BF/PAGES/rx.lua | 7 +- src/SCRIPTS/BF/PAGES/simplified_tuning.lua | 7 +- src/SCRIPTS/BF/PAGES/vtx.lua | 24 +++--- .../default_template.lua => 128x64.lua} | 0 .../default_template.lua => 128x96.lua} | 0 .../default_template.lua => 212x64.lua} | 0 .../default_template.lua => 320x480.lua} | 0 .../default_template.lua => 480x272.lua} | 0 src/SCRIPTS/BF/radios.lua | 74 +++++++++---------- 21 files changed, 61 insertions(+), 135 deletions(-) rename src/SCRIPTS/BF/TEMPLATES/{128x64/default_template.lua => 128x64.lua} (100%) rename src/SCRIPTS/BF/TEMPLATES/{128x96/default_template.lua => 128x96.lua} (100%) rename src/SCRIPTS/BF/TEMPLATES/{212x64/default_template.lua => 212x64.lua} (100%) rename src/SCRIPTS/BF/TEMPLATES/{320x480/default_template.lua => 320x480.lua} (100%) rename src/SCRIPTS/BF/TEMPLATES/{480x272/default_template.lua => 480x272.lua} (100%) diff --git a/src/SCRIPTS/BF/CONFIRM/acc_cal.lua b/src/SCRIPTS/BF/CONFIRM/acc_cal.lua index 1294e5c0..41a3c8de 100644 --- a/src/SCRIPTS/BF/CONFIRM/acc_cal.lua +++ b/src/SCRIPTS/BF/CONFIRM/acc_cal.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."acc_cal.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua b/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua index 33d98dc5..5d51e617 100644 --- a/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua +++ b/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."vtx_tables.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/failsafe.lua b/src/SCRIPTS/BF/PAGES/failsafe.lua index 39298c37..1ce6fbaa 100644 --- a/src/SCRIPTS/BF/PAGES/failsafe.lua +++ b/src/SCRIPTS/BF/PAGES/failsafe.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."failsafe.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/filters1.lua b/src/SCRIPTS/BF/PAGES/filters1.lua index 430d566d..68db6c8e 100644 --- a/src/SCRIPTS/BF/PAGES/filters1.lua +++ b/src/SCRIPTS/BF/PAGES/filters1.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."filters1.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/filters2.lua b/src/SCRIPTS/BF/PAGES/filters2.lua index 5984a61c..bf16d411 100644 --- a/src/SCRIPTS/BF/PAGES/filters2.lua +++ b/src/SCRIPTS/BF/PAGES/filters2.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."filters2.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/gpspids.lua b/src/SCRIPTS/BF/PAGES/gpspids.lua index dd6af065..95382972 100644 --- a/src/SCRIPTS/BF/PAGES/gpspids.lua +++ b/src/SCRIPTS/BF/PAGES/gpspids.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."gpspids.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index fd596d5f..8a364b4c 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."pid_advanced.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua index b3e9830f..ec829c3d 100644 --- a/src/SCRIPTS/BF/PAGES/pids1.lua +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."pids1.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index 2e56efdf..009591d6 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."pids2.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index a6531c5e..882e755b 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."pwm.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua index 927b74aa..355674fb 100644 --- a/src/SCRIPTS/BF/PAGES/rates.lua +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."rates.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index a409add9..c3bc9a2b 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."rescue.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index 9fa40d2e..c6099cb4 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."rx.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/simplified_tuning.lua b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua index 49c31303..8701d383 100644 --- a/src/SCRIPTS/BF/PAGES/simplified_tuning.lua +++ b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua @@ -1,9 +1,4 @@ -local template = loadScript(radio.templateHome.."simplified_pids.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index 6b4bca9d..e957b225 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -1,17 +1,4 @@ -local vtx_tables -if apiVersion >= 1.042 then - vtx_tables = assert(loadScript("/BF/VTX/"..mcuId..".lua"))() -else - vtx_tables = assert(loadScript("/BF/VTX/vtx_defaults.lua"))() -end -local deviceTable = { [1]="6705", [3]="SA", [4]="Tramp", [255]="None" } -local pitModeTable = { [0]="OFF", "ON" } -local template = loadScript(radio.templateHome.."vtx.lua") -if template then - template = template() -else - template = assert(loadScript(radio.templateHome.."default_template.lua"))() -end +local template = assert(loadScript(radio.template))() local margin = template.margin local indent = template.indent local lineSpacing = template.lineSpacing @@ -24,6 +11,15 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +local vtx_tables +if apiVersion >= 1.042 then + vtx_tables = assert(loadScript("/BF/VTX/"..mcuId..".lua"))() +else + vtx_tables = assert(loadScript("/BF/VTX/vtx_defaults.lua"))() +end +local deviceTable = { [1]="6705", [3]="SA", [4]="Tramp", [255]="None" } +local pitModeTable = { [0]="OFF", "ON" } + if apiVersion >= 1.036 then fields[#fields + 1] = { t = "Band", x = x, y = inc.y(lineSpacing), sp = x + sp, min=0, max=#(vtx_tables.bandTable), vals = { 2 }, table = vtx_tables.bandTable, upd = function(self) self.handleBandChanUpdate(self) end } fields[#fields + 1] = { t = "Channel", x = x, y = inc.y(lineSpacing), sp = x + sp, min=1, max=vtx_tables.frequenciesPerBand, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end } diff --git a/src/SCRIPTS/BF/TEMPLATES/128x64/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/128x64.lua similarity index 100% rename from src/SCRIPTS/BF/TEMPLATES/128x64/default_template.lua rename to src/SCRIPTS/BF/TEMPLATES/128x64.lua diff --git a/src/SCRIPTS/BF/TEMPLATES/128x96/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/128x96.lua similarity index 100% rename from src/SCRIPTS/BF/TEMPLATES/128x96/default_template.lua rename to src/SCRIPTS/BF/TEMPLATES/128x96.lua diff --git a/src/SCRIPTS/BF/TEMPLATES/212x64/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/212x64.lua similarity index 100% rename from src/SCRIPTS/BF/TEMPLATES/212x64/default_template.lua rename to src/SCRIPTS/BF/TEMPLATES/212x64.lua diff --git a/src/SCRIPTS/BF/TEMPLATES/320x480/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/320x480.lua similarity index 100% rename from src/SCRIPTS/BF/TEMPLATES/320x480/default_template.lua rename to src/SCRIPTS/BF/TEMPLATES/320x480.lua diff --git a/src/SCRIPTS/BF/TEMPLATES/480x272/default_template.lua b/src/SCRIPTS/BF/TEMPLATES/480x272.lua similarity index 100% rename from src/SCRIPTS/BF/TEMPLATES/480x272/default_template.lua rename to src/SCRIPTS/BF/TEMPLATES/480x272.lua diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index eccc21c2..13eecaa8 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -3,13 +3,13 @@ local supportedRadios = ["128x64"] = { msp = { - templateHome = "TEMPLATES/128x64/", - MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, - SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, - NoTelem = { 30, 55, "No Telemetry", BLINK }, - textSize = SMLSIZE, - yMinLimit = 12, - yMaxLimit = 52, + template = "TEMPLATES/128x64.lua", + MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, + SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, + NoTelem = { 30, 55, "No Telemetry", BLINK }, + textSize = SMLSIZE, + yMinLimit = 12, + yMaxLimit = 52, }, cms = { rows = 8, @@ -30,13 +30,13 @@ local supportedRadios = ["128x96"] = { msp = { - templateHome = "TEMPLATES/128x96/", - MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, - SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, - NoTelem = { 30, 87, "No Telemetry", BLINK }, - textSize = SMLSIZE, - yMinLimit = 12, - yMaxLimit = 84, + template = "TEMPLATES/128x96.lua", + MenuBox = { x=15, y=12, w=100, x_offset=36, h_line=8, h_offset=3 }, + SaveBox = { x=15, y=12, w=100, x_offset=4, h=30, h_offset=5 }, + NoTelem = { 30, 87, "No Telemetry", BLINK }, + textSize = SMLSIZE, + yMinLimit = 12, + yMaxLimit = 84, }, cms = { rows = 12, @@ -57,13 +57,13 @@ local supportedRadios = ["212x64"] = { msp = { - templateHome = "TEMPLATES/212x64/", - MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 }, - SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, - NoTelem = { 70, 55, "No Telemetry", BLINK }, - textSize = SMLSIZE, - yMinLimit = 12, - yMaxLimit = 52, + template = "TEMPLATES/212x64.lua", + MenuBox = { x=40, y=12, w=120, x_offset=36, h_line=8, h_offset=3 }, + SaveBox = { x=40, y=12, w=120, x_offset=4, h=30, h_offset=5 }, + NoTelem = { 70, 55, "No Telemetry", BLINK }, + textSize = SMLSIZE, + yMinLimit = 12, + yMaxLimit = 52, }, cms = { rows = 8, @@ -84,14 +84,14 @@ local supportedRadios = ["480x272"] = { msp = { - templateHome = "TEMPLATES/480x272/", - highRes = true, - MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, - SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, - NoTelem = { 192, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, - textSize = 0, - yMinLimit = 35, - yMaxLimit = 235, + template = "TEMPLATES/480x272.lua", + highRes = true, + MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, + SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, + NoTelem = { 192, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, + textSize = 0, + yMinLimit = 35, + yMaxLimit = 235, }, cms = { rows = 9, @@ -112,14 +112,14 @@ local supportedRadios = ["320x480"] = { msp = { - templateHome = "TEMPLATES/320x480/", - highRes = true, - MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, - SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, - NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, - textSize = 0, - yMinLimit = 35, - yMaxLimit = 435, + template = "TEMPLATES/320x480.lua", + highRes = true, + MenuBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=200, x_offset=68, h_line=20, h_offset=6 }, + SaveBox = { x= (LCD_W -200)/2, y=LCD_H/2, w=180, x_offset=12, h=60, h_offset=12 }, + NoTelem = { LCD_W/2 - 50, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, + textSize = 0, + yMinLimit = 35, + yMaxLimit = 435, }, cms = nil, }, From 248d0fa8b770bf096769dd102f8ea5c0ba6269ef Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 10 Oct 2021 21:02:19 +0200 Subject: [PATCH 124/193] Download board info --- src/SCRIPTS/BF/BOARD_INFO/readme.txt | 1 + src/SCRIPTS/BF/board_info.lua | 137 +++++++++++++++++++++++++++ src/SCRIPTS/BF/ui_init.lua | 25 ++++- 3 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 src/SCRIPTS/BF/BOARD_INFO/readme.txt create mode 100644 src/SCRIPTS/BF/board_info.lua diff --git a/src/SCRIPTS/BF/BOARD_INFO/readme.txt b/src/SCRIPTS/BF/BOARD_INFO/readme.txt new file mode 100644 index 00000000..2fe32c7e --- /dev/null +++ b/src/SCRIPTS/BF/BOARD_INFO/readme.txt @@ -0,0 +1 @@ +Board info downloaded from the flight controller will be stored in this folder. diff --git a/src/SCRIPTS/BF/board_info.lua b/src/SCRIPTS/BF/board_info.lua new file mode 100644 index 00000000..e29f91dd --- /dev/null +++ b/src/SCRIPTS/BF/board_info.lua @@ -0,0 +1,137 @@ +local MSP_BOARD_INFO = 4 + +local boardInfoReceived = false + +local boardIdentifier = "" +local hardwareRevision = 0 +local boardType = 0 +local targetCapabilities = 0 +local targetName = "" +local boardName = "" +local manufacturerId = "" +local signature = {} +local mcuTypeId = 255 +local configurationState = 0 +local gyroSampleRateHz = 0 +local configurationProblems = 0 +local spiRegisteredDeviceCount = 0 +local i2cRegisteredDeviceCount = 0 + +local lastRunTS = 0 +local INTERVAL = 100 + +local function processMspReply(cmd, payload) + if cmd == MSP_BOARD_INFO then + local length + local i = 1 + length = 4 + for c = 1, 4 do + boardIdentifier = boardIdentifier..string.char(payload[i]) + i = i + 1 + end + for idx = 1, 2 do + local raw_val = bit32.lshift(payload[i], (idx-1)*8) + hardwareRevision = bit32.bor(hardwareRevision, raw_val) + i = i + 1 + end + if apiVersion >= 1.035 then + boardType = payload[i] + end + i = i + 1 + if apiVersion >= 1.037 then + targetCapabilities = payload[i] + i = i + 1 + length = payload[i] + i = i + 1 + for c = 1, length do + targetName = targetName..string.char(payload[i]) + i = i + 1 + end + end + if apiVersion >= 1.039 then + length = payload[i] + i = i + 1 + for c = 1, length do + boardName = boardName..string.char(payload[i]) + i = i + 1 + end + length = payload[i] + i = i + 1 + for c = 1, length do + manufacturerId = manufacturerId..string.char(payload[i]) + i = i + 1 + end + length = 32 + for c = 1, 32 do + signature[#signature + 1] = payload[i] + i = i + 1 + end + end + i = i + 1 + if apiVersion >= 1.041 then + mcuTypeId = payload[i] + end + i = i + 1 + if apiVersion >= 1.042 then + configurationState = payload[i] + end + if apiVersion >= 1.043 then + for idx = 1, 2 do + local raw_val = bit32.lshift(payload[i], (idx-1)*8) + gyroSampleRateHz = bit32.bor(gyroSampleRateHz, raw_val) + i = i + 1 + end + for idx = 1, 4 do + local raw_val = bit32.lshift(payload[i], (idx-1)*8) + configurationProblems = bit32.bor(configurationProblems, raw_val) + i = i + 1 + end + end + if apiVersion >= 1.044 then + spiRegisteredDeviceCount = payload[i] + i = i + 1 + i2cRegisteredDeviceCount = payload[i] + end + boardInfoReceived = true + end +end + +local function getBoardInfo() + if lastRunTS + INTERVAL < getTime() then + lastRunTS = getTime() + if not boardInfoReceived then + protocol.mspRead(MSP_BOARD_INFO) + end + end + mspProcessTxQ() + processMspReply(mspPollReply()) + if boardInfoReceived then + local f = io.open("BOARD_INFO/"..mcuId..".lua", 'w') + io.write(f, "return {", "\n") + io.write(f, " boardIdentifier = "..boardIdentifier..",", "\n") + io.write(f, " hardwareRevision = "..tostring(hardwareRevision)..",", "\n") + io.write(f, " boardType = "..tostring(boardType)..",", "\n") + io.write(f, " targetCapabilities = "..tostring(targetCapabilities)..",", "\n") + io.write(f, " targetName = "..targetName..",", "\n") + io.write(f, " boardName = "..boardName..",", "\n") + io.write(f, " manufacturerId = "..manufacturerId..",", "\n") + local signatureString = " signature = { " + for i = 1, #signature do + signatureString = signatureString..tostring(signature[i])..", " + end + signatureString = signatureString.."}," + io.write(f, signatureString, "\n") + io.write(f, " mcuTypeId = "..tostring(mcuTypeId)..",", "\n") + io.write(f, " configurationState = "..tostring(configurationState)..",", "\n") + io.write(f, " gyroSampleRateHz = "..tostring(gyroSampleRateHz)..",", "\n") + io.write(f, " configurationProblems = "..tostring(configurationProblems)..",", "\n") + io.write(f, " spiRegisteredDeviceCount = "..tostring(spiRegisteredDeviceCount)..",", "\n") + io.write(f, " i2cRegisteredDeviceCount = "..tostring(i2cRegisteredDeviceCount)..",", "\n") + io.write(f, "}", "\n") + io.close(f) + assert(loadScript("BOARD_INFO/"..mcuId..".lua", 'c')) + end + return boardInfoReceived +end + +return { f = getBoardInfo, t = "Downloading board info" } diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index f535e8b4..6a851ad1 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -1,7 +1,8 @@ local apiVersionReceived = false local vtxTablesReceived = false local mcuIdReceived = false -local getApiVersion, getVtxTables, getMCUId +local boardInfoReceived = false +local getApiVersion, getVtxTables, getMCUId, getBoardInfo local returnTable = { f = nil, t = "" } local function modelActive() @@ -25,10 +26,16 @@ local function init() mcuIdReceived = getMCUId.f() if mcuIdReceived then getMCUId = nil - local vtxTables = loadScript("/BF/VTX/"..mcuId..".lua") - if vtxTables and vtxTables() then + local f = loadScript("/BF/VTX/"..mcuId..".lua") + if f and f() then vtxTablesReceived = true - vtxTables = nil + f = nil + end + collectgarbage() + f = loadScript("BOARD_INFO/"..mcuId..".lua") + if f and f() then + boardInfoReceived = true + f = nil end collectgarbage() end @@ -40,10 +47,18 @@ local function init() getVtxTables = nil collectgarbage() end + elseif not boardInfoReceived then + getBoardInfo = getBoardInfo or assert(loadScript("board_info.lua"))() + returnTable.t = getBoardInfo.t + boardInfoReceived = getBoardInfo.f() + if boardInfoReceived then + getBoardInfo = nil + collectgarbage() + end else return true end - return apiVersionReceived and vtxTablesReceived and mcuId + return apiVersionReceived and vtxTablesReceived and mcuId and boardInfoReceived end returnTable.f = init From 51d92671e1bcf6ee3fcfa6bcd18fe2b91579b34f Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 10 Oct 2021 22:05:08 +0200 Subject: [PATCH 125/193] PWM page improvements --- src/SCRIPTS/BF/PAGES/pwm.lua | 30 +++++++++++++++++++----------- src/SCRIPTS/BF/pages.lua | 2 +- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index a6531c5e..22a3212b 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -16,6 +16,12 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +local gyroSampleRateKhz + +if apiVersion >= 1.043 then + gyroSampleRateKhz = assert(loadScript("BOARD_INFO/"..mcuId..".lua"))().gyroSampleRateHz / 1000 +end + local escProtocols = { [0] = "PWM", "OS125", "OS42", "MSHOT" } if apiVersion >= 1.020 then @@ -37,23 +43,24 @@ if apiVersion >= 1.043 then escProtocols[#escProtocols + 1] = "DISABLED" end +labels[#labels + 1] = { t = "System Config", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.031 and apiVersion <= 1.040 then - fields[#fields + 1] = { t = "32kHz Sampling", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end } + fields[#fields + 1] = { t = "32kHz Sampling", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end } end - -if apiVersion >= 1.016 then - if apiVersion <= 1.042 then - fields[#fields + 1] = { t = "Gyro Update", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end, mult = -1 } - fields[#fields + 1] = { t = "PID Loop", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {}, mult = -1 } - end - fields[#fields + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #escProtocols, vals = { 4 }, table = escProtocols } - fields[#fields + 1] = { t = "Unsynced PWM", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 3 }, table = { [0] = "OFF", "ON" } } - fields[#fields + 1] = { t = "PWM Frequency", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 200, max = 32000, vals = { 5, 6 }, } +if apiVersion >= 1.043 then + fields[#fields + 1] = { t = "Gyro Update", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end, mult = -1, ro = true } +else + fields[#fields + 1] = { t = "Gyro Update", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end, mult = -1 } end +fields[#fields + 1] = { t = "PID Loop", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {}, mult = -1 } +labels[#labels + 1] = { t = "ESC/Motor", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Protocol", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #escProtocols, vals = { 4 }, table = escProtocols } if apiVersion >= 1.031 then - fields[#fields + 1] = { t = "Idle Throttle %", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2000, vals = { 7, 8 }, scale = 100 } + fields[#fields + 1] = { t = "Idle Throttle %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2000, vals = { 7, 8 }, scale = 100 } end +fields[#fields + 1] = { t = "Unsynced PWM", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 3 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { t = "Frequency", x = x + indent*2, y = inc.y(lineSpacing), sp = x + sp, min = 200, max = 32000, vals = { 5, 6 }, } return { read = 90, -- MSP_ADVANCED_CONFIG @@ -81,6 +88,7 @@ return { end, calculateGyroRates = function(self, baseRate) local idx = self.getGyroDenomFieldIndex(self) + baseRate = gyroSampleRateKhz or baseRate for i=1, 32 do self.gyroRates[i] = baseRate/i self.fields[idx].table[i] = string.format("%.2f",baseRate/i) diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index d4745b7b..c3bb9574 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -33,7 +33,7 @@ if apiVersion >= 1.042 then end if apiVersion >= 1.016 then - PageFiles[#PageFiles + 1] = { title = "Gyro / Motor", script = "pwm.lua" } + PageFiles[#PageFiles + 1] = { title = "System / Motor", script = "pwm.lua" } end if apiVersion >= 1.016 then From 952c58cb5fd73777d6fcb1335a88fd3d95a803ad Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 10 Oct 2021 18:05:26 +0200 Subject: [PATCH 126/193] Update simplified_tuning.lua --- src/SCRIPTS/BF/PAGES/simplified_tuning.lua | 29 +++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/simplified_tuning.lua b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua index 8701d383..b57119f9 100644 --- a/src/SCRIPTS/BF/PAGES/simplified_tuning.lua +++ b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua @@ -11,21 +11,22 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} -labels[#labels + 1] = { t = "Simplified Pid", x = x, y = inc.y(lineSpacing) } -fields[#fields + 1] = { t = "Pid Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 1 }, table = { [0] = "OFF", "RP", "RPY" } } -fields[#fields + 1] = { t = "Master Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 2 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "R/P Ratio", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 3 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "I Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 4 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "P/D Ratio", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 5 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "PD Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 6 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "Dmin Ratio", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 7 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "FF Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 8 }, scale = 100, mult = 5 } +labels[#labels + 1] = { t = "Simplified PID", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "PID Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 1 }, table = { [0] = "OFF", "RP", "RPY" } } +fields[#fields + 1] = { t = "Master Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 2 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "P/I Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 6 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "D Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 5 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "FF Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 8 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "I Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 4 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "D Max Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 7 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Pitch D Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 3 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Pitch P/I/FF Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 9 }, scale = 100, mult = 5 } labels[#labels + 1] = { t = "Simplified Filter", x = x, y = inc.y(lineSpacing) } -fields[#fields + 1] = { t = "Gyro Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" } } -fields[#fields + 1] = { t = "Gyro Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 10 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "D Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 11 }, table = { [0] = "OFF", "ON" } } -fields[#fields + 1] = { t = "D Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 12 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Gyro Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 12 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { t = "Gyro Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 13 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "D Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 10 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { t = "D Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 11 }, scale = 100, mult = 5 } return { read = 140, -- MSP_SIMPLIFIED_TUNING @@ -33,7 +34,7 @@ return { title = "Simplified Tuning", reboot = false, eepromWrite = true, - minBytes = 12, + minBytes = 13, labels = labels, fields = fields, } From 1814455dc5b87ce8490b79e1a37a7b0fefeefe8e Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 10 Oct 2021 20:00:16 +0200 Subject: [PATCH 127/193] Update PID max limits Update max limits for pids and dMin --- src/SCRIPTS/BF/PAGES/pids1.lua | 24 +++++++++++++++--------- src/SCRIPTS/BF/PAGES/pids2.lua | 12 +++++++++--- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua index ec829c3d..4e3defdd 100644 --- a/src/SCRIPTS/BF/PAGES/pids1.lua +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -11,6 +11,12 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +local pidMax = 200 + +if apiVersion >= 1.044 then + pidMax = 250 +end + if apiVersion >= 1.016 then x = margin y = yMinLim - tableSpacing.header @@ -24,26 +30,26 @@ if apiVersion >= 1.016 then y = yMinLim - tableSpacing.header labels[#labels + 1] = { t = "P", x = x, y = inc.y(tableSpacing.header) } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 1 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 4 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 7 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 1 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 4 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 7 } } x = x + tableSpacing.col y = yMinLim - tableSpacing.header labels[#labels + 1] = { t = "I", x = x, y = inc.y(tableSpacing.header) } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 2 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 5 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 8 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 2 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 5 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 8 } } x = x + tableSpacing.col y = yMinLim - tableSpacing.header labels[#labels + 1] = { t = "D", x = x, y = inc.y(tableSpacing.header) } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 3 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 6 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 3 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 6 } } if apiVersion >= 1.041 then - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 200, vals = { 9 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 9 } } end end diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index c9e2edb5..6ea7ab4a 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -11,6 +11,12 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +local dMinMax = 100 + +if apiVersion >= 1.044 then + dMinMax = 250 +end + if apiVersion >= 1.040 then x = margin y = yMinLim - tableSpacing.header @@ -33,9 +39,9 @@ if apiVersion >= 1.040 then y = yMinLim - tableSpacing.header labels[#labels + 1] = { t = "D Min", x = x, y = inc.y(tableSpacing.header) } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 40 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 41 } } - fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 42 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = dMinMax, vals = { 40 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = dMinMax, vals = { 41 } } + fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = dMinMax, vals = { 42 } } end x = margin From 1ae54d14a5e1f840a8ef890e78b9200dd766c03b Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 15 Oct 2021 22:45:58 +0200 Subject: [PATCH 128/193] Rename D to D Max --- src/SCRIPTS/BF/PAGES/pids1.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua index 4e3defdd..42c40afd 100644 --- a/src/SCRIPTS/BF/PAGES/pids1.lua +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -12,9 +12,11 @@ local labels = {} local fields = {} local pidMax = 200 +local dLabel = "D" if apiVersion >= 1.044 then pidMax = 250 + dLabel = "D Max" end if apiVersion >= 1.016 then @@ -45,7 +47,7 @@ if apiVersion >= 1.016 then x = x + tableSpacing.col y = yMinLim - tableSpacing.header - labels[#labels + 1] = { t = "D", x = x, y = inc.y(tableSpacing.header) } + labels[#labels + 1] = { t = dLabel, x = x, y = inc.y(tableSpacing.header) } fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 3 } } fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 6 } } if apiVersion >= 1.041 then From 3ada96d80c7a11ed4f7db2a824378f0415177831 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 20 Oct 2021 19:57:22 +0200 Subject: [PATCH 129/193] Delete BF folder --- src/BF/use_tools_menu_instead_of_this.txt | 0 src/SCRIPTS/BF/PAGES/vtx.lua | 4 ++-- src/{BF/VTX => SCRIPTS/BF/VTX_TABLES}/vtx_defaults.lua | 0 src/SCRIPTS/BF/ui_init.lua | 2 +- src/SCRIPTS/BF/vtx_tables.lua | 4 ++-- 5 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 src/BF/use_tools_menu_instead_of_this.txt rename src/{BF/VTX => SCRIPTS/BF/VTX_TABLES}/vtx_defaults.lua (100%) diff --git a/src/BF/use_tools_menu_instead_of_this.txt b/src/BF/use_tools_menu_instead_of_this.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index e957b225..73a035e5 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -13,9 +13,9 @@ local fields = {} local vtx_tables if apiVersion >= 1.042 then - vtx_tables = assert(loadScript("/BF/VTX/"..mcuId..".lua"))() + vtx_tables = assert(loadScript("VTX_TABLES/"..mcuId..".lua"))() else - vtx_tables = assert(loadScript("/BF/VTX/vtx_defaults.lua"))() + vtx_tables = assert(loadScript("VTX_TABLES/vtx_defaults.lua"))() end local deviceTable = { [1]="6705", [3]="SA", [4]="Tramp", [255]="None" } local pitModeTable = { [0]="OFF", "ON" } diff --git a/src/BF/VTX/vtx_defaults.lua b/src/SCRIPTS/BF/VTX_TABLES/vtx_defaults.lua similarity index 100% rename from src/BF/VTX/vtx_defaults.lua rename to src/SCRIPTS/BF/VTX_TABLES/vtx_defaults.lua diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 6a851ad1..db7bc77f 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -26,7 +26,7 @@ local function init() mcuIdReceived = getMCUId.f() if mcuIdReceived then getMCUId = nil - local f = loadScript("/BF/VTX/"..mcuId..".lua") + local f = loadScript("VTX_TABLES/"..mcuId..".lua") if f and f() then vtxTablesReceived = true f = nil diff --git a/src/SCRIPTS/BF/vtx_tables.lua b/src/SCRIPTS/BF/vtx_tables.lua index 91175588..8c72e48d 100644 --- a/src/SCRIPTS/BF/vtx_tables.lua +++ b/src/SCRIPTS/BF/vtx_tables.lua @@ -82,7 +82,7 @@ local function getVtxTables() end end if vtxTablesReceived then - local f = io.open("/BF/VTX/"..mcuId..".lua", 'w') + local f = io.open("VTX_TABLES/"..mcuId..".lua", 'w') io.write(f, "return {", "\n") io.write(f, " frequencyTable = {", "\n") for i = 1, #frequencyTable do @@ -109,7 +109,7 @@ local function getVtxTables() io.write(f, powerString, "\n") io.write(f, "}", "\n") io.close(f) - assert(loadScript("/BF/VTX/"..mcuId..".lua", 'c')) + assert(loadScript("VTX_TABLES/"..mcuId..".lua", 'c')) end mspProcessTxQ() processMspReply(mspPollReply()) From 4f6ed1fe22d7d7b7fe346557d922b65b09161683 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 20 Oct 2021 19:58:05 +0200 Subject: [PATCH 130/193] Delete telemetry version --- src/SCRIPTS/TELEMETRY/bf.lua | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 src/SCRIPTS/TELEMETRY/bf.lua diff --git a/src/SCRIPTS/TELEMETRY/bf.lua b/src/SCRIPTS/TELEMETRY/bf.lua deleted file mode 100644 index e1e7a693..00000000 --- a/src/SCRIPTS/TELEMETRY/bf.lua +++ /dev/null @@ -1,6 +0,0 @@ -local function run(event) - lcd.clear() - lcd.drawText(2, 2, "Use TOOLS menu") -end - -return { run=run } From 7bc425be2bf9274f43364ebbfd505762486d8c9f Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 12 Nov 2021 21:10:24 +0100 Subject: [PATCH 131/193] Use getRSSI() for telemetry detection --- src/SCRIPTS/BF/background.lua | 6 +----- src/SCRIPTS/BF/protocols.lua | 4 ---- src/SCRIPTS/BF/ui.lua | 2 +- src/SCRIPTS/BF/ui_init.lua | 6 +----- 4 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/SCRIPTS/BF/background.lua b/src/SCRIPTS/BF/background.lua index 176198e5..239a5698 100644 --- a/src/SCRIPTS/BF/background.lua +++ b/src/SCRIPTS/BF/background.lua @@ -3,12 +3,8 @@ local timeIsSet = false local getApiVersion, setRtc, rssiTask local rssiEnabled = true -local function modelActive() - return getValue(protocol.stateSensor) > 0 -end - local function run_bg() - if modelActive() then + if getRSSI() > 0 then -- Send data when the telemetry connection is available -- assuming when sensor value higher than 0 there is an telemetry connection if not apiVersionReceived then diff --git a/src/SCRIPTS/BF/protocols.lua b/src/SCRIPTS/BF/protocols.lua index 89f55de2..c415104c 100644 --- a/src/SCRIPTS/BF/protocols.lua +++ b/src/SCRIPTS/BF/protocols.lua @@ -3,8 +3,6 @@ local supportedProtocols = smartPort = { mspTransport = "MSP/sp.lua", - rssi = function() return getValue("RSSI") end, - stateSensor = "Tmp1", push = sportTelemetryPush, maxTxBufferSize = 6, maxRxBufferSize = 6, @@ -16,8 +14,6 @@ local supportedProtocols = { mspTransport = "MSP/crsf.lua", cmsTransport = "CMS/crsf.lua", - rssi = function() return getValue("TQly") end, - stateSensor = "1RSS", push = crossfireTelemetryPush, maxTxBufferSize = 8, maxRxBufferSize = 58, diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index a3839c92..01d6e6e1 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -408,7 +408,7 @@ local function run_ui(event) prevUiState = nil end end - if protocol.rssi() == 0 then + if getRSSI() == 0 then lcd.drawText(radio.NoTelem[1],radio.NoTelem[2],radio.NoTelem[3],radio.NoTelem[4]) end mspProcessTxQ() diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index db7bc77f..62431870 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -5,12 +5,8 @@ local boardInfoReceived = false local getApiVersion, getVtxTables, getMCUId, getBoardInfo local returnTable = { f = nil, t = "" } -local function modelActive() - return getValue(protocol.stateSensor) > 0 -end - local function init() - if not modelActive() then + if getRSSI() == 0 then returnTable.t = "Waiting for connection" elseif not apiVersionReceived then getApiVersion = getApiVersion or assert(loadScript("api_version.lua"))() From 7c8d4a8def2dfee42ffcd23396c2b5b239ed4c3c Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 24 Nov 2021 23:07:21 +0100 Subject: [PATCH 132/193] FF max rate limit and jitter reduction --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 4 ++-- src/SCRIPTS/BF/PAGES/pids2.lua | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 8a364b4c..15ab49e8 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -28,8 +28,8 @@ if apiVersion >= 1.016 and apiVersion <= 1.043 then end if apiVersion >= 1.044 then - fields[#fields + 1] = { t = "Vbat Sag Comp", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 54 } } - fields[#fields + 1] = { t = "Thrust Linear", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 55 } } + fields[#fields + 1] = { t = "Vbat Sag Comp", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 56 } } + fields[#fields + 1] = { t = "Thrust Linear", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 57 } } end if apiVersion >= 1.040 and apiVersion <= 1.041 then diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index 6ea7ab4a..7fdb1d1d 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -49,13 +49,15 @@ if apiVersion >= 1.040 then end if apiVersion >= 1.040 then - labels[#labels + 1] = { t = "Feedforward", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Transition", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 9 }, scale = 100 } + labels[#labels + 1] = { t = "Feedforward", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.044 then - fields[#fields + 1] = { t = "Averaging", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 51 }, table = { [0] = "OFF", "2_POINT", "3_POINT", "4_POINT" } } - fields[#fields + 1] = { t = "Smoothness", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 75, vals = { 52 } } - fields[#fields + 1] = { t = "Boost", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 53 } } + fields[#fields + 1] = { t = "Jitter Reduction", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 55 } } + fields[#fields + 1] = { t = "Smoothness", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 75, vals = { 52 } } + fields[#fields + 1] = { t = "Averaging", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 51 }, table = { [0] = "OFF", "2_POINT", "3_POINT", "4_POINT" } } + fields[#fields + 1] = { t = "Boost", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 53 } } + fields[#fields + 1] = { t = "Max Rate Limit", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 54 } } end + fields[#fields + 1] = { t = "Transition", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 9 }, scale = 100 } end if apiVersion >= 1.041 then From efbfc94c12b8d2c21c2731fc37b8b50c89ada27d Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 30 Nov 2021 18:39:08 +0100 Subject: [PATCH 133/193] Reorder and rename simplified pids Order and names are now the same as in the configurator --- src/SCRIPTS/BF/PAGES/simplified_tuning.lua | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/simplified_tuning.lua b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua index b57119f9..20271037 100644 --- a/src/SCRIPTS/BF/PAGES/simplified_tuning.lua +++ b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua @@ -13,28 +13,28 @@ local fields = {} labels[#labels + 1] = { t = "Simplified PID", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "PID Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 1 }, table = { [0] = "OFF", "RP", "RPY" } } -fields[#fields + 1] = { t = "Master Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 2 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "P/I Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 6 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "D Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 5 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "FF Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 8 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "I Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 4 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "D Max Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 7 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "Pitch D Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 3 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "Pitch P/I/FF Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 9 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "D Gains", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 5 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "P&I Gains", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 6 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "FF Gains", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 8 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "D Max", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 7 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "I Gains", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 4 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Pitch:Roll D", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 3 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Pitch:Roll P,I&FF", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 9 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Master Multiplier", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 2 }, scale = 100, mult = 5 } labels[#labels + 1] = { t = "Simplified Filter", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Gyro Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 12 }, table = { [0] = "OFF", "ON" } } -fields[#fields + 1] = { t = "Gyro Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 13 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Gyro Multiplier", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 13 }, scale = 100, mult = 5 } fields[#fields + 1] = { t = "D Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 10 }, table = { [0] = "OFF", "ON" } } -fields[#fields + 1] = { t = "D Mult", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 11 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "D Multiplier", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 11 }, scale = 100, mult = 5 } return { - read = 140, -- MSP_SIMPLIFIED_TUNING - write = 141, -- MSP_SET_SIMPLIFIED_TUNING - title = "Simplified Tuning", - reboot = false, - eepromWrite = true, - minBytes = 13, - labels = labels, - fields = fields, + read = 140, -- MSP_SIMPLIFIED_TUNING + write = 141, -- MSP_SET_SIMPLIFIED_TUNING + title = "Simplified Tuning", + reboot = false, + eepromWrite = true, + minBytes = 13, + labels = labels, + fields = fields, } From e704adb6df577e49ca3b691080c69c06b8064ced Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 12 Dec 2021 22:32:27 +0100 Subject: [PATCH 134/193] Update MSP protocol --- src/SCRIPTS/BF/MSP/common.lua | 38 +++++++++++++++++------------------ src/SCRIPTS/BF/MSP/sp.lua | 8 +++++--- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/SCRIPTS/BF/MSP/common.lua b/src/SCRIPTS/BF/MSP/common.lua index 46648991..fb119f6c 100644 --- a/src/SCRIPTS/BF/MSP/common.lua +++ b/src/SCRIPTS/BF/MSP/common.lua @@ -6,6 +6,7 @@ local MSP_STARTFLAG = bit32.lshift(1,4) local mspSeq = 0 local mspRemoteSeq = 0 local mspRxBuf = {} +local mspRxSize = 0 local mspRxCRC = 0 local mspRxReq = 0 local mspStarted = false @@ -37,12 +38,6 @@ function mspProcessTxQ() end if i <= protocol.maxTxBufferSize then payload[i] = mspTxCRC - i = i + 1 - -- zero fill - while i <= protocol.maxTxBufferSize do - payload[i] = 0 - i = i + 1 - end protocol.mspSend(payload) mspTxBuf = {} mspTxIdx = 1 @@ -68,25 +63,30 @@ function mspSendRequest(cmd, payload) end function mspReceivedReply(payload) - local idx = 1 - local head = payload[idx] - local err_flag = (bit32.band(head,0x20) ~= 0) + local idx = 1 + local status = payload[idx] + local err = bit32.btest(status, 0x80) + local version = bit32.rshift(bit32.band(status, 0x60), 5) + local start = bit32.btest(status, 0x10) + local seq = bit32.band(status, 0x0F) idx = idx + 1 - if err_flag then - -- error flag set + if err then mspStarted = false return nil end - local start = (bit32.band(head,0x10) ~= 0) - local seq = bit32.band(head,0x0F) if start then - -- start flag set mspRxBuf = {} mspRxSize = payload[idx] - mspRxCRC = bit32.bxor(mspRxSize,mspLastReq) - mspRxReq = mspLastReq + mspRxReq = mspLastReq idx = idx + 1 - mspStarted = true + if version == 1 then + mspRxReq = payload[idx] + idx = idx + 1 + end + mspRxCRC = bit32.bxor(mspRxSize, mspRxReq) + if mspRxReq == mspLastReq then + mspStarted = true + end elseif not mspStarted then return nil elseif bit32.band(mspRemoteSeq + 1, 0x0F) ~= seq then @@ -95,7 +95,7 @@ function mspReceivedReply(payload) end while (idx <= protocol.maxRxBufferSize) and (#mspRxBuf < mspRxSize) do mspRxBuf[#mspRxBuf + 1] = payload[idx] - mspRxCRC = bit32.bxor(mspRxCRC,payload[idx]) + mspRxCRC = bit32.bxor(mspRxCRC, payload[idx]) idx = idx + 1 end if idx > protocol.maxRxBufferSize then @@ -104,7 +104,7 @@ function mspReceivedReply(payload) end mspStarted = false -- check CRC - if mspRxCRC ~= payload[idx] then + if mspRxCRC ~= payload[idx] and version == 0 then return nil end return mspRxBuf diff --git a/src/SCRIPTS/BF/MSP/sp.lua b/src/SCRIPTS/BF/MSP/sp.lua index eaabe8cd..ecc15b1b 100644 --- a/src/SCRIPTS/BF/MSP/sp.lua +++ b/src/SCRIPTS/BF/MSP/sp.lua @@ -7,9 +7,11 @@ local REPLY_FRAME_ID = 0x32 local lastSensorId, lastFrameId, lastDataId, lastValue protocol.mspSend = function(payload) - local dataId = payload[1] + bit32.lshift(payload[2],8) - local value = payload[3] + bit32.lshift(payload[4],8) - + bit32.lshift(payload[5],16) + bit32.lshift(payload[6],24) + local dataId = payload[1] + bit32.lshift(payload[2], 8) + local value = 0 + for i = 3, #payload do + value = value + bit32.lshift(payload[i], (i - 3) * 8) + end return protocol.push(LOCAL_SENSOR_ID, REQUEST_FRAME_ID, dataId, value) end From e199bf8c282ec9fa8ae28d0c5104156d4bdff4e9 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 16 Dec 2021 13:59:02 +0100 Subject: [PATCH 135/193] Disable reboot for dynamic idle change --- src/SCRIPTS/BF/PAGES/filters2.lua | 2 +- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/filters2.lua b/src/SCRIPTS/BF/PAGES/filters2.lua index ea02a10d..0ba77145 100644 --- a/src/SCRIPTS/BF/PAGES/filters2.lua +++ b/src/SCRIPTS/BF/PAGES/filters2.lua @@ -46,7 +46,7 @@ return { self.rpmHarmonics = self.values[44] end, preSave = function(self) - self.reboot = self.values[44] == 0 and self.rpmHarmonics ~= 0 + self.reboot = self.values[44] == 0 and self.rpmHarmonics ~= 0 and apiVersion <= 1.043 return self.values end, } diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 15ab49e8..2c8e5e6a 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -77,7 +77,7 @@ return { self.dynamicIdle = self.values[50] end, preSave = function(self) - self.reboot = self.values[50] ~= self.dynamicIdle + self.reboot = self.values[50] ~= self.dynamicIdle and apiVersion <= 1.043 return self.values end, } From c0461d476f1fd6b612b38a63000c11e731abeb27 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 17 Dec 2021 14:50:52 +0100 Subject: [PATCH 136/193] Fix string writes to board info table --- src/SCRIPTS/BF/board_info.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SCRIPTS/BF/board_info.lua b/src/SCRIPTS/BF/board_info.lua index e29f91dd..1fae01e5 100644 --- a/src/SCRIPTS/BF/board_info.lua +++ b/src/SCRIPTS/BF/board_info.lua @@ -108,13 +108,13 @@ local function getBoardInfo() if boardInfoReceived then local f = io.open("BOARD_INFO/"..mcuId..".lua", 'w') io.write(f, "return {", "\n") - io.write(f, " boardIdentifier = "..boardIdentifier..",", "\n") + io.write(f, " boardIdentifier = "..'"'..boardIdentifier..'"'..",", "\n") io.write(f, " hardwareRevision = "..tostring(hardwareRevision)..",", "\n") io.write(f, " boardType = "..tostring(boardType)..",", "\n") io.write(f, " targetCapabilities = "..tostring(targetCapabilities)..",", "\n") - io.write(f, " targetName = "..targetName..",", "\n") - io.write(f, " boardName = "..boardName..",", "\n") - io.write(f, " manufacturerId = "..manufacturerId..",", "\n") + io.write(f, " targetName = "..'"'..targetName..'"'..",", "\n") + io.write(f, " boardName = "..'"'..boardName..'"'..",", "\n") + io.write(f, " manufacturerId = "..'"'..manufacturerId..'"'..",", "\n") local signatureString = " signature = { " for i = 1, #signature do signatureString = signatureString..tostring(signature[i])..", " From e56779fe8f5c3d71d0f97bd81bc06f2fc192fab3 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 19 Dec 2021 22:50:05 +0100 Subject: [PATCH 137/193] Update simplified_tuning.lua --- src/SCRIPTS/BF/PAGES/simplified_tuning.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/simplified_tuning.lua b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua index 20271037..addaf165 100644 --- a/src/SCRIPTS/BF/PAGES/simplified_tuning.lua +++ b/src/SCRIPTS/BF/PAGES/simplified_tuning.lua @@ -23,10 +23,10 @@ fields[#fields + 1] = { t = "Pitch:Roll P,I&FF", x = x + indent, y = inc.y(lineS fields[#fields + 1] = { t = "Master Multiplier", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 2 }, scale = 100, mult = 5 } labels[#labels + 1] = { t = "Simplified Filter", x = x, y = inc.y(lineSpacing) } -fields[#fields + 1] = { t = "Gyro Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 12 }, table = { [0] = "OFF", "ON" } } -fields[#fields + 1] = { t = "Gyro Multiplier", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 13 }, scale = 100, mult = 5 } -fields[#fields + 1] = { t = "D Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 10 }, table = { [0] = "OFF", "ON" } } -fields[#fields + 1] = { t = "D Multiplier", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 11 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "Gyro Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 36 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { t = "Gyro Multiplier", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 10, max = 200, vals = { 37 }, scale = 100, mult = 5 } +fields[#fields + 1] = { t = "D Tuning", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 18 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { t = "D Multiplier", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 10, max = 200, vals = { 19 }, scale = 100, mult = 5 } return { read = 140, -- MSP_SIMPLIFIED_TUNING @@ -34,7 +34,7 @@ return { title = "Simplified Tuning", reboot = false, eepromWrite = true, - minBytes = 13, + minBytes = 53, labels = labels, fields = fields, } From 57e663661c94464ccc69608d8ead75432886bbe8 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 22 Dec 2021 20:19:21 +0100 Subject: [PATCH 138/193] Update firmware requirements --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ae45f13..03ca798c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,9 @@ ## Firmware Considerations - Betaflight - As a best practice, it is recommended to use the most recent stable release of Betaflight to obtain the best possible results; -- OpenTX - 2.3.4 or newer; +- OpenTX - 2.3.12 or newer; +- EdgeTX - 2.4.0 or newer; +- ExpressLRS - 2.0.1 or newer; - Crossfire TX / RX - v2.11 or newer; - FrSky TX / RX with support for SmartPort - While most receivers with SmartPort support work fine, it is recommended to update the receiver to the most recent firmware version to correct any known bugs in telemetry. From 6ee203157bd51b57efff44153399721b8c32be81 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 28 Dec 2021 22:33:25 +0100 Subject: [PATCH 139/193] Clear LCD for CMS script at startup Clears the LCD and draws the "refresh[whateverbuttonrefreshis]" at the top row when the script is launched. The current behaviour is to not clear the screen when the script is launched. If it's not responding and a manual refresh is required, there's no way for the user to know this. By clearing the screen and showing the message, the user should get an idea of what has to be done. --- src/SCRIPTS/BF/CMS/common.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/CMS/common.lua b/src/SCRIPTS/BF/CMS/common.lua index bfb1b11a..6c1f7033 100644 --- a/src/SCRIPTS/BF/CMS/common.lua +++ b/src/SCRIPTS/BF/CMS/common.lua @@ -49,7 +49,7 @@ screen = { end, draw = function() if (screen.buffer ~= nil and screen.config ~= nil and #screen.buffer > 0) then - lcd.clear() + screen.clear() for char = 1, #screen.buffer do if (screen.buffer[char] ~= 32) then -- skip spaces to avoid CPU spikes c = string.char(screen.buffer[char]) @@ -60,8 +60,11 @@ screen = { lcd.drawText(xPos, yPos, c, screen.config.textSize) end end - lcd.drawText(screen.config.refresh.left, screen.config.refresh.top, screen.config.refresh.text, screen.config.textSize) end + end, + clear = function() + lcd.clear() + lcd.drawText(screen.config.refresh.left, screen.config.refresh.top, screen.config.refresh.text, screen.config.textSize) end } @@ -70,6 +73,7 @@ cms = { init = function(cmsConfig) screen.config = assert(cmsConfig, "Resolution not supported") screen.reset() + screen.clear() protocol.cms.close() cms.menuOpen = false end, From 56a88b1fb75bf6fa0b3624d8ae5ef79ded2584b7 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 10 Jan 2022 20:53:18 +0100 Subject: [PATCH 140/193] CMS periodic refresh when stick movement detected --- src/SCRIPTS/BF/CMS/common.lua | 3 +++ src/SCRIPTS/BF/cms.lua | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/SCRIPTS/BF/CMS/common.lua b/src/SCRIPTS/BF/CMS/common.lua index 6c1f7033..b562fedd 100644 --- a/src/SCRIPTS/BF/CMS/common.lua +++ b/src/SCRIPTS/BF/CMS/common.lua @@ -70,12 +70,14 @@ screen = { cms = { menuOpen = false, + synced = false, init = function(cmsConfig) screen.config = assert(cmsConfig, "Resolution not supported") screen.reset() screen.clear() protocol.cms.close() cms.menuOpen = false + cms.synced = false end, open = function() protocol.cms.open(screen.config.rows, screen.config.cols) @@ -112,6 +114,7 @@ cms = { screen.buffer = cRleDecode(screen.data) screen.draw() screen.reset() + cms.synced = true end else protocol.cms.refresh() diff --git a/src/SCRIPTS/BF/cms.lua b/src/SCRIPTS/BF/cms.lua index 15ca3395..364bf054 100644 --- a/src/SCRIPTS/BF/cms.lua +++ b/src/SCRIPTS/BF/cms.lua @@ -1,16 +1,25 @@ -lastMenuEventTime = 0 +local lastMenuEventTime = 0 +local INTERVAL = 80 local function init() cms.init(radio) end +local function stickMovement() + local threshold = 30 + return math.abs(getValue('ele')) > threshold or math.abs(getValue('ail')) > threshold or math.abs(getValue('rud')) > threshold +end + local function run(event) - lastMenuEventTime = getTime() + if stickMovement() then + cms.synced = false + lastMenuEventTime = getTime() + end cms.update() if (cms.menuOpen == false) then cms.open() end - if (event == radio.refresh.event) then + if (event == radio.refresh.event) or (lastMenuEventTime + INTERVAL < getTime() and not cms.synced) then cms.refresh() end if (event == EVT_VIRTUAL_EXIT) then From b7c51964b18e6068f1bc190acde3c37a5262aca8 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 10 Jan 2022 23:00:53 +0100 Subject: [PATCH 141/193] Make BOARD_INFO download conditional to apiVersion >=1.043 --- src/SCRIPTS/BF/ui_init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 62431870..632fea68 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -43,7 +43,7 @@ local function init() getVtxTables = nil collectgarbage() end - elseif not boardInfoReceived then + elseif not boardInfoReceived and apiVersion >= 1.043 then getBoardInfo = getBoardInfo or assert(loadScript("board_info.lua"))() returnTable.t = getBoardInfo.t boardInfoReceived = getBoardInfo.f() From b5a99f0ebd51db590afa134ce0c28c4b4caac4e5 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 12 Jan 2022 15:24:33 +0100 Subject: [PATCH 142/193] CMS move initial screen.clear() to run function --- src/SCRIPTS/BF/CMS/common.lua | 1 - src/SCRIPTS/BF/cms.lua | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/CMS/common.lua b/src/SCRIPTS/BF/CMS/common.lua index b562fedd..5725412f 100644 --- a/src/SCRIPTS/BF/CMS/common.lua +++ b/src/SCRIPTS/BF/CMS/common.lua @@ -74,7 +74,6 @@ cms = { init = function(cmsConfig) screen.config = assert(cmsConfig, "Resolution not supported") screen.reset() - screen.clear() protocol.cms.close() cms.menuOpen = false cms.synced = false diff --git a/src/SCRIPTS/BF/cms.lua b/src/SCRIPTS/BF/cms.lua index 364bf054..1a6e6021 100644 --- a/src/SCRIPTS/BF/cms.lua +++ b/src/SCRIPTS/BF/cms.lua @@ -1,5 +1,6 @@ local lastMenuEventTime = 0 local INTERVAL = 80 +local firstRun = true local function init() cms.init(radio) @@ -11,6 +12,10 @@ local function stickMovement() end local function run(event) + if firstRun then + screen.clear() + firstRun = false + end if stickMovement() then cms.synced = false lastMenuEventTime = getTime() From b11d9eba6ead25fa6b6e4fdb17adacda2ee40fc7 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 16 Jan 2022 21:35:35 +0100 Subject: [PATCH 143/193] CMS fixes --- src/SCRIPTS/BF/CMS/common.lua | 51 ++++++++++++++++------------------- src/SCRIPTS/BF/cms.lua | 26 +++++++++--------- 2 files changed, 35 insertions(+), 42 deletions(-) diff --git a/src/SCRIPTS/BF/CMS/common.lua b/src/SCRIPTS/BF/CMS/common.lua index 5725412f..5581d822 100644 --- a/src/SCRIPTS/BF/CMS/common.lua +++ b/src/SCRIPTS/BF/CMS/common.lua @@ -41,31 +41,26 @@ screen = { data = {}, batchId = 0, sequence = 0, + redraws = 2, reset = function() - screen.buffer = {} screen.data = {} screen.batchId = 0 screen.sequence = 0 end, draw = function() - if (screen.buffer ~= nil and screen.config ~= nil and #screen.buffer > 0) then - screen.clear() - for char = 1, #screen.buffer do - if (screen.buffer[char] ~= 32) then -- skip spaces to avoid CPU spikes - c = string.char(screen.buffer[char]) - row = math.ceil(char / screen.config.cols) - col = char - ((row - 1) * screen.config.cols) - xPos = ((col - 1) * screen.config.pixelsPerChar) + screen.config.xIndent + 1 - yPos = ((row - 1) * screen.config.pixelsPerRow) + screen.config.yOffset + 1 - lcd.drawText(xPos, yPos, c, screen.config.textSize) - end + lcd.clear() + lcd.drawText(screen.config.refresh.left, screen.config.refresh.top, screen.config.refresh.text, screen.config.textSize) + for char = 1, #screen.buffer do + if (screen.buffer[char] ~= 32) then -- skip spaces to avoid CPU spikes + local c = string.char(screen.buffer[char]) + local row = math.ceil(char / screen.config.cols) + local col = char - ((row - 1) * screen.config.cols) + local xPos = ((col - 1) * screen.config.pixelsPerChar) + screen.config.xIndent + 1 + local yPos = ((row - 1) * screen.config.pixelsPerRow) + screen.config.yOffset + 1 + lcd.drawText(xPos, yPos, c, screen.config.textSize) end end end, - clear = function() - lcd.clear() - lcd.drawText(screen.config.refresh.left, screen.config.refresh.top, screen.config.refresh.text, screen.config.textSize) - end } cms = { @@ -91,27 +86,23 @@ cms = { update = function() local command, data = protocol.cms.poll() if (command == "update") then - local firstChunk = bit32.band(data[CONST.offset.meta], CONST.bitmask.firstChunk) - local lastChunk = bit32.band(data[CONST.offset.meta], CONST.bitmask.lastChunk) + local firstChunk = bit32.btest(data[CONST.offset.meta], CONST.bitmask.firstChunk) + local lastChunk = bit32.btest(data[CONST.offset.meta], CONST.bitmask.lastChunk) local batchId = bit32.band(data[CONST.offset.meta], CONST.bitmask.batchId) - local sequence = data[CONST.offset.sequence] - local frameData = {} - for i = CONST.offset.data, #data do - frameData[#frameData + 1] = data[i] - end - if (firstChunk ~= 0) then + local sequence = data[CONST.offset.sequence] + if firstChunk then screen.reset() screen.batchId = batchId screen.sequence = 0 end if (screen.batchId == batchId) and (screen.sequence == sequence) then screen.sequence = sequence + 1 - for i = 1, #frameData do - screen.data[#screen.data + 1] = frameData[i] + for i = CONST.offset.data, #data do + screen.data[#screen.data + 1] = data[i] end - if (lastChunk ~= 0) then + if lastChunk then screen.buffer = cRleDecode(screen.data) - screen.draw() + screen.redraws = 2 screen.reset() cms.synced = true end @@ -122,5 +113,9 @@ cms = { elseif (command == "clear") then screen.reset() end + if screen.redraws > 0 then + screen.draw() + screen.redraws = screen.redraws - 1 + end end } diff --git a/src/SCRIPTS/BF/cms.lua b/src/SCRIPTS/BF/cms.lua index 1a6e6021..fdb5752c 100644 --- a/src/SCRIPTS/BF/cms.lua +++ b/src/SCRIPTS/BF/cms.lua @@ -1,6 +1,5 @@ local lastMenuEventTime = 0 local INTERVAL = 80 -local firstRun = true local function init() cms.init(radio) @@ -12,25 +11,24 @@ local function stickMovement() end local function run(event) - if firstRun then - screen.clear() - firstRun = false - end - if stickMovement() then - cms.synced = false - lastMenuEventTime = getTime() - end cms.update() - if (cms.menuOpen == false) then + if cms.menuOpen == false then cms.open() end - if (event == radio.refresh.event) or (lastMenuEventTime + INTERVAL < getTime() and not cms.synced) then - cms.refresh() - end - if (event == EVT_VIRTUAL_EXIT) then + if event == radio.refresh.event then + cms.synced = false + lastMenuEventTime = 0 + elseif stickMovement() then + cms.synced = false + lastMenuEventTime = getTime() + elseif event == EVT_VIRTUAL_EXIT then cms.close() return 1 end + if lastMenuEventTime + INTERVAL < getTime() and not cms.synced then + lastMenuEventTime = getTime() + cms.refresh() + end return 0 end From 3e1c5f921c350e5426d9a1586490a8eb693ee2e2 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 19 Jan 2022 00:08:51 +0100 Subject: [PATCH 144/193] Rename script in TOOLS menu Rename to "Betaflight Config" to match the name in the title bar. Also fixed the downloading vtx tables string. --- src/SCRIPTS/BF/vtx_tables.lua | 2 +- src/SCRIPTS/TOOLS/bf.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SCRIPTS/BF/vtx_tables.lua b/src/SCRIPTS/BF/vtx_tables.lua index 8c72e48d..2efa8942 100644 --- a/src/SCRIPTS/BF/vtx_tables.lua +++ b/src/SCRIPTS/BF/vtx_tables.lua @@ -116,4 +116,4 @@ local function getVtxTables() return vtxTablesReceived end -return { f = getVtxTables, t = "Downloading VTX Tables" } +return { f = getVtxTables, t = "Downloading VTX tables" } diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index 3c4ee8b1..abab85c8 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -1,4 +1,4 @@ -local toolName = "TNS|Betaflight setup|TNE" +local toolName = "TNS|Betaflight Config|TNE" chdir("/SCRIPTS/BF") apiVersion = 0 From 999bd8c78421746b24ded4a7e8cb7c5027354c11 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 19 Jan 2022 12:33:39 +0100 Subject: [PATCH 145/193] Back to Betaflight setup "config" makes it one character too long to display on 128x64. --- src/SCRIPTS/TOOLS/bf.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index abab85c8..3c4ee8b1 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -1,4 +1,4 @@ -local toolName = "TNS|Betaflight Config|TNE" +local toolName = "TNS|Betaflight setup|TNE" chdir("/SCRIPTS/BF") apiVersion = 0 From 72299cf22fec0f33ce56308bef4bd5f1723830d0 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 20 Jan 2022 13:24:30 +0100 Subject: [PATCH 146/193] Update readme for 1.6.0 --- README.md | 62 ++++++++++++------ .../assets/images/background_script_setup.png | Bin 1353 -> 1287 bytes docs/assets/images/download_vtx_tables.gif | Bin 0 -> 5866 bytes docs/assets/images/how_to_use.gif | Bin 0 -> 11097 bytes docs/assets/images/how_to_use_cms.gif | Bin 0 -> 8781 bytes docs/assets/images/install.gif | Bin 0 -> 266896 bytes 6 files changed, 42 insertions(+), 20 deletions(-) create mode 100644 docs/assets/images/download_vtx_tables.gif create mode 100644 docs/assets/images/how_to_use.gif create mode 100644 docs/assets/images/how_to_use_cms.gif create mode 100644 docs/assets/images/install.gif diff --git a/README.md b/README.md index 03ca798c..9492e11b 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,10 @@ [![Latest version](https://img.shields.io/github/v/release/betaflight/betaflight-tx-lua-scripts)](https://github.com/betaflight/betaflight-tx-lua-scripts/releases) [![Build Status](https://api.travis-ci.com/betaflight/betaflight-tx-lua-scripts.svg?branch=master)](https://travis-ci.com/betaflight/betaflight-tx-lua-scripts) [![Build Status](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_apis/build/status/betaflight.betaflight-tx-lua-scripts?branchName=master)](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_build/latest?definitionId=1&branchName=master) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) -## Firmware Considerations +## Requirements - Betaflight - As a best practice, it is recommended to use the most recent stable release of Betaflight to obtain the best possible results; +- Telemetry - Telemetry has to be enabled and supported by the TX / RX for the scripts to be able to communicate with the flight controller; - OpenTX - 2.3.12 or newer; - EdgeTX - 2.4.0 or newer; - ExpressLRS - 2.0.1 or newer; @@ -19,40 +20,61 @@ Download a zip file containing the latest version from the [releases page](https Unzip the files from the link above and drag the contents of the `obj` folder to your radios SD card. If you do this correctly, the `SCRIPTS` directory will merge with your existing directories, placing the scripts in their appropriate paths. You will know if you did this correctly if the `bf.lua` file shows up in your `/SCRIPTS/TOOLS` directory. -### How to install +![Install](docs/assets/images/install.gif) -Bootloader Method +## How to use -1. Power off your transmitter and power it back on in boot loader mode. -2. Connect a USB cable and open the SD card drive on your computer. -3. Unzip the file and copy the scripts to the root of the SD card. -4. Unplug the USB cable and power cycle your transmitter. +Navigate to the TOOLS menu in OpenTX, select "Betaflight setup" or "Betaflight CMS" and press the [ENTER] button. The first time the script is launched after a clean install or upgrade it will go through it's compile procedure and exit back to the TOOLS menu when it's done. -Manual method (varies, based on the model of your transmitter) +### Betaflight setup -1. Power off your transmitter. -2. Remove the SD card and plug it into a computer -3. Unzip the file and copy the scripts to the root of the SD card. -4. Reinsert your SD card into the transmitter -5. Power up your transmitter. +The "Betaflight setup" script lets you configure Betaflight through the MSP protocol. -If you copied the files correctly, you can now go into the OpenTx Tools screen from the main menu and access the Betaflight Configuration tool. The first time you run the script, a message 'Compiling...' will appear in the display before the script is started - this is normal, and is done to minimise the RAM usage of the script. +![Betaflight setup](docs/assets/images/how_to_use.gif) -### Running the script as a telemetry page +#### Controls -Due to issues with input mapping and memory overruns, running the script as a telemetry page **is no longer supported**. The only way to run the script is through the Tools screen in the OpenTX main menu. +- [+] / [-] / [ROTARY ENCODER] - Used to navigate. +- [PAGE] - Press to move to the next page. Long press to move to the previous page. +- [ENTER] - Press to access the selected element. Long press to open the function menu. +- [EXIT] - Press to go back or exit the script. -### Setting up VTX Tables +#### Saving your changes + +Any changes to parameters in the script will not take effect until a save is manually initiated. Change the parameters you want to change, open the function menu by long pressing [ENTER] and select "save page" to send the modified parameters back to the flight controller. + +#### Setting up VTX tables If you are using a VTX that supports the SmartAudio or Tramp protocols then bands and channels etc. are managed using VTX tables since Betaflight version 4.1.0. The script will be downloading and storing the current VTX table for every model the first time the model is connected and the script is run. If you change the VTX table, you have to re-load the updated VTX table in the script, by choosing the 'vtx tables' option in the function menu. +Depending on the size of the vtx tables and the telemetry protocol used, downloading the vtx tables can take a while. + +![Download VTX tables](docs/assets/images/download_vtx_tables.gif) + +### Betaflight CMS + +**!! IMPORTANT: TBS Crossfire/Tracer only !!** + +"Betaflight CMS" lets you access the same CMS menu that is available in the OSD. + +![Betaflight CMS](docs/assets/images/how_to_use_cms.gif) + +#### Controls + +- [PITCH] - Navigate the current menu. +- [ROLL] - Enter menu or change selected parameter. +- [YAW] - Left to go back and right to enter the "SAVE / EXIT" menu. +- [+] / [ENTER] - Manual refresh. Press if the script doesn't update. +- [EXIT] - Close CMS menu and exit script. **!! IMPORTANT: Single press only. Long press will exit the script without closing CMS and as a result you will not be able to arm !!** + ### Background script -The optional background script offers RTC synchronization and RSSI through MSP. It can be setup as a special or global function in OpenTX. The image below shows how to run the background script as a special function. -![Background script setup](docs/assets/images/background_script_setup.png) +The optional background script offers RTC synchronization and RSSI through MSP. RSSI will only be sent if no other RSSI source is detected. It can be setup as a special or global function in OpenTX. The image below shows how to run the background script as a special function. + +![Background script setup](docs/assets/images/background_script_setup.png) +## Unstable testing versions -## Unstable Testing Versions Unstable testing versions of the latest builds of the Lua Script can be downloaded from [here](https://github.com/betaflight/betaflight-tx-lua-scripts-nightlies/releases). Be aware that these versions are intended for testing / feedback only, and may be buggy or broken. Caution is advised when using these versions. diff --git a/docs/assets/images/background_script_setup.png b/docs/assets/images/background_script_setup.png index fabb458ecd7154d1279477624c35060fab60cb52..09b48066d34cddc801ece1899a0bb653dfeb409c 100644 GIT binary patch literal 1287 zcmV+i1^D`jP)6ciK{6%`g178e&67#J8C85tTH8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRs zBqSsyB_$>%CMPE+C@3f?DJd!{Dl021EG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3d zH8nOiHa9mnI5;>tIXOByIy*Z%JUl!-Jv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwN zMn^|SNJvOYNl8jdN=r*iOiWBoO-)WtPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7 zSXfwDSy@_IT3cINTwGjTU0q&YUSD5dU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@ zX=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&OadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzz zdV70&e0+R;eSLm@et&;|fPjF3fq{a8f`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?Yj zjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@l$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAU zot>VZo}ZteprD|kp`oIpqNAguq@<*!rKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%E zuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dkwzs#pxVX5vxw*Q!y1To(yu7@dCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD) z(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa z^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF){QUg={r&#_{{R2~f&07?0005PNkl?Kscl7uo7#DBIDHzs=)ZLd=!$0o>=>s70go0i9)SSeVZ-Ylzk#AM zGG#V{jjH=}RxiWXrQ<|>Q6@E}tbp@h6D@L+Z!h6JE)W3FH`9D$?QFW0ZJIr%*2cH^ z`Zm0m?19_eTK%(md2{BitweF*R&BeFss1OgC%00bZa0i^}B|ETqynr;OFTmlF{ z00Izz00fj30002B=?}c9Re{a9scZ literal 1353 zcmX|>e^8Ql9LFCeXR=bePOS`Rxye;?S1UA=&^A5u=O}HcrM6}1XxbDpHFeUuHMik2 zGb=U0hQB(<$Dy4eg5Avk(<1UYx(mtDm+XHN)PVG9f17n^%^ zW_;g;F<(~)W)$1`NqW{t#)5Umf@>+&UdMODY^i4kRi%8%j_PX9Dsf$zshZ09>A!sW zct-o!jJ9j3V_}%0FIuu{(Sf-u8qGtI6_JDt(W}ji7R{Bpc`vL)>ndY}4!>$i9$AZ&PF^bK~IFjL-|;1U(;N1&V)b#CBfP5Nj1N^q)qR0 zOJ1;z7CSRKba*i>)vuXK(Dy1lzF%ll-TH8S@*7zNU7SB|8oWDyWcn$xWVk!v)?Xyr zY&OU@SP;%}d@91JPegJXx+RFOupU~n9M&JUUg@q9kj>S;w(6@6$u)*v22d(2`l$D0T6@O$d469D zV|Za3MtWnpJA5dThGDKq5?Xkh!}5L=_(3TS=ws^kwPh6roaVFZ)Izyv=Ghr>JVH-W z2*gr#Yj;m%XEXpEvzg}~aZ`K2LOQ_}h?-h{X03yvo}5?YVzw2S<^@YNU8yUaE|OmLs&PmQCsXd1;v{_*V{i8z zlfHzSAE1P)d4uVOkhuHuE^OAP*4vG8zke5OoL^fD>7JSFq7p}SeCox-%{p;bc$do@K0G{$o>UM!$tv%kVjn1%;m_qvU zQJG2BQJ8#SbP>ED;V~1)`rQY8oMLgMn>%1_O<_V;DkhcCE?em+KX{Sbzg$XWAVc=73^?{8= xDH%7wXL}307xmOTybreqNX3Bi&@$}>0&h0*(^b(Sa`112!a|~ho4+`E_J5>*x^(~m diff --git a/docs/assets/images/download_vtx_tables.gif b/docs/assets/images/download_vtx_tables.gif new file mode 100644 index 0000000000000000000000000000000000000000..350d1200e4fb675d5caac52eaffbad79bd708719 GIT binary patch literal 5866 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 literal 0 HcmV?d00001 diff --git a/docs/assets/images/how_to_use.gif b/docs/assets/images/how_to_use.gif new file mode 100644 index 0000000000000000000000000000000000000000..70b5f252a264e25760fa3089897393ff100050af GIT binary patch literal 11097 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 OXsp<3gawe0DE==wGYx$J literal 0 HcmV?d00001 diff --git a/docs/assets/images/how_to_use_cms.gif b/docs/assets/images/how_to_use_cms.gif new file mode 100644 index 0000000000000000000000000000000000000000..0501478281d783884c1127133d6018051bdb1554 GIT binary patch literal 8781 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 V&oKY^2mg4{|9H{=w_dc=e*q}MF7N;V literal 0 HcmV?d00001 diff --git a/docs/assets/images/install.gif b/docs/assets/images/install.gif new file mode 100644 index 0000000000000000000000000000000000000000..d6f4d0c65fa859ede4d4c961ac9f7b314747f3da GIT binary patch literal 266896 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[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%0A_$VNob%QcJDJ^UsW~J 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

xZoezF&YX^h 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

  • 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�%Ur~ zT-_L>f0-Dc0vZ00W@o~z;~MB^>BRFi$6S&{kZq$o^=^55_xx_qkmRhob()8c`(@6l z($&synO{u9GKnFYL;0Omf3wS#4`>)gd&0O7Ji#s!3e0D-Gj{?xUU7ccQ?JP=Fga2i z1)m<<>MXAJ(2$fX(oJAVgc}w4VngG-F%RyG7QO^nfoz=lvfv&7Pc(RQLqEHQKf8X+y9&K$pIy*L3iVie-G2a@2^~BuR=MZfDqUGGjE2Gh?=pkq@{wF zc5UiY$Bl0k#q2mkKzapdRX*GhS$V3!3yx)i8)?&-1pm?(Tyh87)CLcEspH@z!XAwb zv9K+RH(;IO>3Jz(x#8#W6kH;-1t94WL9cmT{cL*MQG>e|6ZQsyc6&Oi#hq2BXirvd zhJ7B*G+}wVdra!A91{_`>+BD3I$>EDPZ7KQaHf9;wy|+%G5!Z!516uT7#x*zN0r{Y zMq2(5O_|o5Sa@t-l3lVt^j_0|e2|O8S&>6>L;ZE)2`n7c^MLgMg%y-EXj!8inspG19Rsc&`f_wSvM>jvoBp+qk1;4>q1ro2_}5N zxSHR2A6)2@!gy zn&n2IC{HwE8rsK5|@zw8PPlXG5ZrIxj zYA0Hs2(TEq0rfW;>RIJKj<*^Bg*v0mmhp|I4{v}wjc^C3GF9H-f_-bHo)YIk{Rgfz zH(+IQ|v1Ue|z?7SrqIdVLfvo6?tzXHEYMBLy$4;TBYpxt#ECPhHev)$3Hv ztmEb0{U}8D1^~E`(eu@}B^=tx#bJ zFAIIB5b=zbGpQo02JwBvP0`Jqt~AQ$BxjtQDhwvAD!K1-P!+b)S^XU78D<4zN!C(tWnwiXCjuB`>)7Gesp`U*C#UR-Y<6b zzg?nJytra-GJ@l?ct6fpzB25k=`A1T-9GtzlSp;>J~(*9Q~B=eVcU6)QqCcrJdMp8 zsdGLW{dv=m0o7UR0GZ>rl>Qz_=#{A0T}EY~I_sKgeRN;#=jgz><5};Odu|OagmpP` z>%48_%kVr%bEoo&uK=4-0lV<2dop+CyN`qAoq$%GG(twKU}@9HzPL%x*jaW4V-L!M zUH?9j`5p~NMAgIMV0xG>@e{jVL z^E`tU-fu~-djjx_&9vZOI@*55^GK;}yHT^72N6cy_$7w2dFC_9NNGOBPLkcHEmM&Z z(kn%4ICv0=1k#s|XBXM$J!&0y3;33j)?_cXb^|W_@4h3cIO!$YFQWAPt1 z)7m|MzJ7kTwEOXj>1hVbUnGg}I^aga+fuV<&5m9IXfN{$IKK z+f4TlJ9~KK89~Sib@@qkQX(9(-cKIp(asYi4*&-}3hm;y?WmUvVriA51_7x-3Vg*~ zy9za zy1j%YhzcD<<=f1Fkfbw~Q?m_fdfUpv_*|nHxS>F;b*QLaOjc6Xb`}C8g12!_cewKa zG-!iabYk?x@lh|7QH+vFv65-Bl5uUX4i8F42W4K{t09gu&+awl?Rz!SYaG~XWJdgo zv+s?fvRSB-y|A*4zOqw{vU6y!+P3UZn5?^543}IY%Rq+@qYT7B9v|Cd@Q};E0NKQe zlcQDsW0CRuE9TFG^uwx5wy5MblIE&PeVp#Ex-@lkN z@N4CPvK^_b+Ubg4zHr^=-rA`9m-L@PSO8w}%>$W@RT!inWQh}V zWvg)M%jXTKWNWDAHLCp|=HB})$@p*B2LwSy#l81JQ&Ss`)NrFYaBFUJ<=&cEfeT!P zGtGso)U4EUR9fc5jpknA*0NI5va)>W{yg{hzJGas|H2;tTo>=xad2?H&a}C;)yW zAiACSfHYt&sC7pGO?rXGPNL%ujj9)oNrwZk^amfBcHNvbzN2XpXWI1;oR$G*?93Pp z_}za833=RZB0Xn9UhgU8HEL-8Z`==YIU!VsC%(U^{bB$$IlO(~w!V6x)6k@IGaW47HSVq-sazbg1`M1A73Y!V&7W$PM>zKjAb^ef0I_4- zXwqn5drR{_)m(B6v4IreUeF!|h2VItXrPih^rmde+HF~1}9}6CP z32r0lkNmK~%Q&P&xsO=G$Kusez@b?1ERM+m|G6D+8;j#XjB-huuO$sLvEizS47?OT zKpT{~4Vd7U0cuFKsxi*J3DrR-?;Z}sV892?(D}oD26Rd(eC(*IKOWO{qmz!8i}p(# zFNUVaa*TIQnopm!e&4k?1zYfqK=0gyy3l-Up(A%3DD=%HG2i-l{B*gf6ei`NE6&Mc z9neobqo2VRpX6!#ovX`XswiNGk>Uh8KRcPX`)I^;V|p6bqDhK;Z|O#tz1bf zaPM8qFz4T!z~%PSOmhkd>qjSGmswEMUcY0(6pfn;E=Xi70JxB7*16;tMf94n(5P9E zVhtb|Yi;2Ek1!02g=!Q46tPn`V?ne^jdUB-o<#6v(7ab?VbDs481W4yH#cZ1rUuV1GWx0*%JNqZ>hbp=B1=mR%VS@ zXL`#5hcv0A(^Lhp+sJ6oi%~B$ga#P~W0OGGB%LJ?hb>ebYl&{K*pS=)xsP9A(OjrkO)8H2+Cam`wW!4lAkxPvYf}z)Ovj!7&`YBsOet=y&5qq#c9uwsPn^l#$<`<- zizp-@=fd=Bv-kT`PS>HpZc9aMjK(edGYl;h;m&<&VP-INU~*-h{B zfR!i?{6#yBt-Z~1$Qo?zLIp7ePo;pZHA0=y#|wkDcpZ|R55mP7(P2VQR{?^cajAfvA#4 zL1deoyZsB9p0ch~GAy}SP|F3j#x(u*A$)m7%X_86-Nt;w?v^#m#oMgf%lhJmt)chT zr{3@svh~yc3eDuc^>y>_#!5ooMT^Uyd#Sxk-i5tX=QpctBi^ra-Tg+*SMoMjlF2EH z%W0E7uMQd9f=#o)KIINL1lOj|Un_?E{$HlPzv?X#dd6bzlH;7GBKyX`wp$Xt#-S{} zVJwWX@nb)SeWOZ^QYS52hkZSSClXpLf4wj(>hUeo_e)ZQoN^I*9v5o_@A}r6VzAnN z))~IdL+GEm{RzVFi*hY-=C6+rx1&pk?!NI%HQctY+3xwBnlbH1!Weql^x3K<+iuf{ zw2x)qcglSF%3b>^=syPL_E}+)N#CzKaTq7% zT>uAim**IOh{bVZfu=P{`VKe_8e2#K@KLawBp`S@P;46q!r&-Alt+)Zd1i6%?QqR@ z0WX7tX8z*Rq(42l7%&LiVnyH@4cjprshuo=rz8Zh#r4%-^qa2kpi(v9qAQLaL1Xn|Mv@pG`b9_?157q%?yIv0Fw8`K8Us3E$(Y34S>mLU%udb^Ghjry-SyP)^CcHtkS` zXS~puJ%+b?q}otme<+J84>K$69}wx=ENO#x1->X^xz)n9|L%RF%jIOK z34>2}S*cqbp}=zFzBJG_0k*|<%D~5yTa>adeCHLoY`>HoM!P7&W&4AhVOelru19%a zpYN9V4%TYEKQR9t~6-rU0&?sB`C_52Ghaag|??pM^gUgG;%*LYJW}+0f z6I@TDJVTD!82*?o2 zEJ*E6Jnh$c)Bf|@mV)*d?Iuage95hLvH~$T$8k`SH1Zs`AR}sR3Irq0!7a^YgeVQp z;H1d+^pTScxRRtfZ~Rj7y^V(+@DHgx!f~P%tsJbMwCqsE>Vfnk?oq=L6~PcR%|&<3 zi#jY5%t`8XzK^c<0P9t87(-(nth(8T;O7j2b^XxYDVT{p$y^(&R2{f|G-e}T!2e}= zZrzg@ajUOS3T8l%6AufGo!m8;z$n=YAOMNC?z~XSNzIUZ0#GrMz)o7CF4k!#;59yS zHVn()-75&v6x2-M(HLbCHk~hdP1wHMBxECwyJU}fp_U5Pwg!hSmlOsNF_sQNH6spt= z9};4{gpNLJ*(go>$z4qk6D&YMp<ylMT}y4xEv=bgtm&l|jHLq?wcelWRXEsWL&Z z80>iBGg2Z<`cK1)_ZHvep7inE83}ssclJ#5f|n|DP_KYnM&p!gNXEfJ=%WCQF3HOJ zS33iWMFfVk6w#i@rq%RT9l7{DU7*+^LU)3Wwh+6DEmK3-U#8}xH!?3R{hT3oYc)+j z_H_>HcM=h3nsT|4soaA!ayr^s%vl;I_e*!_>|Th7`u17+&)ozRvQ0GJpg-csOT5r+ zOnu-iT_I`_(tJPlOwb42g~p359r+hnZx#oXfCTO<)m$@ z1#NVeL=(@k#cd=x6`I4@fzLmwhkAbWbb-7~)`4g+1sP3V-2@+?JZzPG=!&O%s#-cP zaIdFdy8?!x8hQkB2T~nZ%sGF^yaD}sma?PrfoYu3F>#cJ&wM`5ZG`V_tPV~$h@1w! zeAtbCb;YF|0EW%__775(&)j=C%K3X+ZP&#tF#*%o8`Q z7CdJs)QF~JHhQPRjL+KYoarb_Nh|*9_u88;{Mf+pi|?y9J)=APYKI>Tak_~-o~x(V zeo`o11X~YBHocF!a#xhf5-Wbr)bnXifjUJ*-s_cM6ouh(#f3%? zu&95gaqMwa*xCyTc$?*BsXlsPy@WmXp7S0Zb2FXy~NV} z;MaIs)KboRt)#y>u;uCrHE@TXnRPsz;;B=s_q^qi?&tvW(20MbC>Co0al}Cg`6}pfz-{hg6+Fl>X8w4s+rg_#*0U_SOONme{boK zf?Y^*!iHhi+914&7ut201L27e6(lx}BIndIGb65TFQ(zU-p|#;uQ3m^q0M=e8PJl6 zJW+B0VQEKfz1;+o1#Td&ZUixuOH zWcJD24Ng(A2|X&*yH#)D^A{`BC8Bo~H%CrQ;<=>8wD4ok;_X<7B(^a#C@GP@Z6r3|OP1)^;Y`K0>2AuJwery5!s8+rg;tV)Z zY#kdCdWs6XxfR6O{bHn&Bv7c~A#3rei=!hvAFsl(#|bcuu%wsm`IQz~FU~Ptlm1%! zD!?hQ0QHnjOnQ5sgG$f6WrCqYm2x{QU1t8{sqL#^v3;7b%De_ z|*IK&>%p*~14PtRY?rUo{XHnB1GQ#sh-i+x8 zD|Y0K9ZwVqADMstIffIynYZ4zJtX<{RPDY7gK41W$0msO-mQ=mL5nJZ6&m}gVsSdM zAVS8CHa|-}OUoPH+4{%NX_%5ScJ4Oh_Y34yZ z&N1fN_n6?;BcIoXAuw*{rqElnGi-G-*eCt^U0zrjpzw=+(^cQVU0cBGgxkB&_`yfF z+k2frZ1KF%J4;xco?nQ_EN(c@sqMROU$0YU1A}^Ngls{KJUK?uk6r0FI<(dBr9B|L z^$crU>?eHKz@vCdLn4Tc1%gV^XmdK~j~9v!{t1n9He$|11s3bM$|y5Ds7e5nZ`nI= zK2zmT-aen+X?h}!daWC^b3YMvio^}t)A+}f%iEqGjiS_B;zL?e=?wi6xWn->x6e5M zB#vO!=roYBRmb_{1>a;GlAw(fvQENtNyOBU)wv@QGyGC_TT_T?sTuaEZ`7g!+ENfT z@x^NHCcJ)~51mpR(h){!b%eA!bnJ9DUX+TrJ;pq9V57}n2LYj~G7nXYu-GbR%)%e0iof zQZFMB!`Of6+ZhUcoRT+A%oa0ZW;c#af~xa=gN6HMuH%Vk+H#oYa)Y z{kfiM+4G%nds_dJ=H$Z`&xJBikg`Ft#8~28zH^yXY7FDoU8-t{)?9>|9Xj!Sx_U>~ z_oq~*e5L%&SWLQmk;whqw4Cs}t((b(&bzd?7;{geFfoAF>2Csjq7%Ne$4pKwos$D5NA{)*aF(Vsqwp@)!6B+E{6bk{}4kKvR~z-Fr|3U|1ztZc`bFqOh+Gp`b?i z0VOOjKdeU$v2qbXlj7`S3-*-|lunkKmWq{&Wg}P`p~G@|omux6%Lb)*7Qs5U$0#Dl z@|4K%fdXIMV+8B?Lqr+r#aL+Gzi}*+HHnT7NYF~9Q?*3IE5nP3Ob{iea#0p)7t_yw zsZ*9_rA+z0SYer9Z?X?NlC@W@au!?p-7tPQ+0C^67L@6J2 zXL?FxuDHtbltv07`04hUM7BKn@$o@whP&zy174tr|D5uST1y$39 z52N9g)1A!kiBD*7>_-gCT0?ZVE#rC~1Ci)Srwj+3j$e(cU{o;q<6 zVEF^0>JxxObI;|*Ilp%gx`JnEaYsIIPp8MVLNLrvMd>axF<$Q!(-SCHM6y?kJ!Tb! zo$j%mhTpFzS<>mqtZ1-~02p2pE9z3h;s$*nD~VmIjoJ80saEDX?qK1U{?>T7_JbCH z982yEn%=OJtrD&HE1|U96FJ%h;Da!0nm^bJDWTK(Cur_0yA!k*U zZIb{U1;KcxV4&f4HKOJ~M5p~RM)wkjD(dFu4f)k{`IhsD7(!y&^?RQR<1=EM|1p%5 zURs~o%@ha%_PNPhld*Ze0wfw|JSSQ^2qTWwwE7um@#eh6qCm_iC5czs8XvK#uh7-$ z2vve}A_QYLRLw`bVm(hC3b<+te7BpNc6(g{f%K>W2(_19)Ve1Xem#&`cBqd`$`}J= zK18OuI+WD$mQ?zu*Wp1INIf@)9TjIwaP2)OdgSq1{KVr{>-O}w_8GlfFPo}+osud_7#|&_y z0RPN{ofDp?^#cyF%nNmS0gG@WwZxR-?y2NfR?Q1o4BcA%_||X} zsi?bsg77vb#k+=l5Bg>bGn{ua#ff;IKpBR(1HaSED5;bMIa1+`sIkxz<__3(^$VAn zRMw?(u!!?dpk&^qx@%pN9~Z}W<73gOxgCKM*}n0UJgKtA%vmSBBc{NA1?J8P2xfp% z%;YHdR`yI)-oX2i;gLo8%xZ`J>77V{oEap74qGz0ebQg|ZoCzqV_rFEb<={ke#%CE z41v6nKQncHWa3|O8QbN~Jfb|z1Ra4-xA(n0@;SHt-nD?#>Jq~lGaO`+|+IvA? z2=ut*LF4ceM9kzwB8$;{cINn^l*@9m#UN-w*8sEe9ZP^zy7z+*jny2D0IERV*XE#d#ChCoi!S zo2Mhij+yYu5q1THE6e6N^R@f=0;+$PHVf_>T~B;DvbkRv^=_;FlfuU=<~f&>sgYfA z-}pW!*{Y=AjlAH6mJyqb(s@DZpekZ#A&3eqjSvY!6h37@)GX|5?exgR0l&k4BEBAI zfBk08`i;m+OCvWUm?n$iBOQIVPcusRvX%lfIT>c?vS!xdUkn%PD!{k#w@c-|oG&0T zNX!wCJBcArXNf=HKaTe)N^lCLz(v+gs_bipC}UD5<4elNsW++Tc!`%z(+34A^Y1_1 zQ$kU*@3vn#iLR)*U#s>>wT7&QM34%W!$wm>3C?dEqXmk;CLxY!prz%V7CQg8-o~zR zHTN&x$qapB{CJ5Dey9Ds_I=t-r&C9`yuF)lv@0VUcR06i!W!~+XMs@5{7d^N2?Mh! zYnnijKxIc&&bedZnOv27&osa52T*-jGds;o-peAmK6vt;U1^V64pZE!Xip6*jVe9s zG)rQ7sdQvh##l?tJ6dp?F(NnJO?&<{PLX)*A^c@=={SRKcZTn0ZQ}l?FE9De-uR{V z&Yg`sFO^#7rarp&owRwx8IqlLTdw z_nM`w=n?*D^Bl%ky987{0S_j_CM1aWq}2u0t*n883#6d;EoRk&$@5m8PK3<)bH%D* zid7fSZI}d}7i+AmW^#D$-C5=Gnwxp+od38+>IrYSC7H-}2?Scv71c>(U~`ppn%;Fx z=TnV_J07w1+|4}yB(S#08+U)!t74tuXlDd8iTMS;3gB;6cio%x$YbJt?lWB_c9Svh zs)U8;GsRzRurabx*|SyIhMGgkr>;7xjvC^9SwNs--N0GZdRXg58`4sNp zq5+=j(Lr@6R6&?`EMmL)wn6a6`~1y8VCMitaY_H zRmJ0vVBESd1tNSwS2m*hO2Od)!`a;IL^-8Rb~q!yANONDqDB{%Sm-VNJN-czX~m0; zM6;bU$ z1x}jBP87bTqjS6QA>dK?D@7zqBl45NSN)#sK2xjb9v3+KJ?|N)3}vvMInM*CE&mf= zG$17sBbnW{mJt6CAjWkf``{Y!`sSEh?2QdB^3!+cWI~jxP9K`E7z_@+xjPy80&w=7 zbI7pDxm#!7@Qn8yDDZ#CPJfX1cPPMob5Hk+Y|3GeVcWG7*}gIFdPko^vSj+fD}80J z!$JNbCax;Q*T2~7uUxQ=w$5bVfAQuQO5E)7%g~d1N^kracOTk@Oq?_FBeLD+^XV~2 z;k%wMhgH$%dNOh8{QkMj@(TuaoO4I{Q!y9K8$BOin$TVf$u8Rjr=d4ner7GaMNH#;#45 zl?x0l+G-mr*g;C=b-9iV-dv4jZ4NXsEDHj+gFw+gyKh=@p9Xl>pY^}t-=bag{ms2~ zIW=SwM?Hf@O5(1uj{ggsA+N_>G5e-;S#wo>@A;$V?phamR^mi^x8Av%na$@v)N|ZN zzNvdk3qyW$6<&NT7t*8XYoE9I^VJ6V_627zA0Zx<>ypnggRXqH_?8WXp>uL0CMoZr z@z!=H-&01xbNdw2bahE$@9iCT`{pI*m(5&}PKPfCv}RT_ZX7jVUj}Yr{QuZl1bv@> z*7xT(NUh`cxv|b~yC*e26Z?Wz4<>TT2Z^s0e}ehW-(RfAGN0*czxmntsJ0_RLbS;7 zL(>e`7e@s#>TlN}-l#V>@*YN!{Do>$pfXySdP?+N*6tepr-H2v*X*`c_^k_?p1zed zNwj6BP8y!q;ny1VhEO!a|82j#SJ znRJ&mKhsp#XKH<7dYhrGo=Q2*H!Bg#vbdJbp2rp{(MDB%94Nt-}CQ@=N|5} zr8x+ZE4Xz!KeG_JNfMZFZe9`}+N6KQl9FPm`^NqGTyYh0(&E`pT0OO z{kug=_~am^%b8DFRi%vE{+WTFMCUL_;~U+ z&!y4IFL%=>+dciC6@EOUnInq=D(XK4Nt#&*lrz%L^+>}_^u=|R;q*FseBai#a^deE zxe*)uhAAS;gn)OVeb(t^xm&s~?C0N02QWxC-oc)W%60di@vC9t?6m{nsi9li-XaUvs!i0t&eNpJPnKC z=<`f)+3vgk8H&)8{2~fa#(__cL$KmTPtUjGh0(9X+)E6@v3rGcAj z;@#wvFGdCn$fpG@?+7=Q0#bkWa!*`ocygK(&{I_x&$je!dOWoh8J4&~U;?Ihr*x?@&2`Dn|MVHW7Y3f_ng4bCttch$xOnkhaRN zw(4D3`d!y(sc#p^)=o?!H+~2Yl)e%^re}vXy!J$#-_NU1@i9C3;iYH7HxCA;M@nVr z_8Co5t&4{?3G~xC30eh)J@6Z!PQ`+Ru0Oc2PK1{~A&@kLf!tTf&!RJ5j(rwBH~ou9 zB{-%ZbrQ_8MhZGNBMq=`$%Ykv^zappG0D|M_0RFV(_uSjR%U}O4C0te~$6x$Q3ArDCi)$U~ zBbcOoLw5YxHPwMe?T4R)EYco?ycV8}tsDDQ4ieRzyNORmwmsvxccbY3K7ut>iFxtN zGXruGiUQzmYrnEWBO7tb6+-hbIdQy|l})%O0R#jRz~=|#Zqwny-~^m;To|B$7cQmk zod8@{EQvL}0(fB?>ABA--IKcXj;IEhB3(P666jG3@BJ=BrJ@IRS)fwKIAb1 zG9V8L#@o3q+b{zZ-6?|i9lJh(!&HYBk`)ZqNl(zh!*D!EfS4DKhoZwx)e#ZYO*z&R zKd+y!UiU8sj7eHH0i&xf3VW8Dc!|k(SLm65O*xd|4Uzz8r+Og!I*um^C5;VjE4g=Z4AYV2QLfa2wp%DdHqZq{WOxHX;)Q1 z6^@{U#yJoKYj7?-21ze!Tuyp38i3>%xKzZjRn4$9A(Q}W4^lctnK(@{aQ(ZG?Z7pAktBeY!a(D2C8`bftl|65Ik)0KFFn*3<1 zQ!z*_c|V}P%-JZV4Z6Ln+f@nuD39Gs@7VByZ8^j0pN|r@&F4Eux06P(fW~BrFI>NTwvyO0h*>By6qSB0ZhJ(+1pdHb0f`tzQ_m8a5}L9|Lv10^Ne`NixCW z31F#qdMTz|Nv7ir3vRLDD;mk0C(tV<=Bv0%+S+PL|%c}4(02>{lw>QZ68-7OC&J#CcC)qlnx@P0i z|DiJ5Y{ZjkNFM%LD3%5eTDd^KRne$SpxrIpIY^gC6zjzj+Y1WmR(oSc8x)%5(S?Wt z^;)B8$Y(76`y$AL3y%_d%bYiPrvM83GjO9b(F<#Cx+ zl*mBK{*s`s$>zQ^gCiO$O$JDZ($Btz{sS=G6Jz}5A7x&ht)w-70SpcE_UM1*Um7c{ zN>e-{@c$H#q6sno08EHA7eqgb&c^|2fV6d?Otbs}TRK1kFrb3u4p0Gv;c)th2HYmnIe@mM(g}iAe=!)>SpvV=;X#^FxEQ-@4Xb`p5TQ9piz@H+qP)* zKlh^U_S~t0(h^OwIc*D-ZWyIOkz%}d44U?eH2RPViV9lJPj*$DO^Dg1XNYxFRXd}_ zJlUV;6wI4|YaX3so(DW}7Fk*(P{(dkQqF*25MG%UWGvW{*TJ9pvPZN1>Mgw4?ap{4KvBu%dZ=R*VsYEx zvHkR_80t)hE!55@C4}~Ck^<3}7JW6Nc?N_?R&apXNYgsf*f3WM7n*yMVC2rs? z{Czs=WK}%>dSS5ZrOy;UyZ)!%>t!h@LvA0bO^<>AQsjS73P5uD=3Sa9Ahx#J_=l*KZReb$7vU+UiQ? zg0Ys<7292(j>&lM-7u-$uD%KXqsic8>%q-&{mI4DzLC-OpwrP4(`8r4itv{)dC2PD z;Z+~A53a!MW)p#CtIH#UoMywEUxuqjww{`OaUJ1707vruMuTB&fDnWd@NhJ6 zPw^`|c^4)B6@)hAa{%&Ta6`Sj>?AU)JIvP^$L>HFW(nmY;)=X+tbVi{E{=OoXK(b~ zuq}?}ZZsq7_)KEiX?!I)RICliXz@lnBLvVNnCfK+VBHge?TrYB;Ew@pNFZAcOjr=e zCjv~X-}kB?tXup_*!#-OgYy~=;r~De0YXk(2^@Rfut(qlc_1?YCjrC4`*#n__kCW3 zvGariABA&WPUkHPJ9~P-*S}v|3_G*+j-9ywHU+JHa&9lB6I^;el(zXGK@Kgq!O8M` zm22H+??2cxTvs@ot_Y3L5dkWf>7?==>c}v0pJHWr1|^6D73eput#6lO?xBn#&z?O@ z?TqAe!|~mLiNz2&jsZe$1fvgOXYNN1Z+;W3Km6VnX)Y6~{Nd2yG&1EFi@5_kW&v2= z`>Jvp<*V5v5`8p_jWVA(l)w|Nwnn9(zY}JUT%pnKV?hcs(Y~WmFFKHk~2xC~eWGy?+uH`AC1paj@J#?S$at*dzw>KRD39aKKgC35Rp%S?femA81S?ldx%9 z!%8=Sz2<8 zZ4v*S0#0NSF>i0%UnA$7aT{%a`E83*d8N#};}tCh{5;^pXvgaxU#Z>cry>?_+I>Ve znN+4S9_7gRCyD^CzWvEo`YxSu{m~sqOCSpRPL(A-26#Y-uh>wfT!eJuM_gh7*#mxm zxsoyy6D6%?aDccJk`6@)i4etQ%&s`anjSdbzLyazqC>}6RgQ`n-k!#RGOHca8CM$# zIP7AKDNb9vLe%$%!ht6+jVk6Q6Wfd|N1X)am)$cfbwEi#^kX;f7`OP@r5j|^iwgf$ zn1hL4HYBgz(P2Dq0p#7y5+NRx^Hqua${k1$wf*N1MOXmHSllvd`WjwFSe8=qLqVOQ zrOYW>b_;95SA${;{yNUKCKYfY##pbsZL$&msBCUB8s5tuQ?>PhP$WcHhAuF zS;8H7uAUDOHYqL%wL5`H%9&>m^zrdjdFt+PHW=y8)y=LZDfpbBB&m45!`=NM?6{5k zc9*=RCphUKW||04A)u5<`jj4cxjpY4K@3fy1ilc&O)rMY1l}<+?kHq(=E&4#cB^!c zoKb3PU^h?IP3kh2Gq@m!xDc4%-4n5Z0W6_;Lc6b)bFyJfbgNJPEM5M=iD}cpM{pzl zM^8$nos#DOhyT|p5!dgl2dLos>A8P%nN|EJn9avVpTR2VNuiQbQXcSMVC>=KO#l!4 z3ua5o>KdejL|tnDz)I27GP!6um%$gcC@xifPQ<>h90hl-x+!$9`LR7-zJ)(hr%Rf# z(T#RWoB#^{KR6}4|4zxzZ`6dTL2SG z-ws>YnFvb1Ac1Qz0BVQ{KcIc=6#ferSSm!>bPdxvBI_Aa3&mWHbyDf_Y&mUP70}>d8OkULdcgMW; z{Ub~zZFn`;P0>2$j9iX@R3gr}D_h>U<^MIjsvkH1&+zg90JE`h45}X0c^!rJnltD9HJ7~A%A(Q(Lv(Vr3i^MHp9t1#@=FV-0VgUVPLPvz2)oKK}zcMTt){4b`E|99tNBs zA4fs?Vxp5g$RTjWMkv(IDn`$tz6gF|vI}9Qp4>&8t(0xUzjcU~?uSWB% z;l+Zi0T+e%u42!M*bxdypN#!HZpgp!lMNp7FmkB2?nQpcsOz-^Tox-amb+Zlmjz~b z>#{Wk#&Vw`OzYcfa7kHctGRKtHBQQ>XA7DV`ngZ?^(Xv)Gf0B-u3i)n$PZEuC`9!d ziV>aB<2Uj{S0x={(FA@vsrsxjF;339vYM&Laa;a0d+dp2uZB=zXH3-oQ?%tj9le4y=+=P z>WdCEyEw5-{5Gh<0QSwQ0WR&|oG5cn%lzajA|}H?ioHD7Qssq@kie7Yrtf?A-urU~ z6mtEQ@_@7$mHR}X1+b>#TxvmdnEF zE0yOBp_#6Lb-a2~WRe6Q6XO`2Ip<-7yh!-hREu?X{?Kx0T}c&dTZ7)69{moL>|U_u}iDwQ)lfGo8qS`+__yy+?yW9@AJ?b$&x6GFPqPiZ?5-VW28vTYC zk96fsn@o17LS1fvF?{3&GhB#lW4OR#wQ&Q{BQARx7L4ZY-7A7!`Nqo5*qc;T0fr|Y z=$aHaAO(MN>Sm)}#gfeLIsGo+i{I>SKCdEqZ(!<+Zuqm?yAr;cV%d&0?#ce)3|EcS z1{`!flC$Ra9j+~kACvYZkV*1>KBh8PDQ)JpmYXKQlX}Ce*Q*c2HVS5NqO(1Hrvp~p z)Z0RZM%s)@l)Ig>dVGwaiisIEKW=vc9RT2i4a1{1E`G>7FE-A}FxW+SL< zacT_rsk&`N7tTwve=HKQq2O%)Kq=@hHSdmt6H833HGl5IC!Kgbx=Qz{(H<+@L` zl#G4v0UTzlFnsc;2^;8~#A}QhU~jP!?V{IXqEhbaALdjBvdAV|InuL3a=0Qf08DXG zBF&%UtfKjMjjV*gJqk?qcd_ zjG>H1s$mLd7s}kO26lRR3~?P!fX7oS)T(3L2K2>lKI?R?a@l7b*=?2o^CaV1!+M`O zeTZVzMo9wSV>I}1g^q2rGW^5_8&Et}b)aJ7`EtUYk*}dlLQ0v5KF0H|E}2U(-bfU4 z5|BG`4N;IG#-*0Fs?&b0S<$rr^2B~3UE8Y2)9o!WfB527Zl)4O(IdQa!r0L;f&E)U zwN3c-Mwh!Dg3cFn+Akf@YeAp9@;B~!HG02EOuad4`9T8T;BVe*Q;+T*tNU}G1ae<$ zANGGr=&@gW0Jay@E&d)H>D@M1c%^K-B&U&|lgelx?m42Fc`7+oF3zuHUHL$hT^FUm z7<$(!^o+NgwRy^Tq$&LSx5m?q`jwPbJjY%f63NmjHi=7O^;$#dqVdwuau%_8DnGu{ zOB8`M_VQ)d6Nv0hTm%E`7uUE>y3Cb(mV@kGsUWTB;bvJ2>Svx^8hSf0drti!DZ#pR z*zdY0kY$It*`P()z*$k(R3BdeMjoTKOHO#^1D)h9YnfY+xL)Xh(-9x!=7Mx4>qK__#wTKjl(;b<4adrb>WWh5dZw(cPBG z1QWg=)?I&0ei})!@7!g1_3VT*`u(2rS8i7I2x%Q#z_N=q&?zpgh@sB@D<-T z6jkMGgc>-o!-6j)2Ixp{J(sSu0*Fkj#!*0V02AeYuB}c5LS+PFo}M$1Wm((=#wAOc z5z|*zGMZ7Xj$)SCWB#$nY!L&VdIbD{V*RkkjHg^Z)0g4`4Ll^W*zKvl$TR81I@KRB zf0~J|YV^9|a|iPdu52Tw*mDiDa_9A=HN;PP`4q&u84A`~*YFkNHj(ljOp?gdXZGxq zLS0kP3}xlVggzFR)c*#7`*O!MxVDp^#tjC~F!0_`m?O$f39aR^?>GNE{jsOpjeRZS zN@!7N_!y2qMv8s8i*=IXzytF56Ry~Ybm-~lvS<_Jd>9V_utG2>4qdU33i{+;VH`?n zS4S**55ki`50wH9mEVP7=>;n2l~MpQdq^OO{)YFW$7;l5KPc~c zUi0r~Ww3Ws2{A|G&c8|F&MT}`l%ypWqaQI%I|r;AYMKOwSZ1F&US};X0B57kALGC> zqF?~M!Max(uewTJ0r&vS9qkTvJVkK(yE7@}n6+-p+Z>!{tW>gJOIL0au|ue6*KoJv zEN1sS*bnIFqJ=53rn1(Ve0HireO%Y^LgL@^0J7k?Jvw>z2suw36SC^cs_Jm8RWP3w zkdObj%KaQkUWq<+nJC>fvNJuIbzUu5NEzZ{%YLSfAsWk_KZ`!3GIFb((?MnhbxJ5l z$V+-CU~O{JT0kX= zjsfxt6EJe@GA*JGvJvQy2aHp^0DLoRj08JmHg79T?QWhmPh>uB(n;LgsyGsr<0-t% zeg7pcz;J%P&mR?m$Ap*!(e>DIRm<$@K?IKzC#oH^T!ShXXTK4NBg&_&)w1dl&om|!kZdE_|S+Crw=cSBwQmh)~amwfN9+~=Oaoy7s4)qiVTr)XH z07$NiN{EXy6jre5iw5sh1jq5-;HsoL0?t1`I9}ymjF8fn<*`0*Uz=+1)0^9r9cnf~ zpIj%IAS-44s^<7~sa3%heB=JV4sswMU4k^C zq9CCoq`RAel!%0MI=XR!gycY4KtM`Lx=W;UNJxn@KzcvE&-0w~`*-JT_u0<5uluv> zeZAhVvTSC#2mO+F7hGHHII3db-W3qpV`2cML*Adl!afzsP8KFey$9(jzK&zX18;Br z%8Bx04^l|aVXnwNEyJso6qK_SmNRASgqIB#mX~v+AbGzlzMonUZip*NUf}L2_k1c? zu~MGHS3s9<_6~(8@(LA4`f?;AnRtPfWrKoSW|hCCSZB+NnohYN_@=Kmf9N>8=l-C? zTdKUYnMuh%JlPN8=FT%A^?`z%{jgkmzPvJ7F&oGNeXZ3*H8(n2|b8XW*zp$1Bw2K#6A zPFW4kEe$S<4X$Sm?ktTjq#M1=8+`&B{TA!YI~l(Wm{_QnumKw=#DJ7y4GxO{|E#9C zmZpTorlhkb9LuL<=}&L=>T<&XVbTp`9e~L9fEe>nc$Ve@>E=T7=HkHSQuBKIZ}r@A zbV@C(Y-*{i430oY0d zvjSThr2$~E)|tSzxvaK@mbRs=I<>%u6{L7=B(~m?hVG+K0~w&L(Y#@5vF+fjo!HX0 z7T@^iS?e#MR)sIkThgD8-vGHgYuI#w;qfhYi+~@2bs$b!i2LU&1DmG#&EUNb3!Bfw zjZNq8>t6?U(gr>JlKZ#Pu0lR7K2Y)fQu&WTs1ve=1tLA z9qz)tX);4UhZ$p@0T?g<=C8o6KsV-(~DnxS1d`yd*z%+lBfNLml5bo~SW4 z)*-#g)dJN4=D3W`1@*yXzu@<}7^~$LRD8W4X8nqFW|K*rv3D2JTr-DFsheTHIuups_%k zsGN6>E%rt3wX*59EwN6j5jP1{=BL;?nRD+f7m10$Y|9%@YMjf`5f&A2SjP$e)w z3IcqB0H`|#QL@ueF~HLwGeMU1olCP=%|`cSl^2Pf4QF3t-p`U(%!Dq_C0)#=oOORN zx@m>`s^LDbp#ykJIiI~epR3s{2msaXH!>0d?J*DL?p zR?l-5UtSI5_~p~(RfrWKbQvT{0I6~k{!}jB(gEBefY@l(U{-5Qi7S*zi-Hp%mK6~D z*dhb_x17W^zv49!cQAML8jI*R;jww1mF32^HEvFj2ob~@@{o^nO{9I@?Bd&Q&Y}o< z{mu%Fkj{qC1dW*chD`g0(vNla%22LOkj~2DqxL!x0Qkz!B#8UQ?6jeLuqGwF}PBb2blzOt1h+Ul0H`kQV0n(TMOF_3SS0pS7|&rTa;wQ&Q#aUZwyQ-n7Ba%+on zdue$aN(AzvcVDsZ6|?M6XzjdU-(=3%yej*E;=i$mtP8H}-5XmI)B(+1wRl&9MDZJ< z?jS+@x4Tt4CAqt8&$lt{+w4^O(x-QurY+`c>ItRa^w6u}GL3TCphtC{r^1XlN+jU1PrU}<|jARGj7|DWe*no=cV&LxN41k zGIq5EODE~UU8tF-nkp(%-L(@J={#j4Si`+oq4`H@vL&i-zd&_{J(WIJ_Ny||+Y8$_!5c*zE zfXRMg{*U8C{^M6kv2SiaohnlW(W||=t12{WFs{Ws^OV#d;WX)Q7P_%0tbH`$HN`dk zmAu~>XD9t$v{FGsPvZG$nxd8^Y@`E@LL6JyZ3WFfV<>vy%<<-6_5Qk8g4 z9O5gBK_X5+zpt*6US?_xBLx8D`?2-;akK(lOUcLlkn0q0P&|DGPM!I-wzvT*il+d% z%2=Q3%`8zdRX)19DZTF%z6I)zY3xb<(FI<2OrMq0cMXq6T$g0rNLBQ~17Y-WJ%d!< zE;Vu~{j5@3Q5zGJZt{Zf>wc@{xp%!7euMIQE|--c6-p-h-eN$$tm@=@uBk17GsXAd zq(76b;!}U-jj8++teaT=I}uct`f%FIOB;vB(c+mTL?Zoi%Xd>yS<_ zAL~0bxdCgaHNBS3fSXc`5*Rk{HZ(H#rdPj3FB8{cOd?;KL1|&QAcewqKq!stFu54L z(OeyXp04{@O|zL_KK45Iz7zE3wBK4p?|u7;cjmIRauMfZ%RXGKw8?9c*L%KtL(8Tl z8;tzcQ+=%hY~l{) z?bu-Zm}`0BRG4Da{4p>cMtqVg+U7NLj=v=FJC^$@%{a!JitP$G?!5?bsU5zbC7)uR za=1^z0Bm?Xo?7y+W@iSJe=F(v#zv^*Ao; zAoP2~RfF@NgVLY5pJsmlGzY^&!Hu1ZQk(ty#=+hsR!26p^=4Jex6r2?GXfg_W|n_O zwm2GTDCaiJ38c3jeZDp%?Yk`7*!s`yG5^wDW%|F%K%%)Ci+y;v zWBo~1!B5lOSpQ7K?!pN1}=*rwO`XH3q3vKd|56b6cwZn6|6HuS{`?O{8a&< z;8|V3WMp0|NaWg2S)dF)?k*Zcy`&1_M9HQoe7~T6retS(ZIic$W?>>WM~?eS1@T$H zK{viUnTzrdU$4k%Vcg~V8f~|qk~lMe++&S*8hxeh_xp5{oGZ9kzRx9VZtC*bHb3FG z$jH2RseAKL6OaqZM9a>T3=gxjyAgax5iT{!8zsC!i7Hc3bExfLq@bpi`U7^G1e8h3=Dz>DJ`ys(lqcTqJBw=Hf;%=Lh7li;sTx`rma4AnGc2)X%XI=aZT} z(ek^j&hbfbl>MRl*?&bp@2tZ5;mL_MmVG=A$m=9`{oiQP#8*7|6`_VYeH?k;px~PQ zw1UDMh}h8qWiE13mTeY{H1bYc2Cf3S<0Y3DYf!>@H0zq=GpU+)Iy)lXBxlMW-5;itJyEE zl5Q!Jp8Ivxp0X~sZ0Zxewe_T$S4H~|ZZ8oNiyK|hP! zSW@?fPq!Ll|5+A?TnsB-%K!ZgPIC-O6~KV_<|2VN3&Pm;36*?LP*=w!$|_fGt?b34&!e=F0Y znvBsA-a85>BhN&2GUv}7!~@^<8%BBNEDC?;dNw~6cjFhyWsUinXNILWh^ zeJPX^&$)iFT_kQcjw|-k=CRyTb2Ph|ZuGHOHj!5ArP6+qtkSB6X@hJ0*MO?%dT5>n0ZzKtY3RD?C@qG)l_wcrbF%UFt4uTN)`Mt~<*Th|t(UQCMuaJP7#OIZtzO^voyi ziPV9oVyAM57*xOu0FJzcrja7jP!l;}>`cMHE>T*(o(`xI9JTid{BJP&7YF-E5O9P5 z#JN1=c?F0ik023F(f?$`t6#}p6M0IzwFXhyCis?+lkl&7{eF!fhdVM5fIRbP zl^L;Q4lg{}<83M8yi(9!H<9wi0B}M78_?CO3klVce;}oc6)II=bo>cC8nwO&ei!>j z{j+p!l!Qw7{?}&EL>wq16yzQ)q4E%i!*aPtgSN3ZN@bmPf$Rehb3Ic5Jok3rGlH^j z+(JdmpjyiI5FW=dT-z}+M6B~bGzi}*kO4aNgzMl#*-&9$7b7dz@AY4$Zo*w$=jAsx z>ffpJMEz-?ZM|_D3sesa{UHQ+K#as>0D0Y`CHb)oJ)L7<1vc>(maAGhOl0LB;0+6f zD|=lC@``VCL|n9Ck!w!32&s4hAYCAGk}lz z0lj+&zGEQQKy5#GG;tQFCo%u zr^e>A_6`PWELd(qauUY^>zY%m!`DGTYtWCVt&-%@oixhVUb6SDE6#a1{ zz}oO;^Ha5IeT9z}8g?5!88M$!6_B3<0PX?+TJ)9icewd#DPxsy-w4$OwdmF=?n@VS zM>Mw>@brwR_qmKxYxLz{H3o%Z2lo+Q=QU<_M$GSMK0Y0p_#3Lft3jGl9PQE=RW#G= z_0pW(r$xg`w9~@t4}Xuq=P4GkGHU+S z(5^k#+}Ggw(W*4HKh~q6MWh&7V;LV1)}}VoRyWf=D%9G8j2#VY{n*f&{;M_9s(lVg z+}hCQ2$KRpC%!;NfwD#83EB`@Eoi+qtZiWS>-c=c#Kr3?5%)Nm_c&k^NSQMZsT`*k z8AdIu*e+_*ig0qEr32jNdD8YG~WAY77RPK+=Tw|BHwX(&5-QbH%%1s5q8 zgB3}bbmoi{K!bD~MnMBmwcU5l7a#qHNiyy~Ws({1)hJoNtQSF+xIT)mi(gup5}jpzR1D6#T&;T+dyVmk{+5AMJz-?-uEM zT-4vSKGR#7$5I-mT4$CX5z5IABDqb;u;YPzrJ(S?q2o{xm1Gz_Z2@6`_%%g2-2%nRPO<@pu!FfRWhaqoz9i_ZxnK^sqT-i za7SnsXDIyCWaX$1tsI##5*m7K-Ijhvr&4{nZLD#7KCJR8=m27{&bD8EZc$up?|@DO4Os zfGj3o6nFbh6-O9+*3Ki>(%J}2#WoxB1lGABj%wf+)`{`nc3tK*7Sy-Tg@uvA3h=G! zaq%v(`+YlJ3SyQ@Hyb!ed{MRnm+IB;ZS|OK*k!_M-W7fNGjwZ3T~Va#wrJm-hw?l( z=Mvwn9cVt;$X|7B1y-E_83{Vz_A%CD3!gXR8t3a=JS|Tuq@3&&$hQV~@7uiShrrg7!xEV}mH?UMQ{Mo+KNkXqUX7kCxr*V<#`%bEP;<*;BdS!R58f zeId)8z3T`GW8t(m>Eo$5P^`SPs}jxPz+#gy9Z(D?5Z~!_40%8d^E!^Ub&uBd1N2-* z2NA+SCecCLQ4Rzsq66&P1a^%8P~)P42H>VKfSaY!LB~*6H1xqX)*g4wG$YI!AMKBe zx}jrkR}Cjg%z-_yE)tg3NI=xfM648lv~+d2_kfFpj-DMJE`@_t;vx@jKp$XS1Dc{= zYW89zf7r}5UrIk=?%nCI%F$;=8fJtUyU$7!V8+`3^Xh2+P1yJa#D;%bFedCN5#)-7 z+(ywN{2))AR>Zdz3`;>qCh$3{D2o{2RwZaO3*@B(so#tg@B<&WF9d8uxKLrWKca5? z0W9YtrH^6g(oiK7OyW4oMlwt_2FBsOy_W{|i23=TG+KB2AvzJlEDSi|byEtS|0A0F zb^VJgKh}ZMfXM(NB?;GE?oua)4dg@z#Y7pfM$$+uTKa|hP&~TjclBs^bn7@u!W~44 zF9I9>=%8W@(`Nupi|CGe!Tp2y>6yNGOqhdC*aN@lpt*xY5x6pX+7}h|t6Nr0 z4B|Twu1gCu+-^5A0W%3>?@6}qFRq4(yqG~s-<+G|L-Zwyg>!E|d{pCkWkeIt2>TWP zSilb;`m>o8@ra@{)D->Wff!o+dz3O`L_iam3-S4pZa7snEY|S3^lBH|(mYc}q)i6Y zDkJpjxgg%L$0r%);|`(rTQNreI57Wf%~ABk9l9jl141dPRP4lx{;b^csvX=)0(2+o zMBX=X*J}#*a*t#}cWVs*JQ!g{w?IrTkr!JqsSKDR{;%^f=&{-8J4IUrjLFW$!w*U^ zclE~+EWD!0^_rmO+o3AzN{xjoOlF_xAF0*~E=>= zF|=XQ`&?x}oZFvW#Z|5Wq^v)QSixi8O{k{_(=13+b{}-;JWoklFn9GX=xtStZFh zg$aN7Ch+pnv?3F~ost1i0OG{`+fHnOUWs0%^P%8Og<0c^AG?P_bJe!}$s*5=gcs^e zy}4Z$pA^b-NmS9}{~e6JVPp3c^P2k&r{a*A`$o_OA9SVN5Fj;BuxxS_Dd3q;woiC1b-mrtG~kJCoYM5A%)*_W$zq*%wN=m0?jI~Q`~ErjaVFtj;If<+ zLR({}!J+Skm;p_@KppHuK)Q)`8i=-abi{YsO`?tv~jw z-%3R?pFg}jKmGUT=T8#JaCU7fO)W#!H(W&aLzb^@+R(hk!D0T)|LJkqIkV+B0TKi!7)By#{2jNPR?0ng)-sd zI6sDS=4PJW-_axPH@a#McvB58m08o=cxO;b+I5B|6by2HBukt<*$HRndaUWqWSNNV ztz@42PrvCKE%@{0`tN??(=}~?n=0^J5Q}W!r}X)6V;y3)!kt6lc3EyoF;m%x(}R4) zZ=IV3N?OXk^U1$nCibW>+f0RP$;fQaW9$S^%bz9u&RBk@EDy8Je$(e5@I2@ARH(X> zjAg0>uhj6`gJ+p&RBoHJbED$RklFiEmzCY(b{h> zh*Hy+N$)&UqenY___h#utNjF~d{7bhNuttvpUkEB^_Q+;u*;v{<+r*irO&HP&h_>z zo5AKmHIZ;Wjaxlzf#N^5O{?hLs*3zcZIMxT@JjNB#{^602D%DywU?=1Xb z_|Dn+-3gz`*3!WTEYIDmel@hZPiRVCh{q|YBZyaCQ-P{b=RhO|9?x8TW=p-_-!P=Qug1BacgVbD$2UN^W8JBifP-(yy|$TW_ZPYH~fQ@ z``&}kTBrMMXP1>z4Xe3lUt02xrGF2Sn1g&87d2(Z`mD=k4yS)2Wsj znU8ndI!X_J`S4Wt)#rx`1)ht+r@w|@ahx5hn>^hAv-g?w()H*puhOicw{7Rw2P{lu zm~eccq4Lz&i}< zpSk)6lee+LEjQqY{3<1niT(;+9Go8{2ObZNgdm)NQF#=mJ0jl8&QcCKzy3MQvQ(NS<)`+go}I zwScB`EXwv+9Y*%??Hc!%2uT;K+#r-}VR2J9r)>1Cy&KnxaIv_D0Ep3|Fx|BW<5OE( zsm6eX3KL_cmp_gAzfcQWu~WI7xO0uN6`!rGSn_P@L^*x%W6rNaKKT#nZSg&L@XgrJ z+eIhW0ywcSWyWMKZ$5gO`kOflYy3JLDNU~Q;<-OH_|+mCCX&Uccp6%Zvbt#vGIRZ3z&FA>#bJlNk^%nmwaPGpC5sVr8Ft&%+o?dpqH~$*ZlP= z8R|-{evIo%^i2LnZL-rwvQiW>E96}cl>3lcEsQA1-ZX{OSDocA?FQM-1fm|_Xo<+z z_KIt06s&sx;v!au^4VMI5{GJuiOEPx-p`$$1Xee!DBs!A5GgVlen0!$=VR@~k6>X~8rd>KW5%?LTMGHo z=BZMXwScIrXZ+H}QQD^&%Ejgm+GP&5#`>v?1EUW@D<2UQ!ZS-%*kp5>YZ5~WzSDbL6jgtg&k^plDLFqC&KH#!>*U3Z`XytKZu_n;UlDyn*r$6i{|@{`+jGEDOshiHBUq| ze9Sm=u^0GgI+3)Mn14fLM^z|b)Mf1VySs^Ls-DeX^;RG^#X`5|4Nk|?T|XA0@$*K^a15XO+6`K3guzTA^CP31aZr0w9h_O4f%)<@2%&q;A_pIy+c`ZVRlL{?V4 z(`0Y}MSgwETTne*@tCc;XwtlJ|Udx zYh%PF`a#2^f|k_=-GBA#7H|ANV4&+pK5e2uenyr+35u^j>J;e3YSMKG%pb*O)+{(h zc?K=K?mKLOhImN#w-|eu*A|^D|4M!Tc#?CxF(aBbm0@mio^RYw#Mq&)zj?W&h=?Ut|SI z2xy}eb@3gi|Kf8{Z~Ia7AD{~jmT{MB{p|jox*9#htiwZPfdOAHEe1S1MpBGeU~?Ne ze?e8G*20tjmIMJ{qSZ39uP?8W`o^2T`{qe+KM#)*Zsq3x$loEPMj|uLes~CV@7*N_ zz{K#Of*9Pz{ug58vUw;OS`I{CfQwwaW-a&;-hJ>{?0n+xs@9E8{Ctu_oQ)d@~WQeO0{3j=yqGfvi@~9^hf^F%V|Lbrox% z2`4>f^(9QX{A<$sW_H9jY=9^*NH=!Xe9v?0~=gu1o++ws)(dGitOGTb$YoJr-b!R!jDqA$* z|8q^$SCioqD{#-l2tXU0i0)A`uW)4I)tmnHgrFtvda< z7`8#r2Hs*%)N(6m03b+`;TWBa7X`hblV;dTmaYnLf+d9~ACzAEtVq}7!>D?TPw2#l z6X^YIEt6)tG-S&=koT!=b+J}oNVaZ+t8x+J_nv; zBzT`_(M*pXi$k!YoK#MYO3IZ{JJI+M{>SlEwbbbqx;-L^_p2W_S(%_{m;K|OGTofb zo@!{mLa9)2)Id%7u(MsN{4pr-^*B7$T?H7=>5vFy_+3VOcFnCPo zLgmFR$03Y->?{7+{%}ENXMeWW^4^)F67F8fwXokq0j@wq2uUA6yJK<&TxBeO@|<=T zB9ChSiIVn{gL|bbuDA#lO-!l`r}N;9Er#QjMB=L8NiETI4KE{^rt9?4~6@NwsJ+=cm^bwo$n;EZ*rt;yZmH;^^J`PgE zbhV=SPKL;LTxiIXsSDT4FmxRs(3#x7B46tSg%o7O@kig@EFzVF)b<~pM7pDD-)^v#>mZS8i2yKX{4|fJ3)ouk+@4N36+*TZPZ#I> z9rdvXDUx*!!9n(olll`ia=DzG9+rRqk_{?=lTS`2ZSVbb_;Vdg4t641{lr#zK@8=op`oe!2SL_$m=lS2(epu$ZW-wJkd?vi zfu6=wcFtXE8lh5Fwo5Z|zn)An)Wc=A#LdxLC6FJ}ZoXjws2UGVrdG!g+Y7QW=+7t_KE?YJs<6wWIx`pW~%8r;`GIvEJ zT?EjVvH}BNOs6t)0fXLl7=Fl{1yNuCcDxmKeD9~)4h%sW{2dVS_W)RHJrKl*b`nru zm^_-QhWnxA7={6v_h;&=6Mv`)^%;LAQ7G16MX-)+EM_1@qlOMjR~cP%z)dl9O|u~y z{K6bC!EM+yk$AxOZ^$@I3{aiJhHwfNT0RK4o-hSPIlOug*l0hjS=IayAQT-DZ-{R- zK6C+FwXB>jT*usf`V)O8esPQn+y0NT8vAs*Gqg3GGZ89+g^v(m(gHfyZ-D%nCQN{0 zS4_EkRk*~64N5bK^IB6CI_+$=^|GOxU+b4eEw~hPoceKQb2rRTW1Tsg2F=b7pbG8wB)YaH1W4LljfP<_nk z*Vwv~bu!|l^)b`53*=dOLK=PO>IpQ^!7{Ysq3&ZJbN`KeFZ(t>M(^R72NyAy`|xTa zMysyi`slWj^eK;DNL?YH=8l^A>14)OU9rUIj#l95S3FgHsj}v-Ue@VUsaAct@#wBm z%jtA=QhkM^=APN&=}gmDeHHwDn99%7+1}lI)zKGaa_60MGCU2nJB48m(k-JCNe%hw zn$Nc-7w4zPe3Gh`U7iOnqL+&QH1@OQxTl;gRo#|oo|U~W)snSLOd6(k75nMmf3~7o zCeh}G{Tafy2?J0!eTH9N3tr43AbbZ~g9+i`f3R>+s9zV~!{kVb>{Y0rU!TC(uh&dpX8_vwEko+o^MHxe;V^0`;&Wi{vA!-JQ1z+ zw;*p`&qyVpBw@v)Q0SuSUTMtmjU;gK>eP;r$*F;92(DbajZ3n$Sy|lGTTGsRM^$23 zFBFY?&7!z3#E+dLC%j-sgu?#z0Vy8J`xt|>>ts|MfLesVC8yX`yIDUf25nq)eA^1> z>4UbwiST%t)}LTx)0VE)?q~h`L^`fkxjL<>;XjxyYHOKw_&2}MeFEVT9=I&vb~4Oj z_Xl)Kx&!?P^~E!;tXQILH#!g8FJXbmO+Tl0qNZI6wEB1OtqmQdjhdvscbv}GzMDu2 zpIt?NJ8uV){yh2?G^W5|KFM*uH`Q*iUt)FE`yEJ?ly^>iwR&Uo(aXQDQKyII)};r& z0mS~`l}3*vWB<|bK@AN7kWP2l8kPa*p7Bp(M>!b$>!s|bpRKR|Bf!gF5-&x*ztE5N zU_SPd#QWdA?rwA4=QJt|3UIgi7xcal3kHT#ZiBCLh0+>p(r>?1D+*2R4`n|F|LzBi zyZeeL`&RJ1q`V%cIv1f;>Ms-n7Rd+{^9$ROc=`wczK;*M7Xy~Xg3*Ae*T#VRDDSU# zJ;kx%P@St+AbxzF;xRAc`+XMpP@axpOG!`2FK=-tlon%5s3eMAG6>8S6SEy1Ie?Aj zkBJ~P#aPXSzbi4&p95ca1iy9+hoYjya1o+#$US$k2S4gz$BTh+iNqmD}eA9M>oIUsv8rgmv-_D5al1zAwL8hURuK@{faEMeiG8KdDbwb8r zkzK3HE@=qyYLEZb zZxf_}0*Zkj#W2lW)FF=8sL5pN?;qL>cM;o)BoNn`mT+!Bixhm{%&{ zIF%r#FDX*~H0Yg3#zSmef-l+ebWOzr3cNYhn%EinKHs2 zWOy?fh(sfUR8Wi6sBr+;;22EN@6N3P7VVEpeacK(8gaN4!K&h`IPk(c-9uUh^^zYY z>mO6!loA<}Sy!6LK9E@{5c|30jXWOe)R87~10`$#=*Gcq{9za!m_0Go=0TbX5qec= z<%oq@&8H5YWLxf}+D$;s{nIe0oH-=ysVeNtN!r{=4uL868|gvrhH37Wf9|$wZqx}l zrYu0RDGMS;B`%h!e?8NW-=`cApE`(oH>g%?8mxW~X9s|3zs)*EQA0VYuTC;tR8x9j zU=GAoODxP7pXSX3#c-xu$HE5RLYMrrn0C_~=Tq%4(6zVORy#RMZ*zqg3Peu}#7=Ye zVl&`e)GR>Azi54ue<-jVXN`rSnBnV~ci>QJa1AvTS-w?SjwKdqR|d7lL1#~(Pv)T* zEX)!EwVuy;`k=@Tm2NMV`*kpNlEx$(H1uFw8+{WswS4^MufeHg~d3-Eb*z0r1@+ocbMx{C`BkV!@%4yP@A|MBW#h& zPR`RSLW#MY@Tr(5pA2NfDt)hHKivTAU*a!S2)8Mua?Wx%ftmo2dpPQC48j!ybH-5q z!@u{!!+sK}PHvN%;bFUI_!XGDr^A{{gbfe`LBFVab;xQ8;Pry#OAD2bYUSjec%=Xu z7e3V8SgfR>u8ucY9t)jCrUsf7ehcLbc1|zg;6$=Kt-C(Kpg%S3i2NSfRg4Qz|>atk4K_i`qHOX1?N+ zSn6^42NNvJ!2Rko>k{#>d;*m-9`==pL@kn8=l~BV$aHq0V`wtp4(O6Qg+DV~DuV;P_vq2(`2;{neBB6y= zz<#UUaBl2;-ox2XUjqx@h24Abgz8CIj_E|3Sv4@ioyymps+<6$3xIAfB3X3EyQ@Eh z@4=u1q?IYmts~zGSJPew`L|2{1qU?~%LZC>uS#`@JA2)VhuRTg0SgUKk2cWj)~n9i zEKJrWio%zZ3`!t((}9H($Xs=(5$bUGd)N}LWfRlo8wj&;{v1O@-~cdZ6lFKMi1e)6 zd8uGr$VeY_-1|yyABpjuu z80AQFuQRrE7zq>FZ?fW~LeNtB<657#_T^gSKF_9$j|Mv*$2~m`dx&YMn5lZPbmy#E z?e2h(ZJ{^DQcNXRx;E6O_`;fwDs zXZ0du>i;TDNhP*eJaqsVUc@BrfA}P?8&0O{WI?h z3;cZ{RE7a+P6uE`k#0sDwLHz9jV)L;O&c5;A!bk9YA#;9o^t(mJd<(WC#U%8zM)6V zsYY+V7(Xcb;gYr%lzT^`=%8YPXS5I8igaPlJbD1V2k@hiW0tKMN2`FXJs_F!9@YMQza;jJiH1u7gulvp0Z}eoR4J@aPf~O;o!S_3K zwGFeJ=AkxZMYcJuPgG&DvIVdoUw~{QtV7u#*-4k>5x3`4;+nH^Ik}!WvlFqi0Xeh6 z3$r0PBjW-F@~Bt+{7GrJ#Mt13?YV@(P1!gUs)UzI}5idGS300k} zrSt(~1D`g6EjLGnFpz`irXe{^@`d8@_dEcFo7vt*fRBTu!L(PqYetytM}pZ_`)fJ@ zMQ$r;159Zq?l5C)(U|F~Uwa?Wh;ln^({ksAxRBrlhS#_ZW?c?3#v%U^E27-tQd!g| z?$o_Hr50k8l@sk21gactjdj(qS_fr50j9lPF@%DvVPX01)PJj~Vu-MjpxHdphJQtn zJ*8c1bQ?T>S70Pt4Ubr=hMNEorsPQ8Y`80qvaPHxsim=FtZ5%j(PIU8k3m4IktTT9 z0gBQQhuBPlhU3Zn(Z#du9Y^=b*mWqEbpTpouBJ&@@O%tOEd8178_yG0k=nIKkwS%>s24hR z^Y?#w3Zsoy8AE{1`b7nYv8L4ZL?+26<3r|S9|md)L|4lEJoc#qZ?GI3^YKp3f_8C-lq}rz2cp}ztNy|*(%9}~5eK&t}X+RU<7B4@rgx&1}Ru|I*n-@sf}T32JBOpK9x~szS=5-H_9V!xT-|9( zE89JZcfCA`atO8rS9vlaR{kjFh?smhmoq;noLqsH7pow=FObpY z=_V7m>n3>&39)#KOWeJYT89Xad-1MH%~2Q^6@Xhp>G9$OOMs#dCQX3rX@N} z4h;=0Qzr)vIqDB*5cj6NjjaL?y^XnQOVx}_h2-gV_)55aOpQ~6Qw+;6JojfDQ+f~0 zT*^+p&0Sj#j}}{R*4i$4v~f3D*nE)sM=m$dD?u(do9MeFy!%|j%6EL)cQyFOW}~$q zX?oT=bd|CR6F{w$feG&PKDLRuk(L2x$DzL2CfuFzdy*u5bo}IhxTa+F`zIT(c#Zt+ z)6DOu*k(LQ^LNO6)^OsG?K$J`m>YO>@;%#*L3Dm_thxydBdX5+4H9Lv_RM9y@oT_);}|WZtZ7B zXKo$f>p|{aD?8W%*wEZ@)_q z3D|w#cp0$&aW*9IpyfZVsr&lNpx?t1q@cfFjb8>IE&7szkJr=xtA?JT)U%tFN z`$xJePSwGJc`!gqKQ!b(^vY)dyCd@kjSx+Q+~WiyA+%vA90p3WL6|_JNMWH<1jrp7 zIk=`%9jX-%5atIUw2!-D^6`K>5jK?Oeex_@I?>V_Hq^n#3Y;+A7zG|%nnXWEo}0R{ z|F66E3~I7n*tJ7KLJ}Yey<<>BkYeaXz)%H54NZ!a&_O`~(FYJP^bVnSq=SMOq(~Ek z6cLc#1*CT|C{;vup8c-bYpr*enQy+?Gw}7{bD#yCG zaKjX8uSw*luby!!wb$g}C~9@AXVztyR#WUK?(TcTa@8=sdD-zw!0`<{#3-X(&`C1R zSKmR%D6`kWNjmpf-$mOfYoypo_Lc8Vw@oLb>@Uks^6!psdW2JZO@hvfpM7t6Q+rKY z4$jnt9|wt z&o0;^mJcp8+Iqv8cNiIf)Y`ta=V&2(nXSqPY>+-}9MljkvG&pw_exLuGAkNx8fJOt zW9QgMN4Cm%`ZR34(w$BkEY#(3j>Xip!rRuzo}Q`q7uPK&+Gp8bhZ)^xKgd!LEtW+8 zGyeJr45Xm}&;S4+pc(9+FB7OvK^@@Y|4zcFm!nhtuc;VoGU4A+vEKA6$$~+^f3^KZ z7{JZApkYFvpX>aciq%qWe_SujqU^wWDHS&P_hzXQMyjf`J(};v-?qP7F)vMG{@1Ef zK^lKy4`IOk->TAaKm31Jl~%}D0)m!%skXm(AD6#XrC*~fEzz@Rfeko>uUric2)V97 zRh6EI1W&xBZ&CH&0RVba=+5gfx4hw=t)r?+tA5tmt~G&l4y^{|fg9jbBj>+ue~GUX zzn%rEG94aLC5)zfRxP$q_o))bwWGk+)03m0TVDs>zdxhe{)FcVwCpbPK~SOc`CtaQ z_4yE#w(vqI>m8ScFixlPg>c>{>kAR+aN)&B!8Dh}DB;rb#b~km^~D%Wm+(@o%(%-^ zoWg4PQoQoP`ceWGBC<@>WOrRo)De2IoTM+ev7C(47FkI#zT>)*YUcD}CC&25#!5Oq zTx2!FAxHp$o9jhH?aLd*DR=H|lw>%)+$ha?vbj-~AAWhW{6FT`OJ8ojtgPSMtRQurUEZp! z9ly8rs$uozR#nTv=GJR6^=w4yV86dz-7QqH{iaWDYrAGpTl8CP{46B|D>;e-AV(!W zz0$lETH&synnF)y5(8r%yk!ooAU4xZdEgpXRa2^(C=ypwLX-!;fDqvM`S$uPcJGI6 z$}=8UwCT!Dwp&4t1$ZRu2_b~6BIZVE1J34?+Bsw`J!(+&f}X*wrZXW(t{5>~`;|w$ zZ+iRFEXkjsrIn9*F)Wpy1ME>buiwZm`Oo)@(DVHqkfOUO{RzzFjvi(e{U+UwHFekz z=YPs;JH&E`CidTH?yFT(p|^T6@*6R_&uDXgYy4eFsMAxjH}VkA`G+1x{9kLYdB z{dJ3{{woVzsE~!!?-GBGmcPeq`T*-5;E%W8e*beq`8jv;;aaS~Am;%G@%^b4@>&aJ z!HZX|sx!o+VC%2M3jTw7s(jr##&01co$4`b3Lo6DB(*yR0PXY{#tLG zJrB%4n=ud|-^3UT8Em%v2ps?L!My@7u9UIrg(3C1$J1d^Uz*Rtotn$u-FkdaV{tCU zrQ-sBamW@=0c)9#7AlQ`U&Tk((JG)8KjF}_MAKym5Hk?4i&n%y8C|dngV;o@No*1C zT1K-dLemROrc+y#B+9}U(BV`JbWQ=S#QlR98JeRjq=52WPDG!gBNrJALur`|u~Ey} zAEg?bZ+ay~Ua)nb*=s{7vum;g3nGFfxbknqKPOie^NC5jUJs@eoevhnvcUnNr~W&% zOuyz4zUv@wD+a5T%hvB>qe7x#uRYa|%$i#06#Ps^>=ns0^k?8}--D2zH7WMujKK+k zDK&sZhe(vc!t-DQx(pQaDx$Yj-+>tk?Okr`%xOGRUe_YhjVg1#ix$D1lj*nn(xE2* zo{pA1_$P5`lz7z!G(Z>N5vPn6l9n~C>S9D%ox$yBY;~&N2Gu%F3JR$p>)&`;#fFKo z+Ke$j0Y$S7JiQ<4I)Tn&Hn4LkWND%f6*UdVc-B6bN4w|<9EI>v2!2;j+w_f;2E*%& z3q)(vWFE}q?3XXZYj9fzq+mE+)V{Pb^Fv>iWc(_uAI@9##I|OHfqmt;HMFozQ ze~|o?za7i4+#|)nO9R!4Y`gQl?hT>?P)#$Id+CNB=)0^e;q-zqUvE!A4aDfx`-YF# zv~MKXv(B@0^{O!(pyM@k>Pp&Kf)V^`30`L%L6B4vF=Q2)(U7&kl21WhQJE&Bvoywz zFJD7Nj3$IL^5Gj5irJ%(L(sZoTAA?f3k|6z^gtQo0VzU#TLv?+D^==aBqr< zsq?hNKy9wh<@blH*4H!MvM8g}5taau9VD^o_T=lUylo+D+J_Mg)}RQ}?XOSWZ{d3` zkRqRDggi@=Xv4>~fp(h1y%N10uMN&PiTrMi_)QH1`FNHr^)M?i2f8aHwKg3hnZkyK zh@Awfvq1GU!Z4B2IG}H548pY1{*153EF|EX0l@Y5g>!FE!Kf5mobR#*=WSBE(z;rL zm2n&B@Fs{4a!UUsc9F)KQls(%|J7x3iP1=>=BmU(kYnr}_D82QwC8gZbe;3LYs%?V zEG6l$AvIbyJ*0D1(D9F#mw5X;z)Re_jFBx zNO^}79{vms6|Aj|aj^jN@EKN(F?s=T&`Ym7J zF4OMhzJ~+7d}_*UJk>u$`0Ek0RE7hjKRn2YxyHym+1remWztRYfJh z89d|VGA5WFl|#5o$tMEx4GZCb8^Rp4P}y^H?>(>}VR>msH)KsJUALP- z0MT#9#G0?vH5YG_Mz}38Pv7PN;>CcZNlq>Ma84544gnge4fi49~NQe zdDtNqxle%%KJu2tfP&>*ist_sqbfv6h%+3+4jIObp*tWVojL4fQ4!JvL^=ifP!1W1 zhFm+F2QraqgM98wmOpt`hUmt+G-Cpqh{$Oah!4l`nf%m$0s;YREI4Qpoo|E2d^(Nw zKZ9r+!hAV3WX00gNuzb0${HLr-Sd_XSKmUiCa}yZj-l8 zr-0N1l{?x&(t|YZ02@hwBfGsg;&JHi2(z0#Dp*i?LLnw2{f2w3o0*FnyRlQWr)nGY z8e9u>6|WFjagj=@ljRd65$@)Py>IEk}MpuzUU z1dz&L`;+^7@pDT+If}&>Y5UxH{hzY5*7&<=`v%C8z^H{gKmqTJphTd7!S5ex%w6(- zmavD5*Jg~c=ZhSyxo*xFDYmZL+nOtWxInv!g~k~{Rmx93Gx)>KZ1dCuf!D3f4Q+G3;|2a#6hqDiEL!X-XFgXBA#QN-0RHQUrr24Cf%37%_6>C})Yx@=JWEJZ*73)tI-}+UI<1R5& zDlxVwx#L%2mQ`ZWRAM<@V*RTG&s}P#RO(<+`gbapReGGH;8r zCw^rVFJ7v@>|TwY6>g$FPHawl5!lpnl_`NCuQ@NR|ip8PY-^v#71?D!6wyR-JE_H#vHt;K3Cs}HeaLK?k7xh1lV&=-g;51^xMOkloY zH8mlRUptxDqsxN`b(yD^E2Vj9w#p5!RCy-flV*q6SOZZW@9%^JAK?H9Sr`A1Zr~7FvlC1alg^T>iT#PZdfSqW)Isu< z4bsB4_ePCP-S@}LoL}vaTmJQJe*zyNelY2f?tU=kQugX#+U@PPgD)N*#Sdq^C)^Kb zeb)H+IKYIn3i$+;WpevRAr3~(PpX1D?T8Vn+y<;Z2YUajBqR^SDDO7YzN#`$0IkXV zq-ZSaiO$NbNIeK_-@N>+Ul9Q&`~e}ePY9rrs52~RM6c+N9kPOcxl!%S$GMPi4H|*% z?X5MF8ss*fWyQ}}Wy#asw`=&Cog(=&Vo9W6E93Su6)FW&>ub(?WlQdV3CO zLqrMZA%zjay!PnZ$`@ki22uLmyV?sHVY>A`A60)ZrO(>XK9BFR9G)rS6pQ9z_}vgAhq$Av##H2pQ(| zqQ|5jng%VP-i$S#w}d;SzbU?W#eDgOIkRSZ`*z74LR6naX?aE;YpJvW?Pq(vM_EEI zSFu@9pP5~MrcZ3IMz(VGnMaRg_tusw4k-3}KakGZ{*6*>3tkZR--h;xUEOoz2H#4h0D50@9U*d)b>9xtokuC=_Kn-d6IQ1hW#pqcg{ES98ha4mT zA0T1ZyE*Vu<@Q{c4PyMV&P~n->-TQ1yWQz5d1qXKXRI*$s7I{M+OKrESz$5JGhSbB zf>zgoo6seNoXb~Z^!Z$2J?1gd(%Oc2fYZS5PEWM%?2{sIR@!m&PIf6BR1@PW9oX*E z33U7@RiuhI^xCG3Qh@Al0pem$Xkv!4?y!}aY2CX~4Ie8VuPcjmce53}J8?EFSC{v# z(#`qqm)TzjZ^?{RRO7(RBKKiKw>VgLRgb9WUeEf5?>bFaL4v2wVbhWi#M`RZe0_1e z`91ixTS3K_rD%@Ebt*$R(Q7^5RG87nXn`1={{q}A0{p;Gf4gAkCZ9~yyxM;#V%#=0 zo_3x!?;0rg!e?HJMhtojcJP+TP+_+EdM0hs9c@B zil7;4&jUBDRA&RYaRyQ+No$)c&mfvXXV>7rq68vU02%2$5uIlbord^~T zXtLwpJEBuEUWoo{Mg!fc&?!2)5N%pn1lSYCVs2H(KATxO2TX)qVYVVjJk9LO=$G;O zY-ucWX%c`*WxV3WUprWX;cN zNqK7-!~+>L*eiADlI+Fq`z>qmz2d8_a()N5x#~aIF)mvbPh-oL&ar|UAobkn@d`F> zMh`S-38#IV(w{E`e8hJu`7gjSP0fdDNY@KS;yj;DF7Yv50}Dd<7%0=++~m1mtwsHZ zd$)3nP2M(P_asp+E_|P!gm;L<8z6N2c_u5xwK@_6;!MmeC!!&888!mZe)H-dk|wki zKb(GT&CYxG?40X7lU+Oz2V!Ts<1X&gw&JDP&Q|C1QPOxj#x_!Y=$lZJ%AM*578Uhm z{@2nHJ_aifjaA7{uf5v~$@WWxSdW5TPZgdpo#2thyf4Xb&&1~v*Hpf9&sGhBXC4Iv zc3=4V)AH8!!uQqi+a6bcjSM_ntRMLJWoP%D6CN z2Bm~idXN>{H;xv?`(cH3^lxwk?Tk>-F1)xfzAnuD)_N!y62hVo=5HD%Is^ox|F)%` z?SZoE?lK)j5RM}JoWn1sg=(^gv8;yQG_&;-ju1XGh2uQTuLuBz$x^TqbGdN4EY3%F z%N|~w49@3_E>wsv$iNr-M3-kozif!EoQ%$=O7Vk$e>8D&`E)_~bPeTnPlz!M4Rp;e zbpEJV|9rZ(a_a3;YydvCJ2LhuDK=o9?&&;Tzd~G(Pwa3*?4Uy2bVJ%zkeZ+H`zQgxMFd7Aq+o~; zUm`S<2yY}ZOc5D%VJRpZx}f+oVbrS$Kahacya)8eEP)o5h>A)$$CY&ElK_Dwp+%@L zAu(#6C~=&G;Y!9dS~82ESU)9D&HzY|n$HQFL*5{CqnjvnOq4QD(e_Qz5h1R28^}i` zfKkD8Ot8fH1b{gaq?mH%k_vp03VH!G%S^#@rRg-L@QkHAkwN_+Al-#fJL}XxO9UUM z@_kCsa82;eOr;S?x1%zIT*(eE44k4+rz9lprPK{Gq7NB<=z%;&(-SDrN(wTGi!q%D z%OoILaYQ1TYAuCr;2Ej?qyzwL9~HPr#eXQsZY(?(M;HAmqXL^6pqO2&NPL!Q5G3LQ zCLu%30Xq!|$HLG>68t%uN~S>*kKxf2=o*SKng}atgr!iRi+K79B4QoGkVb(HZqWOn z5v>$h_8A_zf`xz3&3TDp@H5Zeo=SfkWe}w6a}b6+L8DGcHffZ!jY()F8j**EXQN<` z=NWpia4H}Ae!`-Z9hO1LY?#mdaz3lrHLC*vPoO+ixP&Oi!ndaK_%Ek@_choRL7ifs zABdoiClliGVLl|p8s%@u^o=(B6%m?3plf^sUzw->)sV?(3V2NnN;5~!i6A<#@FH{S zbpmV)#aKR=bdI}ZMeOU5vQ^BIZ;3k)sFuW%KzkENs%N+!?Bko$_L z_Ca_YK0PHL>VtaNLoTi$7o-vBMlkelO7wf{`4u?8!bkX5RM{aUFQ1b0F$tRX>uC?Z zyw)!z(!wBG54ErBldy>#CBvNWrITJlKM)xo;~0aRa$e#9`{|6{7O*ms`z#kMo5I+H zLw1ldI|%T{l&7z72~k97Cz0{8dBy4`@vWXgqhDdjVR;oDJ=UC9kD>RoKy(kjI`E($ zI7W1%vbqU~0vxQ5#E?mWt)uC)@}XRb$PPkLGxd#m!H|xjuO~s1@vpJIRouPA4Y)y0 zVfiYtq{RY7Au;BlUZ?uGoZ<2oUS<&G7>Y5_3<{KB0oXYs6lYQp4S$2bm8tA-peOPG zPoF}9DW15jQNhH`$PFUsdBPbysnnEgw!PF!G5}n{F7I$lT znsStTYZ55Xf)~(a3N(72I_Z*ne=9YYToXE7%k!lg$yUdvi~0jVo?Rl$0bUDbLJuR8 zE}Ik4Q%O-bUZtUP)yxx8=HtIL#FJjW&B`YFZ{Y&zlRz{Gpi3PvvM#D3{vj+en*fU@ zB~(03$VR0cLlgO@nrM&XQvoTFcVVxZVRB8i*%ghsTR5d+$YaH3ROWNnr_eM?aw;bE zp>BeA6s$TXA?ZuPpYnLMrc(zXAC9@MkScJrut;ZzxvWj)v^0G#%Ew!7)w;T zvQtw`)1xm(%!KMjf3V-d#m3Np zVyMRfEO?EZq!m*HWof)Mc%)4n&Sums!gL|sxJiFRNqsp)a$Wnqz~HMIog+H;Xw3~*!2 z_5Qt0yS<#U&M#tn+m%`5F|@*3k{Pyr9ATeoTl%B~FzZzJmp9k2WwK)%Oleues*YuL z`?FmlGG~x=sgh;It^W=U{G1U$whX*1xN&@AC6Z&tD%@0zupn{F;*`sBb}V;y4F8VHPGvmPVBG2RXW88G;h=H1 zn_Lf0$K#nMygqY!TTMiJPWS{2-G4XHTQCv$Za9E%vYTcybe1DLVDf3=WVHKm$n0c$ z+axiUJxOKC*&u3qxXY5?<;QlBTSI2t?hSLn;1Qx{*xFGKXqbSkka&Q%9xySd_{R@OB`Y zH4pRLj0#$Wu`+4A& z4Ia$6yEP@S-7dI2ytB0N5wQGAb5~!I66lz^!Rdo+c_`5W*#J}TA zZBhUrn|XU$w;@hgh{iK2f(>4Kurr~$+t~lZoB*a1*ke$KI1Yl%a1cBJY&!qVh5)w0 zLDv7Uer)~zX=gL&+4p^kqe~ArK?Og$|7?XJe_VL}{RqKVph|HjZM}H_k$wn)oMXF# z-EzTh-N8|cS`W04`&Q5PtjPN}YydaU_N+(;MmGCE&u^;|Keb-(SyR8b<{_Ro)N10c zId;n-0V4i>7l?#>C!xVt4jqYLQ^1}BVax9s#QQk~k^r_D1Rq+ngrB|N?7p@Aw)H6F z?1+f`6ZP!q>(`@@D?g&&^Oo?R)({yR3=va!Iwv$+(cE4O`m7CrGVaS)ly;uFB<0lS zB59Nl$OOWxb7+=G01Yvg0q+H~>R9!7gg}x=k*2PUA-IRIVF-v}4|g!jlKB~akxSgP zDpIh>f$Ig87_{()uJRcaQ{Cu})1w|k1miu4|+oep$ z*pG(Czuj%{nCgi;85fvs^4+h`efqXar_g@_A!Ip88Eb;+7J9CTF0fsUcx~4xbt#2i zc33P^@e$+)kL-}LYtRv9kt~WIww6h*mi|aAvriCw6xMszc*CW~qYo%8bp7IIv8nA~ zqf1k-RCQO(Gg%o_J`I)JF0;U@Yy74~-K^Ms$q|7@zI`@TRVlPv4 z1e0qA;G*@xt{|QKMthJ!WK_9wp|b9Wl5WZtP!-e8YSenzJpz=7to699EBD1ATK|t; zPe;0PzKbs78gY;5k}N@T86n??v(MBo7AecIU&Nf1=eR){)wxY8kGt4RTaUXqq*Jh6 zh9-TJ;%c|Pa&~ZQA3_H@72g~S@u>3tUdi@yGI!#BlFwylY<66(KWtG&bFZ#A-s_Q> zU5rVz?xoN9!|7L3%0XFF`9$)I`xKs^7H&1}z4|g&EJn;c=ml$PqT=&s@e$;d?~e+Px!$v@6{p{`u#{*sXI2h~=R6=HE*3|1 z*jUa)b}{*je`;s3Vcr8LO5f3k2umbwEHe_{>1d}ZYkIDBN%iCOCOsaFAFB#|zpRV0 z%L>r!*@ho2j|$eA_-(i)fADfHzsQq5qZsXbb|GH6waDIVtRFR1DkfogKC|equ^rK^ zCv!F1US{X8{#H0XF-0+HcjaniGj2H>KZiSS;$6D1njvqIW1pqLBnxH2)}3s`HT8O4 z_jHd*XK~zd_Dw$xA3P}`paTw}MR&E4-xHU*tPr2t16(V@K8+9?$M0Eo~7E8eoB{!Y5 zbmw0if?S^mukTaA>Tjat|-AfPCPp+%i4x9SNr7a{YBQLNwZD7kx~V?=Mq_G znVv@%4}0>v2yN_g7-rAANKY0e@JJP%PhiDJPu@Nk1?H{oA+`-7koGWLo$H1E}Wh>gjIF>JCtL_xlwFTHrk3i8wIj=hL}6tAHl%rk`_`)iOA>0105RcH}j zGW{e@2QOekQtJ9CXo4^oE?|%RppLel>bY*F$2n|vE2L!|g_$8JJ?xemj!TIV z;Aw+tD!gH%?otcAFLu2f#db^FTTR$z5UBphkD~Mwa1R0-g0 zS}nE&i`{h1e<{6K@7xdw)6WRbHY*uBEE;@V>1}H?TVyTYoVp@${ahh9dX!D*wKzzl z=YC>h`SQ!nZ@{NFPOKyHiOq1Q>HxI5>AROEH-E42W}+-_0qNe7@k$sk#u>W-@V`tX zU!%r=Ml{y{ix|*02%y9JpP@;1q%tcf;D5w`7jFOna5Q1#P3eD3B%70#b@H$w|A&d> z{|rt37u$FLe9w|1H-U83Jx_Qvmj ze|NN6@xAr;0X6ai(1}sVv>a465_+kU@_|8qo6@fS2EE(CYU;Mz$?06V+r@iBe+7n) zV33LsPjU15q*IL}bYD1E{3cR@jBoFgnQ;60Sz)cRhLJi7{c}L|XZ`{Qi@ELIkj|x7 zd&Bzj?%wQRg24VLzE2@(J&+d}vzZ~LYfCP8iUj+*u3&EFe`4b90vR&j!Kmt`4?2;?=G8wg1e=ntos)(x7 zyDdzDg?cf@$k^=<@hj}-94@E|pt_#(5+2i^yVcULyVOkuiThg`f36J{QD?*7HSKRr z*4+R4AG6`@F<<}ZHTVC@(RldBX*IFE>CBPHL^t|KM1Qz5RH@ImbD`7R8C*b97-3 eM~s5i;x79Q7J;;0nqvQnL;P=;@_&E%>VE^#E3In) literal 0 HcmV?d00001 From 4702acf2e6f811d98db3b9246f7d308b785f474e Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 20 Jan 2022 23:17:06 +0100 Subject: [PATCH 147/193] Add BF lua logo to readme --- README.md | 3 ++- docs/assets/images/bf_lua_logo_dark_mode.png | Bin 0 -> 54611 bytes docs/assets/images/bf_lua_logo_light_mode.png | Bin 0 -> 68844 bytes 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 docs/assets/images/bf_lua_logo_dark_mode.png create mode 100644 docs/assets/images/bf_lua_logo_light_mode.png diff --git a/README.md b/README.md index 9492e11b..9e7dd41e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# Betaflight TX Lua Scripts +![BF lua logo light mode](docs/assets/images/bf_lua_logo_light_mode.png#gh-light-mode-only) +![BF lua logo dark mode](docs/assets/images/bf_lua_logo_dark_mode.png#gh-dark-mode-only) [![Latest version](https://img.shields.io/github/v/release/betaflight/betaflight-tx-lua-scripts)](https://github.com/betaflight/betaflight-tx-lua-scripts/releases) [![Build Status](https://api.travis-ci.com/betaflight/betaflight-tx-lua-scripts.svg?branch=master)](https://travis-ci.com/betaflight/betaflight-tx-lua-scripts) [![Build Status](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_apis/build/status/betaflight.betaflight-tx-lua-scripts?branchName=master)](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_build/latest?definitionId=1&branchName=master) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) diff --git a/docs/assets/images/bf_lua_logo_dark_mode.png b/docs/assets/images/bf_lua_logo_dark_mode.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff9afa400c69a479378f2d5139c498ec249c589 GIT binary patch literal 54611 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
      *rMuZbENLRyYZ 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

      AQi; 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 BOtAm} literal 0 HcmV?d00001 From 9523c75ff4897c98c6fe4f921555d85d83cd0849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Daleck=C3=BD?= Date: Wed, 29 Dec 2021 16:04:02 +0100 Subject: [PATCH 148/193] Ghost MSP support --- src/SCRIPTS/BF/MSP/ghst.lua | 28 ++++++++++++++++++++++++++++ src/SCRIPTS/BF/protocols.lua | 12 ++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/SCRIPTS/BF/MSP/ghst.lua diff --git a/src/SCRIPTS/BF/MSP/ghst.lua b/src/SCRIPTS/BF/MSP/ghst.lua new file mode 100644 index 00000000..397b3e14 --- /dev/null +++ b/src/SCRIPTS/BF/MSP/ghst.lua @@ -0,0 +1,28 @@ +-- GHST Frame Types +local GHST_FRAMETYPE_MSP_REQ = 0x21 +local GHST_FRAMETYPE_MSP_WRITE = 0x22 +local GHST_FRAMETYPE_MSP_RESP = 0x28 + +local ghstMspType = 0 + +protocol.mspSend = function(payload) + return protocol.push(ghstMspType, payload) +end + +protocol.mspRead = function(cmd) + ghstMspType = GHST_FRAMETYPE_MSP_REQ + return mspSendRequest(cmd, {}) +end + +protocol.mspWrite = function(cmd, payload) + ghstMspType = GHST_FRAMETYPE_MSP_WRITE + return mspSendRequest(cmd, payload) +end + +protocol.mspPoll = function() + local type, data = ghostTelemetryPop() + if type == GHST_FRAMETYPE_MSP_RESP then + return mspReceivedReply(data) + end + return nil +end diff --git a/src/SCRIPTS/BF/protocols.lua b/src/SCRIPTS/BF/protocols.lua index c415104c..80348218 100644 --- a/src/SCRIPTS/BF/protocols.lua +++ b/src/SCRIPTS/BF/protocols.lua @@ -20,6 +20,16 @@ local supportedProtocols = saveMaxRetries = 2, saveTimeout = 150, cms = {}, + }, + ghst = + { + mspTransport = "MSP/ghst.lua", + push = ghostTelemetryPush, + maxTxBufferSize = 10, -- Tx -> Rx (Push) + maxRxBufferSize = 6, -- Rx -> Tx (Pop) + saveMaxRetries = 2, + saveTimeout = 250, + cms = {}, } } @@ -28,6 +38,8 @@ local function getProtocol() return supportedProtocols.smartPort elseif supportedProtocols.crsf.push() ~= nil then return supportedProtocols.crsf + elseif supportedProtocols.ghst.push() ~= nil then + return supportedProtocols.ghst end end From acec1d98bdf8debd5894aab37be94ab5d53d924a Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sat, 22 Jan 2022 19:34:10 +0100 Subject: [PATCH 149/193] Ignore .vscode add .vscode to .gitignore --- .gitignore | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 95b7ddbd..63c3ae72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # Compiled Lua sources luac.out -# luarocks build files +# Luarocks build files *.src.rock *.zip *.tar.gz @@ -42,6 +42,9 @@ luac.out # Eclipse .project -#directories +# Visual Studio Code +.vscode + +# Directories tmp obj From d10ed7537f9165d72e87b389d5468cbe33d48154 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 3 Feb 2022 14:51:48 +0100 Subject: [PATCH 150/193] Add motor output limit --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 2c8e5e6a..5c136d66 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -20,6 +20,7 @@ if apiVersion >= 1.040 then end if apiVersion >= 1.043 then + fields[#fields + 1] = { t = "Motor Output Limit",x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 100, vals = { 48 } } fields[#fields + 1] = { t = "Dynamic Idle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 50 } } end From 1a1522eb37f858c89aa96cf51fe261981f9378c2 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 3 Feb 2022 19:56:29 +0100 Subject: [PATCH 151/193] Add Profiles page. --- src/SCRIPTS/BF/PAGES/profiles.lua | 46 +++++++++++++++++++++++++++++++ src/SCRIPTS/BF/pages.lua | 4 +++ 2 files changed, 50 insertions(+) create mode 100644 src/SCRIPTS/BF/PAGES/profiles.lua diff --git a/src/SCRIPTS/BF/PAGES/profiles.lua b/src/SCRIPTS/BF/PAGES/profiles.lua new file mode 100644 index 00000000..c59ad529 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/profiles.lua @@ -0,0 +1,46 @@ +local template = assert(loadScript(radio.template))() +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +local RATEPROFILE_MASK = bit32.lshift(1, 7) +local profileNumbers = { [0] = "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" } + +fields[#fields + 1] = { t = "PID Profile", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 11 }, table = profileNumbers } +fields[#fields + 1] = { t = "Rate Profile", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 5, vals = { 15 }, table = profileNumbers } + +return { + read = 150, -- MSP_STATUS_EX + write = 210, -- MSP_SELECT_SETTING + title = "Profiles", + reboot = false, + eepromWrite = true, + minBytes = 11, + labels = labels, + fields = fields, + pidProfile = 0, + postLoad = function(self) + local pidProfileCount = self.values[14] + self.fields[1].max = pidProfileCount - 1 + self.pidProfile = self.fields[1].value + end, + preSave = function(self) + local value = 0 + if self.fields[1].value ~= self.pidProfile then + value = self.fields[1].value + else + value = bit32.bor(self.fields[2].value, RATEPROFILE_MASK) + end + self.values = {} + self.values[1] = value + return self.values + end, +} diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index c3bb9574..68f95ee8 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -4,6 +4,10 @@ if apiVersion >= 1.036 then PageFiles[#PageFiles + 1] = { title = "VTX Settings", script = "vtx.lua" } end +if apiVersion >= 1.016 then + PageFiles[#PageFiles + 1] = { title = "Profiles", script = "profiles.lua" } +end + if apiVersion >= 1.016 then PageFiles[#PageFiles + 1] = { title = "PIDs 1", script = "pids1.lua" } end From 170c9a50df4ce31d13ccb5f96d1055e7e49de724 Mon Sep 17 00:00:00 2001 From: Richard Marko Date: Tue, 31 May 2022 09:34:44 +0200 Subject: [PATCH 152/193] fix shebang in bin/build.sh Using env is a more portable approach. --- bin/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/build.sh b/bin/build.sh index a58209fa..be6cb2ac 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash if [ -d obj ]; then rm -fR obj/* From 3bb28614a78ecaef1c1e8ce63dcda7c680404dcf Mon Sep 17 00:00:00 2001 From: blckmn Date: Tue, 14 Jun 2022 14:34:25 +1000 Subject: [PATCH 153/193] Auto generation of release notes. --- .github/release.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/release.yml diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 00000000..6c1dd378 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,26 @@ +changelog: + exclude: + labels: + - "cleanup" + - "RN: IGNORE" + categories: + - title: Features + labels: + - "RN: FEATURE" + - "RN: MAJOR FEATURE" + - "RN: MINOR FEATURE" + - title: Improvements + labels: + - "RN: IMPROVEMENT" + - "RN: UI" + - "RN: REFACTOR" + - "RN: FONT" + - title: Fixes + labels: + - "RN: BUGFIX" + - title: Translation + labels: + - "RN: TRANSLATION" + - title: Known Issues + labels: + - BUG From ad053800e83176e0c6f046f8db7c3c8e0b657431 Mon Sep 17 00:00:00 2001 From: blckmn Date: Tue, 14 Jun 2022 16:41:58 +1000 Subject: [PATCH 154/193] Moving to github actions, to attach on release. --- .github/workflows/build-release.yml | 39 ++++++++++++++ .github/workflows/ci.yml | 38 +++++++++++++ .github/workflows/pr.yml | 12 +++++ azure-pipelines.yml | 82 ----------------------------- 4 files changed, 89 insertions(+), 82 deletions(-) create mode 100644 .github/workflows/build-release.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/pr.yml delete mode 100644 azure-pipelines.yml diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 00000000..a0a2c225 --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,39 @@ +name: Release + +on: + release: + types: [published] + +jobs: + ci: + name: CI + uses: ./.github/workflows/ci.yml + with: + release_build: true + + release: + name: Release + needs: ci + runs-on: ubuntu-20.04 + steps: + - name: Code Checkout + uses: actions/checkout@v2 + + - name: Fetch build artifacts + uses: actions/download-artifact@v2 + + - name: List assets + run: ls -al Assets + + - name: Attach assets to release + run: | + set -x + assets=() + for asset in Assets/*.zip; do + assets+=("-a" "$asset") + echo "$asset" + done + tag_name="${GITHUB_REF##*/}" + hub release edit "${assets[@]}" -m "" "$tag_name" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..2c177ffa --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,38 @@ +# Builds Betaflight Lua Scripts. +# +# After building, artifacts are kept for 7 days. + +name: CI + +on: + workflow_call: + inputs: + release_build: + description: 'Specifies if it is a debug build or a release build' + default: false + required: false + type: boolean + +jobs: + build: + name: Build + runs-on: ubuntu-20.04 + steps: + - name: Code Checkout + uses: actions/checkout@v2 + + - name: Install Lua + run: sudo apt-get -y install lua5.2 + + - name: Install Zip + run: sudo apt-get -y install zip + + - name: Execute Build + run: make release + + - name: Publish build artifacts + uses: actions/upload-artifact@v3 + with: + name: Assets + path: ./release/*.zip + retention-days: 7 diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 00000000..c207e7e4 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,12 @@ +name: PR + +on: + pull_request: + branches: + - master + - '*-maintenance' + +jobs: + ci: + name: CI + uses: ./.github/workflows/ci.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index 837910b3..00000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,82 +0,0 @@ -# Builds the Betaflight TX lua scripts. -# -# After building, artifacts are released to a seperate repository. -# -# Azure Pipelines requires the following extensions to be installed: -# - GitHub Tool: https://marketplace.visualstudio.com/items?itemName=marcelo-formentao.github-tools -# -# You'll also need to setup the follwing pipeline variables: -# "releaseNotes" - This is used to add the release notes in the windows job in the build stage so they can be published as part of the github release in the release stage -# "endpoint" - The name of the github endpoint link setup in AzDo - setup when linking AzDo and GitHub -# "owner" - The owner of the repository to release to e.g. betaflight -# "repoName" - The name of the repository to release to e.g. betaflight-configurator-nightly - -variables: - owner: betaflight - repoName: betaflight-tx-lua-scripts-nightlies - releaseNotes: This is a nightly build off the tip of 'master'. It may be unstable and result in corrupted configurations or data loss. **Use only for testing.** - vmImage: 'ubuntu-20.04' - -name: $(Date:yyyyMMdd).$(BuildID) - -trigger: - batch: true - branches: - include: - - master - -pr: - drafts: false - branches: - include: - - master - - "*-maintenance" - -stages: -- stage: Build - jobs: - - job: 'Linux' - pool: - vmImage: '$(vmImage)' - steps: - - script: sudo apt-get -y install lua5.2 - displayName: 'Install lua compiler.' - - script: make release -C $(System.DefaultWorkingDirectory) - displayName: 'Test and build the release.' - - task: PublishPipelineArtifact@1 - displayName: 'Publish release' - inputs: - artifactName: betaflight-tx-lua-scripts - targetPath: '$(System.DefaultWorkingDirectory)/release' - -- stage: Release - jobs: - - job: Release - pool: - vmImage: '$(vmImage)' - steps: - - task: DownloadPipelineArtifact@2 - inputs: - buildType: 'current' - targetPath: '$(Pipeline.Workspace)' - - task: GitHubReleasePublish@1 - inputs: - githubEndpoint: '$(endpoint)' - manuallySetRepository: true - githubOwner: '$(owner)' - githubRepositoryName: '$(repoName)' - githubReleaseNotes: |+ - $(releaseNotes) - - ### Changes: - $(Build.SourceVersionMessage) - githubReleaseDraft: false - githubReleasePrerelease: false - githubIgnoreAssets: false - githubReleaseAsset: | - $(Pipeline.Workspace)/betaflight-tx-lua-scripts/** - githubReuseRelease: true - githubReuseDraftOnly: true - githubSkipDuplicatedAssets: false - githubEditRelease: false - githubDeleteEmptyTag: false From 8809aa39bd85eadb0df715799fbf8251c1be595f Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sat, 22 Jan 2022 21:08:51 +0100 Subject: [PATCH 155/193] Read lua input buffer until empty --- src/SCRIPTS/BF/MSP/common.lua | 17 ++++++++--------- src/SCRIPTS/BF/MSP/crsf.lua | 17 +++++++++-------- src/SCRIPTS/BF/MSP/ghst.lua | 11 +++++++---- src/SCRIPTS/BF/MSP/sp.lua | 33 ++++++++++++++++++--------------- 4 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/SCRIPTS/BF/MSP/common.lua b/src/SCRIPTS/BF/MSP/common.lua index fb119f6c..dc20f9bd 100644 --- a/src/SCRIPTS/BF/MSP/common.lua +++ b/src/SCRIPTS/BF/MSP/common.lua @@ -100,25 +100,24 @@ function mspReceivedReply(payload) end if idx > protocol.maxRxBufferSize then mspRemoteSeq = seq - return true + return false end mspStarted = false -- check CRC if mspRxCRC ~= payload[idx] and version == 0 then return nil end - return mspRxBuf + return true end function mspPollReply() while true do - local ret = protocol.mspPoll() - if type(ret) == "table" then + local mspData = protocol.mspPoll() + if mspData == nil then + return nil + elseif mspReceivedReply(mspData) then mspLastReq = 0 - return mspRxReq, ret - else - break - end + return mspRxReq, mspRxBuf + end end - return nil end diff --git a/src/SCRIPTS/BF/MSP/crsf.lua b/src/SCRIPTS/BF/MSP/crsf.lua index 63c92006..9fb4eeed 100644 --- a/src/SCRIPTS/BF/MSP/crsf.lua +++ b/src/SCRIPTS/BF/MSP/crsf.lua @@ -6,7 +6,7 @@ local CRSF_FRAMETYPE_MSP_REQ = 0x7A -- response request using msp local CRSF_FRAMETYPE_MSP_RESP = 0x7B -- reply with 60 byte chunked binary local CRSF_FRAMETYPE_MSP_WRITE = 0x7C -- write with 60 byte chunked binary -crsfMspCmd = 0 +local crsfMspCmd = 0 protocol.mspSend = function(payload) local payloadOut = { CRSF_ADDRESS_BETAFLIGHT, CRSF_ADDRESS_RADIO_TRANSMITTER } @@ -27,15 +27,16 @@ protocol.mspWrite = function(cmd, payload) end protocol.mspPoll = function() - local command, data = crossfireTelemetryPop() - if command == CRSF_FRAMETYPE_MSP_RESP then - if data[1] == CRSF_ADDRESS_RADIO_TRANSMITTER and data[2] == CRSF_ADDRESS_BETAFLIGHT then + while true do + local cmd, data = crossfireTelemetryPop() + if cmd == CRSF_FRAMETYPE_MSP_RESP and data[1] == CRSF_ADDRESS_RADIO_TRANSMITTER and data[2] == CRSF_ADDRESS_BETAFLIGHT then local mspData = {} - for i=3, #(data) do - mspData[i-2] = data[i] + for i = 3, #data do + mspData[i - 2] = data[i] end - return mspReceivedReply(mspData) + return mspData + elseif cmd == nil then + return nil end end - return nil end diff --git a/src/SCRIPTS/BF/MSP/ghst.lua b/src/SCRIPTS/BF/MSP/ghst.lua index 397b3e14..53ef6166 100644 --- a/src/SCRIPTS/BF/MSP/ghst.lua +++ b/src/SCRIPTS/BF/MSP/ghst.lua @@ -20,9 +20,12 @@ protocol.mspWrite = function(cmd, payload) end protocol.mspPoll = function() - local type, data = ghostTelemetryPop() - if type == GHST_FRAMETYPE_MSP_RESP then - return mspReceivedReply(data) + while true do + local type, data = ghostTelemetryPop() + if type == GHST_FRAMETYPE_MSP_RESP then + return data + elseif type == nil then + return nil + end end - return nil end diff --git a/src/SCRIPTS/BF/MSP/sp.lua b/src/SCRIPTS/BF/MSP/sp.lua index ecc15b1b..7d2bc991 100644 --- a/src/SCRIPTS/BF/MSP/sp.lua +++ b/src/SCRIPTS/BF/MSP/sp.lua @@ -42,20 +42,23 @@ local function smartPortTelemetryPop() end protocol.mspPoll = function() - local sensorId, frameId, dataId, value = smartPortTelemetryPop() - if (sensorId == SMARTPORT_REMOTE_SENSOR_ID or sensorId == FPORT_REMOTE_SENSOR_ID) and frameId == REPLY_FRAME_ID then - local payload = {} - payload[1] = bit32.band(dataId,0xFF) - dataId = bit32.rshift(dataId,8) - payload[2] = bit32.band(dataId,0xFF) - payload[3] = bit32.band(value,0xFF) - value = bit32.rshift(value,8) - payload[4] = bit32.band(value,0xFF) - value = bit32.rshift(value,8) - payload[5] = bit32.band(value,0xFF) - value = bit32.rshift(value,8) - payload[6] = bit32.band(value,0xFF) - return mspReceivedReply(payload) + while true do + local sensorId, frameId, dataId, value = smartPortTelemetryPop() + if (sensorId == SMARTPORT_REMOTE_SENSOR_ID or sensorId == FPORT_REMOTE_SENSOR_ID) and frameId == REPLY_FRAME_ID then + local payload = {} + payload[1] = bit32.band(dataId, 0xFF) + dataId = bit32.rshift(dataId, 8) + payload[2] = bit32.band(dataId, 0xFF) + payload[3] = bit32.band(value, 0xFF) + value = bit32.rshift(value, 8) + payload[4] = bit32.band(value, 0xFF) + value = bit32.rshift(value, 8) + payload[5] = bit32.band(value, 0xFF) + value = bit32.rshift(value, 8) + payload[6] = bit32.band(value, 0xFF) + return payload + elseif sensorId == nil then + return nil + end end - return nil end From 188a884c899973244de1ab71477f59fc6c4bac70 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Wed, 14 Sep 2022 19:28:48 +0200 Subject: [PATCH 156/193] Remove gyro/pid rate for BF 4.2 --- src/SCRIPTS/BF/PAGES/pwm.lua | 10 ++++++---- src/SCRIPTS/BF/ui_init.lua | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index 5a5c4258..86a7845c 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -13,7 +13,7 @@ local fields = {} local gyroSampleRateKhz -if apiVersion >= 1.043 then +if apiVersion >= 1.044 then gyroSampleRateKhz = assert(loadScript("BOARD_INFO/"..mcuId..".lua"))().gyroSampleRateHz / 1000 end @@ -42,12 +42,14 @@ labels[#labels + 1] = { t = "System Config", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.031 and apiVersion <= 1.040 then fields[#fields + 1] = { t = "32kHz Sampling", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end } end -if apiVersion >= 1.043 then +if apiVersion >= 1.044 then fields[#fields + 1] = { t = "Gyro Update", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end, mult = -1, ro = true } -else +elseif apiVersion <= 1.042 then fields[#fields + 1] = { t = "Gyro Update", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end, mult = -1 } end -fields[#fields + 1] = { t = "PID Loop", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {}, mult = -1 } +if apiVersion <= 1.042 or apiVersion >= 1.044 then + fields[#fields + 1] = { t = "PID Loop", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {}, mult = -1 } +end labels[#labels + 1] = { t = "ESC/Motor", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Protocol", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #escProtocols, vals = { 4 }, table = escProtocols } diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 632fea68..939aa586 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -43,7 +43,7 @@ local function init() getVtxTables = nil collectgarbage() end - elseif not boardInfoReceived and apiVersion >= 1.043 then + elseif not boardInfoReceived and apiVersion >= 1.044 then getBoardInfo = getBoardInfo or assert(loadScript("board_info.lua"))() returnTable.t = getBoardInfo.t boardInfoReceived = getBoardInfo.f() From 67e7afa8d4c06e6ac5ef882193a21cd47011f07f Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 2 Oct 2022 23:02:47 +0200 Subject: [PATCH 157/193] Fix api version calculation --- src/SCRIPTS/BF/PAGES/failsafe.lua | 4 ++-- src/SCRIPTS/BF/PAGES/filters1.lua | 30 +++++++++++++-------------- src/SCRIPTS/BF/PAGES/filters2.lua | 10 ++++----- src/SCRIPTS/BF/PAGES/gpspids.lua | 2 +- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 26 +++++++++++------------ src/SCRIPTS/BF/PAGES/pids1.lua | 6 +++--- src/SCRIPTS/BF/PAGES/pids2.lua | 16 +++++++------- src/SCRIPTS/BF/PAGES/pwm.lua | 22 ++++++++++---------- src/SCRIPTS/BF/PAGES/rates.lua | 16 +++++++------- src/SCRIPTS/BF/PAGES/rescue.lua | 6 +++--- src/SCRIPTS/BF/PAGES/rx.lua | 12 +++++------ src/SCRIPTS/BF/PAGES/vtx.lua | 8 +++---- src/SCRIPTS/BF/api_version.lua | 2 +- src/SCRIPTS/BF/background.lua | 2 +- src/SCRIPTS/BF/board_info.lua | 14 ++++++------- src/SCRIPTS/BF/pages.lua | 28 ++++++++++++------------- src/SCRIPTS/BF/rtc.lua | 2 +- src/SCRIPTS/BF/ui.lua | 2 +- src/SCRIPTS/BF/ui_init.lua | 6 +++--- 19 files changed, 107 insertions(+), 107 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/failsafe.lua b/src/SCRIPTS/BF/PAGES/failsafe.lua index 1ce6fbaa..5269a390 100644 --- a/src/SCRIPTS/BF/PAGES/failsafe.lua +++ b/src/SCRIPTS/BF/PAGES/failsafe.lua @@ -13,11 +13,11 @@ local fields = {} local procedure = { [0] = "Land", "Drop" } -if apiVersion >= 1.039 then +if apiVersion >= 1.39 then procedure[#procedure + 1] = "Rescue" end -if apiVersion >= 1.039 then +if apiVersion >= 1.39 then labels[#labels + 1] = { t = "Failsafe Switch", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Action", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 5 }, table = { [0] = "Stage 1", "Kill", "Stage 2" } } else diff --git a/src/SCRIPTS/BF/PAGES/filters1.lua b/src/SCRIPTS/BF/PAGES/filters1.lua index 68db6c8e..4b85a745 100644 --- a/src/SCRIPTS/BF/PAGES/filters1.lua +++ b/src/SCRIPTS/BF/PAGES/filters1.lua @@ -13,29 +13,29 @@ local fields = {} local gyroFilterType = { [0] = "PT1", "BIQUAD" } -if apiVersion >= 1.044 then +if apiVersion >= 1.44 then gyroFilterType[#gyroFilterType + 1] = "PT2" gyroFilterType[#gyroFilterType + 1] = "PT3" end local dtermFilterType = gyroFilterType -if apiVersion >= 1.036 and apiVersion <= 1.038 then +if apiVersion >= 1.36 and apiVersion <= 1.38 then dtermFilterType = { [0] = "PT1", "BIQUAD", "FIR" } end local dtermFilterType2 = gyroFilterType -if apiVersion >= 1.041 then +if apiVersion >= 1.41 then labels[#labels + 1] = { t = "Gyro Lowpass 1 Dynamic", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 30, 31 } } fields[#fields + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 32, 33 } } fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #gyroFilterType, vals = { 25 }, table = gyroFilterType } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then labels[#labels + 1] = { t = "Gyro Lowpass 1", x = x, y = inc.y(lineSpacing) } - if apiVersion >= 1.039 then + if apiVersion >= 1.39 then fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 21, 22 } } fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #gyroFilterType, vals = { 25 }, table = gyroFilterType } else @@ -43,54 +43,54 @@ if apiVersion >= 1.016 then end end -if apiVersion >= 1.039 then +if apiVersion >= 1.39 then labels[#labels + 1] = { t = "Gyro Lowpass 2", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 23, 24 } } fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #gyroFilterType, vals = { 26 }, table = gyroFilterType } end -if apiVersion >= 1.020 then +if apiVersion >= 1.20 then labels[#labels + 1] = { t = "Gyro Notch 1", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 6, 7 } } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 8, 9 } } end -if apiVersion >= 1.021 then +if apiVersion >= 1.21 then labels[#labels + 1] = { t = "Gyro Notch 2", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 14, 15 } } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 16, 17 } } end -if apiVersion >= 1.041 then +if apiVersion >= 1.41 then labels[#labels + 1] = { t = "D Term Lowpass 1 Dynamic", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Min Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 34, 35 } } fields[#fields + 1] = { t = "Max Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1000, vals = { 36, 37 } } fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #dtermFilterType, vals = { 18 }, table = dtermFilterType } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then labels[#labels + 1] = { t = "D Term Lowpass 1", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 2, 3 } } - if apiVersion >= 1.036 then + if apiVersion >= 1.36 then fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #dtermFilterType, vals = { 18 }, table = dtermFilterType } end end -if apiVersion >= 1.039 then +if apiVersion >= 1.39 then labels[#labels + 1] = { t = "D Term Lowpass 2", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 27, 28 } } - if apiVersion >= 1.041 then + if apiVersion >= 1.41 then fields[#fields + 1] = { t = "Filter Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #dtermFilterType2, vals = { 29 }, table = dtermFilterType2 } end end -if apiVersion >= 1.020 then +if apiVersion >= 1.20 then labels[#labels + 1] = { t = "D Term Notch", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 10, 11 } } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 16000, vals = { 12, 13 } } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then labels[#labels + 1] = { t = "Yaw Lowpass", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 4, 5 } } end diff --git a/src/SCRIPTS/BF/PAGES/filters2.lua b/src/SCRIPTS/BF/PAGES/filters2.lua index 0ba77145..7fb2e44f 100644 --- a/src/SCRIPTS/BF/PAGES/filters2.lua +++ b/src/SCRIPTS/BF/PAGES/filters2.lua @@ -11,21 +11,21 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} -if apiVersion >= 1.042 then +if apiVersion >= 1.42 then labels[#labels + 1] = { t = "Gyro RPM Filter", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Harmonics", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 44 } } fields[#fields + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 200, vals = { 45 } } labels[#labels + 1] = { t = "Dynamic Notch Filter", x = x, y = inc.y(lineSpacing) } - if apiVersion < 1.043 then + if apiVersion < 1.43 then fields[#fields + 1] = { t = "Range", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 38 }, table = { [0]="HIGH", "MEDIUM", "LOW", "AUTO" } } end - if apiVersion >= 1.044 then + if apiVersion >= 1.44 then fields[#fields + 1] = { t = "Count", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 5, vals = { 49 } } else fields[#fields + 1] = { t = "Width %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 39 } } end fields[#fields + 1] = { t = "Q", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 1000, vals = { 40, 41 } } - if apiVersion >= 1.043 then + if apiVersion >= 1.43 then fields[#fields + 1] = { t = "Min Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 60, max = 250, vals = { 42, 43 } } fields[#fields + 1] = { t = "Max Frequency", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 200, max = 1000, vals = { 46, 47 } } else @@ -46,7 +46,7 @@ return { self.rpmHarmonics = self.values[44] end, preSave = function(self) - self.reboot = self.values[44] == 0 and self.rpmHarmonics ~= 0 and apiVersion <= 1.043 + self.reboot = self.values[44] == 0 and self.rpmHarmonics ~= 0 and apiVersion <= 1.43 return self.values end, } diff --git a/src/SCRIPTS/BF/PAGES/gpspids.lua b/src/SCRIPTS/BF/PAGES/gpspids.lua index 95382972..a28685f1 100644 --- a/src/SCRIPTS/BF/PAGES/gpspids.lua +++ b/src/SCRIPTS/BF/PAGES/gpspids.lua @@ -11,7 +11,7 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} -if apiVersion >= 1.041 then +if apiVersion >= 1.41 then x = margin y = yMinLim - tableSpacing.header labels[#labels + 1] = { t = "", x = x, y = inc.y(tableSpacing.header) } diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 5c136d66..6ec3452b 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -11,7 +11,7 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} -if apiVersion >= 1.040 then +if apiVersion >= 1.40 then labels[#labels + 1] = { t = "Acro Trainer", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Angle Limit", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 80, vals = { 32 } } fields[#fields + 1] = { t = "Throttle Boost", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 31 } } @@ -19,45 +19,45 @@ if apiVersion >= 1.040 then fields[#fields + 1] = { t = "I Term Rotation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } } end -if apiVersion >= 1.043 then +if apiVersion >= 1.43 then fields[#fields + 1] = { t = "Motor Output Limit",x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 100, vals = { 48 } } fields[#fields + 1] = { t = "Dynamic Idle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 50 } } end -if apiVersion >= 1.016 and apiVersion <= 1.043 then +if apiVersion >= 1.16 and apiVersion <= 1.43 then fields[#fields + 1] = { t = "VBAT Compensation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } } end -if apiVersion >= 1.044 then +if apiVersion >= 1.44 then fields[#fields + 1] = { t = "Vbat Sag Comp", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 56 } } fields[#fields + 1] = { t = "Thrust Linear", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 57 } } end -if apiVersion >= 1.040 and apiVersion <= 1.041 then +if apiVersion >= 1.40 and apiVersion <= 1.41 then fields[#fields + 1] = { t = "Smart Feedforward", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 27 }, table = { [0] = "OFF", "ON" } } end -if apiVersion >= 1.041 then +if apiVersion >= 1.41 then fields[#fields + 1] = { t = "Integrated Yaw", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } } end -if apiVersion >= 1.040 then +if apiVersion >= 1.40 then labels[#labels + 1] = { t = "I Term Relax", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Axes", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } } fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } } - if apiVersion >= 1.043 then + if apiVersion >= 1.43 then fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 50, vals = { 47 } } - elseif apiVersion >= 1.042 then + elseif apiVersion >= 1.42 then fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 100, vals = { 47 } } end end -if apiVersion >= 1.036 then +if apiVersion >= 1.36 then labels[#labels + 1] = { t = "Anti Gravity", x = x, y = inc.y(lineSpacing) } - if apiVersion >= 1.040 then + if apiVersion >= 1.40 then fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } } end - if apiVersion >= 1.044 then + if apiVersion >= 1.44 then fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } else fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } @@ -78,7 +78,7 @@ return { self.dynamicIdle = self.values[50] end, preSave = function(self) - self.reboot = self.values[50] ~= self.dynamicIdle and apiVersion <= 1.043 + self.reboot = self.values[50] ~= self.dynamicIdle and apiVersion <= 1.43 return self.values end, } diff --git a/src/SCRIPTS/BF/PAGES/pids1.lua b/src/SCRIPTS/BF/PAGES/pids1.lua index 42c40afd..5102e316 100644 --- a/src/SCRIPTS/BF/PAGES/pids1.lua +++ b/src/SCRIPTS/BF/PAGES/pids1.lua @@ -14,12 +14,12 @@ local fields = {} local pidMax = 200 local dLabel = "D" -if apiVersion >= 1.044 then +if apiVersion >= 1.44 then pidMax = 250 dLabel = "D Max" end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then x = margin y = yMinLim - tableSpacing.header @@ -50,7 +50,7 @@ if apiVersion >= 1.016 then labels[#labels + 1] = { t = dLabel, x = x, y = inc.y(tableSpacing.header) } fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 3 } } fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 6 } } - if apiVersion >= 1.041 then + if apiVersion >= 1.41 then fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = pidMax, vals = { 9 } } end end diff --git a/src/SCRIPTS/BF/PAGES/pids2.lua b/src/SCRIPTS/BF/PAGES/pids2.lua index 7fdb1d1d..5acca134 100644 --- a/src/SCRIPTS/BF/PAGES/pids2.lua +++ b/src/SCRIPTS/BF/PAGES/pids2.lua @@ -13,11 +13,11 @@ local fields = {} local dMinMax = 100 -if apiVersion >= 1.044 then +if apiVersion >= 1.44 then dMinMax = 250 end -if apiVersion >= 1.040 then +if apiVersion >= 1.40 then x = margin y = yMinLim - tableSpacing.header @@ -34,7 +34,7 @@ if apiVersion >= 1.040 then fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 2000, vals = { 35, 36 } } fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 2000, vals = { 37, 38 } } - if apiVersion >= 1.041 then + if apiVersion >= 1.41 then x = x + tableSpacing.col y = yMinLim - tableSpacing.header @@ -48,9 +48,9 @@ if apiVersion >= 1.040 then y = inc.y(lineSpacing*0.4) end -if apiVersion >= 1.040 then +if apiVersion >= 1.40 then labels[#labels + 1] = { t = "Feedforward", x = x, y = inc.y(lineSpacing) } - if apiVersion >= 1.044 then + if apiVersion >= 1.44 then fields[#fields + 1] = { t = "Jitter Reduction", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 55 } } fields[#fields + 1] = { t = "Smoothness", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 75, vals = { 52 } } fields[#fields + 1] = { t = "Averaging", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 51 }, table = { [0] = "OFF", "2_POINT", "3_POINT", "4_POINT" } } @@ -60,15 +60,15 @@ if apiVersion >= 1.040 then fields[#fields + 1] = { t = "Transition", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 9 }, scale = 100 } end -if apiVersion >= 1.041 then +if apiVersion >= 1.41 then labels[#labels + 1] = { t = "D Min", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 43 } } fields[#fields + 1] = { t = "Advance", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 44 } } end -if apiVersion >= 1.021 and apiVersion <= 1.039 then +if apiVersion >= 1.21 and apiVersion <= 1.39 then labels[#labels + 1] = { t = "Dterm Setpoint", x = x, y = inc.y(lineSpacing) } - if apiVersion >= 1.021 and apiVersion <= 1.038 then + if apiVersion >= 1.21 and apiVersion <= 1.38 then fields[#fields + 1] = { t = "Weight", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 254, vals = { 10 }, scale = 100 } else fields[#fields + 1] = { t = "Weight", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 254, vals = { 25 }, scale = 100 } diff --git a/src/SCRIPTS/BF/PAGES/pwm.lua b/src/SCRIPTS/BF/PAGES/pwm.lua index 86a7845c..0712d7a5 100644 --- a/src/SCRIPTS/BF/PAGES/pwm.lua +++ b/src/SCRIPTS/BF/PAGES/pwm.lua @@ -13,47 +13,47 @@ local fields = {} local gyroSampleRateKhz -if apiVersion >= 1.044 then +if apiVersion >= 1.44 then gyroSampleRateKhz = assert(loadScript("BOARD_INFO/"..mcuId..".lua"))().gyroSampleRateHz / 1000 end local escProtocols = { [0] = "PWM", "OS125", "OS42", "MSHOT" } -if apiVersion >= 1.020 then +if apiVersion >= 1.20 then escProtocols[#escProtocols + 1] = "BRSH" end -if apiVersion >= 1.031 then +if apiVersion >= 1.31 then escProtocols[#escProtocols + 1] = "DS150" escProtocols[#escProtocols + 1] = "DS300" escProtocols[#escProtocols + 1] = "DS600" - if apiVersion < 1.042 then + if apiVersion < 1.42 then escProtocols[#escProtocols + 1] = "DS1200" end - if apiVersion >= 1.036 then + if apiVersion >= 1.36 then escProtocols[#escProtocols + 1] = "PS1000" end end -if apiVersion >= 1.043 then +if apiVersion >= 1.43 then escProtocols[#escProtocols + 1] = "DISABLED" end labels[#labels + 1] = { t = "System Config", x = x, y = inc.y(lineSpacing) } -if apiVersion >= 1.031 and apiVersion <= 1.040 then +if apiVersion >= 1.31 and apiVersion <= 1.40 then fields[#fields + 1] = { t = "32kHz Sampling", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 9 }, table = { [0] = "OFF", "ON" }, upd = function(self) self.updateRateTables(self) end } end -if apiVersion >= 1.044 then +if apiVersion >= 1.44 then fields[#fields + 1] = { t = "Gyro Update", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end, mult = -1, ro = true } -elseif apiVersion <= 1.042 then +elseif apiVersion <= 1.42 then fields[#fields + 1] = { t = "Gyro Update", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 32, vals = { 1 }, table = {}, upd = function(self) self.updatePidRateTable(self) end, mult = -1 } end -if apiVersion <= 1.042 or apiVersion >= 1.044 then +if apiVersion <= 1.42 or apiVersion >= 1.44 then fields[#fields + 1] = { t = "PID Loop", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 16, vals = { 2 }, table = {}, mult = -1 } end labels[#labels + 1] = { t = "ESC/Motor", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Protocol", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = #escProtocols, vals = { 4 }, table = escProtocols } -if apiVersion >= 1.031 then +if apiVersion >= 1.31 then fields[#fields + 1] = { t = "Idle Throttle %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2000, vals = { 7, 8 }, scale = 100 } end fields[#fields + 1] = { t = "Unsynced PWM", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 3 }, table = { [0] = "OFF", "ON" } } diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua index 355674fb..55676ab6 100644 --- a/src/SCRIPTS/BF/PAGES/rates.lua +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -11,7 +11,7 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then y = yMinLim - tableSpacing.header labels[#labels + 1] = { t = "", x = x, y = inc.y(tableSpacing.header) } @@ -25,7 +25,7 @@ if apiVersion >= 1.016 then labels[#labels + 1] = { t = "RC", x = x, y = inc.y(tableSpacing.header) } labels[#labels + 1] = { t = "Rate", x = x, y = inc.y(tableSpacing.header) } - if apiVersion >= 1.037 then + if apiVersion >= 1.37 then fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 255, vals = { 1 }, scale = 100 } fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 255, vals = { 13 }, scale = 100 } else @@ -48,7 +48,7 @@ if apiVersion >= 1.016 then labels[#labels + 1] = { t = "RC", x = x, y = inc.y(tableSpacing.header) } labels[#labels + 1] = { t = "Expo", x = x, y = inc.y(tableSpacing.header) } - if apiVersion >= 1.037 then + if apiVersion >= 1.37 then fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 2 }, scale = 100 } fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 100, vals = { 14 }, scale = 100 } else @@ -61,21 +61,21 @@ if apiVersion >= 1.016 then inc.y(lineSpacing*0.4) end -if apiVersion >= 1.043 then +if apiVersion >= 1.43 then fields[#fields + 1] = { t = "Rates Type", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 23 }, table = { [0] = "BF", "RF", "KISS", "ACTUAL", "QUICK"}, postEdit = function(self) self.updateRatesType(self, true) end } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then labels[#labels + 1] = { t = "Throttle", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Mid", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 7 }, scale = 100 } fields[#fields + 1] = { t = "Expo", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 8 }, scale = 100 } - if apiVersion >= 1.041 then + if apiVersion >= 1.41 then fields[#fields + 1] = { t = "Limit Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 2, vals = { 15 }, table = { [0] = "OFF", "SCALE", "CLIP" } } fields[#fields + 1] = { t = "Limit %", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 25, max = 100, vals = { 16 } } end end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then labels[#labels + 1] = { t = "TPA", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Rate", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 6 } , scale = 100 } fields[#fields + 1] = { t = "Breakpoint", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 9, 10 } } @@ -131,7 +131,7 @@ return { self.ratesType = self.getRatesType(self) end, postLoad = function(self) - if apiVersion >= 1.043 then + if apiVersion >= 1.43 then self.updateRatesType(self) end end, diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index c3bc9a2b..448de7bb 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -11,14 +11,14 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} -if apiVersion >= 1.041 then +if apiVersion >= 1.41 then fields[#fields + 1] = { t = "Min Sats.", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 16 } } fields[#fields + 1] = { t = "Angle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 1, 2 } } fields[#fields + 1] = { t = "Initial Altitude", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 100, vals = { 3, 4 } } fields[#fields + 1] = { t = "Descent Distance", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 30, max = 500, vals = { 5, 6 } } fields[#fields + 1] = { t = "Ground Speed", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 30, max = 3000, vals = { 7, 8 } } - if apiVersion >= 1.043 then + if apiVersion >= 1.43 then fields[#fields + 1] = { t = "Ascend Rate", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 100, max = 2500, vals = { 17, 18 }, scale = 100 } fields[#fields + 1] = { t = "Descend Rate", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 100, max = 500, vals = { 19, 20 }, scale = 100 } fields[#fields + 1] = { t = "Arm w/o fix", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 21 }, table = { [0]="OFF","ON"} } @@ -31,7 +31,7 @@ if apiVersion >= 1.041 then fields[#fields + 1] = { t = "Hover", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 13, 14 } } fields[#fields + 1] = { t = "Max", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 11, 12 } } - if apiVersion >= 1.044 then + if apiVersion >= 1.44 then fields[#fields + 1] = { t = "Min Dth", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 50, max = 1000, vals = { 23, 24 } } end end diff --git a/src/SCRIPTS/BF/PAGES/rx.lua b/src/SCRIPTS/BF/PAGES/rx.lua index 8c6cd8f8..a78540c2 100644 --- a/src/SCRIPTS/BF/PAGES/rx.lua +++ b/src/SCRIPTS/BF/PAGES/rx.lua @@ -11,14 +11,14 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then labels[#labels + 1] = { t = "Stick", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Low", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 6, 7 } } fields[#fields + 1] = { t = "Center", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 4, 5 } } fields[#fields + 1] = { t = "High", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 2, 3 } } end -if apiVersion >= 1.044 then +if apiVersion >= 1.44 then labels[#labels + 1] = { t = "RC Smoothing", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "ON", "OFF" } } labels[#labels + 1] = { t = "Cutoffs", x = x + indent, y = inc.y(lineSpacing) } @@ -27,7 +27,7 @@ if apiVersion >= 1.044 then labels[#labels + 1] = { t = "Auto Smoothness", x = x + indent, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Setpoint", x = x + indent*2, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 250, vals = { 31 } } else - if apiVersion >= 1.040 then + if apiVersion >= 1.40 then labels[#labels + 1] = { t = "RC Smoothing", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 25 }, table = { [0] = "Interpolation", "Filter" } } fields[#fields + 1] = { t = "Channels", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 24 }, table = { [0] = "RP", "RPY", "RPYT", "T", "RT" } } @@ -39,17 +39,17 @@ else fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 29 }, table = { [0] = "Off", "PT1", "BIQUAD", "Auto"} } end - if apiVersion >= 1.020 then + if apiVersion >= 1.20 then fields[#fields + 1] = { t = "Interpolation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3, vals = { 13 }, table={ [0]="Off", "Preset", "Auto", "Manual"} } fields[#fields + 1] = { t = "Interval", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 50, vals = { 14 } } end - if apiVersion >= 1.042 then + if apiVersion >= 1.42 then fields[#fields + 1] = { t = "Auto Smoothness", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 50, vals = { 31 } } end end -if apiVersion >= 1.031 then +if apiVersion >= 1.31 then fields[#fields + 1] = { t = "Cam Angle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 90, vals = { 23 } } end diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index 73a035e5..e2a978e0 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -12,7 +12,7 @@ local labels = {} local fields = {} local vtx_tables -if apiVersion >= 1.042 then +if apiVersion >= 1.42 then vtx_tables = assert(loadScript("VTX_TABLES/"..mcuId..".lua"))() else vtx_tables = assert(loadScript("VTX_TABLES/vtx_defaults.lua"))() @@ -20,7 +20,7 @@ end local deviceTable = { [1]="6705", [3]="SA", [4]="Tramp", [255]="None" } local pitModeTable = { [0]="OFF", "ON" } -if apiVersion >= 1.036 then +if apiVersion >= 1.36 then fields[#fields + 1] = { t = "Band", x = x, y = inc.y(lineSpacing), sp = x + sp, min=0, max=#(vtx_tables.bandTable), vals = { 2 }, table = vtx_tables.bandTable, upd = function(self) self.handleBandChanUpdate(self) end } fields[#fields + 1] = { t = "Channel", x = x, y = inc.y(lineSpacing), sp = x + sp, min=1, max=vtx_tables.frequenciesPerBand, vals = { 3 }, upd = function(self) self.handleBandChanUpdate(self) end } fields[#fields + 1] = { t = "Power", x = x, y = inc.y(lineSpacing), sp = x + sp, min=1, vals = { 4 }, upd = function(self) self.updatePowerTable(self) end } @@ -28,9 +28,9 @@ if apiVersion >= 1.036 then fields[#fields + 1] = { t = "Protocol", x = x, y = inc.y(lineSpacing), sp = x + sp, vals = { 1 }, write = false, ro = true, table = deviceTable } end -if apiVersion >= 1.037 then +if apiVersion >= 1.37 then fields[#fields + 1] = { t = "Frequency", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 5000, max = 5999, vals = { 6 }, upd = function(self) self.handleFreqValUpdate(self) end } -elseif apiVersion >= 1.036 then +elseif apiVersion >= 1.36 then fields[#fields + 1] = { t = "Frequency", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 5000, max = 5999, ro = true } end diff --git a/src/SCRIPTS/BF/api_version.lua b/src/SCRIPTS/BF/api_version.lua index 366fa500..c80efb3d 100644 --- a/src/SCRIPTS/BF/api_version.lua +++ b/src/SCRIPTS/BF/api_version.lua @@ -6,7 +6,7 @@ local INTERVAL = 50 local function processMspReply(cmd,rx_buf) if cmd == MSP_API_VERSION and #rx_buf >= 3 then - apiVersion = rx_buf[2] + rx_buf[3] / 1000 + apiVersion = rx_buf[2] + rx_buf[3] / 100 apiVersionReceived = true end end diff --git a/src/SCRIPTS/BF/background.lua b/src/SCRIPTS/BF/background.lua index 239a5698..a0086f58 100644 --- a/src/SCRIPTS/BF/background.lua +++ b/src/SCRIPTS/BF/background.lua @@ -21,7 +21,7 @@ local function run_bg() setRtc = nil collectgarbage() end - elseif rssiEnabled and apiVersion >= 1.037 then + elseif rssiEnabled and apiVersion >= 1.37 then rssiTask = rssiTask or assert(loadScript("rssi.lua"))() rssiEnabled = rssiTask() if not rssiEnabled then diff --git a/src/SCRIPTS/BF/board_info.lua b/src/SCRIPTS/BF/board_info.lua index 1fae01e5..10efbe40 100644 --- a/src/SCRIPTS/BF/board_info.lua +++ b/src/SCRIPTS/BF/board_info.lua @@ -34,11 +34,11 @@ local function processMspReply(cmd, payload) hardwareRevision = bit32.bor(hardwareRevision, raw_val) i = i + 1 end - if apiVersion >= 1.035 then + if apiVersion >= 1.35 then boardType = payload[i] end i = i + 1 - if apiVersion >= 1.037 then + if apiVersion >= 1.37 then targetCapabilities = payload[i] i = i + 1 length = payload[i] @@ -48,7 +48,7 @@ local function processMspReply(cmd, payload) i = i + 1 end end - if apiVersion >= 1.039 then + if apiVersion >= 1.39 then length = payload[i] i = i + 1 for c = 1, length do @@ -68,14 +68,14 @@ local function processMspReply(cmd, payload) end end i = i + 1 - if apiVersion >= 1.041 then + if apiVersion >= 1.41 then mcuTypeId = payload[i] end i = i + 1 - if apiVersion >= 1.042 then + if apiVersion >= 1.42 then configurationState = payload[i] end - if apiVersion >= 1.043 then + if apiVersion >= 1.43 then for idx = 1, 2 do local raw_val = bit32.lshift(payload[i], (idx-1)*8) gyroSampleRateHz = bit32.bor(gyroSampleRateHz, raw_val) @@ -87,7 +87,7 @@ local function processMspReply(cmd, payload) i = i + 1 end end - if apiVersion >= 1.044 then + if apiVersion >= 1.44 then spiRegisteredDeviceCount = payload[i] i = i + 1 i2cRegisteredDeviceCount = payload[i] diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index 68f95ee8..571a390a 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -1,58 +1,58 @@ local PageFiles = {} -if apiVersion >= 1.036 then +if apiVersion >= 1.36 then PageFiles[#PageFiles + 1] = { title = "VTX Settings", script = "vtx.lua" } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "Profiles", script = "profiles.lua" } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "PIDs 1", script = "pids1.lua" } end -if apiVersion >= 1.021 then +if apiVersion >= 1.21 then PageFiles[#PageFiles + 1] = { title = "PIDs 2", script = "pids2.lua" } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "Rates", script = "rates.lua" } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "Advanced PIDs", script = "pid_advanced.lua" } end -if apiVersion >= 1.044 then +if apiVersion >= 1.44 then PageFiles[#PageFiles + 1] = { title = "Simplified Tuning", script = "simplified_tuning.lua" } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "Filters 1", script = "filters1.lua" } end -if apiVersion >= 1.042 then +if apiVersion >= 1.42 then PageFiles[#PageFiles + 1] = { title = "Filters 2", script = "filters2.lua" } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "System / Motor", script = "pwm.lua" } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "Receiver", script = "rx.lua" } end -if apiVersion >= 1.016 then +if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "Failsafe", script = "failsafe.lua" } end -if apiVersion >= 1.041 then +if apiVersion >= 1.41 then PageFiles[#PageFiles + 1] = { title = "GPS Rescue", script = "rescue.lua" } end -if apiVersion >= 1.041 then +if apiVersion >= 1.41 then PageFiles[#PageFiles + 1] = { title = "GPS PIDs", script = "gpspids.lua" } end diff --git a/src/SCRIPTS/BF/rtc.lua b/src/SCRIPTS/BF/rtc.lua index 955c91e9..148a2fd3 100644 --- a/src/SCRIPTS/BF/rtc.lua +++ b/src/SCRIPTS/BF/rtc.lua @@ -15,7 +15,7 @@ local function setRtc() -- only send datetime one time after telemetry connection became available -- or when connection is restored after e.g. lipo refresh local values = {} - if apiVersion >= 1.041 then + if apiVersion >= 1.41 then -- format: seconds after the epoch (32) / milliseconds (16) local now = getRtcTime() diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 01d6e6e1..97a2c74b 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -91,7 +91,7 @@ local function createPopupMenu() end popupMenu[#popupMenu + 1] = { t = "reboot", f = rebootFc } popupMenu[#popupMenu + 1] = { t = "acc cal", f = function() confirm("CONFIRM/acc_cal.lua") end } - if apiVersion >= 1.042 then + if apiVersion >= 1.42 then popupMenu[#popupMenu + 1] = { t = "vtx tables", f = function() confirm("CONFIRM/vtx_tables.lua") end } end end diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 939aa586..29ca80ec 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -16,7 +16,7 @@ local function init() getApiVersion = nil collectgarbage() end - elseif not mcuIdReceived and apiVersion >= 1.042 then + elseif not mcuIdReceived and apiVersion >= 1.42 then getMCUId = getMCUId or assert(loadScript("mcu_id.lua"))() returnTable.t = getMCUId.t mcuIdReceived = getMCUId.f() @@ -35,7 +35,7 @@ local function init() end collectgarbage() end - elseif not vtxTablesReceived and apiVersion >= 1.042 then + elseif not vtxTablesReceived and apiVersion >= 1.42 then getVtxTables = getVtxTables or assert(loadScript("vtx_tables.lua"))() returnTable.t = getVtxTables.t vtxTablesReceived = getVtxTables.f() @@ -43,7 +43,7 @@ local function init() getVtxTables = nil collectgarbage() end - elseif not boardInfoReceived and apiVersion >= 1.044 then + elseif not boardInfoReceived and apiVersion >= 1.44 then getBoardInfo = getBoardInfo or assert(loadScript("board_info.lua"))() returnTable.t = getBoardInfo.t boardInfoReceived = getBoardInfo.f() From 50e9c519330a3c11f8be3a216b1dbd7aea9ba9cf Mon Sep 17 00:00:00 2001 From: Mark Haslinghuis Date: Tue, 9 Aug 2022 13:37:42 +0200 Subject: [PATCH 158/193] Update PID Profile --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 6 ++++++ src/SCRIPTS/BF/PAGES/rates.lua | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 6ec3452b..29d1a5b9 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -33,6 +33,12 @@ if apiVersion >= 1.44 then fields[#fields + 1] = { t = "Thrust Linear", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 150, vals = { 57 } } end +if apiVersion >= 1.45 then + labels[#labels + 1] = { t = "TPA", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Rate", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 58 } , scale = 100 } + fields[#fields + 1] = { t = "Breakpoint", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 750, max = 2250, vals = { 59, 60 } } +end + if apiVersion >= 1.40 and apiVersion <= 1.41 then fields[#fields + 1] = { t = "Smart Feedforward", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 27 }, table = { [0] = "OFF", "ON" } } end diff --git a/src/SCRIPTS/BF/PAGES/rates.lua b/src/SCRIPTS/BF/PAGES/rates.lua index 55676ab6..a1571237 100644 --- a/src/SCRIPTS/BF/PAGES/rates.lua +++ b/src/SCRIPTS/BF/PAGES/rates.lua @@ -75,7 +75,7 @@ if apiVersion >= 1.16 then end end -if apiVersion >= 1.16 then +if apiVersion >= 1.16 and apiVersion <= 1.44 then labels[#labels + 1] = { t = "TPA", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Rate", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 6 } , scale = 100 } fields[#fields + 1] = { t = "Breakpoint", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 2000, vals = { 9, 10 } } From 9e73791c0634f5f4ab504812c0dddf3191cd716a Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Tue, 4 Oct 2022 16:38:57 +0200 Subject: [PATCH 159/193] Increase dynamic idle limit Increase dynamic upper limit to 200 --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 6ec3452b..a91928f0 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -21,7 +21,11 @@ end if apiVersion >= 1.43 then fields[#fields + 1] = { t = "Motor Output Limit",x = x, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 100, vals = { 48 } } - fields[#fields + 1] = { t = "Dynamic Idle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 50 } } + if apiVersion >= 1.45 then + fields[#fields + 1] = { t = "Dynamic Idle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 50 } } + else + fields[#fields + 1] = { t = "Dynamic Idle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 50 } } + end end if apiVersion >= 1.16 and apiVersion <= 1.43 then From 811b462e136a475b09a2f58b97b42f68b314ca84 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 6 Oct 2022 20:52:38 +0200 Subject: [PATCH 160/193] Update anti gravity --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 6ec3452b..fa07baef 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -54,15 +54,19 @@ end if apiVersion >= 1.36 then labels[#labels + 1] = { t = "Anti Gravity", x = x, y = inc.y(lineSpacing) } - if apiVersion >= 1.40 then + if apiVersion >= 1.40 and apiVersion <= 1.44 then fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } } end - if apiVersion >= 1.44 then + if apiVersion >= 1.45 then + fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 250, vals = { 22, 23 } } + elseif apiVersion >= 1.44 then fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } else fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1000, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } end - fields[#fields + 1] = { t = "Threshold", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 1000, vals = { 20, 21 } } + if apiVersion <= 1.44 then + fields[#fields + 1] = { t = "Threshold", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 1000, vals = { 20, 21 } } + end end return { From d8c44d8625a1911aec03f94d49aec2df696a7532 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Fri, 7 Oct 2022 14:18:40 +0200 Subject: [PATCH 161/193] Change anti gravity gain scale --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 55d4b100..f4ffd408 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -62,7 +62,7 @@ if apiVersion >= 1.36 then fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } } end if apiVersion >= 1.45 then - fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 250, vals = { 22, 23 } } + fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 250, vals = { 22, 23 }, scale = 10 } elseif apiVersion >= 1.44 then fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 30000, vals = { 22, 23 }, scale = 1000, mult = 100 } else From 21f287b1c6668b14fee9cb4c208758a8ac20d5fe Mon Sep 17 00:00:00 2001 From: Mark Haslinghuis Date: Thu, 10 Nov 2022 04:46:07 +0100 Subject: [PATCH 162/193] Fix tpa --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index d81d8c36..16d54cf6 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -16,7 +16,7 @@ if apiVersion >= 1.40 then fields[#fields + 1] = { t = "Angle Limit", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 80, vals = { 32 } } fields[#fields + 1] = { t = "Throttle Boost", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 31 } } fields[#fields + 1] = { t = "Absolute Control", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 20, vals = { 30 } } - fields[#fields + 1] = { t = "I Term Rotation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 26 }, table = { [0]="OFF", "ON" } } + fields[#fields + 1] = { t = "I Term Rotation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 26 }, table = { [0] = "OFF", "ON" } } end if apiVersion >= 1.43 then @@ -29,7 +29,7 @@ if apiVersion >= 1.43 then end if apiVersion >= 1.16 and apiVersion <= 1.43 then - fields[#fields + 1] = { t = "VBAT Compensation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 8 }, table = { [0]="OFF", "ON" } } + fields[#fields + 1] = { t = "VBAT Compensation", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 8 }, table = { [0] = "OFF", "ON" } } end if apiVersion >= 1.44 then @@ -39,8 +39,9 @@ end if apiVersion >= 1.45 then labels[#labels + 1] = { t = "TPA", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Rate", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 58 } , scale = 100 } - fields[#fields + 1] = { t = "Breakpoint", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 750, max = 2250, vals = { 59, 60 } } + fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 58 }, table = { [0] = "PD", "D" } } + fields[#fields + 1] = { t = "Rate", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 100, vals = { 59 } , scale = 100 } + fields[#fields + 1] = { t = "Breakpoint", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 750, max = 2250, vals = { 60, 61 } } end if apiVersion >= 1.40 and apiVersion <= 1.41 then @@ -48,13 +49,13 @@ if apiVersion >= 1.40 and apiVersion <= 1.41 then end if apiVersion >= 1.41 then - fields[#fields + 1] = { t = "Integrated Yaw", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 45 }, table = { [0]="OFF", "ON" } } + fields[#fields + 1] = { t = "Integrated Yaw", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 45 }, table = { [0] = "OFF", "ON" } } end if apiVersion >= 1.40 then labels[#labels + 1] = { t = "I Term Relax", x = x, y = inc.y(lineSpacing) } - fields[#fields + 1] = { t = "Axes", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 28 }, table = { [0]="NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } } - fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 29 }, table = { [0]="Gyro", "Setpoint" } } + fields[#fields + 1] = { t = "Axes", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 4, vals = { 28 }, table = { [0] = "NONE", "RP", "RPY", "RP (inc)", "RPY (inc)" } } + fields[#fields + 1] = { t = "Type", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 29 }, table = { [0] = "Gyro", "Setpoint" } } if apiVersion >= 1.43 then fields[#fields + 1] = { t = "Cutoff", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 1, max = 50, vals = { 47 } } elseif apiVersion >= 1.42 then @@ -65,7 +66,7 @@ end if apiVersion >= 1.36 then labels[#labels + 1] = { t = "Anti Gravity", x = x, y = inc.y(lineSpacing) } if apiVersion >= 1.40 and apiVersion <= 1.44 then - fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 39 }, table = { [0]="Smooth", "Step" } } + fields[#fields + 1] = { t = "Mode", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 1, vals = { 39 }, table = { [0] = "Smooth", "Step" } } end if apiVersion >= 1.45 then fields[#fields + 1] = { t = "Gain", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 250, vals = { 22, 23 }, scale = 10 } From 138c7d49f0d6d546d75630b09c20abd8453d7598 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 13 Nov 2022 16:21:40 +0100 Subject: [PATCH 163/193] Handle signed values --- src/SCRIPTS/BF/ui.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 97a2c74b..42db07f7 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -121,6 +121,10 @@ local function processMspReply(cmd,rx_buf) raw_val = bit32.lshift(raw_val, (idx-1)*8) f.value = bit32.bor(f.value, raw_val) end + local bits = #f.vals * 8 + if f.min < 0 and bit32.btest(f.value, bit32.lshift(1, bits - 1)) then + f.value = f.value - (2 ^ bits) + end f.value = f.value/(f.scale or 1) end end From 9c9c84867e2d96797f45b89aa23ba5549f966355 Mon Sep 17 00:00:00 2001 From: druckgott Date: Mon, 14 Nov 2022 08:00:59 +0100 Subject: [PATCH 164/193] Implement Trim Pitch Roll for ACC --- src/SCRIPTS/BF/PAGES/acc_trim.lua | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/SCRIPTS/BF/PAGES/acc_trim.lua diff --git a/src/SCRIPTS/BF/PAGES/acc_trim.lua b/src/SCRIPTS/BF/PAGES/acc_trim.lua new file mode 100644 index 00000000..96ab0896 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/acc_trim.lua @@ -0,0 +1,27 @@ +local template = assert(loadScript(radio.template))() +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +labels[#labels + 1] = { t = "Trim Accelerometer", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Pitch", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = -300, max = 300, vals = { 1, 2 } } +fields[#fields + 1] = { t = "Roll", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = -300, max = 300, vals = { 3, 4 } } + +return { + read = 240, -- MSP_ACC_TRIM + write = 239, -- MSP_SET_ACC_TRIM + title = "Acc", + reboot = false, + eepromWrite = true, + minBytes = 4, + labels = labels, + fields = fields, +} From a2165ace38708b4022596b2843980691f2d53115 Mon Sep 17 00:00:00 2001 From: druckgott Date: Mon, 14 Nov 2022 08:01:43 +0100 Subject: [PATCH 165/193] Add new Page for Trim Acc --- src/SCRIPTS/BF/pages.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index 571a390a..db0d078e 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -56,4 +56,8 @@ if apiVersion >= 1.41 then PageFiles[#PageFiles + 1] = { title = "GPS PIDs", script = "gpspids.lua" } end +if apiVersion >= 1.16 then + PageFiles[#PageFiles + 1] = { title = "Trim Accelerometer", script = "acc_trim.lua" } +end + return PageFiles From 0877a7b5c912fbdbd8dbc3f3a9be4e6d7d9aef60 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 14 Nov 2022 14:46:47 +0100 Subject: [PATCH 166/193] Check for min attribute --- src/SCRIPTS/BF/ui.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 42db07f7..23f5bb9f 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -122,7 +122,7 @@ local function processMspReply(cmd,rx_buf) f.value = bit32.bor(f.value, raw_val) end local bits = #f.vals * 8 - if f.min < 0 and bit32.btest(f.value, bit32.lshift(1, bits - 1)) then + if f.min and f.min < 0 and bit32.btest(f.value, bit32.lshift(1, bits - 1)) then f.value = f.value - (2 ^ bits) end f.value = f.value/(f.scale or 1) From 331d5478988fa47f93b3fd604d1f2ef68122ac3f Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 17 Nov 2022 14:58:55 +0100 Subject: [PATCH 167/193] Fix nightly build --- .github/workflows/build-release.yml | 6 +-- .github/workflows/ci.yml | 4 +- .github/workflows/nightly.yml | 68 +++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/nightly.yml diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index a0a2c225..dbf60c75 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -14,13 +14,13 @@ jobs: release: name: Release needs: ci - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Code Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Fetch build artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 - name: List assets run: ls -al Assets diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c177ffa..e10e5e56 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,10 +16,10 @@ on: jobs: build: name: Build - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Code Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install Lua run: sudo apt-get -y install lua5.2 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 00000000..f2116b87 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,68 @@ +# You'll need to setup the follwing environment variables: +# env.repo_nightly - The repository to release nightly builds to e.g. betaflight-tx-lua-scripts-nightlies +# env.release_notes - The release notes to be published as part of the github release +# env.debug_release_notes - The release notes to be published as part of the github debug release +# secrets.REPO_TOKEN - A GitHub token with permissions to push and publish releases to the nightly repo + +env: + repo_nightly: betaflight/betaflight-tx-lua-scripts-nightlies + debug_release_notes: > + This is an automated development build. + It may be unstable and result in corrupted configurations or data loss. + **Use only for testing.** + release_notes: This is a release build. + +name: Nightly + +on: + push: + branches: + - master + +jobs: + ci: + name: CI + uses: ./.github/workflows/ci.yml + with: + release_build: false + + release: + name: Nightly release + needs: ci + runs-on: ubuntu-22.04 + steps: + - name: Code Checkout + uses: actions/checkout@v3 + + - name: Fetch build artifacts + uses: actions/download-artifact@v3 + + - name: Select release notes + id: notes + run: | + set -- Assets/*.zip + echo "notes=$(test -e "$1" && echo '${{ env.debug_release_notes }}' || echo '${{ env.release_notes }}')" >> $GITHUB_OUTPUT + - name: Get current date + id: date + run: echo "today=$(date '+%Y%m%d')" >> $GITHUB_OUTPUT + + - name: Release + uses: softprops/action-gh-release@1e07f4398721186383de40550babbdf2b84acfc5 # v0.1.14 + with: + token: ${{ secrets.REPO_TOKEN }} + repository: ${{ env.repo_nightly }} + tag_name: v${{ steps.date.outputs.today }}.${{ github.run_number }} + files: Assets/*.zip + draft: false + prerelease: false + fail_on_unmatched_files: true + body: | + ${{ steps.notes.outputs.notes }} + ### Repository: + ${{ github.repository }} ([link](${{ github.event.repository.html_url }})) + ### Branch: + ${{ github.ref_name }} ([link](${{ github.event.repository.html_url }}/tree/${{ github.ref_name }})) + ### Latest changeset: + ${{ github.event.head_commit.id }} ([link](${{ github.event.head_commit.url }})) + ### Changes: + ${{ github.event.head_commit.message }} From c997403b8322f788316986b1a8acc58bced78f72 Mon Sep 17 00:00:00 2001 From: druckgott Date: Mon, 5 Dec 2022 21:38:40 +0100 Subject: [PATCH 168/193] Add Page for Position OSD Elements (Betaflight 4.4 MSP), small Fix Add Page for Position OSD Elements (Betaflight 4.4 MSP) Add osd pos Page Update pos_osd.lua Update pages.lua Update pos_osd.lua --- src/SCRIPTS/BF/PAGES/pos_osd.lua | 161 +++++++++++++++++++++++++++++++ src/SCRIPTS/BF/pages.lua | 4 + 2 files changed, 165 insertions(+) create mode 100644 src/SCRIPTS/BF/PAGES/pos_osd.lua diff --git a/src/SCRIPTS/BF/PAGES/pos_osd.lua b/src/SCRIPTS/BF/PAGES/pos_osd.lua new file mode 100644 index 00000000..3417ac2f --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/pos_osd.lua @@ -0,0 +1,161 @@ +local template = assert(loadScript(radio.template))() +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +local items = { + {["address"] = 0, ["firstVal"] = 11, ["secondVal"] = 12, ["nameCli"] = "rssi_pos"}, + {["address"] = 1, ["firstVal"] = 13, ["secondVal"] = 14, ["nameCli"] = "vbat_pos"}, + {["address"] = 2, ["firstVal"] = 15, ["secondVal"] = 16, ["nameCli"] = "crosshairs_pos"}, + {["address"] = 3, ["firstVal"] = 17, ["secondVal"] = 18, ["nameCli"] = "ah_pos"}, + {["address"] = 4, ["firstVal"] = 19, ["secondVal"] = 20, ["nameCli"] = "ah_sbar_pos"}, + {["address"] = 5, ["firstVal"] = 21, ["secondVal"] = 22, ["nameCli"] = "tim_1_pos"}, + {["address"] = 6, ["firstVal"] = 23, ["secondVal"] = 24, ["nameCli"] = "tim_2_pos"}, + {["address"] = 7, ["firstVal"] = 25, ["secondVal"] = 26, ["nameCli"] = "flymode_pos"}, + {["address"] = 8, ["firstVal"] = 27, ["secondVal"] = 28, ["nameCli"] = "craft_name_pos"}, + {["address"] = 9, ["firstVal"] = 29, ["secondVal"] = 30, ["nameCli"] = "throttle_pos"}, + {["address"] = 10, ["firstVal"] = 31, ["secondVal"] = 32, ["nameCli"] = "vtx_channel_pos"}, + {["address"] = 11, ["firstVal"] = 33, ["secondVal"] = 34, ["nameCli"] = "current_pos"}, + {["address"] = 12, ["firstVal"] = 35, ["secondVal"] = 36, ["nameCli"] = "mah_drawn_pos"}, + {["address"] = 13, ["firstVal"] = 37, ["secondVal"] = 38, ["nameCli"] = "gps_speed_pos"}, + {["address"] = 14, ["firstVal"] = 39, ["secondVal"] = 40, ["nameCli"] = "gps_sats_pos"}, + {["address"] = 15, ["firstVal"] = 41, ["secondVal"] = 42, ["nameCli"] = "altitude_pos"}, + {["address"] = 16, ["firstVal"] = 43, ["secondVal"] = 44, ["nameCli"] = "pid_roll_pos"}, + {["address"] = 17, ["firstVal"] = 45, ["secondVal"] = 46, ["nameCli"] = "pid_pitch_pos"}, + {["address"] = 18, ["firstVal"] = 47, ["secondVal"] = 48, ["nameCli"] = "pid_yaw_pos"}, + {["address"] = 19, ["firstVal"] = 49, ["secondVal"] = 50, ["nameCli"] = "power_pos"}, + {["address"] = 20, ["firstVal"] = 51, ["secondVal"] = 52, ["nameCli"] = "pidrate_profile_pos"}, + {["address"] = 21, ["firstVal"] = 53, ["secondVal"] = 54, ["nameCli"] = "warnings_pos"}, + {["address"] = 22, ["firstVal"] = 55, ["secondVal"] = 56, ["nameCli"] = "avg_cell_voltage_pos"}, + {["address"] = 23, ["firstVal"] = 57, ["secondVal"] = 58, ["nameCli"] = "gps_lon_pos"}, + {["address"] = 24, ["firstVal"] = 59, ["secondVal"] = 60, ["nameCli"] = "gps_lat_pos"}, + {["address"] = 25, ["firstVal"] = 61, ["secondVal"] = 62, ["nameCli"] = "debug_pos"}, + {["address"] = 26, ["firstVal"] = 63, ["secondVal"] = 64, ["nameCli"] = "pit_ang_pos"}, + {["address"] = 27, ["firstVal"] = 65, ["secondVal"] = 66, ["nameCli"] = "rol_ang_pos"}, + {["address"] = 28, ["firstVal"] = 67, ["secondVal"] = 68, ["nameCli"] = "battery_usage_pos"}, + {["address"] = 29, ["firstVal"] = 69, ["secondVal"] = 70, ["nameCli"] = "disarmed_pos"}, + {["address"] = 30, ["firstVal"] = 71, ["secondVal"] = 72, ["nameCli"] = "home_dir_pos"}, + {["address"] = 31, ["firstVal"] = 73, ["secondVal"] = 74, ["nameCli"] = "home_dist_pos"}, + {["address"] = 32, ["firstVal"] = 75, ["secondVal"] = 76, ["nameCli"] = "nheading_pos"}, + {["address"] = 33, ["firstVal"] = 77, ["secondVal"] = 78, ["nameCli"] = "nvario_pos"}, + {["address"] = 34, ["firstVal"] = 79, ["secondVal"] = 80, ["nameCli"] = "compass_bar_pos"}, + {["address"] = 35, ["firstVal"] = 81, ["secondVal"] = 82, ["nameCli"] = "esc_tmp_pos"}, + {["address"] = 36, ["firstVal"] = 83, ["secondVal"] = 84, ["nameCli"] = "esc_rpm_pos"}, + {["address"] = 37, ["firstVal"] = 85, ["secondVal"] = 86, ["nameCli"] = "remaining_time_estimate_pos"}, + {["address"] = 38, ["firstVal"] = 87, ["secondVal"] = 88, ["nameCli"] = "rtc_date_time_pos"}, + {["address"] = 39, ["firstVal"] = 89, ["secondVal"] = 90, ["nameCli"] = "adjustment_range_pos"}, + {["address"] = 40, ["firstVal"] = 91, ["secondVal"] = 92, ["nameCli"] = "core_temp_pos"}, + {["address"] = 41, ["firstVal"] = 93, ["secondVal"] = 94, ["nameCli"] = "anti_gravity_pos"}, + {["address"] = 42, ["firstVal"] = 95, ["secondVal"] = 96, ["nameCli"] = "g_force_pos"}, + {["address"] = 43, ["firstVal"] = 97, ["secondVal"] = 98, ["nameCli"] = "motor_diag_pos"}, + {["address"] = 44, ["firstVal"] = 99, ["secondVal"] = 100, ["nameCli"] = "log_status_pos"}, + {["address"] = 45, ["firstVal"] = 101, ["secondVal"] = 102, ["nameCli"] = "flip_arrow_pos"}, + {["address"] = 46, ["firstVal"] = 103, ["secondVal"] = 104, ["nameCli"] = "link_quality_pos"}, + {["address"] = 47, ["firstVal"] = 105, ["secondVal"] = 106, ["nameCli"] = "flight_dist_pos"}, + {["address"] = 48, ["firstVal"] = 107, ["secondVal"] = 108, ["nameCli"] = "stick_overlay_left_pos"}, + {["address"] = 49, ["firstVal"] = 109, ["secondVal"] = 110, ["nameCli"] = "stick_overlay_right_pos"}, + {["address"] = 50, ["firstVal"] = 111, ["secondVal"] = 112, ["nameCli"] = "display_name_pos"}, + {["address"] = 51, ["firstVal"] = 113, ["secondVal"] = 114, ["nameCli"] = "esc_rpm_freq_pos"}, + {["address"] = 52, ["firstVal"] = 115, ["secondVal"] = 116, ["nameCli"] = "rate_profile_name_pos"}, + {["address"] = 53, ["firstVal"] = 117, ["secondVal"] = 118, ["nameCli"] = "pid_profile_name_pos"}, + {["address"] = 54, ["firstVal"] = 119, ["secondVal"] = 120, ["nameCli"] = "profile_name_pos"}, + {["address"] = 55, ["firstVal"] = 121, ["secondVal"] = 122, ["nameCli"] = "rssi_dbm_pos"}, + {["address"] = 56, ["firstVal"] = 123, ["secondVal"] = 124, ["nameCli"] = "rcchannels_pos"}, + {["address"] = 57, ["firstVal"] = 125, ["secondVal"] = 126, ["nameCli"] = "camera_frame_pos"}, + {["address"] = 58, ["firstVal"] = 127, ["secondVal"] = 128, ["nameCli"] = "efficiency_pos"}, + {["address"] = 59, ["firstVal"] = 129, ["secondVal"] = 130, ["nameCli"] = "total_flights_pos"}, + {["address"] = 60, ["firstVal"] = 131, ["secondVal"] = 132, ["nameCli"] = "up_down_reference_pos"}, + {["address"] = 61, ["firstVal"] = 133, ["secondVal"] = 134, ["nameCli"] = "link_tx_power_pos"}, + {["address"] = 62, ["firstVal"] = 135, ["secondVal"] = 136, ["nameCli"] = "wh_drawn_pos"}, + {["address"] = 63, ["firstVal"] = 137, ["secondVal"] = 138, ["nameCli"] = "aux_pos"}, + {["address"] = 64, ["firstVal"] = 139, ["secondVal"] = 140, ["nameCli"] = "ready_mode_pos"}, + {["address"] = 65, ["firstVal"] = 141, ["secondVal"] = 142, ["nameCli"] = "rsnr_pos"}, + {["address"] = 66, ["firstVal"] = 143, ["secondVal"] = 144, ["nameCli"] = "sys_goggle_voltage_pos"}, + {["address"] = 67, ["firstVal"] = 145, ["secondVal"] = 146, ["nameCli"] = "sys_vtx_voltage_pos"}, + {["address"] = 68, ["firstVal"] = 147, ["secondVal"] = 148, ["nameCli"] = "sys_bitrate_pos"}, + {["address"] = 69, ["firstVal"] = 149, ["secondVal"] = 150, ["nameCli"] = "sys_delay_pos"}, + {["address"] = 70, ["firstVal"] = 151, ["secondVal"] = 152, ["nameCli"] = "sys_distance_pos"}, + {["address"] = 71, ["firstVal"] = 153, ["secondVal"] = 154, ["nameCli"] = "sys_lq_pos"}, + {["address"] = 72, ["firstVal"] = 155, ["secondVal"] = 156, ["nameCli"] = "sys_goggle_dvr_pos"}, + {["address"] = 73, ["firstVal"] = 157, ["secondVal"] = 158, ["nameCli"] = "sys_vtx_dvr_pos"}, + {["address"] = 74, ["firstVal"] = 159, ["secondVal"] = 160, ["nameCli"] = "sys_warnings_pos"}, + {["address"] = 75, ["firstVal"] = 161, ["secondVal"] = 162, ["nameCli"] = "sys_vtx_temp_pos"}, + {["address"] = 76, ["firstVal"] = 163, ["secondVal"] = 164, ["nameCli"] = "sys_fan_speed_pos"}, +} + +address = address or 0 +local firstVal = items[address + 1]["firstVal"] +local secondVal = items[address + 1]["secondVal"] +local nameCli = items[address + 1]["nameCli"] + +x = margin +y = yMinLim - tableSpacing.header + +fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.header), min = 0, max = (#items - 1), vals = { 1 }, upd = function(self) self.updateItems(self) end } +labels[#labels + 1] = { t = nameCli, x = x + tableSpacing.col * 1, y = y } + +labels[#labels + 1] = { t = "POS", x = x, y = inc.y(tableSpacing.header) } +labels[#labels + 1] = { t = "OP1", x = x + tableSpacing.col, y = y } +labels[#labels + 1] = { t = "OP2", x = x + tableSpacing.col * 2, y = y } +labels[#labels + 1] = { t = "OP3", x = x + tableSpacing.col * 3, y = y } + +fields[#fields + 1] = { x = x, y = inc.y(tableSpacing.row), min = 0, max = 2047, vals = { 2, 3 } } +fields[#fields + 1] = { x = x + tableSpacing.col, y = y, min = 0, max = 1, vals = { 1, 2 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { x = x + tableSpacing.col * 2, y = y, min = 0, max = 1, vals = { 1, 2 }, table = { [0] = "OFF", "ON" } } +fields[#fields + 1] = { x = x + tableSpacing.col * 3, y = y, min = 0, max = 1, vals = { 1, 2 }, table = { [0] = "OFF", "ON" } } + +return { + read = 84, -- MSP_OSD_CONFIG + write = 85, -- MSP_SET_OSD_CONFIG + title = "OSD Elements", + reboot = false, + eepromWrite = true, + minBytes = 3, + labels = labels, + fields = fields, + postLoad = function(self) + self.fields[1].value = address + self.fields[2].value, self.fields[3].value, self.fields[4].value, self.fields[5].value = self.splitVal(self, self.values[firstVal], self.values[secondVal]) + end, + preSave = function(self) + self.values = {} + self.values[1] = self.fields[1].value + local combineValue = self.checkProfile(self, self.fields[2].value, self.fields[3].value, self.fields[4].value, self.fields[5].value) + self.values[2] = bit32.band(combineValue, 0xFF) + self.values[3] = bit32.rshift(combineValue, 8) + return self.values + end, + checkProfile = function(self, value, profileFirst, profileSecond, profileThird) + local profiles = profileFirst + bit32.lshift(profileSecond, 1) + bit32.lshift(profileThird, 2) + local output = bit32.replace(value, profiles, 11, 3) + return output + end, + splitVal = function(self, inputFirstVal, inputSecondVal) + local inputVal = inputFirstVal + bit32.lshift(inputSecondVal, 8) + local profiles = bit32.extract(inputVal, 11, 3) + local fieldPos = bit32.extract(inputVal, 0, 11) + local fieldFirstProfile = bit32.band(bit32.rshift(profiles, 0), 1) + local FieldSecondProfile = bit32.band(bit32.rshift(profiles, 1), 1) + local FieldThirdProfile = bit32.band(bit32.rshift(profiles, 2), 1) + return fieldPos, fieldFirstProfile, FieldSecondProfile, FieldThirdProfile + end, + updateItems = function(self) + if self.fields[1].value ~= items[address + 1]["address"] then + address = self.fields[1].value + firstVal = items[address + 1]["firstVal"] + secondVal = items[address + 1]["secondVal"] + address = items[address + 1]["address"] + nameCli = items[address + 1]["nameCli"] + self.labels[1].t = nameCli + self.fields[2].value, self.fields[3].value, self.fields[4].value, self.fields[5].value = self.splitVal(self, self.values[firstVal], self.values[secondVal]) + end + end +} diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index db0d078e..d1f1e017 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -60,4 +60,8 @@ if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "Trim Accelerometer", script = "acc_trim.lua" } end +if apiVersion >= 1.45 then + PageFiles[#PageFiles + 1] = { title = "OSD Elements", script = "pos_osd.lua" } +end + return PageFiles From 9f07432ebc105b370ddaba21f919525021703b5e Mon Sep 17 00:00:00 2001 From: Mark Haslinghuis Date: Sat, 14 Jan 2023 21:12:25 +0100 Subject: [PATCH 169/193] Add scale to ground speed for >= API 1.45 --- src/SCRIPTS/BF/PAGES/rescue.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/PAGES/rescue.lua b/src/SCRIPTS/BF/PAGES/rescue.lua index 448de7bb..cdbd21a4 100644 --- a/src/SCRIPTS/BF/PAGES/rescue.lua +++ b/src/SCRIPTS/BF/PAGES/rescue.lua @@ -16,7 +16,12 @@ if apiVersion >= 1.41 then fields[#fields + 1] = { t = "Angle", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 200, vals = { 1, 2 } } fields[#fields + 1] = { t = "Initial Altitude", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 100, vals = { 3, 4 } } fields[#fields + 1] = { t = "Descent Distance", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 30, max = 500, vals = { 5, 6 } } - fields[#fields + 1] = { t = "Ground Speed", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 30, max = 3000, vals = { 7, 8 } } + + if apiVersion >= 1.45 then + fields[#fields + 1] = { t = "Ground Speed", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 3000, vals = { 7, 8 }, scale = 100 } + else + fields[#fields + 1] = { t = "Ground Speed", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 30, max = 3000, vals = { 7, 8 } } + end if apiVersion >= 1.43 then fields[#fields + 1] = { t = "Ascend Rate", x = x, y = inc.y(lineSpacing), sp = x + sp, min = 100, max = 2500, vals = { 17, 18 }, scale = 100 } From 633d3ba5a1f588193c0aa82dded1b7a0319a6ad0 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 30 Jan 2023 20:24:56 +0100 Subject: [PATCH 170/193] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9e7dd41e..2464a147 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![BF lua logo light mode](docs/assets/images/bf_lua_logo_light_mode.png#gh-light-mode-only) ![BF lua logo dark mode](docs/assets/images/bf_lua_logo_dark_mode.png#gh-dark-mode-only) - [![Latest version](https://img.shields.io/github/v/release/betaflight/betaflight-tx-lua-scripts)](https://github.com/betaflight/betaflight-tx-lua-scripts/releases) [![Build Status](https://api.travis-ci.com/betaflight/betaflight-tx-lua-scripts.svg?branch=master)](https://travis-ci.com/betaflight/betaflight-tx-lua-scripts) [![Build Status](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_apis/build/status/betaflight.betaflight-tx-lua-scripts?branchName=master)](https://dev.azure.com/Betaflight/Betaflight%20Nightlies/_build/latest?definitionId=1&branchName=master) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) + [![Latest version](https://img.shields.io/github/v/release/betaflight/betaflight-tx-lua-scripts)](https://github.com/betaflight/betaflight-tx-lua-scripts/releases) [![Build](https://img.shields.io/github/actions/workflow/status/betaflight/betaflight-tx-lua-scripts/nightly.yml?branch=master)](https://github.com/betaflight/betaflight-tx-lua-scripts/actions/workflows/nightly.yml) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) ## Requirements @@ -10,8 +10,9 @@ - OpenTX - 2.3.12 or newer; - EdgeTX - 2.4.0 or newer; - ExpressLRS - 2.0.1 or newer; -- Crossfire TX / RX - v2.11 or newer; +- TBS Crossfire/Tracer TX / RX - v2.11 or newer; - FrSky TX / RX with support for SmartPort - While most receivers with SmartPort support work fine, it is recommended to update the receiver to the most recent firmware version to correct any known bugs in telemetry. +- ImmersionRC Ghost - Latest firmware. ## Installing From 0d472a324706c3cecf179f85ec400540064b5ba9 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Thu, 16 Feb 2023 20:18:34 +0100 Subject: [PATCH 171/193] Add baud rate requirement --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2464a147..0f40f746 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ - TBS Crossfire/Tracer TX / RX - v2.11 or newer; - FrSky TX / RX with support for SmartPort - While most receivers with SmartPort support work fine, it is recommended to update the receiver to the most recent firmware version to correct any known bugs in telemetry. - ImmersionRC Ghost - Latest firmware. +- Baud rate - Set to 400K in EdgeTX/OpenTX for Crossfire, Tracer, ExpressLRS and Ghost. ## Installing From 7bf0f044e16fd7427c5c9dcc75a94f9f0e2edca1 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 5 Mar 2023 22:59:10 +0100 Subject: [PATCH 172/193] Add level angle limit --- src/SCRIPTS/BF/PAGES/pid_advanced.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/SCRIPTS/BF/PAGES/pid_advanced.lua b/src/SCRIPTS/BF/PAGES/pid_advanced.lua index 16d54cf6..5be23f12 100644 --- a/src/SCRIPTS/BF/PAGES/pid_advanced.lua +++ b/src/SCRIPTS/BF/PAGES/pid_advanced.lua @@ -11,6 +11,14 @@ local inc = { x = function(val) x = x + val return x end, y = function(val) y = local labels = {} local fields = {} +if apiVersion >= 1.31 then + labels[#labels + 1] = { t = "Angle/Horizon", x = x, y = inc.y(lineSpacing) } + fields[#fields + 1] = { t = "Angle Limit", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 10, max = 90, vals = { 18 } } + if apiVersion < 1.36 then + fields[#fields + 1] = { t = "Stick Sensitivity", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 10, max = 200, vals = { 19 } } + end +end + if apiVersion >= 1.40 then labels[#labels + 1] = { t = "Acro Trainer", x = x, y = inc.y(lineSpacing) } fields[#fields + 1] = { t = "Angle Limit", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 20, max = 80, vals = { 32 } } From e2597af37aa0a3ee24c97acdcc12ea00f2f1c94e Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 12 Mar 2023 20:29:27 +0100 Subject: [PATCH 173/193] Skip vtx tables download if not available --- src/SCRIPTS/BF/MSP/common.lua | 9 +++------ src/SCRIPTS/BF/PAGES/vtx.lua | 5 +++-- src/SCRIPTS/BF/acc_cal.lua | 4 ++-- src/SCRIPTS/BF/api_version.lua | 4 ++-- src/SCRIPTS/BF/board_info.lua | 4 ++-- src/SCRIPTS/BF/mcu_id.lua | 4 ++-- src/SCRIPTS/BF/rssi.lua | 4 ++-- src/SCRIPTS/BF/rtc.lua | 4 ++-- src/SCRIPTS/BF/ui.lua | 4 ++-- src/SCRIPTS/BF/vtx_tables.lua | 9 +++++++-- 10 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/SCRIPTS/BF/MSP/common.lua b/src/SCRIPTS/BF/MSP/common.lua index dc20f9bd..467c1ce1 100644 --- a/src/SCRIPTS/BF/MSP/common.lua +++ b/src/SCRIPTS/BF/MSP/common.lua @@ -6,6 +6,7 @@ local MSP_STARTFLAG = bit32.lshift(1,4) local mspSeq = 0 local mspRemoteSeq = 0 local mspRxBuf = {} +local mspRxError = false local mspRxSize = 0 local mspRxCRC = 0 local mspRxReq = 0 @@ -65,17 +66,13 @@ end function mspReceivedReply(payload) local idx = 1 local status = payload[idx] - local err = bit32.btest(status, 0x80) local version = bit32.rshift(bit32.band(status, 0x60), 5) local start = bit32.btest(status, 0x10) local seq = bit32.band(status, 0x0F) idx = idx + 1 - if err then - mspStarted = false - return nil - end if start then mspRxBuf = {} + mspRxError = bit32.btest(status, 0x80) mspRxSize = payload[idx] mspRxReq = mspLastReq idx = idx + 1 @@ -117,7 +114,7 @@ function mspPollReply() return nil elseif mspReceivedReply(mspData) then mspLastReq = 0 - return mspRxReq, mspRxBuf + return mspRxReq, mspRxBuf, mspRxError end end end diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index e2a978e0..b40e9125 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -12,8 +12,9 @@ local labels = {} local fields = {} local vtx_tables -if apiVersion >= 1.42 then - vtx_tables = assert(loadScript("VTX_TABLES/"..mcuId..".lua"))() +local f = loadScript("VTX_TABLES/"..mcuId..".lua") +if apiVersion >= 1.42 and f then + vtx_tables = f() else vtx_tables = assert(loadScript("VTX_TABLES/vtx_defaults.lua"))() end diff --git a/src/SCRIPTS/BF/acc_cal.lua b/src/SCRIPTS/BF/acc_cal.lua index 582d459c..0ebfc17b 100644 --- a/src/SCRIPTS/BF/acc_cal.lua +++ b/src/SCRIPTS/BF/acc_cal.lua @@ -3,8 +3,8 @@ local accCalibrated = false local lastRunTS = 0 local INTERVAL = 500 -local function processMspReply(cmd,rx_buf) - if cmd == MSP_ACC_CALIBRATION then +local function processMspReply(cmd,rx_buf,err) + if cmd == MSP_ACC_CALIBRATION and not err then accCalibrated = true end end diff --git a/src/SCRIPTS/BF/api_version.lua b/src/SCRIPTS/BF/api_version.lua index c80efb3d..5bcb4c2b 100644 --- a/src/SCRIPTS/BF/api_version.lua +++ b/src/SCRIPTS/BF/api_version.lua @@ -4,8 +4,8 @@ local apiVersionReceived = false local lastRunTS = 0 local INTERVAL = 50 -local function processMspReply(cmd,rx_buf) - if cmd == MSP_API_VERSION and #rx_buf >= 3 then +local function processMspReply(cmd,rx_buf,err) + if cmd == MSP_API_VERSION and #rx_buf >= 3 and not err then apiVersion = rx_buf[2] + rx_buf[3] / 100 apiVersionReceived = true end diff --git a/src/SCRIPTS/BF/board_info.lua b/src/SCRIPTS/BF/board_info.lua index 10efbe40..2ba3ec1c 100644 --- a/src/SCRIPTS/BF/board_info.lua +++ b/src/SCRIPTS/BF/board_info.lua @@ -20,8 +20,8 @@ local i2cRegisteredDeviceCount = 0 local lastRunTS = 0 local INTERVAL = 100 -local function processMspReply(cmd, payload) - if cmd == MSP_BOARD_INFO then +local function processMspReply(cmd, payload, err) + if cmd == MSP_BOARD_INFO and not err then local length local i = 1 length = 4 diff --git a/src/SCRIPTS/BF/mcu_id.lua b/src/SCRIPTS/BF/mcu_id.lua index 26d1e2ba..f3c84387 100644 --- a/src/SCRIPTS/BF/mcu_id.lua +++ b/src/SCRIPTS/BF/mcu_id.lua @@ -5,8 +5,8 @@ local MCUIdReceived = false local lastRunTS = 0 local INTERVAL = 100 -local function processMspReply(cmd, payload) - if cmd == MSP_UID then +local function processMspReply(cmd, payload, err) + if cmd == MSP_UID and not err then local i = 1 local id = "" for j = 1, 3 do diff --git a/src/SCRIPTS/BF/rssi.lua b/src/SCRIPTS/BF/rssi.lua index 401e7103..dc31dd03 100644 --- a/src/SCRIPTS/BF/rssi.lua +++ b/src/SCRIPTS/BF/rssi.lua @@ -9,8 +9,8 @@ local rssiSource = RSSI_SOURCE_NONE local lastRunTS = 0 local INTERVAL = 50 -local function processMspReply(cmd,rx_buf) - if cmd == MSP_TX_INFO and #rx_buf >= 1 then +local function processMspReply(cmd,rx_buf,err) + if cmd == MSP_TX_INFO and #rx_buf >= 1 and not err then rssiSource = rx_buf[1] rssiSourceReceived = true end diff --git a/src/SCRIPTS/BF/rtc.lua b/src/SCRIPTS/BF/rtc.lua index 148a2fd3..f0cd3306 100644 --- a/src/SCRIPTS/BF/rtc.lua +++ b/src/SCRIPTS/BF/rtc.lua @@ -4,8 +4,8 @@ local timeIsSet = false local lastRunTS = 0 local INTERVAL = 50 -local function processMspReply(cmd,rx_buf) - if cmd == MSP_SET_RTC then +local function processMspReply(cmd,rx_buf,err) + if cmd == MSP_SET_RTC and not err then timeIsSet = true end end diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 23f5bb9f..8a3722ce 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -96,8 +96,8 @@ local function createPopupMenu() end end -local function processMspReply(cmd,rx_buf) - if not Page or not rx_buf then +local function processMspReply(cmd,rx_buf,err) + if not Page or not rx_buf or err then elseif cmd == Page.write then if Page.eepromWrite then eepromWrite() diff --git a/src/SCRIPTS/BF/vtx_tables.lua b/src/SCRIPTS/BF/vtx_tables.lua index 2efa8942..1340af8f 100644 --- a/src/SCRIPTS/BF/vtx_tables.lua +++ b/src/SCRIPTS/BF/vtx_tables.lua @@ -2,6 +2,7 @@ local MSP_VTX_CONFIG = 88 local MSP_VTXTABLE_BAND = 137 local MSP_VTXTABLE_POWERLEVEL = 138 +local vtxAvailable = true local vtxTableAvailable = false local vtxConfigReceived = false local vtxFrequencyTableReceived = false @@ -18,8 +19,12 @@ local powerTable = {} local lastRunTS = 0 local INTERVAL = 100 -local function processMspReply(cmd, payload) +local function processMspReply(cmd, payload, err) if cmd == MSP_VTX_CONFIG then + if err then + vtxAvailable = false + return + end vtxConfigReceived = true vtxTableAvailable = payload[12] ~= 0 vtxTableConfig.bands = payload[13] @@ -113,7 +118,7 @@ local function getVtxTables() end mspProcessTxQ() processMspReply(mspPollReply()) - return vtxTablesReceived + return vtxTablesReceived or not vtxAvailable end return { f = getVtxTables, t = "Downloading VTX tables" } From 3ea553eda0d04e3a15745705824aaf8abc294a84 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Sun, 12 Mar 2023 21:55:58 +0100 Subject: [PATCH 174/193] Display message if page not available --- src/SCRIPTS/BF/ui.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 8a3722ce..fee070ea 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -97,7 +97,7 @@ local function createPopupMenu() end local function processMspReply(cmd,rx_buf,err) - if not Page or not rx_buf or err then + if not Page or not rx_buf then elseif cmd == Page.write then if Page.eepromWrite then eepromWrite() @@ -109,6 +109,9 @@ local function processMspReply(cmd,rx_buf,err) rebootFc() end invalidatePages() + elseif cmd == Page.read and err then + Page.fields = { { x = 6, y = radio.yMinLimit, value = "", ro = true } } + Page.labels = { { x = 6, y = radio.yMinLimit, t = "N/A" } } elseif cmd == Page.read and #rx_buf > 0 then Page.values = rx_buf for i=1,#Page.fields do From 61d302980967f05f3e8a4957dfc45c859559cdf0 Mon Sep 17 00:00:00 2001 From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com> Date: Mon, 13 Mar 2023 14:08:18 +0100 Subject: [PATCH 175/193] Create empty vtx table if not available --- src/SCRIPTS/BF/PAGES/vtx.lua | 5 ++--- src/SCRIPTS/BF/vtx_tables.lua | 14 ++++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index b40e9125..e2a978e0 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -12,9 +12,8 @@ local labels = {} local fields = {} local vtx_tables -local f = loadScript("VTX_TABLES/"..mcuId..".lua") -if apiVersion >= 1.42 and f then - vtx_tables = f() +if apiVersion >= 1.42 then + vtx_tables = assert(loadScript("VTX_TABLES/"..mcuId..".lua"))() else vtx_tables = assert(loadScript("VTX_TABLES/vtx_defaults.lua"))() end diff --git a/src/SCRIPTS/BF/vtx_tables.lua b/src/SCRIPTS/BF/vtx_tables.lua index 1340af8f..d7edbba6 100644 --- a/src/SCRIPTS/BF/vtx_tables.lua +++ b/src/SCRIPTS/BF/vtx_tables.lua @@ -2,7 +2,6 @@ local MSP_VTX_CONFIG = 88 local MSP_VTXTABLE_BAND = 137 local MSP_VTXTABLE_POWERLEVEL = 138 -local vtxAvailable = true local vtxTableAvailable = false local vtxConfigReceived = false local vtxFrequencyTableReceived = false @@ -12,7 +11,6 @@ local requestedBand = 1 local requestedPowerLevel = 1 local vtxTableConfig = {} local frequencyTable = {} -local frequenciesPerBand = 0 local bandTable = {} local powerTable = {} @@ -22,7 +20,15 @@ local INTERVAL = 100 local function processMspReply(cmd, payload, err) if cmd == MSP_VTX_CONFIG then if err then - vtxAvailable = false + -- Vtx not available. Create empty vtx table to skip future download attempts + frequencyTable[1] = {} + vtxTableConfig.channels = 0 + bandTable = { [0] = "U", "1" } + powerTable = { "LV0" } + vtxConfigReceived = true + vtxTableAvailable = true + vtxFrequencyTableReceived = true + vtxPowerTableReceived = true return end vtxConfigReceived = true @@ -118,7 +124,7 @@ local function getVtxTables() end mspProcessTxQ() processMspReply(mspPollReply()) - return vtxTablesReceived or not vtxAvailable + return vtxTablesReceived end return { f = getVtxTables, t = "Downloading VTX tables" } From 47f9efbbe45c958108862d2ec63fb30a2fc73a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Thu, 25 May 2023 19:02:19 +0200 Subject: [PATCH 176/193] Hide VTX menu when feature is unavailable --- src/SCRIPTS/BF/features.lua | 5 +++++ src/SCRIPTS/BF/ui.lua | 20 +++++++++++++++++++- src/SCRIPTS/BF/ui_init.lua | 13 +++++++++---- src/SCRIPTS/BF/vtx_tables.lua | 2 ++ src/SCRIPTS/TOOLS/bf.lua | 1 + 5 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 src/SCRIPTS/BF/features.lua diff --git a/src/SCRIPTS/BF/features.lua b/src/SCRIPTS/BF/features.lua new file mode 100644 index 00000000..d56d8ff2 --- /dev/null +++ b/src/SCRIPTS/BF/features.lua @@ -0,0 +1,5 @@ +local features = { + vtx = true, +} + +return features diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index fee070ea..1dd11612 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -82,6 +82,24 @@ local function confirm(page) collectgarbage() end +local function filterAvailablePages(pageFiles) + local newPageFiles = pageFiles + + local function skipPage(script) + local currentPageFiles = {} + for i = 1, #newPageFiles do + if newPageFiles[i].script ~= script then + currentPageFiles[#currentPageFiles + 1] = newPageFiles[i] + end + end + newPageFiles = currentPageFiles + end + + if not features.vtx then skipPage("vtx.lua") end + + return newPageFiles +end + local function createPopupMenu() popupMenuActive = 1 popupMenu = {} @@ -296,7 +314,7 @@ local function run_ui(event) return 0 end init = nil - PageFiles = assert(loadScript("pages.lua"))() + PageFiles = filterAvailablePages(assert(loadScript("pages.lua"))()) invalidatePages() uiState = prevUiState or uiStatus.mainMenu prevUiState = nil diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 29ca80ec..1c624c8f 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -22,10 +22,15 @@ local function init() mcuIdReceived = getMCUId.f() if mcuIdReceived then getMCUId = nil - local f = loadScript("VTX_TABLES/"..mcuId..".lua") - if f and f() then - vtxTablesReceived = true - f = nil + local f = loadScript("VTX_TABLES/" .. mcuId .. ".lua") + if f then + local table = f() + if table then + vtxTablesReceived = true + features.vtx = 0 < table.frequenciesPerBand + f = nil + table = nil + end end collectgarbage() f = loadScript("BOARD_INFO/"..mcuId..".lua") diff --git a/src/SCRIPTS/BF/vtx_tables.lua b/src/SCRIPTS/BF/vtx_tables.lua index d7edbba6..13f05265 100644 --- a/src/SCRIPTS/BF/vtx_tables.lua +++ b/src/SCRIPTS/BF/vtx_tables.lua @@ -29,10 +29,12 @@ local function processMspReply(cmd, payload, err) vtxTableAvailable = true vtxFrequencyTableReceived = true vtxPowerTableReceived = true + features.vtx = false return end vtxConfigReceived = true vtxTableAvailable = payload[12] ~= 0 + features.vtx = vtxTableAvailable vtxTableConfig.bands = payload[13] vtxTableConfig.channels = payload[14] vtxTableConfig.powerLevels = payload[15] diff --git a/src/SCRIPTS/TOOLS/bf.lua b/src/SCRIPTS/TOOLS/bf.lua index 3c4ee8b1..2b42f18b 100644 --- a/src/SCRIPTS/TOOLS/bf.lua +++ b/src/SCRIPTS/TOOLS/bf.lua @@ -12,6 +12,7 @@ if scriptsCompiled then radio = assert(loadScript("radios.lua"))().msp assert(loadScript(protocol.mspTransport))() assert(loadScript("MSP/common.lua"))() + features = assert(loadScript("features.lua"))() run = assert(loadScript("ui.lua"))() else run = assert(loadScript("COMPILE/compile.lua"))() From 59b9d74d73231ca19b5ff54d1f277f8d671a31a6 Mon Sep 17 00:00:00 2001 From: adarkthinline <48429025+adarkthinline@users.noreply.github.com> Date: Tue, 29 Aug 2023 12:31:27 +0000 Subject: [PATCH 177/193] Modified Readme.md Ghost Race250 requirement for LUA script --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0f40f746..5611d6fc 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,14 @@ ## Requirements - Betaflight - As a best practice, it is recommended to use the most recent stable release of Betaflight to obtain the best possible results; -- Telemetry - Telemetry has to be enabled and supported by the TX / RX for the scripts to be able to communicate with the flight controller; +- Telemetry - Telemetry has to be enabled in Betaflight Receiver tab and supported by the TX / RX for the scripts to be able to communicate with the flight controller; - OpenTX - 2.3.12 or newer; - EdgeTX - 2.4.0 or newer; - ExpressLRS - 2.0.1 or newer; - TBS Crossfire/Tracer TX / RX - v2.11 or newer; - FrSky TX / RX with support for SmartPort - While most receivers with SmartPort support work fine, it is recommended to update the receiver to the most recent firmware version to correct any known bugs in telemetry. -- ImmersionRC Ghost - Latest firmware. -- Baud rate - Set to 400K in EdgeTX/OpenTX for Crossfire, Tracer, ExpressLRS and Ghost. +- ImmersionRC Ghost RX module - Latest firmware and module set to RF Mode "Race250" - see (Ghost receiver manual pg 36-38) (Other RF Modes have issues or do not have telemetry to allow Betaflight LUA to work). +- Baud rate - Set to 400K in EdgeTX/OpenTX for Crossfire, Tracer, ExpressLRS. ## Installing From 64903c6668c9904907c3440a21d0d53e5bcd689a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Fri, 20 Oct 2023 14:52:47 +0200 Subject: [PATCH 178/193] Information about hiding the menu, followup to #480 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5611d6fc..67a520b6 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ Depending on the size of the vtx tables and the telemetry protocol used, downloa ![Download VTX tables](docs/assets/images/download_vtx_tables.gif) +Please note that if the "VTX" feature wasn't included in your Betaflight firmware build, the downloading of the VTX tables will be skipped and the VTX menu item won't be available. The initial setup of the VTX/VTX tables must be done using the [Configurator](https://github.com/betaflight/betaflight-configurator). + ### Betaflight CMS **!! IMPORTANT: TBS Crossfire/Tracer only !!** From 1f890f533f7c752e3b7ee9e01c3ad161c07b01fe Mon Sep 17 00:00:00 2001 From: Mark Haslinghuis Date: Mon, 8 Jan 2024 15:23:34 +0100 Subject: [PATCH 179/193] Migrate hub to gh See: actions/runner-images#8362 Usage: https://cli.github.com/manual/gh_release_edit --- .github/workflows/build-release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index dbf60c75..fba4d048 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -28,12 +28,12 @@ jobs: - name: Attach assets to release run: | set -x - assets=() + ASSETS=() for asset in Assets/*.zip; do - assets+=("-a" "$asset") + ASSETS+=("-a" "$asset") echo "$asset" done - tag_name="${GITHUB_REF##*/}" - hub release edit "${assets[@]}" -m "" "$tag_name" + TAG_NAME="${GITHUB_REF##*/}" + gh release edit "${ASSETS[@]}" "{TAG_NAME}" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 8c3dcd33d70297b460e07e0c9c3f202599ac51c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Sun, 14 Jan 2024 13:02:39 +0100 Subject: [PATCH 180/193] Hide GPS settings if unavailable --- src/SCRIPTS/BF/PAGES/vtx.lua | 2 -- src/SCRIPTS/BF/features.lua | 1 + src/SCRIPTS/BF/features_info.lua | 52 ++++++++++++++++++++++++++++++++ src/SCRIPTS/BF/pages.lua | 6 ++-- src/SCRIPTS/BF/ui.lua | 20 +----------- src/SCRIPTS/BF/ui_init.lua | 13 ++++++-- 6 files changed, 68 insertions(+), 26 deletions(-) create mode 100644 src/SCRIPTS/BF/features_info.lua diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index e2a978e0..0e002b40 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -1,8 +1,6 @@ local template = assert(loadScript(radio.template))() local margin = template.margin -local indent = template.indent local lineSpacing = template.lineSpacing -local tableSpacing = template.tableSpacing local sp = template.listSpacing.field local yMinLim = radio.yMinLimit local x = margin diff --git a/src/SCRIPTS/BF/features.lua b/src/SCRIPTS/BF/features.lua index d56d8ff2..383252ae 100644 --- a/src/SCRIPTS/BF/features.lua +++ b/src/SCRIPTS/BF/features.lua @@ -1,5 +1,6 @@ local features = { vtx = true, + gps = true, } return features diff --git a/src/SCRIPTS/BF/features_info.lua b/src/SCRIPTS/BF/features_info.lua new file mode 100644 index 00000000..bb28ecfa --- /dev/null +++ b/src/SCRIPTS/BF/features_info.lua @@ -0,0 +1,52 @@ +local MSP_GPS_CONFIG = 135 +local MSP_VTX_CONFIG = 88 + +local isGpsRead = false +local isVtxRead = true -- Checking VTX is done in `vtx_tables.lua` + +local lastRunTS = 0 +local INTERVAL = 100 + +local returnTable = { + f = nil, + t = "", +} + +local function processMspReply(cmd, payload, err) + local isOkay = not err + if cmd == MSP_GPS_CONFIG then + isGpsRead = true + local providerSet = payload[1] ~= 0 + features.gps = isOkay and providerSet + elseif cmd == MSP_VTX_CONFIG then + isVtxRead = true + local vtxTableAvailable = payload[12] ~= 0 + features.vtx = isOkay and vtxTableAvailable + end +end + +local function updateFeatures() + if lastRunTS + INTERVAL < getTime() then + lastRunTS = getTime() + local cmd + if not isGpsRead then + cmd = MSP_GPS_CONFIG + returnTable.t = "Checking GPS..." + elseif not isVtxRead then + cmd = MSP_VTX_CONFIG + returnTable.t = "Checking VTX..." + end + if cmd then + protocol.mspRead(cmd) + else + return true + end + end + mspProcessTxQ() + processMspReply(mspPollReply()) + return false +end + +returnTable.f = updateFeatures + +return returnTable diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index d1f1e017..979b733f 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -1,6 +1,6 @@ local PageFiles = {} -if apiVersion >= 1.36 then +if apiVersion >= 1.36 and features.vtx then PageFiles[#PageFiles + 1] = { title = "VTX Settings", script = "vtx.lua" } end @@ -48,11 +48,11 @@ if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "Failsafe", script = "failsafe.lua" } end -if apiVersion >= 1.41 then +if apiVersion >= 1.41 and features.gps then PageFiles[#PageFiles + 1] = { title = "GPS Rescue", script = "rescue.lua" } end -if apiVersion >= 1.41 then +if apiVersion >= 1.41 and features.gps then PageFiles[#PageFiles + 1] = { title = "GPS PIDs", script = "gpspids.lua" } end diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index 1dd11612..fee070ea 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -82,24 +82,6 @@ local function confirm(page) collectgarbage() end -local function filterAvailablePages(pageFiles) - local newPageFiles = pageFiles - - local function skipPage(script) - local currentPageFiles = {} - for i = 1, #newPageFiles do - if newPageFiles[i].script ~= script then - currentPageFiles[#currentPageFiles + 1] = newPageFiles[i] - end - end - newPageFiles = currentPageFiles - end - - if not features.vtx then skipPage("vtx.lua") end - - return newPageFiles -end - local function createPopupMenu() popupMenuActive = 1 popupMenu = {} @@ -314,7 +296,7 @@ local function run_ui(event) return 0 end init = nil - PageFiles = filterAvailablePages(assert(loadScript("pages.lua"))()) + PageFiles = assert(loadScript("pages.lua"))() invalidatePages() uiState = prevUiState or uiStatus.mainMenu prevUiState = nil diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 1c624c8f..939307f4 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -2,7 +2,8 @@ local apiVersionReceived = false local vtxTablesReceived = false local mcuIdReceived = false local boardInfoReceived = false -local getApiVersion, getVtxTables, getMCUId, getBoardInfo +local featuresReceived = false +local getApiVersion, getVtxTables, getMCUId, getBoardInfo, getFeaturesInfo local returnTable = { f = nil, t = "" } local function init() @@ -56,10 +57,18 @@ local function init() getBoardInfo = nil collectgarbage() end + elseif not featuresReceived and apiVersion >= 1.41 then + getFeaturesInfo = getFeaturesInfo or assert(loadScript("features_info.lua"))() + returnTable.t = getFeaturesInfo.t + featuresReceived = getFeaturesInfo.f() + if featuresReceived then + getFeaturesInfo = nil + collectgarbage() + end else return true end - return apiVersionReceived and vtxTablesReceived and mcuId and boardInfoReceived + return apiVersionReceived and vtxTablesReceived and mcuId and boardInfoReceived and featuresReceived end returnTable.f = init From 571dfd52ec1b5f45ae42db9877952c4362dce8b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Tue, 23 Jan 2024 18:05:48 +0100 Subject: [PATCH 181/193] Do not download VTX table prematurely --- src/SCRIPTS/BF/CONFIRM/vtx_tables.lua | 3 --- src/SCRIPTS/BF/PAGES/INIT/vtx.lua | 11 +++++++++++ src/SCRIPTS/BF/PAGES/vtx.lua | 2 +- src/SCRIPTS/BF/features_info.lua | 2 +- src/SCRIPTS/BF/pages.lua | 2 +- src/SCRIPTS/BF/ui.lua | 19 +++++++++++++++++-- src/SCRIPTS/BF/ui_init.lua | 27 +-------------------------- 7 files changed, 32 insertions(+), 34 deletions(-) create mode 100644 src/SCRIPTS/BF/PAGES/INIT/vtx.lua diff --git a/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua b/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua index 5d51e617..f619fda5 100644 --- a/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua +++ b/src/SCRIPTS/BF/CONFIRM/vtx_tables.lua @@ -1,9 +1,6 @@ local template = assert(loadScript(radio.template))() local margin = template.margin -local indent = template.indent local lineSpacing = template.lineSpacing -local tableSpacing = template.tableSpacing -local sp = template.listSpacing.field local yMinLim = radio.yMinLimit local x = margin local y = yMinLim - lineSpacing diff --git a/src/SCRIPTS/BF/PAGES/INIT/vtx.lua b/src/SCRIPTS/BF/PAGES/INIT/vtx.lua new file mode 100644 index 00000000..ac5dbe33 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/INIT/vtx.lua @@ -0,0 +1,11 @@ +local function precondition() + local hasVtxTable = loadScript("VTX_TABLES/"..mcuId..".lua") + collectgarbage() + if hasVtxTable then + return nil + else + return "CONFIRM/vtx_tables.lua" + end +end + +return precondition() diff --git a/src/SCRIPTS/BF/PAGES/vtx.lua b/src/SCRIPTS/BF/PAGES/vtx.lua index 0e002b40..7c61da3d 100644 --- a/src/SCRIPTS/BF/PAGES/vtx.lua +++ b/src/SCRIPTS/BF/PAGES/vtx.lua @@ -11,7 +11,7 @@ local fields = {} local vtx_tables if apiVersion >= 1.42 then - vtx_tables = assert(loadScript("VTX_TABLES/"..mcuId..".lua"))() + vtx_tables = assert(loadScript("VTX_TABLES/"..mcuId..".lua"), "No VTX table!")() else vtx_tables = assert(loadScript("VTX_TABLES/vtx_defaults.lua"))() end diff --git a/src/SCRIPTS/BF/features_info.lua b/src/SCRIPTS/BF/features_info.lua index bb28ecfa..d37e21d1 100644 --- a/src/SCRIPTS/BF/features_info.lua +++ b/src/SCRIPTS/BF/features_info.lua @@ -2,7 +2,7 @@ local MSP_GPS_CONFIG = 135 local MSP_VTX_CONFIG = 88 local isGpsRead = false -local isVtxRead = true -- Checking VTX is done in `vtx_tables.lua` +local isVtxRead = false local lastRunTS = 0 local INTERVAL = 100 diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index 979b733f..63c4b23f 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -1,7 +1,7 @@ local PageFiles = {} if apiVersion >= 1.36 and features.vtx then - PageFiles[#PageFiles + 1] = { title = "VTX Settings", script = "vtx.lua" } + PageFiles[#PageFiles + 1] = { title = "VTX Settings", script = "vtx.lua", init = "PAGES/INIT/vtx.lua" } end if apiVersion >= 1.16 then diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index fee070ea..f849223b 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -385,8 +385,23 @@ local function run_ui(event) end end if not Page then - Page = assert(loadScript("PAGES/"..PageFiles[currentPage].script))() - collectgarbage() + local function selectPage(page) + Page = assert(loadScript("PAGES/"..page))() + collectgarbage() + end + + local selectedPage = PageFiles[currentPage] + if selectedPage.init then + local initScript = assert(loadScript(selectedPage.init), "Missing init script")() + collectgarbage() + if initScript then + confirm(initScript) + else + selectPage(selectedPage.script) + end + else + selectPage(selectedPage.script) + end end if not Page.values and pageState == pageStatus.display then requestPage() diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 939307f4..89d2a9bb 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -1,9 +1,8 @@ local apiVersionReceived = false -local vtxTablesReceived = false local mcuIdReceived = false local boardInfoReceived = false local featuresReceived = false -local getApiVersion, getVtxTables, getMCUId, getBoardInfo, getFeaturesInfo +local getApiVersion, getMCUId, getBoardInfo, getFeaturesInfo local returnTable = { f = nil, t = "" } local function init() @@ -23,30 +22,6 @@ local function init() mcuIdReceived = getMCUId.f() if mcuIdReceived then getMCUId = nil - local f = loadScript("VTX_TABLES/" .. mcuId .. ".lua") - if f then - local table = f() - if table then - vtxTablesReceived = true - features.vtx = 0 < table.frequenciesPerBand - f = nil - table = nil - end - end - collectgarbage() - f = loadScript("BOARD_INFO/"..mcuId..".lua") - if f and f() then - boardInfoReceived = true - f = nil - end - collectgarbage() - end - elseif not vtxTablesReceived and apiVersion >= 1.42 then - getVtxTables = getVtxTables or assert(loadScript("vtx_tables.lua"))() - returnTable.t = getVtxTables.t - vtxTablesReceived = getVtxTables.f() - if vtxTablesReceived then - getVtxTables = nil collectgarbage() end elseif not boardInfoReceived and apiVersion >= 1.44 then From 1204ebdd26f458e74abcdb67ee8193142471365e Mon Sep 17 00:00:00 2001 From: Mark Haslinghuis Date: Wed, 7 Feb 2024 17:16:33 +0100 Subject: [PATCH 182/193] Bump workflow actions --- .github/workflows/build-release.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/nightly.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index fba4d048..102ca5fc 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Code Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Fetch build artifacts uses: actions/download-artifact@v3 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e10e5e56..2b9f24e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Code Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Lua run: sudo apt-get -y install lua5.2 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index f2116b87..62eab7d3 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Code Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Fetch build artifacts uses: actions/download-artifact@v3 From 1c0f49dffa9bfb830cf81d08b5e99525d0b0a120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Fri, 16 Feb 2024 13:10:47 +0100 Subject: [PATCH 183/193] Download board info if necessary --- src/SCRIPTS/BF/CONFIRM/pwm.lua | 21 +++++++++++++++++++++ src/SCRIPTS/BF/PAGES/INIT/pwm.lua | 15 +++++++++++++++ src/SCRIPTS/BF/pages.lua | 2 +- src/SCRIPTS/BF/ui.lua | 3 +++ src/SCRIPTS/BF/ui_init.lua | 13 ++----------- 5 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 src/SCRIPTS/BF/CONFIRM/pwm.lua create mode 100644 src/SCRIPTS/BF/PAGES/INIT/pwm.lua diff --git a/src/SCRIPTS/BF/CONFIRM/pwm.lua b/src/SCRIPTS/BF/CONFIRM/pwm.lua new file mode 100644 index 00000000..f2c90233 --- /dev/null +++ b/src/SCRIPTS/BF/CONFIRM/pwm.lua @@ -0,0 +1,21 @@ +local template = assert(loadScript(radio.template))() +local margin = template.margin +local lineSpacing = template.lineSpacing +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +labels[#labels + 1] = { t = "Download Board Info? Press", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "[ENTER] to download, or", x = x, y = inc.y(lineSpacing) } +labels[#labels + 1] = { t = "[EXIT] to cancel.", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { x = x, y = inc.y(lineSpacing), value = "", ro = true } + +return { + title = "Board Info", + labels = labels, + fields = fields, + init = assert(loadScript("board_info.lua"))(), +} diff --git a/src/SCRIPTS/BF/PAGES/INIT/pwm.lua b/src/SCRIPTS/BF/PAGES/INIT/pwm.lua new file mode 100644 index 00000000..34232f85 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/INIT/pwm.lua @@ -0,0 +1,15 @@ +local function precondition() + if apiVersion < 1.44 then + -- BOARD_INFO is unavailable below 1.44 + return nil + end + local hasBoardInfo = loadScript("BOARD_INFO/"..mcuId..".lua") + collectgarbage() + if hasBoardInfo then + return nil + else + return "CONFIRM/pwm.lua" + end +end + +return precondition() diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index 63c4b23f..9e5fd8df 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -37,7 +37,7 @@ if apiVersion >= 1.42 then end if apiVersion >= 1.16 then - PageFiles[#PageFiles + 1] = { title = "System / Motor", script = "pwm.lua" } + PageFiles[#PageFiles + 1] = { title = "System / Motor", script = "pwm.lua", init = "PAGES/INIT/pwm.lua" } end if apiVersion >= 1.16 then diff --git a/src/SCRIPTS/BF/ui.lua b/src/SCRIPTS/BF/ui.lua index f849223b..df45bba1 100644 --- a/src/SCRIPTS/BF/ui.lua +++ b/src/SCRIPTS/BF/ui.lua @@ -94,6 +94,9 @@ local function createPopupMenu() if apiVersion >= 1.42 then popupMenu[#popupMenu + 1] = { t = "vtx tables", f = function() confirm("CONFIRM/vtx_tables.lua") end } end + if apiVersion >= 1.44 then + popupMenu[#popupMenu + 1] = { t = "board info", f = function() confirm("CONFIRM/pwm.lua") end } + end end local function processMspReply(cmd,rx_buf,err) diff --git a/src/SCRIPTS/BF/ui_init.lua b/src/SCRIPTS/BF/ui_init.lua index 89d2a9bb..c00f0351 100644 --- a/src/SCRIPTS/BF/ui_init.lua +++ b/src/SCRIPTS/BF/ui_init.lua @@ -1,8 +1,7 @@ local apiVersionReceived = false local mcuIdReceived = false -local boardInfoReceived = false local featuresReceived = false -local getApiVersion, getMCUId, getBoardInfo, getFeaturesInfo +local getApiVersion, getMCUId, getFeaturesInfo local returnTable = { f = nil, t = "" } local function init() @@ -24,14 +23,6 @@ local function init() getMCUId = nil collectgarbage() end - elseif not boardInfoReceived and apiVersion >= 1.44 then - getBoardInfo = getBoardInfo or assert(loadScript("board_info.lua"))() - returnTable.t = getBoardInfo.t - boardInfoReceived = getBoardInfo.f() - if boardInfoReceived then - getBoardInfo = nil - collectgarbage() - end elseif not featuresReceived and apiVersion >= 1.41 then getFeaturesInfo = getFeaturesInfo or assert(loadScript("features_info.lua"))() returnTable.t = getFeaturesInfo.t @@ -43,7 +34,7 @@ local function init() else return true end - return apiVersionReceived and vtxTablesReceived and mcuId and boardInfoReceived and featuresReceived + return apiVersionReceived and mcuId and featuresReceived end returnTable.f = init From 3a9121d4305446ae37b2403fa5281ea421c4ea05 Mon Sep 17 00:00:00 2001 From: Mark Haslinghuis Date: Tue, 19 Mar 2024 16:04:31 +0100 Subject: [PATCH 184/193] Release assets upload fix --- .github/workflows/build-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 102ca5fc..07bae5bb 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -30,10 +30,10 @@ jobs: set -x ASSETS=() for asset in Assets/*.zip; do - ASSETS+=("-a" "$asset") + ASSETS+=("$asset") echo "$asset" done TAG_NAME="${GITHUB_REF##*/}" - gh release edit "${ASSETS[@]}" "{TAG_NAME}" + gh release upload "${TAG_NAME}" "${ASSETS[@]}" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 61e8f4c6cd0584fbab69e207b05cdd0599c98fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Wed, 24 Jan 2024 19:17:54 +0100 Subject: [PATCH 185/193] Hide OSD (SD) settings --- src/SCRIPTS/BF/PAGES/pos_osd.lua | 6 ++-- src/SCRIPTS/BF/features.lua | 6 ++-- src/SCRIPTS/BF/features_info.lua | 62 ++++++++++++++++++++++++++++---- src/SCRIPTS/BF/pages.lua | 2 +- 4 files changed, 63 insertions(+), 13 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/pos_osd.lua b/src/SCRIPTS/BF/PAGES/pos_osd.lua index 3417ac2f..2e5c2628 100644 --- a/src/SCRIPTS/BF/PAGES/pos_osd.lua +++ b/src/SCRIPTS/BF/PAGES/pos_osd.lua @@ -1,9 +1,7 @@ local template = assert(loadScript(radio.template))() local margin = template.margin -local indent = template.indent local lineSpacing = template.lineSpacing local tableSpacing = template.tableSpacing -local sp = template.listSpacing.field local yMinLim = radio.yMinLimit local x = margin local y = yMinLim - lineSpacing @@ -133,12 +131,12 @@ return { self.values[3] = bit32.rshift(combineValue, 8) return self.values end, - checkProfile = function(self, value, profileFirst, profileSecond, profileThird) + checkProfile = function(_, value, profileFirst, profileSecond, profileThird) local profiles = profileFirst + bit32.lshift(profileSecond, 1) + bit32.lshift(profileThird, 2) local output = bit32.replace(value, profiles, 11, 3) return output end, - splitVal = function(self, inputFirstVal, inputSecondVal) + splitVal = function(_, inputFirstVal, inputSecondVal) local inputVal = inputFirstVal + bit32.lshift(inputSecondVal, 8) local profiles = bit32.extract(inputVal, 11, 3) local fieldPos = bit32.extract(inputVal, 0, 11) diff --git a/src/SCRIPTS/BF/features.lua b/src/SCRIPTS/BF/features.lua index 383252ae..c76251cf 100644 --- a/src/SCRIPTS/BF/features.lua +++ b/src/SCRIPTS/BF/features.lua @@ -1,6 +1,8 @@ local features = { - vtx = true, - gps = true, + vtx = true, + gps = true, + osdSD = true, + blackbox = true, } return features diff --git a/src/SCRIPTS/BF/features_info.lua b/src/SCRIPTS/BF/features_info.lua index d37e21d1..5fe599bd 100644 --- a/src/SCRIPTS/BF/features_info.lua +++ b/src/SCRIPTS/BF/features_info.lua @@ -1,20 +1,61 @@ local MSP_GPS_CONFIG = 135 local MSP_VTX_CONFIG = 88 +local MSP_OSD_CONFIG = 84 + +local MSP_BUILD_INFO = 5 + +local BUILD_OPTION_GPS = 16412 +local BUILD_OPTION_VTX = 16421 +local BUILD_OPTION_OSD_SD = 16416 local isGpsRead = false local isVtxRead = false +local isOsdSDRead = false local lastRunTS = 0 local INTERVAL = 100 +local isInFlight = false local returnTable = { f = nil, t = "", } +local function processBuildInfoReply(payload) + local headLength = 26 -- DATE(11) + TIME(8) + REVISION(7) + local optionsLength = #payload - headLength + if (optionsLength <= 0) or ((optionsLength % 2) ~= 0) then + return -- invalid payload + end + + features.gps = false + features.vtx = false + features.osdSD = false + for i = headLength + 1, #payload, 2 do + local byte1 = bit32.lshift(payload[i], 0) + local byte2 = bit32.lshift(payload[i + 1], 8) + local word = bit32.bor(byte1, byte2) + if word == BUILD_OPTION_GPS then + features.gps = true + elseif word == BUILD_OPTION_VTX then + features.vtx = true + elseif word == BUILD_OPTION_OSD_SD then + features.osdSD = true + end + end +end + local function processMspReply(cmd, payload, err) + isInFlight = false local isOkay = not err - if cmd == MSP_GPS_CONFIG then + if cmd == MSP_BUILD_INFO then + isGpsRead = true + isVtxRead = true + isOsdSDRead = true + if isOkay then + processBuildInfoReply(payload) + end + elseif cmd == MSP_GPS_CONFIG then isGpsRead = true local providerSet = payload[1] ~= 0 features.gps = isOkay and providerSet @@ -22,6 +63,10 @@ local function processMspReply(cmd, payload, err) isVtxRead = true local vtxTableAvailable = payload[12] ~= 0 features.vtx = isOkay and vtxTableAvailable + elseif cmd == MSP_OSD_CONFIG then + isOsdSDRead = true + local osdSDAvailable = payload[1] ~= 0 + features.osdSD = isOkay and osdSDAvailable end end @@ -29,22 +74,27 @@ local function updateFeatures() if lastRunTS + INTERVAL < getTime() then lastRunTS = getTime() local cmd - if not isGpsRead then + if apiVersion >= 1.46 then + cmd = MSP_BUILD_INFO + returnTable.t = "Checking options..." + elseif not isGpsRead then cmd = MSP_GPS_CONFIG returnTable.t = "Checking GPS..." elseif not isVtxRead then cmd = MSP_VTX_CONFIG returnTable.t = "Checking VTX..." + elseif not isOsdSDRead then + cmd = MSP_OSD_CONFIG + returnTable.t = "Checking OSD (SD)..." end - if cmd then + if cmd and not isInFlight then protocol.mspRead(cmd) - else - return true + isInFlight = true end end mspProcessTxQ() processMspReply(mspPollReply()) - return false + return isGpsRead and isVtxRead and isOsdSDRead end returnTable.f = updateFeatures diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index 9e5fd8df..9763e1ce 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -60,7 +60,7 @@ if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "Trim Accelerometer", script = "acc_trim.lua" } end -if apiVersion >= 1.45 then +if apiVersion >= 1.45 and features.osdSD then PageFiles[#PageFiles + 1] = { title = "OSD Elements", script = "pos_osd.lua" } end From 0978a0e500e57eae8fc847beb7d4fe6851aa94c5 Mon Sep 17 00:00:00 2001 From: 3djc <3djc@gh.com> Date: Thu, 16 May 2024 14:51:38 +0200 Subject: [PATCH 186/193] feat: add 480x320 support --- src/SCRIPTS/BF/TEMPLATES/480x320.lua | 7 ++++++ src/SCRIPTS/BF/radios.lua | 32 ++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/SCRIPTS/BF/TEMPLATES/480x320.lua diff --git a/src/SCRIPTS/BF/TEMPLATES/480x320.lua b/src/SCRIPTS/BF/TEMPLATES/480x320.lua new file mode 100644 index 00000000..cf01908c --- /dev/null +++ b/src/SCRIPTS/BF/TEMPLATES/480x320.lua @@ -0,0 +1,7 @@ +return { + margin = 5, + indent = 15, + lineSpacing = 22, + listSpacing = { line = 20, field = 170 }, + tableSpacing = { row = 25, col = 60, header = 20 }, +} diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index 13eecaa8..2e7abf2b 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -109,7 +109,35 @@ local supportedRadios = } }, }, - ["320x480"] = + ["480x320"] = + { + msp = { + template = "TEMPLATES/480x320.lua", + highRes = true, + MenuBox = { x=120, y=100, w=200, x_offset=68, h_line=20, h_offset=6 }, + SaveBox = { x=120, y=100, w=180, x_offset=12, h=60, h_offset=12 }, + NoTelem = { 192, LCD_H - 28, "No Telemetry", (TEXT_COLOR or 0) + INVERS + BLINK }, + textSize = 0, + yMinLimit = 35, + yMaxLimit = 280, + }, + cms = { + rows = 9, + cols = 32, + pixelsPerRow = 24, + pixelsPerChar = 14, + xIndent = 14, + yOffset = 32, + textSize = MIDSIZE, + refresh = { + event = EVT_VIRTUAL_ENTER, + text = "Refresh: [ENT]", + top = 1, + left = 300, + } + }, + }, + ["320x480"] = { msp = { template = "TEMPLATES/320x480.lua", @@ -128,4 +156,4 @@ local supportedRadios = local resolution = LCD_W.."x"..LCD_H local radio = assert(supportedRadios[resolution], resolution.." not supported") -return radio +return radio \ No newline at end of file From a999c65d5c10c5d5a0e12517a87953c8e13682c7 Mon Sep 17 00:00:00 2001 From: 3djc <3djc@gh.com> Date: Thu, 16 May 2024 15:22:46 +0200 Subject: [PATCH 187/193] chore:EOF line --- src/SCRIPTS/BF/radios.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/radios.lua b/src/SCRIPTS/BF/radios.lua index 2e7abf2b..b6d5e22a 100644 --- a/src/SCRIPTS/BF/radios.lua +++ b/src/SCRIPTS/BF/radios.lua @@ -156,4 +156,4 @@ local supportedRadios = local resolution = LCD_W.."x"..LCD_H local radio = assert(supportedRadios[resolution], resolution.." not supported") -return radio \ No newline at end of file +return radio From f259f036fd9a8173fef0c59aaad4c7e2fe2a90d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 22:39:29 +0000 Subject: [PATCH 188/193] Bump actions/download-artifact from 3 to 4.1.7 in /.github/workflows Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4.1.7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4.1.7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/build-release.yml | 2 +- .github/workflows/nightly.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index 07bae5bb..7d7fe79d 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -20,7 +20,7 @@ jobs: uses: actions/checkout@v4 - name: Fetch build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4.1.7 - name: List assets run: ls -al Assets diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 62eab7d3..c60f4255 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -35,7 +35,7 @@ jobs: uses: actions/checkout@v4 - name: Fetch build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4.1.7 - name: Select release notes id: notes From b5e2d989daa44ffafe96bdd13ab9126163ca12bc Mon Sep 17 00:00:00 2001 From: Mark Haslinghuis Date: Fri, 25 Jul 2025 13:25:04 +0200 Subject: [PATCH 189/193] Fix CI --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2b9f24e9..905afc76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: run: make release - name: Publish build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Assets path: ./release/*.zip From a4969ab2450e460d9a139be72c36c52e88a12486 Mon Sep 17 00:00:00 2001 From: Mark Haslinghuis Date: Fri, 25 Jul 2025 16:29:49 +0200 Subject: [PATCH 190/193] Use specific version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 905afc76..b9c9b0f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: run: make release - name: Publish build artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v4.3.0 with: name: Assets path: ./release/*.zip From a76cd41cadee98dd190b6723d67b4c4905b267c8 Mon Sep 17 00:00:00 2001 From: Marc Ole Bulling Date: Sun, 3 Aug 2025 21:45:18 +0200 Subject: [PATCH 191/193] Added battery menu Changed API to 1.41 --- src/SCRIPTS/BF/PAGES/battery.lua | 31 +++++++++++++++++++++++++++++++ src/SCRIPTS/BF/pages.lua | 4 ++++ 2 files changed, 35 insertions(+) create mode 100644 src/SCRIPTS/BF/PAGES/battery.lua diff --git a/src/SCRIPTS/BF/PAGES/battery.lua b/src/SCRIPTS/BF/PAGES/battery.lua new file mode 100644 index 00000000..75c008c8 --- /dev/null +++ b/src/SCRIPTS/BF/PAGES/battery.lua @@ -0,0 +1,31 @@ +local template = assert(loadScript(radio.template))() +local margin = template.margin +local indent = template.indent +local lineSpacing = template.lineSpacing +local tableSpacing = template.tableSpacing +local sp = template.listSpacing.field +local yMinLim = radio.yMinLimit +local x = margin +local y = yMinLim - lineSpacing +local inc = { x = function(val) x = x + val return x end, y = function(val) y = y + val return y end } +local labels = {} +local fields = {} + +labels[#labels + 1] = { t = "Voltage Settings", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Minimum Cell ", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 8, 9 }, scale = 100 } +fields[#fields + 1] = { t = "Maximum Cell ", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 10, 11 }, scale = 100 } +fields[#fields + 1] = { t = "Warning Cell ", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 12, 13 }, scale = 100 } + +labels[#labels + 1] = { t = "Capacity Settings", x = x, y = inc.y(lineSpacing) } +fields[#fields + 1] = { t = "Battery Capacity ", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, steps = 25, max = 10000, vals = { 4, 5 } } + +return { + read = 32, -- MSP_BATTERY_CONFIG + write = 33, -- MSP_SET_BATTERY_CONFIG + title = "Battery", + reboot = false, + eepromWrite = true, + minBytes = 13, + labels = labels, + fields = fields +} diff --git a/src/SCRIPTS/BF/pages.lua b/src/SCRIPTS/BF/pages.lua index 9763e1ce..4deddf51 100644 --- a/src/SCRIPTS/BF/pages.lua +++ b/src/SCRIPTS/BF/pages.lua @@ -40,6 +40,10 @@ if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "System / Motor", script = "pwm.lua", init = "PAGES/INIT/pwm.lua" } end +if apiVersion >= 1.41 then + PageFiles[#PageFiles + 1] = { title = "Battery", script = "battery.lua" } +end + if apiVersion >= 1.16 then PageFiles[#PageFiles + 1] = { title = "Receiver", script = "rx.lua" } end From 1acac3c709ef09e4b88d4f8a042e2d7612118db4 Mon Sep 17 00:00:00 2001 From: Marc Ole Bulling Date: Sun, 3 Aug 2025 22:02:08 +0200 Subject: [PATCH 192/193] Removed spaces again, fixed formatting --- src/SCRIPTS/BF/PAGES/battery.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SCRIPTS/BF/PAGES/battery.lua b/src/SCRIPTS/BF/PAGES/battery.lua index 75c008c8..39c22937 100644 --- a/src/SCRIPTS/BF/PAGES/battery.lua +++ b/src/SCRIPTS/BF/PAGES/battery.lua @@ -12,12 +12,12 @@ local labels = {} local fields = {} labels[#labels + 1] = { t = "Voltage Settings", x = x, y = inc.y(lineSpacing) } -fields[#fields + 1] = { t = "Minimum Cell ", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 8, 9 }, scale = 100 } -fields[#fields + 1] = { t = "Maximum Cell ", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 10, 11 }, scale = 100 } -fields[#fields + 1] = { t = "Warning Cell ", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 12, 13 }, scale = 100 } +fields[#fields + 1] = { t = "Minimum Cell", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 8, 9 }, scale = 100 } +fields[#fields + 1] = { t = "Maximum Cell", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 10, 11 }, scale = 100 } +fields[#fields + 1] = { t = "Warning Cell", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 12, 13 }, scale = 100 } labels[#labels + 1] = { t = "Capacity Settings", x = x, y = inc.y(lineSpacing) } -fields[#fields + 1] = { t = "Battery Capacity ", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, steps = 25, max = 10000, vals = { 4, 5 } } +fields[#fields + 1] = { t = "Battery Capacity", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, steps = 25, max = 10000, vals = { 4, 5 } } return { read = 32, -- MSP_BATTERY_CONFIG From 49ea1aed2ef703d8aae9bdfb279bcb174d76dc91 Mon Sep 17 00:00:00 2001 From: Marc Ole Bulling Date: Sun, 10 Aug 2025 10:12:50 +0200 Subject: [PATCH 193/193] Fix battery capacity steps, changed max capacity to 20000 --- src/SCRIPTS/BF/PAGES/battery.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SCRIPTS/BF/PAGES/battery.lua b/src/SCRIPTS/BF/PAGES/battery.lua index 39c22937..43a08f1f 100644 --- a/src/SCRIPTS/BF/PAGES/battery.lua +++ b/src/SCRIPTS/BF/PAGES/battery.lua @@ -17,7 +17,7 @@ fields[#fields + 1] = { t = "Maximum Cell", x = x + indent, y = inc.y(li fields[#fields + 1] = { t = "Warning Cell", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, max = 500, vals = { 12, 13 }, scale = 100 } labels[#labels + 1] = { t = "Capacity Settings", x = x, y = inc.y(lineSpacing) } -fields[#fields + 1] = { t = "Battery Capacity", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, steps = 25, max = 10000, vals = { 4, 5 } } +fields[#fields + 1] = { t = "Battery Capacity", x = x + indent, y = inc.y(lineSpacing), sp = x + sp, min = 0, mult = 25, max = 20000, vals = { 4, 5 } } return { read = 32, -- MSP_BATTERY_CONFIG