Add rainbow effect to led strip and cleanup (#3322)

* Add rainbow effect and cleanup

* reduce indentation
master
ASDosjani 2023-03-16 15:08:59 +01:00 committed by GitHub
parent 36628523db
commit b21468d41f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 174 additions and 113 deletions

View File

@ -3527,17 +3527,16 @@
"message": "LEDs without wire ordering number will not be saved.",
"description": "Message in the wiring modes in Led Strip"
},
"ledStripVtxFunction": {
"message": "Larson scanner"
},
"ledStripBlinkTitle": {
"message": "Blink"
"ledStripLarsonOverlay": {
"message": "Larson scanner",
"description": "Larson effect switch label on LED Strip tab"
},
"ledStripBlinkAlwaysOverlay": {
"message": "Blink always"
},
"ledStripBlinkLandingOverlay": {
"message": "Blink on landing"
"ledStripRainbowOverlay": {
"message": "Rainbow",
"description": "Rainbow effect switch label on LED Strip tab"
},
"ledStripOverlayTitle": {
"message": "Overlay"

View File

@ -150,14 +150,14 @@
margin-left: -9px;
}
}
.gPoint.function-n {
.overlay-n {
.gPoint.function-y {
.overlay-y {
float: left;
height: 6px;
width: 16px;
background-image: radial-gradient(1px at 8px 50% , blue 0%, blue 2px, rgba(0, 0, 0, 0.3) 3px, rgba(0, 0, 0, 0) 4px);
margin-top: -18px;
margin-left: 16px;
background-image: radial-gradient(1px at 8px 50% , rgb(0, 242, 12) 0%, rgb(0, 242, 12) 0% 2px, rgba(0, 0, 0, 0.3) 3px, rgba(0, 0, 0, 0) 4px);
margin-top: -30px;
margin-left: 4px;
}
}
.gPoint {
@ -232,9 +232,6 @@
.overlays {
display: inline-block;
}
.blinkers {
display: inline-block;
}
.modifiers {
display: inline-block;
.auxSelect {
@ -384,14 +381,14 @@
}
.north {
top: -9px;
left: 4px;
left: 5px;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid rgba(0,0,0,.8);
}
.south {
bottom: -8px;
left: 4px;
left: 5px;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid rgba(0,0,0,.8);

View File

@ -8,7 +8,7 @@ import semver from 'semver';
import vtxDeviceStatusFactory from "../utils/VtxDeviceStatus/VtxDeviceStatusFactory";
import MSP from "../msp";
import MSPCodes from "./MSPCodes";
import { API_VERSION_1_42, API_VERSION_1_43, API_VERSION_1_44, API_VERSION_1_45 } from '../data_storage';
import { API_VERSION_1_42, API_VERSION_1_43, API_VERSION_1_44, API_VERSION_1_45, API_VERSION_1_46 } from '../data_storage';
import EscProtocols from "../utils/EscProtocols";
import huffmanDecodeBuf from "../huffman";
import { defaultHuffmanTree, defaultHuffmanLenIndex } from "../default_huffman_tree";
@ -20,7 +20,7 @@ import { OSD } from "../tabs/osd";
// Used for LED_STRIP
const ledDirectionLetters = ['n', 'e', 's', 'w', 'u', 'd']; // in LSB bit order
const ledBaseFunctionLetters = ['c', 'f', 'a', 'l', 's', 'g', 'r']; // in LSB bit
let ledOverlayLetters = ['t', 'o', 'b', 'v', 'i', 'w']; // in LSB bit
let ledOverlayLetters = ['t', 'y', 'o', 'b', 'v', 'i', 'w']; // in LSB bit
function MspHelper() {
const self = this;
@ -1167,50 +1167,102 @@ MspHelper.prototype.process_data = function(dataHandler) {
case MSPCodes.MSP_LED_STRIP_CONFIG:
FC.LED_STRIP = [];
let ledCount = (data.byteLength - 2) / 4;
// The 32 bit config of each LED contains these in LSB:
// +--------------------+--------------------+------------------+------------------+----------------------+-----------+-----------+
// | Parameters - 3 bit | Directions - 6 bit | Color ID - 4 bit | Overlays - 7 bit | Function ID - 4 bit | X - 4 bit | Y - 4 bit |
// +--------------------+--------------------+------------------+------------------+----------------------+-----------+-----------+
// According to betaflight/src/main/msp/msp.c
// API 1.41 - add indicator for advanced profile support and the current profile selection
// 0 = basic ledstrip available
// 1 = advanced ledstrip available
// Following byte is the current LED profile
let ledCount = (data.byteLength - 2) / 4;
for (let i = 0; i < ledCount; i++) {
//Before API_VERSION_1_46 Parameters were 4 bit and Overlays 6 bit
const mask = data.readU32();
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_46)) {
const functionId = (mask >> 8) & 0xF;
const functions = [];
for (let baseFunctionLetterIndex = 0; baseFunctionLetterIndex < ledBaseFunctionLetters.length; baseFunctionLetterIndex++) {
if (functionId == baseFunctionLetterIndex) {
functions.push(ledBaseFunctionLetters[baseFunctionLetterIndex]);
break;
for (let i = 0; i < ledCount; i++) {
const mask = data.readU32();
const functionId = (mask >> 8) & 0xF;
const functions = [];
for (let baseFunctionLetterIndex = 0; baseFunctionLetterIndex < ledBaseFunctionLetters.length; baseFunctionLetterIndex++) {
if (functionId == baseFunctionLetterIndex) {
functions.push(ledBaseFunctionLetters[baseFunctionLetterIndex]);
break;
}
}
}
const overlayMask = (mask >> 12) & 0x3F;
for (let overlayLetterIndex = 0; overlayLetterIndex < ledOverlayLetters.length; overlayLetterIndex++) {
if (bit_check(overlayMask, overlayLetterIndex)) {
functions.push(ledOverlayLetters[overlayLetterIndex]);
const overlayMask = (mask >> 12) & 0x7F;
for (let overlayLetterIndex = 0; overlayLetterIndex < ledOverlayLetters.length; overlayLetterIndex++) {
if (bit_check(overlayMask, overlayLetterIndex)) {
functions.push(ledOverlayLetters[overlayLetterIndex]);
}
}
}
const directionMask = (mask >> 22) & 0x3F;
const directions = [];
for (let directionLetterIndex = 0; directionLetterIndex < ledDirectionLetters.length; directionLetterIndex++) {
if (bit_check(directionMask, directionLetterIndex)) {
directions.push(ledDirectionLetters[directionLetterIndex]);
const directionMask = (mask >> 23) & 0x3F;
const directions = [];
for (let directionLetterIndex = 0; directionLetterIndex < ledDirectionLetters.length; directionLetterIndex++) {
if (bit_check(directionMask, directionLetterIndex)) {
directions.push(ledDirectionLetters[directionLetterIndex]);
}
}
}
const led = {
y: (mask) & 0xF,
x: (mask >> 4) & 0xF,
functions: functions,
color: (mask >> 18) & 0xF,
directions: directions,
parameters: (mask >> 28) & 0xF,
};
const led = {
y: (mask) & 0xF,
x: (mask >> 4) & 0xF,
functions: functions,
color: (mask >> 19) & 0xF,
directions: directions,
parameters: (mask >>> 29) & 0x7,
};
FC.LED_STRIP.push(led);
FC.LED_STRIP.push(led);
}
}
else {
ledOverlayLetters = ledOverlayLetters.filter(x => x !== 'y');
for (let i = 0; i < ledCount; i++) {
const mask = data.readU32();
const functionId = (mask >> 8) & 0xF;
const functions = [];
for (let baseFunctionLetterIndex = 0; baseFunctionLetterIndex < ledBaseFunctionLetters.length; baseFunctionLetterIndex++) {
if (functionId == baseFunctionLetterIndex) {
functions.push(ledBaseFunctionLetters[baseFunctionLetterIndex]);
break;
}
}
const overlayMask = (mask >> 12) & 0x3F;
for (let overlayLetterIndex = 0; overlayLetterIndex < ledOverlayLetters.length; overlayLetterIndex++) {
if (bit_check(overlayMask, overlayLetterIndex)) {
functions.push(ledOverlayLetters[overlayLetterIndex]);
}
}
const directionMask = (mask >> 22) & 0x3F;
const directions = [];
for (let directionLetterIndex = 0; directionLetterIndex < ledDirectionLetters.length; directionLetterIndex++) {
if (bit_check(directionMask, directionLetterIndex)) {
directions.push(ledDirectionLetters[directionLetterIndex]);
}
}
const led = {
y: (mask) & 0xF,
x: (mask >> 4) & 0xF,
functions: functions,
color: (mask >> 18) & 0xF,
directions: directions,
parameters: (mask >> 28) & 0xF,
};
FC.LED_STRIP.push(led);
}
}
break;
case MSPCodes.MSP_SET_LED_STRIP_CONFIG:
@ -2491,25 +2543,49 @@ MspHelper.prototype.sendLedStripConfig = function(onCompleteCallback) {
}
}
for (let overlayLetterIndex = 0; overlayLetterIndex < led.functions.length; overlayLetterIndex++) {
const bitIndex = ledOverlayLetters.indexOf(led.functions[overlayLetterIndex]);
if (bitIndex >= 0) {
mask |= bit_set(mask, bitIndex + 12);
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_46)) {
for (let overlayLetterIndex = 0; overlayLetterIndex < led.functions.length; overlayLetterIndex++) {
const bitIndex = ledOverlayLetters.indexOf(led.functions[overlayLetterIndex]);
if (bitIndex >= 0) {
mask |= bit_set(mask, bitIndex + 12);
}
}
}
mask |= (led.color << 18);
mask |= (led.color << 19);
for (let directionLetterIndex = 0; directionLetterIndex < led.directions.length; directionLetterIndex++) {
const bitIndex = ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
if (bitIndex >= 0) {
mask |= bit_set(mask, bitIndex + 22);
for (let directionLetterIndex = 0; directionLetterIndex < led.directions.length; directionLetterIndex++) {
const bitIndex = ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
if (bitIndex >= 0) {
mask |= bit_set(mask, bitIndex + 23);
}
}
mask |= (0 << 29); // parameters
buffer.push32(mask);
}
else {
for (let overlayLetterIndex = 0; overlayLetterIndex < led.functions.length; overlayLetterIndex++) {
const bitIndex = ledOverlayLetters.indexOf(led.functions[overlayLetterIndex]);
if (bitIndex >= 0) {
mask |= bit_set(mask, bitIndex + 12);
}
}
mask |= (0 << 28); // parameters
mask |= (led.color << 18);
buffer.push32(mask);
for (let directionLetterIndex = 0; directionLetterIndex < led.directions.length; directionLetterIndex++) {
const bitIndex = ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
if (bitIndex >= 0) {
mask |= bit_set(mask, bitIndex + 22);
}
}
mask |= (0 << 28); // parameters
buffer.push32(mask);
}
// prepare for next iteration
ledIndex++;

View File

@ -2,8 +2,10 @@ import { i18n } from "../localization";
import GUI, { TABS } from '../gui';
import { mspHelper } from "../msp/MSPHelper";
import FC from "../fc";
import semver from 'semver';
import MSP from "../msp";
import MSPCodes from "../msp/MSPCodes";
import { API_VERSION_1_46 } from '../data_storage';
import { gui_log } from "../gui_log";
const led_strip = {
@ -16,9 +18,13 @@ led_strip.initialize = function (callback, scrollPosition) {
let selectedModeColor = null;
const functionTag = '.function-';
TABS.led_strip.functions = ['i', 'w', 'f', 'a', 't', 'r', 'c', 'g', 's', 'b', 'l', 'o', 'n'];
TABS.led_strip.functions = ['i', 'w', 'f', 'a', 't', 'r', 'c', 'g', 's', 'b', 'l', 'o', 'y'];
TABS.led_strip.baseFuncs = ['c', 'f', 'a', 'l', 's', 'g', 'r'];
TABS.led_strip.overlays = ['t', 'o', 'b', 'v', 'i', 'w'];
TABS.led_strip.overlays = ['t', 'y', 'o', 'b', 'v', 'i', 'w'];
if (semver.lt(FC.CONFIG.apiVersion,API_VERSION_1_46)) {
TABS.led_strip.overlays = TABS.led_strip.overlays.filter(x => x !== 'y');
}
TABS.led_strip.wireMode = false;
@ -64,12 +70,12 @@ led_strip.initialize = function (callback, scrollPosition) {
const theHTML = [];
let theHTMLlength = 0;
for (let i = 0; i < 256; i++) {
theHTML[theHTMLlength++] = ('<div class="gPoint"><div class="indicators"><span class="north"></span><span class="south"></span><span class="west"></span><span class="east"></span><span class="up">U</span><span class="down">D</span></div><span class="wire"></span><span class="overlay-t"> </span><span class="overlay-o"> </span><span class="overlay-b"> </span><span class="overlay-v"> </span><span class="overlay-i"> </span><span class="overlay-w"> </span><span class="overlay-color"> </span></div>');
theHTML[theHTMLlength++] = ('<div class="gPoint"><div class="indicators"><span class="north"></span><span class="south"></span><span class="west"></span><span class="east"></span><span class="up">U</span><span class="down">D</span></div><span class="wire"></span><span class="overlay-t"> </span><span class="overlay-y"> </span><span class="overlay-o"> </span><span class="overlay-b"> </span><span class="overlay-v"> </span><span class="overlay-i"> </span><span class="overlay-w"> </span><span class="overlay-color"> </span></div>');
}
$('.mainGrid').html(theHTML.join(''));
$('.tempOutput').click(function() {
$(this).select();
$('.tempOutput').on('click', function() {
$(this).trigger('select');
});
// Aux channel drop-down
@ -85,11 +91,10 @@ led_strip.initialize = function (callback, scrollPosition) {
setModeColor(AuxMode, AuxDir, $('.auxSelect').val());
});
$('.landingBlinkOverlay').css("visibility", "hidden");
$('.vtxOverlay').show();
// Clear button
$('.funcClear').click(function() {
$('.funcClear').on('click', function() {
$('.gPoint').each(function() {
if ($(this).is('.ui-selected')) {
removeFunctionsAndDirections(this);
@ -102,7 +107,7 @@ led_strip.initialize = function (callback, scrollPosition) {
});
// Clear All button
$('.funcClearAll').click(function() {
$('.funcClearAll').on('click', function() {
$('.gPoint').each(function() {
removeFunctionsAndDirections(this);
});
@ -263,13 +268,13 @@ led_strip.initialize = function (callback, scrollPosition) {
},
});
$('.funcWire').click(function() {
$('.funcWire').on('click', function() {
$(this).toggleClass('btnOn');
TABS.led_strip.wireMode = $(this).hasClass('btnOn');
$('.mainGrid').toggleClass('gridWire');
});
$('.funcWireClearSelect').click(function() {
$('.funcWireClearSelect').on('click', function() {
$('.ui-selected').each(function() {
const thisWire = $(this).find('.wire');
if (thisWire.html() !== '') {
@ -279,7 +284,7 @@ led_strip.initialize = function (callback, scrollPosition) {
});
});
$('.funcWireClear').click(function() {
$('.funcWireClear').on('click', function() {
$('.gPoint .wire').html('');
updateBulkCmd();
});
@ -444,16 +449,13 @@ led_strip.initialize = function (callback, scrollPosition) {
switch (letter) {
case 't':
case 'y':
case 'o':
case 's':
if (areModifiersActive(`function-${f}`))
p.addClass(`function-${letter}`);
break;
case 'b':
case 'n':
if (areBlinkersActive(`function-${f}`))
p.addClass(`function-${letter}`);
break;
case 'i':
if (areOverlaysActive(`function-${f}`))
p.addClass(`function-${letter}`);
@ -503,25 +505,9 @@ led_strip.initialize = function (callback, scrollPosition) {
}
if ($('.ui-selected').length > 0) {
TABS.led_strip.overlays.forEach(function(letter) {
if ($(that).is(functionTag + letter)) {
const ret = toggleSwitch(that, letter);
const cbn = $('.checkbox .function-n'); // blink on landing
const cbb = $('.checkbox .function-b'); // blink
if (ret) {
if (letter == 'b' && cbn.is(':checked')) {
cbn.prop('checked', false);
cbn.trigger('change');
toggleSwitch(cbn, 'n');
} else if (letter == 'n' && cbb.is(':checked')) {
cbb.prop('checked', false);
cbb.trigger('change');
toggleSwitch(cbb, 'b');
}
}
toggleSwitch(that, letter);
}
});
@ -736,7 +722,9 @@ led_strip.initialize = function (callback, scrollPosition) {
case "function-s":
case "function-l":
case "function-r":
case "function-y":
case "function-o":
case "function-b":
case "function-g":
return true;
default:
@ -745,14 +733,16 @@ led_strip.initialize = function (callback, scrollPosition) {
return false;
}
function areBlinkersActive(activeFunction) {
switch (activeFunction) {
case "function-c":
case "function-a":
case "function-f":
return true;
default:
break;
function isRainbowActive(activeFunction) {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_46)) {
switch (activeFunction) {
case "function-c":
case "function-a":
case "function-f":
return true;
default:
break;
}
}
return false;
}
@ -799,7 +789,7 @@ led_strip.initialize = function (callback, scrollPosition) {
$('.modifiers').toggle(areModifiersActive(activeFunction));
$('.blinkers').toggle(areBlinkersActive(activeFunction));
$('.rainbowOverlay').toggle(isRainbowActive(activeFunction));
$('.warningOverlay').toggle(isWarningActive(activeFunction));
@ -881,18 +871,18 @@ led_strip.initialize = function (callback, scrollPosition) {
function unselectOverlays(letter) {
// MSP 1.20
if (letter == 'r' || letter == '') {
unselectOverlay(letter, 'y');
unselectOverlay(letter, 'o');
unselectOverlay(letter, 'b');
unselectOverlay(letter, 'n');
unselectOverlay(letter, 't');
}
if (letter == 'l' || letter == 'g' || letter == 's') {
unselectOverlay(letter, 'w');
unselectOverlay(letter, 'v');
unselectOverlay(letter, 't');
unselectOverlay(letter, 'y');
unselectOverlay(letter, 'o');
unselectOverlay(letter, 'b');
unselectOverlay(letter, 'n');
}
}

View File

@ -47,6 +47,7 @@ export function checkChromeRuntimeError() {
}
const majorFirmwareVersions = {
"1.46": "4.5.*",
"1.45": "4.4.*",
"1.44": "4.3.*",
"1.43": "4.2.*",

View File

@ -77,19 +77,17 @@
<div class="checkbox extra_functions20">
<input type="checkbox" name="LarsonScanner" class="toggle function-o" />
<label> <span i18n="ledStripVtxFunction"></span></label>
<label> <span i18n="ledStripLarsonOverlay"></span></label>
</div>
</div>
<div class="blinkers extra_functions20">
<span class="color_section" i18n="ledStripBlinkTitle"></span>
<div class="checkbox blinkOverlay">
<div class="checkbox extra_functions20">
<input type="checkbox" name="blink" class="toggle function-b" />
<label> <span i18n="ledStripBlinkAlwaysOverlay"></span></label>
</div>
<div class="checkbox landingBlinkOverlay">
<input type="checkbox" name="landingBlink" class="toggle function-n" />
<label> <span i18n="ledStripBlinkLandingOverlay"></span></label>
<div class="checkbox extra_functions20 rainbowOverlay">
<input type="checkbox" name="Rainbow" class="toggle function-y" />
<label> <span i18n="ledStripRainbowOverlay"></span></label>
</div>
</div>