1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-18 22:05:17 +03:00

Allow saving of LED Strip configuratiion via MSP. Requires firmware

with new MSP_SET_LED_STRIP_CONFIG.

Remove some .toUpperCase() duplication since it was only needed for the
CLI commands panel.
Minor CSS cleanups.
Some variable and class renaming to align with firmware code.
This commit is contained in:
Dominic Clifton 2015-01-16 00:15:41 +00:00
parent db68d567d3
commit 519de30f6e
9 changed files with 192 additions and 93 deletions

View file

@ -948,7 +948,9 @@
"ledStripHelp": {
"message": "The flight controller can control colors and effects of individual LEDs on a strip.<br />Configure LEDs on the grid, configure wiring order then attach LEDs on your aircraft according to grid positions."
},
"ledStripButtonSave": {
"message": "Save"
}
}

View file

@ -93,6 +93,9 @@ var MSP = {
callbacks: [],
packet_error: 0,
ledDirectionLetters: ['n', 'e', 's', 'w', 'u', 'd'], // in LSB bit order
ledFunctionLetters: ['i', 'w', 'f', 'a', 't'], // in LSB bit order
read: function (readInfo) {
var data = new Uint8Array(readInfo.data);
@ -626,10 +629,9 @@ var MSP = {
offset += 2;
var directions = [];
var directionLetters = ['n', 'e', 's', 'w', 'u', 'd'];
for (var directionLetterIndex = 0; directionLetterIndex < directionLetters.length; directionLetterIndex++) {
for (var directionLetterIndex = 0; directionLetterIndex < MSP.ledDirectionLetters.length; directionLetterIndex++) {
if (bit_check(directionMask, directionLetterIndex)) {
directions.push(directionLetters[directionLetterIndex]);
directions.push(MSP.ledDirectionLetters[directionLetterIndex]);
}
}
@ -637,10 +639,9 @@ var MSP = {
offset += 2;
var functions = [];
var functionLetters = ['i', 'w', 'f', 'a', 't'];
for (var functionLetterIndex = 0; functionLetterIndex < functionLetters.length; functionLetterIndex++) {
for (var functionLetterIndex = 0; functionLetterIndex < MSP.ledFunctionLetters.length; functionLetterIndex++) {
if (bit_check(functionMask, functionLetterIndex)) {
functions.push(functionLetters[functionLetterIndex]);
functions.push(MSP.ledFunctionLetters[functionLetterIndex]);
}
}
@ -655,6 +656,10 @@ var MSP = {
}
break;
case MSP_codes.MSP_SET_LED_STRIP_CONFIG:
console.log('Led strip config saved');
break;
case MSP_codes.MSP_SET_MODE_RANGE:
console.log('Mode range saved');
@ -989,3 +994,53 @@ MSP.sendAdjustmentRanges = function(onCompleteCallback) {
}
};
MSP.sendLedStripConfig = function(onCompleteCallback) {
var nextFunction = send_next_led_strip_config;
var ledIndex = 0;
send_next_led_strip_config();
function send_next_led_strip_config() {
var led = LED_STRIP[ledIndex];
var buffer = [];
buffer.push(ledIndex);
var directionMask = 0;
for (var directionLetterIndex = 0; directionLetterIndex < led.directions.length; directionLetterIndex++) {
var bitIndex = MSP.ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
if (bitIndex >= 0) {
directionMask = bit_set(directionMask, bitIndex);
}
}
buffer.push(specificByte(directionMask, 0));
buffer.push(specificByte(directionMask, 1));
var functionMask = 0;
for (var functionLetterIndex = 0; functionLetterIndex < led.functions.length; functionLetterIndex++) {
var bitIndex = MSP.ledFunctionLetters.indexOf(led.functions[functionLetterIndex]);
if (bitIndex >= 0) {
functionMask = bit_set(functionMask, bitIndex);
}
}
buffer.push(specificByte(functionMask, 0));
buffer.push(specificByte(functionMask, 1));
buffer.push(led.x);
buffer.push(led.y);
// prepare for next iteration
ledIndex++;
if (ledIndex == LED_STRIP.length) {
nextFunction = onCompleteCallback;
}
MSP.send_message(MSP_codes.MSP_SET_LED_STRIP_CONFIG, buffer, false, nextFunction);
}
}

View file

@ -98,10 +98,7 @@
}
.tab-adjustments > .buttons {
width: calc(100% - 20px);
margin-top: 10px;
bottom: 10px;
}
.tab-adjustments > .buttons a {

View file

@ -139,10 +139,7 @@
}
.tab-auxiliary > .buttons {
width: calc(100% - 20px);
margin-top: 10px;
bottom: 10px;
}
.tab-auxiliary > .buttons a {

View file

@ -140,13 +140,6 @@
margin-left: 15px;
}
.tab-auxiliary > .buttons {
width: calc(100% - 20px);
margin-top: 10px;
bottom: 10px;
}
.tab-configuration .save {
display: block;
float: right;

View file

@ -29,35 +29,35 @@
cursor: pointer;
}
.tab-led-strip .gPoint.mode-w { /* warning */
.tab-led-strip .gPoint.function-w { /* warning */
background: red;
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
border-color: red;
}
.tab-led-strip .gPoint.mode-f { /* flight mode & orientation */
.tab-led-strip .gPoint.function-f { /* flight mode & orientation */
background: rgb(50, 205, 50);
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
border-color: rgb(50, 205, 50);
}
.tab-led-strip .gPoint.mode-w.mode-f {
.tab-led-strip .gPoint.function-w.function-f {
background: linear-gradient(to bottom, #42c949 0%,#d2ff52 52%,#d2ff52 52%,#ff5454 52%,#ba3535 100%);
}
.tab-led-strip .gPoint.mode-i { /* indicator */
.tab-led-strip .gPoint.function-i { /* indicator */
background: yellow;
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
border-color: yellow;
}
.tab-led-strip .gPoint.mode-a { /* Armed Mode */
.tab-led-strip .gPoint.function-a { /* Armed Mode */
background: rgb(52, 155, 255);
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
border-color: rgb(52, 155, 255);
}
.tab-led-strip .gPoint.mode-t { /* Armed Mode */
.tab-led-strip .gPoint.function-t { /* Armed Mode */
background: orange;
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
border-color: orange;
@ -136,18 +136,13 @@
width: 32%;
}
.tab-led-strip .modeW.btnOn {background: red;}
.tab-led-strip .modeF.btnOn {background: rgb(50, 205, 50);}
.tab-led-strip .modeI.btnOn {background: yellow; color: #333;}
.tab-led-strip .modeA.btnOn {background: blue;}
.tab-led-strip .modeT.btnOn {background: orange;}
.tab-led-strip .functions .function-w.btnOn {background: red;}
.tab-led-strip .functions .function-f.btnOn {background: rgb(50, 205, 50);}
.tab-led-strip .functions .function-i.btnOn {background: yellow; color: #333;}
.tab-led-strip .functions .function-a.btnOn {background: blue;}
.tab-led-strip .functions .function-t.btnOn {background: orange;}
.tab-led-strip .dirN.btnOn {background: #FFF; color: #000;}
.tab-led-strip .dirE.btnOn {background: #FFF; color: #000;}
.tab-led-strip .dirS.btnOn {background: #FFF; color: #000;}
.tab-led-strip .dirW.btnOn {background: #FFF; color: #000;}
.tab-led-strip .dirU.btnOn {background: #FFF; color: #000;}
.tab-led-strip .dirD.btnOn {background: #FFF; color: #000;}
.tab-led-strip .directions .btnOn {background: #FFF; color: #000;}
.tab-led-strip .indicators {
position: relative;
@ -235,24 +230,24 @@
outline: none;
}
.tab-led-strip .orientation {
.tab-led-strip .directions {
width: 130px;
height: 100px;
position: relative;
}
.tab-led-strip .orientation button {
.tab-led-strip .directions button {
position: absolute;
width: 30px;
height: 30px;
}
.tab-led-strip .orientation .dirN {top: 0; left: 32px;}
.tab-led-strip .orientation .dirS {bottom: 0; left: 32px;}
.tab-led-strip .orientation .dirE {left: 64px; top: 32px;}
.tab-led-strip .orientation .dirW {left: 0; top: 32px;}
.tab-led-strip .orientation .dirU {right: 0; top: 15px;}
.tab-led-strip .orientation .dirD {right: 0; bottom: 15px;}
.tab-led-strip .directions .dir-n {top: 0; left: 32px;}
.tab-led-strip .directions .dir-s {bottom: 0; left: 32px;}
.tab-led-strip .directions .dir-e {left: 64px; top: 32px;}
.tab-led-strip .directions .dir-w {left: 0; top: 32px;}
.tab-led-strip .directions .dir-u {right: 0; top: 15px;}
.tab-led-strip .directions .dir-d {right: 0; bottom: 15px;}
.tab-led-strip .wires-remaining {
float: right;
@ -289,3 +284,26 @@
z-index: 100;
border: 1px dotted white;
}
.tab-led-strip > .buttons {
margin-top: 10px;
}
.tab-led-strip .save {
display: block;
float: right;
height: 28px;
line-height: 28px;
padding: 0 15px 0 15px;
text-align: center;
font-weight: bold;
border: 1px solid silver;
background-color: #ececec;
}
.tab-led-strip.save:hover {
background-color: #dedcdc;
}

View file

@ -8,23 +8,23 @@
<div class="wires-remaining"><div></div>Remaining</div>
<button class="funcClear">Clear selected</button>
<div class="section">LED Modes</div>
<div class="modes">
<button class="modeW w50">Warnings</button>
<button class="modeF w50">Flight &amp; Orientation</button><br>
<button class="modeI w33">Indicator</button>
<button class="modeA w33">Arm State</button>
<button class="modeT w33">Thrust</button>
<div class="section">LED Functions</div>
<div class="functions">
<button class="function-w w50">Warnings</button>
<button class="function-f w50">Flight &amp; Orientation</button><br>
<button class="function-i w33">Indicator</button>
<button class="function-a w33">Arm State</button>
<button class="function-t w33">Thrust</button>
</div>
<div class="section">LED Orientation</div>
<div class="orientation">
<button class="dirN">N</button>
<button class="dirE">E</button>
<button class="dirS">S</button>
<button class="dirW">W</button>
<button class="dirU">U</button>
<button class="dirD">D</button>
<div class="directions">
<button class="dir-n">N</button>
<button class="dir-e">E</button>
<button class="dir-s">S</button>
<button class="dir-w">W</button>
<button class="dir-u">U</button>
<button class="dir-d">D</button>
</div>
@ -43,4 +43,9 @@
</div>
</div>
<div class="clear-both"></div>
<div class="buttons">
<a class="save" href="#" i18n="ledStripButtonSave"></a>
</div>
</div>

View file

@ -2,8 +2,8 @@
TABS.led_strip = {
wireMode: false,
flightModes: ['w', 'f', 'i', 'a', 't'],
ledOrientations: ['n', 'e', 's', 'w', 'u', 'd'],
functions: ['w', 'f', 'i', 'a', 't'],
directions: ['n', 'e', 's', 'w', 'u', 'd'],
};
TABS.led_strip.initialize = function (callback, scrollPosition) {
@ -71,11 +71,11 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
// Directional Buttons
$('.orientation').on('click', 'button', function() {
$('.directions').on('click', 'button', function() {
var that = this;
if ($('.ui-selected').length > 0) {
TABS.led_strip.ledOrientations.forEach(function(letter) {
if ($(that).is('.dir' + letter.toUpperCase())) {
TABS.led_strip.directions.forEach(function(letter) {
if ($(that).is('.dir-' + letter)) {
$(that).toggleClass('btnOn');
$('.ui-selected').toggleClass('dir-' + letter);
}
@ -87,13 +87,13 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
// Mode Buttons
$('.modes').on('click', 'button', function() {
$('.functions').on('click', 'button', function() {
var that = this;
if ($('.ui-selected').length > 0) {
TABS.led_strip.flightModes.forEach(function(letter) {
if ($(that).is('.mode' + letter.toUpperCase())) {
TABS.led_strip.functions.forEach(function(letter) {
if ($(that).is('.function-' + letter)) {
$(that).toggleClass('btnOn');
$('.ui-selected').toggleClass('mode-' + letter);
$('.ui-selected').toggleClass('function-' + letter);
}
});
@ -145,19 +145,19 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
var that = this;
TABS.led_strip.ledOrientations.forEach(function(letter) {
TABS.led_strip.directions.forEach(function(letter) {
if ($(that).is('.dir-' + letter)) {
$('.dir' + letter.toUpperCase()).addClass('btnOn');
$('.dir-' + letter).addClass('btnOn');
} else {
$('.dir' + letter.toUpperCase()).removeClass('btnOn');
$('.dir-' + letter).removeClass('btnOn');
}
});
TABS.led_strip.flightModes.forEach(function(letter) {
if ($(that).is('.mode-' + letter)) {
$('.mode' + letter.toUpperCase()).addClass('btnOn');
TABS.led_strip.functions.forEach(function(letter) {
if ($(that).is('.function-' + letter)) {
$('.function-' + letter).addClass('btnOn');
} else {
$('.mode' + letter.toUpperCase()).removeClass('btnOn');
$('.function-' + letter).removeClass('btnOn');
}
});
@ -191,7 +191,7 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
$(this).find('.wire').html(ledIndex);
for (var modeIndex = 0; modeIndex < led.functions.length; modeIndex++) {
$(this).addClass('mode-' + led.functions[modeIndex]);
$(this).addClass('function-' + led.functions[modeIndex]);
}
for (var directionIndex = 0; directionIndex < led.directions.length; directionIndex++) {
@ -201,6 +201,16 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
});
updateBulkCmd();
$('a.save').click(function () {
MSP.sendLedStripConfig(save_to_eeprom);
function save_to_eeprom() {
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, reboot);
}
});
if (callback) callback();
}
@ -216,38 +226,50 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
function updateBulkCmd() {
$('.tempOutput').empty();
$('.tempOutput').html('# Copy and paste commands below into the CLI' + "\n\n");
$('.tempOutput').html('# CLI commands' + "\n\n");
var counter = 0;
var lines = [];
var ledStripLength = LED_STRIP.length;
LED_STRIP = [];
$('.gPoint').each(function(){
if ($(this).is('[class*="mode"]')) {
if ($(this).is('[class*="function"]')) {
var gridNumber = ($(this).index() + 1);
var row = Math.ceil(gridNumber / 16) - 1;
var col = gridNumber/16 % 1 * 16 - 1;
if (col < 0) {col = 15;}
var wireNumber = $(this).find('.wire').html();
var ledModes = '';
var functions = '';
var directions = '';
var that = this;
TABS.led_strip.flightModes.forEach(function(letter){
if ($(that).is('.mode-' + letter)) {
ledModes += letter.toUpperCase();
TABS.led_strip.functions.forEach(function(letter){
if ($(that).is('.function-' + letter)) {
functions += letter;
}
});
TABS.led_strip.ledOrientations.forEach(function(letter){
TABS.led_strip.directions.forEach(function(letter){
if ($(that).is('.dir-' + letter)) {
directions += letter.toUpperCase();
directions += letter;
}
});
if (wireNumber != '') {
var line = 'led ' + wireNumber + ' ' + col + ',' + row + ':' + directions + ':' + ledModes;
var line = 'led ' + wireNumber + ' ' + col + ',' + row + ':' + directions.toUpperCase() + ':' + functions.toUpperCase();
lines[wireNumber] = line;
var led = {
x: col,
y: row,
directions: directions,
functions: functions
}
LED_STRIP[wireNumber] = led;
}
counter++;
}
@ -255,9 +277,25 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
$('.tempOutput').append(lines.join("\n"));
var defaultLed = {
x: 0,
y: 0,
directions: '',
functions: ''
};
for (var i = 0; i < ledStripLength; i++) {
if (LED_STRIP[i]) {
continue;
}
LED_STRIP[i] = defaultLed;
}
console.log(LED_STRIP);
var usedWireNumbers = buildUsedWireNumbers();
var remaining = LED_STRIP.length - usedWireNumbers.length;
$('.wires-remaining div').html(remaining);
}

View file

@ -38,12 +38,6 @@
.tab-ports select {
border: 1px solid silver;
}
.tab-ports > .buttons {
width: calc(100% - 20px);
margin-top: 10px;
bottom: 10px;
}
.tab-ports .save {
display: block;