SD1 configurator for Horus series

Script to config SD1 on the Horus:

Save code below as: HORUSSD1-Rev1.lua and place it in the \scripts\tools folder on the SD-Card

local VALUE = 0
local COMBO = 1

local edit = false
local page = 1
local current = 1
local refreshState = 0
local refreshIndex = 0
local pageOffset = 0
local pages = {}
local fields = {}
local modifications = {}
local SD1setupflag = 0

local configFields = {
{"Channel select", COMBO, 0x80, nil, {"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15} },
}

-- Change display attribute to current field
local function addField(step)
local field = fields[current]
local min, max
if field[2] == VALUE then
min = field[5]
max = field[6]
elseif field[2] == COMBO then
min = 0
max = #(field[5]) - 1
end
if (step < 0 and field[4] > min) or (step > 0 and field[4] < max) then
field[4] = field[4] + step
end
end

-- Select the next or previous page
local function selectPage(step)
page = 1 + ((page + step - 1 + #pages) % #pages)
refreshIndex = 0
pageOffset = 0
end

-- Select the next or previous editable field
local function selectField(step)
current = 1 + ((current + step - 1 + #fields) % #fields)
if current > 7 + pageOffset then
pageOffset = current - 7
elseif current <= pageOffset then
pageOffset = current - 1
end
end

local function drawProgressBar()
local width = (330 * refreshIndex) / #fields
lcd.drawRectangle(80, 15, 330, 10)
lcd.drawFilledRectangle(81, 17, width, 8);
end

-- Redraw the current page
local function redrawFieldsPage()
lcd.clear()
-- lcd.drawRectangle(0,0,479,20,SOLID)
lcd.drawRectangle(2, 2, 476, 38, SOLID)
lcd.drawText(10,2,"SD1",DBLSIZE)
lcd.drawText(476,2,page.."/"..#pages,DBLSIZE + RIGHT)

--lcd.drawScreenTitle("SD1", page, #pages)
if refreshIndex < #fields then
drawProgressBar()
end

for index = 1, 7, 1 do
local field = fields[pageOffset+index]
if field == nil then
break
end

local attr = current == (pageOffset+index) and ((edit == true and BLINK or 0) + INVERS) or 0
lcd.drawRectangle(2, 86, 476, 40, SOLID)

lcd.drawText(10, 87*index, field[1], DBLSIZE)

if field[4] == nil then
lcd.drawText(LCD_W-5, 90*index, "---", attr + RIGHT + DBLSIZE)
else
if field[2] == VALUE then
lcd.drawNumber(LCD_W-5, 90*index, field[4], attr + RIGHT + DBLSIZE)
elseif field[2] == COMBO then
if field[4] >= 0 and field[4] < #(field[5]) then
lcd.drawText(LCD_W-5, 90*index, field[5][1+field[4]], attr + RIGHT + DBLSIZE)
end
end
end
end
end

local function telemetrySet()
return sportTelemetryPush(0x1b, 0x21, 0x0b40, 0)
end

local function telemetryRead(field)
return sportTelemetryPush(0x1b, 0x30, 0x0b40, field)
end

local function telemetryWrite(field, value)
return sportTelemetryPush(0x1b, 0x31, 0x0b40, field + value*256)
end

local telemetryPopTimeout = 0

local function refreshNext()
if refreshState == 0 then
if SD1setupflag == 0 then
telemetrySet()--
SD1setupflag = 1
end
if #modifications > 0 then --and SD1setupflag = 2
telemetryWrite(modifications[1][1], modifications[1][2]) --page,value
modifications[1] = nil
elseif refreshIndex < #fields then
local field = fields[refreshIndex + 1]
if telemetryRead(field[3]) == true then
refreshState = 1
telemetryPopTimeout = getTime() + 80 -- normal delay is 500ms
end
end
elseif refreshState == 1 then
local physicalId, primId, dataId, value = sportTelemetryPop()
if primId == 0x32 and dataId == 0x0b40 then -- and physicalID == 0x03
local fieldId = value % 256
local field = fields[refreshIndex + 1]
if fieldId == field[3] then --page is right
local value = math.floor(value / 256)
if value > 0xf then
value = 0
end --for SD1 default

if field[3] >= 0x9E and field[3] <= 0xA0 then
local b1 = value % 256
local b2 = math.floor(value / 256)
value = b1*256 + b2
value = value - bit32.band(value, 0x8000) * 2
end
if field[2] == COMBO and #field == 6 then
for index = 1, #(field[6]), 1 do
if value == field[6][index] then
value = index - 1
break
end
end
elseif field[2] == VALUE and #field == 8 then
value = value - field[8] + field[5]
end
fields[refreshIndex + 1][4] = value
refreshIndex = refreshIndex + 1
refreshState = 0
end
elseif getTime() > telemetryPopTimeout then
refreshState = 0
else
SD1setupflag = 0
end
end
end

local function updateField(field)
local value = field[4]
if field[2] == COMBO and #field == 6 then
value = field[6][1+value]
elseif field[2] == VALUE and #field == 8 then
value = value + field[8] - field[5]
end
modifications[#modifications+1] = { field[3], value }
end

-- Main
local function runFieldsPage(event)
if event == EVT_EXIT_BREAK then -- exit script
return 2
elseif event == EVT_ENTER_BREAK then -- toggle editing/selecting current field
if fields[current][4] ~= nil then
edit = not edit
if edit == false then
updateField(fields[current])
end
end
elseif edit then
if event == EVT_PLUS_FIRST or event == EVT_ROT_RIGHT or event == EVT_PLUS_REPT then
addField(1)
elseif event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT then
addField(-1)
end
else
if event == EVT_MINUS_FIRST or event == EVT_ROT_RIGHT then
selectField(1)
elseif event == EVT_PLUS_FIRST or event == EVT_ROT_LEFT then
selectField(-1)
end
end
redrawFieldsPage()
return 0
end

--local mountText = {"*--- ---- ---- ----", "-*-- ---- ---- ----", "--*- ---- ---- ----"}

local function runConfigPage(event)
fields = configFields
local result = runFieldsPage(event)
-- if fields[3][4] ~= nil then
-- lcd.drawText(1, 32, "Channals:")
-- lcd.drawText(3, 40, mountText[1 + fields[3][4]]) --mountText[1 + fields[1][4]])
-- end
return result
end

local function runSettingsPage(event)
fields = settingsFields
return runFieldsPage(event)
end

-- Init
local function init()
current, edit, refreshState, refreshIndex = 1, false, 0, 0
pages = {
runConfigPage
-- runSettingsPage,
}

end

-- Main
local function run(event)
if event == nil then
error("Cannot be run as a sensor script!")
return 2
elseif event == EVT_PAGE_BREAK then
selectPage(1)
elseif event == EVT_PAGE_LONG then
killEvents(event);
selectPage(-1)
end

local result = pages[page](event)
refreshNext()

return result
end

return { init=init, run=run }

You may also like...

2 Responses

  1. Cedric says:

    Thanks for your script HORUS Battpct, very usefull !!!. I’m a beginner in Horus. What does it mean SD1config for HORUS? I Don’t understand for what this script is about? Thanks. Cédric

Leave a Reply

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