SD1 configurator voor Horus series
Script om SD1 op de Horus te configureren:
Sla onderstaande code op als: HORUSSD1-Rev1.lua en plaats deze in de map \scripts\tools op de SD-kaart
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 }
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
Hello,
The Frsky SD1 is a SBUS decoder to 1 analog PWM channel.
https://www.frsky-rc.com/frsky-sbus-decoder-sd1/
This tool allows you to config the SD1.
You can select 1 specific channel on the SBUS train to decode to analog PWM.
Gr. Bjorn H4L