Horus Battery Percentage Widget

Displays Percentage of Lipo, from single voltage source

Widget available for all telemetry panel sizes

Select the Voltage source.

Must be a single voltage source like VFAS, A1,A2, EscV (Neuron), etc

Select lipo cell amount for correct calculation.

 

Save code below as: main.lua

And copy the lua file on to the SD-Card in the widget folder with an created folder named: BattPct
\widgets\BattPct\main.lua

 
---- #########################################################################
---- # #
---- # Battery % Widget for FrSky Horus #
---- # #
---- # This program is free software; you can redistribute it and/or modify #
---- # it under the terms of the GNU General Public License version 3 as #
---- # published by the Free Software Foundation. #
---- # #
---- # Revised by Björn Pasteuning / Hobby4life 2019 #
---- # Version: 3.2 #
---- # #
---- #########################################################################

local options = {
{ "Source", SOURCE, 1 }, -- Defines source Battery Voltage Sensor
{ "Color", COLOR, WHITE },
{ "Cells", VALUE, 6, 1, 12 }, -- Defines the amount of lipo cells
}

function create(zone, options)
local Context = { zone=zone, options=options }
return Context
end

-- This function allow updates when you change widgets settings
local function update(Context, options)
Context.options = options
end

--- This function return the percentage remaining in a single Lipo cel
local function getCellPercent(cellValue)
--## Data gathered from commercial lipo sensors
local myArrayPercentList =
{
{3.000, 0},
{3.093, 1},
{3.196, 2},
{3.301, 3},
{3.401, 4},
{3.477, 5},
{3.544, 6},
{3.601, 7},
{3.637, 8},
{3.664, 9},
{3.679, 10},
{3.683, 11},
{3.689, 12},
{3.692, 13},
{3.705, 14},
{3.710, 15},
{3.713, 16},
{3.715, 17},
{3.720, 18},
{3.731, 19},
{3.735, 20},
{3.744, 21},
{3.753, 22},
{3.756, 23},
{3.758, 24},
{3.762, 25},
{3.767, 26},
{3.774, 27},
{3.780, 28},
{3.783, 29},
{3.786, 30},
{3.789, 31},
{3.794, 32},
{3.797, 33},
{3.800, 34},
{3.802, 35},
{3.805, 36},
{3.808, 37},
{3.811, 38},
{3.815, 39},
{3.818, 40},
{3.822, 41},
{3.825, 42},
{3.829, 43},
{3.833, 44},
{3.836, 45},
{3.840, 46},
{3.843, 47},
{3.847, 48},
{3.850, 49},
{3.854, 50},
{3.857, 51},
{3.860, 52},
{3.863, 53},
{3.866, 54},
{3.870, 55},
{3.874, 56},
{3.879, 57},
{3.888, 58},
{3.893, 59},
{3.897, 60},
{3.902, 61},
{3.906, 62},
{3.911, 63},
{3.918, 64},
{3.923, 65},
{3.928, 66},
{3.939, 67},
{3.943, 68},
{3.949, 69},
{3.955, 70},
{3.961, 71},
{3.968, 72},
{3.974, 73},
{3.981, 74},
{3.987, 75},
{3.994, 76},
{4.001, 77},
{4.007, 78},
{4.014, 79},
{4.021, 80},
{4.029, 81},
{4.036, 82},
{4.044, 83},
{4.052, 84},
{4.062, 85},
{4.074, 86},
{4.085, 87},
{4.095, 88},
{4.105, 89},
{4.111, 90},
{4.116, 91},
{4.120, 92},
{4.125, 93},
{4.129, 94},
{4.135, 95},
{4.145, 96},
{4.176, 97},
{4.179, 98},
{4.193, 99},
{4.200, 100}
}

if cellValue >= 4.2 then
cellValue = 4.2
elseif cellValue <= 3 then
result = 0
return result
end

for i, v in ipairs( myArrayPercentList ) do
if v[ 1 ] >= cellValue then
result = v[ 2 ]
break
end
end

return result

end

-- This function returns green at 100%, red bellow 30% and graduate in betwwen
local function getPercentColor(cpercent)
if cpercent < 30 then
return lcd.RGB(0xff, 0, 0)
else
g = math.floor(0xdf * cpercent / 100)
r = 0xdf - g
return lcd.RGB(r, g, 0)
end
end

function Calc_VPercent(LocalContext)

LiveVolt = getValue(LocalContext.options.Source)
LiveCells = LocalContext.options.Cells

if(LiveVolt == nil) then
LiveVolt = 100
return
end

if LiveVolt > 0 then
Volt = LiveVolt / LiveCells
VPercent = getCellPercent(Volt)
end

end

function ScreenUpdate(LocalContext)

if LiveVolt > 0 then

if LocalContext.zone.w > 220 and LocalContext.zone.h > 160 then

lcd.setColor(CUSTOM_COLOR, LocalContext.options.Color)
lcd.drawText(LocalContext.zone.x + 5, LocalContext.zone.y + 2, "BATTERY LEFT", CUSTOM_COLOR + SHADOWED)
lcd.setColor(CUSTOM_COLOR, getPercentColor(VPercent))
lcd.drawText(LocalContext.zone.x + 5, LocalContext.zone.y +15, round(VPercent).."%" , CUSTOM_COLOR + DBLSIZE + SHADOWED)
lcd.drawText(LocalContext.zone.x + 5, LocalContext.zone.y +45, round(LiveVolt,2).."V" , CUSTOM_COLOR + DBLSIZE + SHADOWED)

lcd.setColor(CUSTOM_COLOR, LocalContext.options.Color)
lcd.drawRectangle((LocalContext.zone.x - 1) , (LocalContext.zone.y + (LocalContext.zone.h - 31)), (LocalContext.zone.w + 2), 32, CUSTOM_COLOR)
lcd.setColor(CUSTOM_COLOR, getPercentColor(VPercent))
lcd.drawGauge(LocalContext.zone.x , (LocalContext.zone.y + (LocalContext.zone.h - 30)), LocalContext.zone.w, 30, round(VPercent), 100, CUSTOM_COLOR)

elseif LocalContext.zone.w > 220 and LocalContext.zone.h > 90 then

lcd.setColor(CUSTOM_COLOR, LocalContext.options.Color)
lcd.drawText(LocalContext.zone.x + 5, LocalContext.zone.y + 2, "BATTERY LEFT", CUSTOM_COLOR + SHADOWED)
lcd.setColor(CUSTOM_COLOR, getPercentColor(VPercent))
lcd.drawText(LocalContext.zone.x + 5, LocalContext.zone.y +15, round(VPercent).."%" , CUSTOM_COLOR + DBLSIZE + SHADOWED)
lcd.drawText((LocalContext.zone.x + 220 - 15), LocalContext.zone.y +15, round(LiveVolt,2).."V" , CUSTOM_COLOR + RIGHT + DBLSIZE + SHADOWED)

lcd.setColor(CUSTOM_COLOR, LocalContext.options.Color)
lcd.drawRectangle((LocalContext.zone.x - 1) , (LocalContext.zone.y + (LocalContext.zone.h - 31)), (LocalContext.zone.w + 2), 32, CUSTOM_COLOR)
lcd.setColor(CUSTOM_COLOR, getPercentColor(VPercent))
lcd.drawGauge(LocalContext.zone.x , (LocalContext.zone.y + (LocalContext.zone.h - 30)), LocalContext.zone.w, 30, round(VPercent), 100, CUSTOM_COLOR)

elseif LocalContext.zone.w == 192 and LocalContext.zone.h == 152 then

lcd.setColor(CUSTOM_COLOR, LocalContext.options.Color)
lcd.drawText(LocalContext.zone.x + 5, LocalContext.zone.y + 2, "BATTERY LEFT", CUSTOM_COLOR + SHADOWED)
lcd.setColor(CUSTOM_COLOR, getPercentColor(VPercent))
lcd.drawText(LocalContext.zone.x + 5, LocalContext.zone.y +15, round(VPercent).."%" , CUSTOM_COLOR + DBLSIZE + SHADOWED)
lcd.drawText(LocalContext.zone.x + 5, LocalContext.zone.y +45, round(LiveVolt,2).."V" , CUSTOM_COLOR + DBLSIZE + SHADOWED)

lcd.setColor(CUSTOM_COLOR, LocalContext.options.Color)
lcd.drawRectangle((LocalContext.zone.x - 1) , (LocalContext.zone.y + (LocalContext.zone.h - 31)), (LocalContext.zone.w + 2), 32, CUSTOM_COLOR)
lcd.setColor(CUSTOM_COLOR, getPercentColor(VPercent))
lcd.drawGauge(LocalContext.zone.x , (LocalContext.zone.y + (LocalContext.zone.h - 30)), LocalContext.zone.w, 30, round(VPercent), 100, CUSTOM_COLOR)

elseif LocalContext.zone.w == 180 and LocalContext.zone.h == 70 then

lcd.setColor(CUSTOM_COLOR, LocalContext.options.Color)
lcd.drawText(LocalContext.zone.x + 5, LocalContext.zone.y + 2, "BATTERY LEFT", CUSTOM_COLOR + SHADOWED)
lcd.setColor(CUSTOM_COLOR, getPercentColor(VPercent))
lcd.drawText((LocalContext.zone.x + 192 - 15), LocalContext.zone.y +30, round(LiveVolt,2).."V" , CUSTOM_COLOR + RIGHT + SHADOWED)
lcd.drawText(LocalContext.zone.x + 5, LocalContext.zone.y +15, round(VPercent).."%" , CUSTOM_COLOR + DBLSIZE + SHADOWED)

lcd.setColor(CUSTOM_COLOR, LocalContext.options.Color)
lcd.drawRectangle((LocalContext.zone.x - 1) , (LocalContext.zone.y + (LocalContext.zone.h - 21)), (LocalContext.zone.w + 2), 22, CUSTOM_COLOR)
lcd.setColor(CUSTOM_COLOR, getPercentColor(VPercent))
lcd.drawGauge(LocalContext.zone.x , (LocalContext.zone.y + (LocalContext.zone.h - 20)), LocalContext.zone.w, 20, round(VPercent), 100, CUSTOM_COLOR)

elseif LocalContext.zone.w == 160 and LocalContext.zone.h == 32 then

lcd.setColor(CUSTOM_COLOR, lcd.RGB(0,0,0))
lcd.drawSource(LocalContext.zone.x + 6, LocalContext.zone.y + 2, LocalContext.options.Source, CUSTOM_COLOR + SHADOWED)
lcd.setColor(CUSTOM_COLOR, LocalContext.options.Color)
lcd.drawSource(LocalContext.zone.x + 5, LocalContext.zone.y + 1, LocalContext.options.Source, CUSTOM_COLOR + SHADOWED)

lcd.setColor(CUSTOM_COLOR, getPercentColor(VPercent))
lcd.drawText(LocalContext.zone.x + 160, LocalContext.zone.y - 8, round(VPercent).."%" , CUSTOM_COLOR + DBLSIZE + RIGHT + SHADOWED)

lcd.setColor(CUSTOM_COLOR, getPercentColor(VPercent))
lcd.drawGauge(LocalContext.zone.x , (LocalContext.zone.y + (LocalContext.zone.h - 5)), LocalContext.zone.w, 5, round(VPercent), 100, CUSTOM_COLOR)

end

else

lcd.setColor(CUSTOM_COLOR, LocalContext.options.Color)
lcd.drawText(LocalContext.zone.x + LocalContext.zone.w, LocalContext.zone.y + 2, "Sensor Lost", CUSTOM_COLOR + RIGHT + INVERS + BLINK)

end
end

function round(num, decimals)
local mult = 10^(decimals or 0)
return math.floor(num * mult + 0.5) / mult
end

function update(Context, options)
Context.options = options
Context.back = nil
end

function refresh(Context)

Calc_VPercent(Context)
ScreenUpdate(Context)

end

return { name="BattPct", options=options, create=create, update=update, refresh=refresh }

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *