diff --git a/README.md b/README.md index 374353b..8d0fdb3 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,28 @@ -# Taranis-XLite-Q7-Lua-Dashboard -A simple lua-based dashboard for the OpenTX XLite/QX7 Transmitters +# TBS Tango2 Dashboard +A simple lua-based dashboard for the TBS Tango2 A cool review and overview and howto video by a fellow user [![](http://img.youtube.com/vi/ijMYaCudgWI/0.jpg)](http://www.youtube.com/watch?v=ijMYaCudgWI "Farleys Lua Dashboard - by DroneRacer101") +# Thank you Farley Farley to the original dashboard ! + +## WIP : adding TBS logo + +## Crossfire does not display Average cells values - If it does, please open an issue to make me correct this (not an expert) +* By default, you will see the cumulated voltages on the display screen. That means that the battery gauge on the left will display irrelevant informations. If you want to fetch average cells voltage, type `set report_cell_voltage = ON` on Betaflight CLI. + ## Features -* Battery voltage (numerical and graphical) +* Battery voltage (numerical and graphical) (graphical will only work correctly if you put `set report_cell_voltage = ON` on Betaflight CLI.) * Transmitter battery percentage * Model name * Time -* RSSI (graphical and icon (top right)) +* Link Quality * Flight Timer, perfect for whooping * ANIMATED QUAD WHEN ARMED!!! ## Author * Written by Farley Farley - farley neonsurge __dot__ com +* Adapted by Alexandre Santini for Tango2 * From: https://github.com/AndrewFarley/Taranis-XLite-Q7-Lua-Dashboard ## Installing @@ -23,31 +31,23 @@ Download the farl.lua script above and drag it to your radio. You should place 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. Download and copy the the scripts to appropriate location on your SD card. NOTE: If the folders do not exist, create them. -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. Download and copy the the scripts to appropriate location on your SD card. NOTE: If the folders do not exist, create them. -4. Reinsert your SD card into the transmitter +1. Power the Tango2 +2. Choose "USB Storage (SD)" +3. Download and copy the the scripts to "SCRIPTS/TELEMETRY" on your SD card. +4. Eject the Tango2 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. ## Adding the script as a telemetry page -Setting up the script as a telemetry page will enable access at the press of a button. These instructions are for the XLite. The Q7 will also work but the instructions will be a bit different. -1. Hold the circular eraser D-Pad on the right side of the controller to the right until the Model Selection Menu Comes up -1. Press the eraser to the left briefly to rotate to page 13/13 (top right) -1. Press the eraser to the bottom position to select the first screen (which should say none) -1. Press down on the eraser so the "None" is flashing -1. Press right on the eraser repeatedly until it goes to "Script", then press down on the eraser to confirm. -1. Press right on the eraser to select which script, then press down on the eraser should bring up a menu, and "farl" should be in there, select it and press down on the eraser. -1. Press the bottom button to back out to the main menu. -1. From now on, while on the main menu with this model, simply move the eraser to the bottom position for about 2 seconds and it will activate your first telemetry screen! +Setting up the script as a telemetry page will enable access at the press of a button. +1. Click on "Menu" then click on "Page", go to page "12" +2. Click on "None", just right after "Screen 1" (or 2,3,4) +3. Scroll and find "Script", then click to validate +4. Choose farl.lua +5. Click on "Exit" +6. Hold "Page" +7. Ta-da ! ## Script Editing / Modification Notes Since not everyone uses the same controller configuration as myself, here's some tips to edit the script for your uses... diff --git a/farl.lua b/farl.lua old mode 100644 new mode 100755 index fd1329b..e4304c3 --- a/farl.lua +++ b/farl.lua @@ -1,5 +1,6 @@ ---------------------------------------------------------- -- Written by Farley Farley +-- Adapted by Alexandre Santini for the Tango2 -- farley neonsurge __dot__ com -- From: https://github.com/AndrewFarley/Taranis-XLite-Q7-Lua-Dashboard -- Please feel free to submit issues, feedback, etc. @@ -7,16 +8,12 @@ ------- GLOBALS ------- --- The model name when it can't detect a model name from the handset +-- The model name when it can't detect a model name from the handset local modelName = "Unknown" --- I'm using 8 NiMH Batteries in my QX7, which is 1.1v low, and ~1.325v high -local lowVoltage = 8.8 -local currentVoltage = 10.6 -local highVoltage = 10.6 --- For an X-Lite you will need... -local lowVoltage = 6.6 -local currentVoltage = 8.4 -local highVoltage = 8.4 +-- Tango2 Voltage +local lowVoltage = 3.38 +local currentVoltage = 4.2 +local highVoltage = 4.2 -- For our timer tracking local timerLeft = 0 local maxTimerValue = 0 @@ -28,8 +25,8 @@ local mode = 0 local animationIncrement = 0 -- is off trying to go on... local isArmed = 0 --- Our global to get our current rssi -local rssi = 0 +-- Our global to get our link_quality +local link_quality = 0 -- For debugging / development local lastMessage = "None" local lastNumberMessage = "0" @@ -62,7 +59,7 @@ local function drawPropellor(start_x, start_y, invert) animationIncrementLocal = animationIncrementLocal - 4 end end - + -- Animated Quadcopter propellors if ((isArmed == 0 or isArmed == 2) and invert == false) or (isArmed == 1 and animationIncrementLocal == 0) then -- Top left Propellor @@ -85,17 +82,17 @@ end -- A sexy helper to draw a 30x30 quadcopter (since X7 can not draw bitmap) local function drawQuadcopter(start_x,start_y) - + -- Top left to bottom right lcd.drawLine(start_x + 4, start_y + 4, start_x + 26, start_y + 26, SOLID, FORCE) lcd.drawLine(start_x + 4, start_y + 5, start_x + 25, start_y + 26, SOLID, FORCE) lcd.drawLine(start_x + 5, start_y + 4, start_x + 26, start_y + 25, SOLID, FORCE) - + -- Bottom left to top right lcd.drawLine(start_x + 4, start_y + 26, start_x + 26, start_y + 4, SOLID, FORCE) lcd.drawLine(start_x + 4, start_y + 25, start_x + 25, start_y + 4, SOLID, FORCE) lcd.drawLine(start_x + 5, start_y + 26, start_x + 26, start_y + 5, SOLID, FORCE) - + -- Middle of Quad lcd.drawRectangle(start_x + 11, start_y + 11, 9, 9, SOLID) lcd.drawRectangle(start_x + 12, start_y + 12, 7, 7, SOLID) @@ -105,7 +102,7 @@ local function drawQuadcopter(start_x,start_y) if isArmed == 1 then lcd.drawText(start_x + 3, start_y + 12, "ARMED", SMLSIZE + BLINK) end - + -- Top-left propellor drawPropellor(start_x, start_y, false) -- Bottom-Right Propellor @@ -114,15 +111,14 @@ local function drawQuadcopter(start_x,start_y) drawPropellor(start_x + 20, start_y, true) -- Bottom-left Propellor drawPropellor(start_x, start_y + 20, true) - -end +end -- Sexy voltage helper local function drawTransmitterVoltage(start_x,start_y,voltage) - + local batteryWidth = 17 - + -- Battery Outline lcd.drawRectangle(start_x, start_y, batteryWidth + 2, 6, SOLID) lcd.drawLine(start_x + batteryWidth + 2, start_y + 1, start_x + batteryWidth + 2, start_y + 4, SOLID, FORCE) -- Positive Nub @@ -137,9 +133,9 @@ local function drawTransmitterVoltage(start_x,start_y,voltage) else lcd.drawText(start_x + batteryWidth + 5, start_y, curVolPercent.."%", SMLSIZE) end - + end - + -- Filled in battery local pixels = math.ceil((curVolPercent / 100) * batteryWidth) if pixels == 1 then @@ -159,7 +155,7 @@ local function drawFlightTimer(start_x, start_y) local timerHeight = 20 local myWidth = 0 local percentageLeft = 0 - + lcd.drawRectangle( start_x, start_y, timerWidth, 10 ) lcd.drawText( start_x + 2, start_y + 2, "Fly Timer", SMLSIZE ) lcd.drawRectangle( start_x, start_y + 10, timerWidth, timerHeight ) @@ -169,8 +165,8 @@ local function drawFlightTimer(start_x, start_y) lcd.drawText( start_x + 2 + 3, start_y + 12, (timerLeft * -1).."s", DBLSIZE + BLINK ) else lcd.drawTimer( start_x + 2, start_y + 12, timerLeft, DBLSIZE ) - end - + end + percentageLeft = (timerLeft / maxTimerValue) local offset = 0 while offset < (timerWidth - 2) do @@ -180,7 +176,7 @@ local function drawFlightTimer(start_x, start_y) end offset = offset + 1 end - + end local function drawTime() @@ -201,130 +197,130 @@ local function drawTime() lcd.drawText(119,0,min, SMLSIZE) end -local function drawRSSI(start_x, start_y) +local function drawlink_quality(start_x, start_y) local timerWidth = 44 local timerHeight = 15 local myWidth = 0 local percentageLeft = 0 - + lcd.drawRectangle( start_x, start_y, timerWidth, 10 ) - lcd.drawText( start_x + 2, start_y + 2, "RSSI:", SMLSIZE) - if rssi < 50 then - lcd.drawText( start_x + 23, start_y + 2, rssi, SMLSIZE + BLINK) + lcd.drawText( start_x + 2, start_y + 2, "LQ", SMLSIZE) + if link_quality < 50 then + lcd.drawText( start_x + 23, start_y + 2, link_quality, SMLSIZE + BLINK) else - lcd.drawText( start_x + 23, start_y + 2, rssi, SMLSIZE) + lcd.drawText( start_x + 23, start_y + 2, link_quality, SMLSIZE) end lcd.drawRectangle( start_x, start_y + 10, timerWidth, timerHeight ) - - - if rssi > 0 then + + + if link_quality > 0 then lcd.drawLine(start_x + 1, start_y + 20, start_x + 1, start_y + 23, SOLID, FORCE) lcd.drawLine(start_x + 2, start_y + 20, start_x + 2, start_y + 23, SOLID, FORCE) lcd.drawLine(start_x + 3, start_y + 20, start_x + 3, start_y + 23, SOLID, FORCE) lcd.drawLine(start_x + 4, start_y + 20, start_x + 4, start_y + 23, SOLID, FORCE) end - if rssi > 10 then + if link_quality > 10 then lcd.drawLine(start_x + 5, start_y + 19, start_x + 5, start_y + 23, SOLID, FORCE) lcd.drawLine(start_x + 6, start_y + 19, start_x + 6, start_y + 23, SOLID, FORCE) end - if rssi > 13 then + if link_quality > 13 then lcd.drawLine(start_x + 7, start_y + 19, start_x + 7, start_y + 23, SOLID, FORCE) lcd.drawLine(start_x + 8, start_y + 19, start_x + 8, start_y + 23, SOLID, FORCE) end - if rssi > 16 then + if link_quality > 16 then lcd.drawLine(start_x + 9, start_y + 18, start_x + 9, start_y + 23, SOLID, FORCE) lcd.drawLine(start_x + 10, start_y + 18, start_x + 10, start_y + 23, SOLID, FORCE) end - if rssi > 19 then + if link_quality > 19 then lcd.drawLine(start_x + 11, start_y + 18, start_x + 11, start_y + 23, SOLID, FORCE) lcd.drawLine(start_x + 12, start_y + 18, start_x + 12, start_y + 23, SOLID, FORCE) end - if rssi > 22 then + if link_quality > 22 then lcd.drawLine(start_x + 13, start_y + 17, start_x + 13, start_y + 23, SOLID, FORCE) lcd.drawLine(start_x + 14, start_y + 17, start_x + 14, start_y + 23, SOLID, FORCE) end - if rssi > 25 then + if link_quality > 25 then lcd.drawLine(start_x + 15, start_y + 17, start_x + 15, start_y + 23, SOLID, FORCE) lcd.drawLine(start_x + 16, start_y + 17, start_x + 16, start_y + 23, SOLID, FORCE) end - if rssi > 28 then + if link_quality > 28 then lcd.drawLine(start_x + 17, start_y + 16, start_x + 17, start_y + 23, SOLID, FORCE) lcd.drawLine(start_x + 18, start_y + 16, start_x + 18, start_y + 23, SOLID, FORCE) end - if rssi > 31 then + if link_quality > 31 then lcd.drawLine(start_x + 19, start_y + 16, start_x + 19, start_y + 23, SOLID, FORCE) end - if rssi > 34 then + if link_quality > 34 then lcd.drawLine(start_x + 20, start_y + 16, start_x + 20, start_y + 23, SOLID, FORCE) end - if rssi > 37 then + if link_quality > 37 then lcd.drawLine(start_x + 21, start_y + 15, start_x + 21, start_y + 23, SOLID, FORCE) end - if rssi > 40 then + if link_quality > 40 then lcd.drawLine(start_x + 22, start_y + 15, start_x + 22, start_y + 23, SOLID, FORCE) end - if rssi > 43 then + if link_quality > 43 then lcd.drawLine(start_x + 23, start_y + 15, start_x + 23, start_y + 23, SOLID, FORCE) end - if rssi > 46 then + if link_quality > 46 then lcd.drawLine(start_x + 24, start_y + 15, start_x + 24, start_y + 23, SOLID, FORCE) end - if rssi > 49 then + if link_quality > 49 then lcd.drawLine(start_x + 25, start_y + 14, start_x + 25, start_y + 23, SOLID, FORCE) end - if rssi > 52 then + if link_quality > 52 then lcd.drawLine(start_x + 26, start_y + 14, start_x + 26, start_y + 23, SOLID, FORCE) end - if rssi > 55 then + if link_quality > 55 then lcd.drawLine(start_x + 27, start_y + 14, start_x + 27, start_y + 23, SOLID, FORCE) end - if rssi > 58 then + if link_quality > 58 then lcd.drawLine(start_x + 28, start_y + 14, start_x + 28, start_y + 23, SOLID, FORCE) end - if rssi > 61 then + if link_quality > 61 then lcd.drawLine(start_x + 29, start_y + 13, start_x + 29, start_y + 23, SOLID, FORCE) end - if rssi > 64 then + if link_quality > 64 then lcd.drawLine(start_x + 30, start_y + 13, start_x + 30, start_y + 23, SOLID, FORCE) end - if rssi > 67 then + if link_quality > 67 then lcd.drawLine(start_x + 31, start_y + 13, start_x + 31, start_y + 23, SOLID, FORCE) end - if rssi > 70 then + if link_quality > 70 then lcd.drawLine(start_x + 32, start_y + 13, start_x + 32, start_y + 23, SOLID, FORCE) end - if rssi > 73 then + if link_quality > 73 then lcd.drawLine(start_x + 33, start_y + 12, start_x + 33, start_y + 23, SOLID, FORCE) end - if rssi > 76 then + if link_quality > 76 then lcd.drawLine(start_x + 34, start_y + 12, start_x + 34, start_y + 23, SOLID, FORCE) end - if rssi > 79 then + if link_quality > 79 then lcd.drawLine(start_x + 35, start_y + 12, start_x + 35, start_y + 23, SOLID, FORCE) end - if rssi > 82 then + if link_quality > 82 then lcd.drawLine(start_x + 36, start_y + 12, start_x + 36, start_y + 23, SOLID, FORCE) end - if rssi > 85 then + if link_quality > 85 then lcd.drawLine(start_x + 37, start_y + 11, start_x + 37, start_y + 23, SOLID, FORCE) end - if rssi > 88 then + if link_quality > 88 then lcd.drawLine(start_x + 38, start_y + 11, start_x + 38, start_y + 23, SOLID, FORCE) end - if rssi > 91 then + if link_quality > 91 then lcd.drawLine(start_x + 39, start_y + 11, start_x + 39, start_y + 23, SOLID, FORCE) end - if rssi > 94 then + if link_quality > 94 then lcd.drawLine(start_x + 40, start_y + 11, start_x + 40, start_y + 23, SOLID, FORCE) end - if rssi > 97 then + if link_quality > 97 then lcd.drawLine(start_x + 41, start_y + 11, start_x + 41, start_y + 23, SOLID, FORCE) end - if rssi > 98 then + if link_quality > 98 then lcd.drawLine(start_x + 42, start_y + 11, start_x + 42, start_y + 23, SOLID, FORCE) end - - if rssi > 0 then + + if link_quality > 0 then lcd.drawLine(101, 5, 101, 5, SOLID, FORCE) lcd.drawLine(100, 2, 102, 2, SOLID, FORCE) lcd.drawLine(99, 3, 99, 3, SOLID, FORCE) @@ -333,15 +329,15 @@ local function drawRSSI(start_x, start_y) lcd.drawLine(98, 1, 98, 1, SOLID, FORCE) lcd.drawLine(104, 1, 104, 1, SOLID, FORCE) end - + end local function drawVoltageText(start_x, start_y) -- First, try to get voltage from VFAS... - local voltage = getValue('VFAS') + local voltage = getValue('RxBt') -- local voltage = getValue('Cels') -- For miniwhoop seems more accurate -- TODO: if that failed, get voltage from somewhere else from my bigger quads? Or rebind the voltage to VFAS? - + if tonumber(voltage) >= 10 then lcd.drawText(start_x,start_y,string.format("%.2f", voltage),MIDSIZE) else @@ -350,10 +346,14 @@ local function drawVoltageText(start_x, start_y) lcd.drawText(start_x + 31, start_y + 4, 'v', MEDSIZE) end +--local function drawTbsLogo(start_x, start_y) + -- lcd.drawPixMap(start_x, start_y, "/test.bmp") +-- end + local function drawVoltageImage(start_x, start_y) - + -- Define the battery width (so we can adjust it later) - local batteryWidth = 12 + local batteryWidth = 12 -- Draw our battery outline lcd.drawLine(start_x + 2, start_y + 1, start_x + batteryWidth - 2, start_y + 1, SOLID, 0) @@ -376,20 +376,20 @@ local function drawVoltageImage(start_x, start_y) lcd.drawLine(start_x + batteryWidth - math.ceil(batteryWidth / 2), start_y + 38, start_x + batteryWidth - 1, start_y + 38, SOLID, 0) -- seven eighth line lcd.drawLine(start_x + batteryWidth - math.ceil(batteryWidth / 4), start_y + 44, start_x + batteryWidth - 1, start_y + 44, SOLID, 0) - + -- Voltage top - lcd.drawText(start_x + batteryWidth + 4, start_y + 0, "4.35v", SMLSIZE) + lcd.drawText(start_x + batteryWidth + 4, start_y + 0, "4.2v", SMLSIZE) -- Voltage middle - lcd.drawText(start_x + batteryWidth + 4, start_y + 24, "3.82v", SMLSIZE) + lcd.drawText(start_x + batteryWidth + 4, start_y + 24, "3.9v", SMLSIZE) -- Voltage bottom - lcd.drawText(start_x + batteryWidth + 4, start_y + 47, "3.3v", SMLSIZE) - + lcd.drawText(start_x + batteryWidth + 4, start_y + 47, "3.7v", SMLSIZE) + -- Now draw how full our voltage is... - local voltage = getValue('VFAS') - voltageLow = 3.3 - voltageHigh = 4.35 + local voltage = getValue('RxBt') + voltageLow = 3.8 + voltageHigh = 4.20 voltageIncrement = ((voltageHigh - voltageLow) / 47) - + local offset = 0 -- Start from the bottom up while offset < 47 do if ((offset * voltageIncrement) + voltageLow) < tonumber(voltage) then @@ -400,9 +400,9 @@ local function drawVoltageImage(start_x, start_y) end local function gatherInput(event) - - -- Get our RSSI - rssi = getRSSI() + + -- Get our link_quality + link_quality = getValue("TQly") -- Get the seconds left in our timer timerLeft = getValue('timer1') @@ -418,13 +418,13 @@ local function gatherInput(event) armed = getValue('sa') -- Our "mode" switch - mode = getValue('sb') + mode = getValue('sc') -- Do some event handling to figure out what button(s) were pressed :) if event > 0 then lastNumberMessage = event end - + if event == 131 then lastMessage = "Page Button HELD" killEvents(131) @@ -442,7 +442,7 @@ local function gatherInput(event) lastMessage = "Menu Button Pressed" killEvents(96) end - + if event == EVT_ROT_RIGHT then lastMessage = "Navigate Right Pressed" killEvents(EVT_ROT_RIGHT) @@ -462,7 +462,7 @@ end local function getModeText() local modeText = "Unknown" if mode < -512 then - modeText = "Air Mode" + modeText = "Angle" elseif mode > -100 and mode < 100 then modeText = "Acro" elseif mode > 512 then @@ -472,13 +472,13 @@ local function getModeText() end local function run(event) - + -- Now begin drawing... lcd.clear() - + -- Gather input from the user gatherInput(event) - + -- Set our animation "frame" setAnimationIncrement() @@ -503,25 +503,27 @@ local function run(event) -- Draw our sexy quadcopter animated (if armed) from scratch drawQuadcopter(47, 16) - + -- Draw our sexy voltage drawTransmitterVoltage(0,0, currentVoltage) -- Draw our flight timer drawFlightTimer(84, 34) - - -- Draw RSSI - drawRSSI(84, 8) - + + -- Draw link_quality + drawlink_quality(84, 8) + -- Draw Time in Top Right drawTime() - + -- Draw Voltage bottom middle drawVoltageText(45,50) - + -- Draw voltage battery graphic drawVoltageImage(3, 10) - + + --drawTbsLogo(50,30) + return 0 end