From 0b2f353e1339a5eeae95308258a4c474776da4c6 Mon Sep 17 00:00:00 2001 From: Shmuely Date: Tue, 26 Apr 2022 08:36:59 +0300 Subject: [PATCH 1/5] new Rotary Gauge widget --- .../horus/WIDGETS/GaugeRotary/gauge_core.lua | 165 ++++++++++ sdcard/horus/WIDGETS/GaugeRotary/main.lua | 303 ++++++++++++++++++ 2 files changed, 468 insertions(+) create mode 100644 sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua create mode 100644 sdcard/horus/WIDGETS/GaugeRotary/main.lua diff --git a/sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua b/sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua new file mode 100644 index 00000000..7386f564 --- /dev/null +++ b/sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua @@ -0,0 +1,165 @@ +local HighAsGreen, p2 = ... + +local self = {} +self.HighAsGreen = HighAsGreen + +-------------------------------------------------------------- +local function log(s) + --return; + print("Gauge_core: " .. s) +end +-------------------------------------------------------------- + +function self.drawArm(armX, armY, armR, percentageValue, color, isFull) + --min = 5.54 + --max = 0.8 + + local degrees + if isFull then + degrees = 5.51 - (4.74 * percentageValue / 100) + else + --degrees = 4.74 - (3.14 * percentageValue / 100) + degrees = 5.05 - (3.84 * percentageValue / 100) + end + + --log("percentageValue: " .. percentageValue .. ", degrees: " .. degrees) + local xh = math.floor(armX + (math.sin(degrees) * armR)) + local yh = math.floor(armY + (math.cos(degrees) * armR)) + + --lcd.setColor(CUSTOM_COLOR, lcd.RGB(0, 0, 255)) + --lcd.setColor(CUSTOM_COLOR, lcd.RGB(255, 255, 255)) + lcd.setColor(CUSTOM_COLOR, color) + + local x1 = math.floor(armX - (math.sin(0) * (20 / 2.3))) + local y1 = math.floor(armY - (math.cos(0) * (20 / 2.3))) + local x2 = math.floor(armX - (math.sin(3) * (20 / 2.3))) + local y2 = math.floor(armY - (math.cos(3) * (20 / 2.3))) + lcd.drawFilledTriangle(x1, y1, x2, y2, xh, yh, CUSTOM_COLOR) +end + +-- This function returns green at gvalue, red at rvalue and graduate in between +function self.getRangeColor(value, red_value, green_value) + local range = math.abs(green_value - red_value) + if range == 0 then + return lcd.RGB(0, 0xdf, 0) + end + if value == nil then + return lcd.RGB(0, 0xdf, 0) + end + + if green_value > red_value then + if value > green_value then + return lcd.RGB(0, 0xdf, 0) + end + if value < red_value then + return lcd.RGB(0xdf, 0, 0) + end + g = math.floor(0xdf * (value - red_value) / range) + r = 0xdf - g + return lcd.RGB(r, g, 0) + else + if value < green_value then + return lcd.RGB(0, 0xdf, 0) + end + if value > red_value then + return lcd.RGB(0xdf, 0, 0) + end + r = math.floor(0xdf * (value - green_value) / range) + g = 0xdf - r + return lcd.RGB(r, g, 0) + end +end + +function self.drawGauge(centerX, centerY, centreR, isFull, percentageValue, percentageValueMin, percentageValueMax, txt1, txt2) + + local fender = 4 + local tickWidth = 9 + local armCenterR = centreR / 2.5 + local armR = centreR - 8 + local txtSize = DBLSIZE + if centreR < 65 then + txtSize = MIDSIZE + end + if centreR < 30 then + txtSize = SMLSIZE + end + + -- main gauge background + if isFull then + lcd.drawFilledCircle(centerX, centerY, centreR, lcd.RGB(0x1A1A1A)) + else + lcd.drawPie(centerX,centerY,centreR, -110,110, lcd.RGB(0x1A1A1A)) + end + + -- fender + if isFull then + lcd.drawAnnulus(centerX, centerY, centreR - fender, centreR, 0, 360, BLACK) + else + lcd.drawAnnulus(centerX, centerY, centreR - fender, centreR, -110, 110, BLACK) + end + + -- ticks + local to_tick + local tick_offset + if isFull then + to_tick = 210 + tick_offset = 250 + else + to_tick = 210 + tick_offset = 250 + end + + for i = 0, to_tick, 10 do + --log("HighAsGreen: " .. self.HighAsGreen) + if (self.HighAsGreen == 1) then + lcd.setColor(CUSTOM_COLOR, self.getRangeColor(i, 0, to_tick - 10)) + else + lcd.setColor(CUSTOM_COLOR, self.getRangeColor(i, to_tick - 10, 0)) + --lcd.setColor(CUSTOM_COLOR, self.getRangeColor(i, 120 , 30)) + end + lcd.drawAnnulus(centerX, centerY, centreR - fender - 3 - tickWidth, centreR - fender - 3, tick_offset + i, tick_offset + i + 7, CUSTOM_COLOR) + --lcd.drawAnnulus(centerX, centerY, centreR -fender -3 -tickWidth, centreR -fender -3 , 250 +i, 250 +i +7, YELLOW) + --lcd.drawAnnulus(centerX, centerY, centreR -fender -3 -tickWidth -15, centreR -fender -3 -tickWidth -4 , 250 +i, 250 +i +7, RED) + end + --lcd.drawPie(centerX,centerY,centreR - fender, 0,20) + + local armColor = lcd.RGB(255, 255, 255) + local armColorMin, armColorMax + if (self.HighAsGreen == 1) then + armColorMin = lcd.RGB(100, 0, 0) + armColorMax = lcd.RGB(0, 100, 0) + else + armColorMin = lcd.RGB(0, 100, 0) + armColorMax = lcd.RGB(100, 0, 0) + end + + --self.drawArm(centerX, centerY, armR, 0, armColorMin, isFull) + --self.drawArm(centerX, centerY, armR, 10, armColorMin, isFull) + --self.drawArm(centerX, centerY, armR, 50, armColorMin, isFull) + --self.drawArm(centerX, centerY, armR, 90, armColorMin, isFull) + --self.drawArm(centerX, centerY, armR, 100, armColorMin, isFull) + + if percentageValueMin ~= nil and percentageValueMax ~= nil then + self.drawArm(centerX, centerY, armR, percentageValueMin, armColorMin, isFull) + self.drawArm(centerX, centerY, armR, percentageValueMax, armColorMax, isFull) + end + self.drawArm(centerX, centerY, armR, percentageValue, armColor, isFull) + + -- hide the base of the arm + lcd.drawFilledCircle(centerX, centerY, armCenterR, BLACK) + + if isFull then + else + end + + -- text in center + lcd.drawText(centerX + 0, centerY - 8, txt2, CENTER + SMLSIZE + WHITE) -- XXLSIZE/DBLSIZE/MIDSIZE/SMLSIZE + if isFull then + -- text below + lcd.drawText(centerX + 8, centerY + 30, txt1, CENTER + txtSize + WHITE) + else + end + +end + +return self \ No newline at end of file diff --git a/sdcard/horus/WIDGETS/GaugeRotary/main.lua b/sdcard/horus/WIDGETS/GaugeRotary/main.lua new file mode 100644 index 00000000..cf020c9c --- /dev/null +++ b/sdcard/horus/WIDGETS/GaugeRotary/main.lua @@ -0,0 +1,303 @@ +---- ######################################################################### +---- # # +---- # Telemetry Widget script for FrSky Horus/RadioMaster TX16s # +---- # Copyright (C) EdgeTX # +-----# # +---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html # +---- # # +---- # This program is free software; you can redistribute it and/or modify # +---- # it under the terms of the GNU General Public License version 2 as # +---- # published by the Free Software Foundation. # +---- # # +---- # This program is distributed in the hope that it will be useful # +---- # but WITHOUT ANY WARRANTY; without even the implied warranty of # +---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +---- # GNU General Public License for more details. # +---- # # +---- ######################################################################### + +-- This GaugeRotary widget display a fancy old style analog gauge with needle +-- Options: +-- HighAsGreen: [checked] for sensor that high values is good (RSSI/Fuel/...) +-- [checked] for sensor that high values is good (RSSI/Fuel/...) +-- [un-checked] for sensor that low values is good (Temp/Battery/...) +-- Note: if the min & max input value are -1, widget will automatically select min/max based on the source name. +-- common sources are: +-- * RSSI +-- * Temp +-- * rpm +-- * fuel +-- * vibration (heli) +-- * Transmitter Battery +-- * batt-capacity +-- * A1/A2 analog voltage + +-- Version: 0.1 +-- Author : Offer Shmuely + +local UNIT_ID_TO_STRING = { "V", "A", "mA", "kts", "m/s", "f/s", "km/h", "mph", "m", "f", "°C", "°F", "%", "mAh", "W", "mW", "dB", "rpm", "g", "°", "rad", "ml", "fOz", "ml/m", "Hz", "uS", "km" } +local DEFAULT_MIN_MAX = { + {"RSSI" , 0, 100, 0}, + {"RxBt" , 4, 10, 1}, + {"TxBt" , 6, 8.4, 1}, + {"Batt" , 6, 8.4, 1}, + {"cell" ,3.5, 4.2, 1}, + {"Fuel" , 0, 100, 0}, + {"Vibr" , 0, 100, 0}, + {"Temp" , 30,120, 0}, + {"Tmp1" , 30,120, 0}, + {"Tmp2" , 30,120, 0}, +} + +local _options = { + { "Source", SOURCE, 253 }, -- RSSI + --{ "Source", SOURCE, 243 }, -- TxBt + --{ "Source", SOURCE, 256 }, -- RxBt + { "Min", VALUE, -1, -1024, 1024 }, + { "Max", VALUE, -1, -1024, 1024 }, + { "HighAsGreen", BOOL, 1 }, + { "Precision", VALUE, 1 , 0 , 1} +} + +-------------------------------------------------------------- +local function log(s) + return; + --print("GaugeRotary: " .. s) +end +-------------------------------------------------------------- + +local function setAutoMinMax(wgt) + if wgt.options.Min ~= -1 and wgt.options.Max ~= -1 then + --if wgt.options.Min ~= wgt.options.Max then + print("GaugeRotary-setting: " .. "no need for AutoMinMax") + return + end + + print("GaugeRotary-setting: " .. "AutoMinMax") + local sourceName = getSourceName(wgt.options.Source) + -- workaround for bug in getFiledInfo() + if string.byte(string.sub(sourceName,1,1)) > 127 then + sourceName = string.sub(sourceName,2,-1) -- ???? why? + end + print("GaugeRotary-setting: " .. "AutoMinMax, source:" .. sourceName) + + for i=1, #DEFAULT_MIN_MAX, 1 do + local def_key = DEFAULT_MIN_MAX[i][1] + local def_min = DEFAULT_MIN_MAX[i][2] + local def_max = DEFAULT_MIN_MAX[i][3] + local def_precision = DEFAULT_MIN_MAX[i][4] + + if def_key == sourceName then + log(string.format("setting min-max from default: %s: min:%d, max:%d, precision:%d", def_key, def_min, def_max, def_precision)) + wgt.options.Min = def_min + wgt.options.Max = def_max + wgt.options.precision = def_precision + break + end + end + + if wgt.options.Min == wgt.options.Max then + print("GaugeRotary-setting: " .. "AutoMinMax else") + wgt.options.Min = 0 + wgt.options.Max = 100 + end + +end + +local function create(zone, options) + local GaugeClass = loadScript("/WIDGETS/GaugeRotary/gauge_core.lua") + + local wgt = { + zone = zone, + options = options, + gauge1 = GaugeClass(options.HighAsGreen, 2) + } + + setAutoMinMax(wgt) + + return wgt +end + +local function update(wgt, options) + wgt.options = options + setAutoMinMax(wgt) + wgt.gauge1.HighAsGreen = wgt.options.HighAsGreen +end + +-- ----------------------------------------------------------------------------------------------------- + +local function getPercentageValue(value, options_min, options_max) + if value == nil then + return nil + end + + local percentageValue = value - options_min; + percentageValue = (percentageValue / (options_max - options_min)) * 100 + percentageValue = tonumber(percentageValue) + percentageValue = math.floor( percentageValue ) + + if percentageValue > 100 then + percentageValue = 100 + elseif percentageValue < 0 then + percentageValue = 0 + end + + log("getPercentageValue(" .. value .. ", " .. options_min .. ", " .. options_max .. ")-->" .. percentageValue) + return percentageValue +end + +local function getWidgetValue(wgt) + local currentValue = getValue(wgt.options.Source) + local sourceName = getSourceName(wgt.options.Source) + log("aaaaaa: ".. sourceName) + log("aaaaaa: ".. sourceName .. ": " .. string.byte(string.sub(sourceName, 1, 1))) + + -- workaround for bug in getFiledInfo() + if string.byte(string.sub(sourceName,1,1)) > 127 then + sourceName = string.sub(sourceName,2,-1) -- ???? why? + end + --log("Source: " .. wgt.options.Source .. ",name: " .. sourceName) + + --local currentValue = getValue(wgt.options.Source) / 10.24 + + local fieldinfo = getFieldInfo(wgt.options.Source) + if (fieldinfo == nil) then + log(string.format("getFieldInfo(%s)==nil", wgt.options.Source)) + return sourceName, -1, nil, nil, "" + end + + local txtUnit = "-" + if (fieldinfo.unit) then + --log("have unit") + if (fieldinfo.unit > 0 and fieldinfo.unit < #UNIT_ID_TO_STRING) then + txtUnit = UNIT_ID_TO_STRING[fieldinfo.unit] + end + end + + log("") + log(string.format("id: %s", fieldinfo.id)) + log(string.format(" sourceName: %s", sourceName)) + log(string.format(" curr: %2.1f", currentValue)) + log(string.format(" name: %s", fieldinfo.name)) + log(string.format(" desc: %s", fieldinfo.desc)) + log(string.format(" idUnit: %s", fieldinfo.unit)) + log(string.format(" txtUnit: %s", txtUnit)) + + -- try to get min/max value (if exist) + local minValue = getValue(sourceName .. "-") + local maxValue = getValue(sourceName .. "+") + --log("min/max: " .. minValue .. " < " .. currentValue .. " < " .. maxValue) + + return sourceName, currentValue, minValue, maxValue, txtUnit +end + +local function refresh_app_mode(wgt, event, touchState, w_name, value, minValue, maxValue, w_unit, percentageValue, percentageValueMin, percentageValueMax) + local w_name, value, minValue, maxValue, w_unit = getWidgetValue(wgt) + if (value == nil) then + return + end + + local percentageValue = getPercentageValue(value, wgt.options.Min, wgt.options.Max) + local percentageValueMin = getPercentageValue(minValue, wgt.options.Min, wgt.options.Max) + local percentageValueMax = getPercentageValue(maxValue, wgt.options.Min, wgt.options.Max) + + local zone_w = 460 + local zone_h = 252 + + local centerX = zone_w / 2 + wgt.gauge1.drawGauge(centerX, 120, 110, false, percentageValue, percentageValueMin, percentageValueMax, percentageValue .. w_unit, w_name) + lcd.drawText(10, 10, string.format("%d%s", percentageValue, w_unit), XXLSIZE + YELLOW) + + -- min / max + wgt.gauge1.drawGauge(100, 180, 50, false, percentageValueMin, nil, nil, "", w_name) + wgt.gauge1.drawGauge(zone_w - 100, 180, 50, false, percentageValueMax, nil, nil, "", w_name) + lcd.drawText(50, 230, string.format("Min: %d%s", percentageValueMin, w_unit), MIDSIZE) + lcd.drawText(350, 230, string.format("Max: %d%s", percentageValueMax, w_unit), MIDSIZE) + +end + + +local function refresh_widget(wgt, w_name, value, minValue, maxValue, w_unit, percentageValue, percentageValueMin, percentageValueMax) + local w_name, value, minValue, maxValue, w_unit = getWidgetValue(wgt) + if (value == nil) then + return + end + + local percentageValue = getPercentageValue(value, wgt.options.Min, wgt.options.Max) + local percentageValueMin = getPercentageValue(minValue, wgt.options.Min, wgt.options.Max) + local percentageValueMax = getPercentageValue(maxValue, wgt.options.Min, wgt.options.Max) + + local value_fmt = "" + if wgt.options.precision == 0 then + value_fmt = string.format("%2.0f%s", value, w_unit) + else + value_fmt = string.format("%2.1f%s", value, w_unit) + end + + -- calculate low-profile or full-circle + local isFull = true + if wgt.zone.h < 60 then + lcd.drawText(wgt.zone.x + 10, wgt.zone.y, "too small for GaugeRotary", SMLSIZE + RED) + return + elseif wgt.zone.h < 90 then + log("widget too low (" .. wgt.zone.h .. ")") + if wgt.zone.w * 1.2 > wgt.zone.h then + log("wgt wider then height, use low profile ") + isFull = false + end + end + + local centerR, centerX, centerY + + if isFull then + centerR = math.min(wgt.zone.h, wgt.zone.w) / 2 + --local centerX = wgt.zone.x + (wgt.zone.w / 2) + centerX = wgt.zone.x + wgt.zone.w - centerR + centerY = wgt.zone.y + (wgt.zone.h / 2) + else + centerR = wgt.zone.h - 20 + centerX = wgt.zone.x + wgt.zone.w - centerR + centerY = wgt.zone.y + wgt.zone.h - 20 + end + + wgt.gauge1.drawGauge(centerX, centerY, centerR, isFull, percentageValue, percentageValueMin, percentageValueMax, value_fmt, w_name) + --lcd.drawText(wgt.zone.x, wgt.zone.y, value_fmt, XXLSIZE + YELLOW) + +end + + +local function refresh(wgt, event, touchState) + if (wgt == nil) then return end + if (wgt.options == nil) then return end + if (wgt.zone == nil) then return end + + --lcd.drawRectangle(wgt.zone.x, wgt.zone.y, wgt.zone.w, wgt.zone.h, BLACK) + + local ver, radio, maj, minor, rev, osname = getVersion() + --log("version: " .. ver) + if osname ~= "EdgeTX" then + local err = string.format("supported only on EdgeTX: ", osname) + log(err) + lcd.drawText(0, 0, err, SMLSIZE) + return + end + if maj == 2 and minor < 7 then + local err = string.format("NOT supported ver: %s", ver) + log(err) + lcd.drawText(0, 0, err, SMLSIZE) + return + end + + if (event ~= nil) then + -- full screen (app mode) + refresh_app_mode(wgt, event, touchState) + else + -- regular screen + refresh_widget(wgt) + end + + -- widget load (debugging) + lcd.drawText(wgt.zone.x + 10, wgt.zone.y, string.format("load: %d%%", getUsage()), SMLSIZE + GREY) -- ??? +end + +return { name = "GaugeRotary", options = _options, create = create, update = update, refresh = refresh } From cbf4c49426b8de703a7eec0284d3a56e6550c0c1 Mon Sep 17 00:00:00 2001 From: Shmuely Date: Sun, 1 May 2022 12:18:40 +0300 Subject: [PATCH 2/5] Rotary Gauge widget: less ticks on small size --- .../horus/WIDGETS/GaugeRotary/gauge_core.lua | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua b/sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua index 7386f564..14bcd877 100644 --- a/sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua +++ b/sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua @@ -101,6 +101,7 @@ function self.drawGauge(centerX, centerY, centreR, isFull, percentageValue, perc -- ticks local to_tick local tick_offset + local tick_step = 10 if isFull then to_tick = 210 tick_offset = 250 @@ -108,8 +109,10 @@ function self.drawGauge(centerX, centerY, centreR, isFull, percentageValue, perc to_tick = 210 tick_offset = 250 end - - for i = 0, to_tick, 10 do + if (centreR < 100) then + tick_step = 10 + 0.15 * (100 - centreR) + end + for i = 0, to_tick, tick_step do --log("HighAsGreen: " .. self.HighAsGreen) if (self.HighAsGreen == 1) then lcd.setColor(CUSTOM_COLOR, self.getRangeColor(i, 0, to_tick - 10)) @@ -147,17 +150,20 @@ function self.drawGauge(centerX, centerY, centreR, isFull, percentageValue, perc -- hide the base of the arm lcd.drawFilledCircle(centerX, centerY, armCenterR, BLACK) - - if isFull then - else - end + lcd.drawAnnulus(centerX, centerY, armCenterR-2, armCenterR, 0, 360, + --lcd.RGB(255, 255, 0) + lcd.RGB(192, 192, 192) + ) -- text in center lcd.drawText(centerX + 0, centerY - 8, txt2, CENTER + SMLSIZE + WHITE) -- XXLSIZE/DBLSIZE/MIDSIZE/SMLSIZE + + -- text below if isFull then - -- text below - lcd.drawText(centerX + 8, centerY + 30, txt1, CENTER + txtSize + WHITE) + --lcd.drawText(centerX + 8, centerY + 30, txt1, CENTER + txtSize + WHITE) + lcd.drawText(centerX + 0, centerY + armCenterR + 2, txt1, CENTER + txtSize + WHITE) else + -- no text below in flat mode end end From 4b6b8834b2bc4aa0a8b5ef9e390d057b3f66dbf5 Mon Sep 17 00:00:00 2001 From: Shmuely Date: Sun, 1 May 2022 12:23:39 +0300 Subject: [PATCH 3/5] new Rotary Gauge widget --- sdcard/horus/WIDGETS/GaugeRotary/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdcard/horus/WIDGETS/GaugeRotary/main.lua b/sdcard/horus/WIDGETS/GaugeRotary/main.lua index cf020c9c..fe9673b5 100644 --- a/sdcard/horus/WIDGETS/GaugeRotary/main.lua +++ b/sdcard/horus/WIDGETS/GaugeRotary/main.lua @@ -16,7 +16,7 @@ ---- # # ---- ######################################################################### --- This GaugeRotary widget display a fancy old style analog gauge with needle +-- This Rotary Gauge widget display a fancy old style analog gauge with needle -- Options: -- HighAsGreen: [checked] for sensor that high values is good (RSSI/Fuel/...) -- [checked] for sensor that high values is good (RSSI/Fuel/...) @@ -297,7 +297,7 @@ local function refresh(wgt, event, touchState) end -- widget load (debugging) - lcd.drawText(wgt.zone.x + 10, wgt.zone.y, string.format("load: %d%%", getUsage()), SMLSIZE + GREY) -- ??? +-- lcd.drawText(wgt.zone.x + 10, wgt.zone.y, string.format("load: %d%%", getUsage()), SMLSIZE + GREY) -- ??? end return { name = "GaugeRotary", options = _options, create = create, update = update, refresh = refresh } From 4da81b3f0ab82c94349d4c0e7addce80fb962c07 Mon Sep 17 00:00:00 2001 From: Shmuely Date: Fri, 6 May 2022 09:20:52 +0300 Subject: [PATCH 4/5] new Rotary Gauge widget --- sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua | 8 ++++---- sdcard/horus/WIDGETS/GaugeRotary/main.lua | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua b/sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua index 14bcd877..09a02784 100644 --- a/sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua +++ b/sdcard/horus/WIDGETS/GaugeRotary/gauge_core.lua @@ -129,11 +129,11 @@ function self.drawGauge(centerX, centerY, centreR, isFull, percentageValue, perc local armColor = lcd.RGB(255, 255, 255) local armColorMin, armColorMax if (self.HighAsGreen == 1) then - armColorMin = lcd.RGB(100, 0, 0) - armColorMax = lcd.RGB(0, 100, 0) + armColorMin = lcd.RGB(200, 0, 0) + armColorMax = lcd.RGB(0, 200, 0) else - armColorMin = lcd.RGB(0, 100, 0) - armColorMax = lcd.RGB(100, 0, 0) + armColorMin = lcd.RGB(0, 200, 0) + armColorMax = lcd.RGB(200, 0, 0) end --self.drawArm(centerX, centerY, armR, 0, armColorMin, isFull) diff --git a/sdcard/horus/WIDGETS/GaugeRotary/main.lua b/sdcard/horus/WIDGETS/GaugeRotary/main.lua index fe9673b5..a5e7232c 100644 --- a/sdcard/horus/WIDGETS/GaugeRotary/main.lua +++ b/sdcard/horus/WIDGETS/GaugeRotary/main.lua @@ -38,6 +38,9 @@ local UNIT_ID_TO_STRING = { "V", "A", "mA", "kts", "m/s", "f/s", "km/h", "mph", "m", "f", "°C", "°F", "%", "mAh", "W", "mW", "dB", "rpm", "g", "°", "rad", "ml", "fOz", "ml/m", "Hz", "uS", "km" } local DEFAULT_MIN_MAX = { {"RSSI" , 0, 100, 0}, + {"1RSS" , -120, 0, 0}, + {"2RSS" , -120, 0, 0}, + {"RQly" , 0, 100, 0}, {"RxBt" , 4, 10, 1}, {"TxBt" , 6, 8.4, 1}, {"Batt" , 6, 8.4, 1}, From c6557ba0837d9753bdf49631bfd5aaa3b6ca8bbd Mon Sep 17 00:00:00 2001 From: oshmuely Date: Tue, 18 Oct 2022 23:11:10 +0300 Subject: [PATCH 5/5] Model Locator: support additional sources (RSSI/1RSS/2RSS/VFR) --- .../SCRIPTS/TOOLS/Model Locator (by RSSI).lua | 229 +++++++++++------- 1 file changed, 142 insertions(+), 87 deletions(-) diff --git a/sdcard/c480x272/SCRIPTS/TOOLS/Model Locator (by RSSI).lua b/sdcard/c480x272/SCRIPTS/TOOLS/Model Locator (by RSSI).lua index 525f6f48..e1ba4cc8 100644 --- a/sdcard/c480x272/SCRIPTS/TOOLS/Model Locator (by RSSI).lua +++ b/sdcard/c480x272/SCRIPTS/TOOLS/Model Locator (by RSSI).lua @@ -18,8 +18,8 @@ -- Model Locator by RSSI -- Offer Shmuely (based on code from Scott Bauer 6/21/2015) --- Date: 2021 --- ver: 0.1 +-- Date: 2022 +-- ver: 0.3 -- This widget help to find a lost/crashed model based on the RSSI (if still available) -- The widget produce audio representation (variometer style) of the RSSI from the lost model @@ -43,107 +43,162 @@ local img = Bitmap.open("/SCRIPTS/TOOLS/Model Locator (by RSSI).png") -------------------------------------------------------------- local function log(s) - --return; - print("locator: " .. s) + -- print("locator: " .. s) end -------------------------------------------------------------- -- init_func is called once when model is loaded local function init() - return 0 -end - --- bg_func is called periodically when screen is not visible -local function bg() - return 0 + return 0 end -- This function returns green at gvalue, red at rvalue and graduate in between local function getRangeColor(value, red_value, green_value) - local range = math.abs(green_value - red_value) - if range == 0 then - return lcd.RGB(0, 0xdf, 0) - end - if value == nil then - return lcd.RGB(0, 0xdf, 0) - end - - if green_value > red_value then - if value > green_value then - return lcd.RGB(0, 0xdf, 0) + local range = math.abs(green_value - red_value) + if range == 0 then + return lcd.RGB(0, 0xdf, 0) + end + if value == nil then + return lcd.RGB(0, 0xdf, 0) + end + + if green_value > red_value then + if value > green_value then + return lcd.RGB(0, 0xdf, 0) + end + if value < red_value then + return lcd.RGB(0xdf, 0, 0) + end + g = math.floor(0xdf * (value - red_value) / range) + r = 0xdf - g + return lcd.RGB(r, g, 0) + else + if value > green_value then + return lcd.RGB(0, 0xdf, 0) + end + if value < red_value then + return lcd.RGB(0xdf, 0, 0) + end + r = math.floor(0xdf * (value - green_value) / range) + g = 0xdf - r + return lcd.RGB(r, g, 0) + end +end + +local function getSignalValues() + + -- try regular RSSI + local fieldinfo = getFieldInfo("RSSI") + if fieldinfo then + local v = getValue("RSSI") + log("RSSI: " .. v) + lcd.drawText(3, 30, "Signal: RSSI", 0) + return v, 0, 100 end - if value < red_value then - return lcd.RGB(0xdf, 0, 0) + + -- try expressLRS + local fieldinfo = getFieldInfo("1RSS") + if fieldinfo then + local v = getValue("1RSS") + lcd.drawText(3, 30, "Signal: 1RSS", 0) + if v == 0 then + v = -115 + end + return v, -115, 20 end - g = math.floor(0xdf * (value - red_value) / range) - r = 0xdf - g - return lcd.RGB(r, g, 0) - else - if value > green_value then - return lcd.RGB(0, 0xdf, 0) + + -- try expressLRS + local fieldinfo = getFieldInfo("2RSS") + if fieldinfo then + local v = getValue("2RSS") + lcd.drawText(3, 30, "Signal: 2RSS", 0) + if v == 0 then + v = -115 + end + return v, -115, 20 end - if value < red_value then - return lcd.RGB(0xdf, 0, 0) + + -- try UNI-ACSST firmware VFR + local fieldinfo = getFieldInfo("VFR") + if fieldinfo then + local v = getValue("VFR") + log("RSSI: " .. v) + lcd.drawText(3, 30, "Signal: VFR", 0) + return v, 0, 100 end - r = math.floor(0xdf * (value - green_value) / range) - g = 0xdf - r - return lcd.RGB(r, g, 0) - end + + -- try elrs RQLY + local fieldinfo = getFieldInfo("RQLY") + if fieldinfo then + local v = getValue("RQLY") + log("RQLY: " .. v) + lcd.drawText(3, 30, "Signal: RQLY", 0) + return v, 0, 100 + end + + lcd.drawText(30, 3, "Signal: not found in RSSI/1RSS/2RSS/VFR", 0) + return nil, 0, 0 end -local function main(event) - - lcd.clear() - local rssi = getValue("RSSI") - -- log(rssi) - - -- background - --lcd.drawBitmap(img, 0, 20, 30) - lcd.drawBitmap(img, 250, 50, 40) - - -- Title - lcd.drawText(3, 3, "RSSI Model Locator", 0) - - --if (rssi > 42) then - -- lcd.setColor(CUSTOM_COLOR, YELLOW) -- RED / YELLOW - --else - -- lcd.setColor(CUSTOM_COLOR, RED) -- RED / YELLOW - --end - myColor = getRangeColor(rssi, 0, 100) - lcd.setColor(CUSTOM_COLOR, myColor) - - -- draw current value - lcd.drawNumber(180, 30, rssi, XXLSIZE + CUSTOM_COLOR) - lcd.drawText(260, 70, "db", 0 + CUSTOM_COLOR) - - -- draw main bar - lcd.setColor(CUSTOM_COLOR, YELLOW) -- RED / YELLOW - local xMin = 0 - local yMin = 270 - local xMax = 480 - local yMax = 200 - local h = 0 - local rssiAsX = (rssi * xMax) / 100 - -- log("rssi:"..rssi) - for xx = xMin, rssiAsX, 20 do - lcd.setColor(CUSTOM_COLOR, getRangeColor(xx, xMin, xMax - 40)) - h = h + 10 - lcd.drawFilledRectangle(xx, yMin - h, 15, h, CUSTOM_COLOR) - end - - -- draw rectangle - --lcd.drawFilledRectangle(0, 250, rssi * 4.8, 20, GREY_DEFAULT) - - -- beep - if getTime() >= nextPlayTime then - playFile("/SCRIPTS/TOOLS/Model Locator (by RSSI).wav") - nextPlayTime = getTime() + delayMillis - rssi - end - - - return 0 + +local function main(event, touchState) + lcd.clear() + + local signalValue, signalMin, signalMax = getSignalValues() + -- log(signalValue) + if signalValue == nil then + return + end + log("signalValue:" .. signalValue .. ", signalMin: " .. signalMin .. ", signalMax: " .. signalMax) + + -- background + --lcd.drawBitmap(img, 0, 20, 30) + lcd.drawBitmap(img, 250, 50, 40) + + -- Title + lcd.drawText(3, 3, "RSSI Model Locator", 0) + + --if (rssi > 42) then + -- lcd.setColor(CUSTOM_COLOR, YELLOW) -- RED / YELLOW + --else + -- lcd.setColor(CUSTOM_COLOR, RED) -- RED / YELLOW + --end + local signalPercent = 100 * ((signalValue - signalMin) / (signalMax - signalMin)) + --myColor = getRangeColor(signalPercent, 0, 100) + --lcd.setColor(CUSTOM_COLOR, myColor) + lcd.setColor(CUSTOM_COLOR, getRangeColor(signalPercent, 0, 100)) + + -- draw current value + lcd.drawNumber(180, 30, signalValue, XXLSIZE + CUSTOM_COLOR) + lcd.drawText(260, 70, "db", 0 + CUSTOM_COLOR) + + -- draw main bar + --lcd.setColor(CUSTOM_COLOR, YELLOW) -- RED / YELLOW + local xMin = 0 + local yMin = 270 + local xMax = 480 + local yMax = 200 + local h = 0 + local rssiAsX = (signalPercent * xMax) / 100 + log("signalPercent:" .. signalPercent .. ", signalValue: " .. signalValue .. ", rssiAsX: " .. rssiAsX) + for xx = xMin, rssiAsX, 20 do + lcd.setColor(CUSTOM_COLOR, getRangeColor(xx, xMin, xMax - 40)) + h = h + 10 + lcd.drawFilledRectangle(xx, yMin - h, 15, h, CUSTOM_COLOR) + end + + -- draw rectangle + --lcd.drawFilledRectangle(0, 250, signalPercent * 4.8, 20, GREY_DEFAULT) + + -- beep + if getTime() >= nextPlayTime then + playFile("/SCRIPTS/TOOLS/Model Locator (by RSSI).wav") + nextPlayTime = getTime() + delayMillis - signalPercent + end + + return 0 end -return {init = init,run = main,background = bg} +return { init = init, run = main }