1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-24 00:35:26 +03:00

Merge pull request #2296 from limonspb/esc_dshot_reverse

This commit is contained in:
Michael Keller 2021-01-01 15:31:06 +01:00 committed by GitHub
commit d5d0146af7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 1255 additions and 103 deletions

View file

@ -181,4 +181,5 @@ const MSPCodes = {
MSP2_BETAFLIGHT_BIND: 0x3000,
MSP2_MOTOR_OUTPUT_REORDERING: 0x3001,
MSP2_SET_MOTOR_OUTPUT_REORDERING: 0x3002,
MSP2_SEND_DSHOT_COMMAND: 0x3003,
};

View file

@ -57,26 +57,6 @@ function MspHelper() {
self.mspMultipleCache = [];
}
MspHelper.prototype.reorderPwmProtocols = function (protocol) {
let result = protocol;
if (semver.lt(FC.CONFIG.apiVersion, "1.26.0")) {
switch (protocol) {
case 5:
result = 7;
break;
case 7:
result = 5;
break;
default:
break;
}
}
return result;
}
MspHelper.prototype.process_data = function(dataHandler) {
const self = this;
const data = dataHandler.dataView; // DataView (allowing us to view arrayBuffer as struct/union)
@ -1039,7 +1019,7 @@ MspHelper.prototype.process_data = function(dataHandler) {
FC.PID_ADVANCED_CONFIG.gyro_sync_denom = data.readU8();
FC.PID_ADVANCED_CONFIG.pid_process_denom = data.readU8();
FC.PID_ADVANCED_CONFIG.use_unsyncedPwm = data.readU8();
FC.PID_ADVANCED_CONFIG.fast_pwm_protocol = self.reorderPwmProtocols(data.readU8());
FC.PID_ADVANCED_CONFIG.fast_pwm_protocol = EscProtocols.ReorderPwmProtocols(FC.CONFIG.apiVersion, data.readU8());
FC.PID_ADVANCED_CONFIG.motor_pwm_rate = data.readU16();
if (semver.gte(FC.CONFIG.apiVersion, "1.24.0")) {
FC.PID_ADVANCED_CONFIG.digitalIdlePercent = data.readU16() / 100;
@ -1569,6 +1549,9 @@ MspHelper.prototype.process_data = function(dataHandler) {
case MSPCodes.MSP2_SET_MOTOR_OUTPUT_REORDERING:
console.log('Motor output reordering set');
break;
case MSPCodes.MSP2_SEND_DSHOT_COMMAND:
console.log('DSHOT command sent');
break;
case MSPCodes.MSP_MULTIPLE_MSP:
@ -1981,7 +1964,7 @@ MspHelper.prototype.crunch = function(code) {
buffer.push8(FC.PID_ADVANCED_CONFIG.gyro_sync_denom)
.push8(FC.PID_ADVANCED_CONFIG.pid_process_denom)
.push8(FC.PID_ADVANCED_CONFIG.use_unsyncedPwm)
.push8(self.reorderPwmProtocols(FC.PID_ADVANCED_CONFIG.fast_pwm_protocol))
.push8(EscProtocols.ReorderPwmProtocols(FC.CONFIG.apiVersion, FC.PID_ADVANCED_CONFIG.fast_pwm_protocol))
.push16(FC.PID_ADVANCED_CONFIG.motor_pwm_rate);
if (semver.gte(FC.CONFIG.apiVersion, "1.24.0")) {
buffer.push16(FC.PID_ADVANCED_CONFIG.digitalIdlePercent * 100);
@ -2278,6 +2261,10 @@ MspHelper.prototype.crunch = function(code) {
break;
case MSPCodes.MSP2_SEND_DSHOT_COMMAND:
buffer.push8(1);
break;
default:
return false;
}

View file

@ -213,14 +213,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
}
function refreshMixerPreview() {
const mixer = FC.MIXER_CONFIG.mixer
let reverse = "";
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
reverse = FC.MIXER_CONFIG.reverseMotorDir ? "_reversed" : "";
}
$('.mixerPreview img').attr('src', './resources/motor_order/' + mixerList[mixer - 1].image + reverse + '.svg');
const imgSrc = CommonUtils.GetMixerImageSrc(FC.MIXER_CONFIG.mixer, FC.MIXER_CONFIG.reverseMotorDir, FC.CONFIG.apiVersion);
$('.mixerPreview img').attr('src', imgSrc);
}
const reverseMotorSwitch_e = $('#reverseMotorSwitch');
@ -462,34 +456,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
}
// ESC protocols
const escProtocols = [
'PWM',
'ONESHOT125',
'ONESHOT42',
'MULTISHOT',
];
if (semver.gte(FC.CONFIG.apiVersion, "1.20.0")) {
escProtocols.push('BRUSHED');
}
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_31)) {
escProtocols.push('DSHOT150');
escProtocols.push('DSHOT300');
escProtocols.push('DSHOT600');
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_42)) {
escProtocols.push('DSHOT1200');
}
}
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
escProtocols.push('PROSHOT1000');
}
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_43)) {
escProtocols.push('DISABLED');
}
const escProtocols = EscProtocols.GetAvailableProtocols(FC.CONFIG.apiVersion);
const esc_protocol_e = $('select.escprotocol');

View file

@ -31,7 +31,8 @@ TABS.motors = {
// These are translated into proper Dshot values on the flight controller
DSHOT_DISARMED_VALUE: 1000,
DSHOT_MAX_VALUE: 2000,
DSHOT_3D_NEUTRAL: 1500
DSHOT_3D_NEUTRAL: 1500,
numberOfValidOutputs: -1,
};
TABS.motors.initialize = function (callback) {
@ -105,7 +106,7 @@ TABS.motors.initialize = function (callback) {
}
function initDataArray(length) {
const data = new Array(length);
const data = Array.from({length: length});
for (let i = 0; i < length; i++) {
data[i] = [];
data[i].min = -1;
@ -126,8 +127,8 @@ TABS.motors.initialize = function (callback) {
}
}
while (data[0].length > 300) {
for (let i = 0; i < data.length; i++) {
data[i].shift();
for (const item of data) {
item.shift();
}
}
return sampleNumber + 1;
@ -220,13 +221,8 @@ TABS.motors.initialize = function (callback) {
}
function update_model(mixer) {
let reverse = "";
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
reverse = FC.MIXER_CONFIG.reverseMotorDir ? "_reversed" : "";
}
$('.mixerPreview img').attr('src', './resources/motor_order/' + mixerList[mixer - 1].image + reverse + '.svg');
const imgSrc = CommonUtils.GetMixerImageSrc(mixer, FC.MIXER_CONFIG.reverseMotorDir, FC.CONFIG.apiVersion);
$('.mixerPreview img').attr('src', imgSrc);
const motorOutputReorderConfig = new MotorOutputReorderConfig(100);
const domMotorOutputReorderDialogOpen = $('#motorOutputReorderDialogOpen');
@ -234,6 +230,8 @@ TABS.motors.initialize = function (callback) {
const isMotorReorderingAvailable = (mixerList[mixer - 1].name in motorOutputReorderConfig)
&& (FC.MOTOR_OUTPUT_ORDER) && (FC.MOTOR_OUTPUT_ORDER.length > 0);
domMotorOutputReorderDialogOpen.toggle(isMotorReorderingAvailable);
self.escProtocolIsDshot = EscProtocols.IsProtocolDshot(FC.CONFIG.apiVersion, FC.PID_ADVANCED_CONFIG.fast_pwm_protocol);
}
function process_html() {
@ -244,12 +242,6 @@ TABS.motors.initialize = function (callback) {
self.feature3DEnabled = FC.FEATURE_CONFIG.features.isEnabled('3D');
if (FC.PID_ADVANCED_CONFIG.fast_pwm_protocol >= TABS.configuration.DSHOT_PROTOCOL_MIN_VALUE) {
self.escProtocolIsDshot = true;
} else {
self.escProtocolIsDshot = false;
}
$('#motorsEnableTestMode').prop('checked', false);
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_42) || !(FC.MOTOR_CONFIG.use_dshot_telemetry || FC.MOTOR_CONFIG.use_esc_sensor)) {
@ -416,7 +408,7 @@ TABS.motors.initialize = function (callback) {
function computeAndUpdate(sensor_data, data, max_read) {
let sum = 0.0;
for (let j = 0, jlength = data.length; j < jlength; j++) {
for (let k = 0, klength = data[j].length; k < klength; k++){
for (let k = 0, klength = data[j].length; k < klength; k++) {
sum += data[j][k][1]*data[j][k][1];
}
}
@ -455,6 +447,7 @@ TABS.motors.initialize = function (callback) {
motor_mah_drawing_e.text(i18n.getMessage('motorsADrawingValue', [FC.ANALOG.amperage.toFixed(2)]));
motor_mah_drawn_e.text(i18n.getMessage('motorsmAhDrawnValue', [FC.ANALOG.mAhdrawn]));
}
GUI.interval_add('motors_power_data_pull_slow', power_data_pull, 250, true); // 4 fps
$('a.reset_max').click(function () {
@ -463,7 +456,7 @@ TABS.motors.initialize = function (callback) {
accelOffsetEstablished = false;
});
const numberOfValidOutputs = (FC.MOTOR_DATA.indexOf(0) > -1) ? FC.MOTOR_DATA.indexOf(0) : 8;
self.numberOfValidOutputs = (FC.MOTOR_DATA.indexOf(0) > -1) ? FC.MOTOR_DATA.indexOf(0) : 8;
let rangeMin;
let rangeMax;
let neutral3d;
@ -526,7 +519,7 @@ TABS.motors.initialize = function (callback) {
function setSlidersEnabled(isEnabled) {
if (isEnabled && !self.armed) {
$('div.sliders input').slice(0, numberOfValidOutputs).prop('disabled', false);
$('div.sliders input').slice(0, self.numberOfValidOutputs).prop('disabled', false);
// unlock master slider
$('div.sliders input:last').prop('disabled', false);
@ -583,14 +576,14 @@ TABS.motors.initialize = function (callback) {
const val = $(this).val();
$('div.sliders input:not(:disabled, :last)').val(val);
$('div.values li:not(:last)').slice(0, numberOfValidOutputs).text(val);
$('div.values li:not(:last)').slice(0, self.numberOfValidOutputs).text(val);
$('div.sliders input:not(:last):first').trigger('input');
});
// check if motors are already spinning
let motorsRunning = false;
for (let i = 0; i < numberOfValidOutputs; i++) {
for (let i = 0; i < self.numberOfValidOutputs; i++) {
if (!self.feature3DEnabled) {
if (FC.MOTOR_DATA[i] > rangeMin) {
motorsRunning = true;
@ -747,7 +740,11 @@ TABS.motors.initialize = function (callback) {
zeroThrottleValue = neutral3d;
}
setup_motor_output_reordering_dialog(content_ready, zeroThrottleValue);
setup_motor_output_reordering_dialog(SetupEscDshotDirectionDialogCallback, zeroThrottleValue);
function SetupEscDshotDirectionDialogCallback() {
SetupdescDshotDirectionDialog(content_ready, zeroThrottleValue);
}
function content_ready() {
GUI.content_ready(callback);
@ -764,9 +761,9 @@ TABS.motors.initialize = function (callback) {
callbackFunction, mixerList[FC.MIXER_CONFIG.mixer - 1].name,
zeroThrottleValue, zeroThrottleValue + 200);
$('#dialogMotorOutputReorder-closebtn').click(closeDialog);
$('#dialogMotorOutputReorder-closebtn').click(closeDialogMotorOutputReorder);
function closeDialog()
function closeDialogMotorOutputReorder()
{
domDialogMotorOutputReorder[0].close();
motorOutputReorderComponent.close();
@ -776,7 +773,7 @@ TABS.motors.initialize = function (callback) {
function onDocumentKeyPress(event)
{
if (27 === event.which) {
closeDialog();
closeDialogMotorOutputReorder();
}
}
@ -786,6 +783,47 @@ TABS.motors.initialize = function (callback) {
domDialogMotorOutputReorder[0].showModal();
});
}
function SetupdescDshotDirectionDialog(callbackFunction, zeroThrottleValue)
{
const domEscDshotDirectionDialog = $('#escDshotDirectionDialog');
const idleThrottleValue = zeroThrottleValue + FC.PID_ADVANCED_CONFIG.digitalIdlePercent * 1000 / 100;
const motorConfig = {
numberOfMotors: self.numberOfValidOutputs,
motorStopValue: zeroThrottleValue,
motorSpinValue: idleThrottleValue,
escProtocolIsDshot: self.escProtocolIsDshot,
};
const escDshotDirectionComponent = new EscDshotDirectionComponent(
$('#escDshotDirectionDialog-Content'), callbackFunction, motorConfig);
$('#escDshotDirectionDialog-closebtn').on("click", closeEscDshotDirectionDialog);
function closeEscDshotDirectionDialog()
{
domEscDshotDirectionDialog[0].close();
escDshotDirectionComponent.close();
$(document).off("keydown", onDocumentKeyPress);
}
function onDocumentKeyPress(event)
{
if (27 === event.which) {
closeEscDshotDirectionDialog();
}
}
$('#escDshotDirectionDialog-Open').click(function()
{
$(document).on("keydown", onDocumentKeyPress);
domEscDshotDirectionDialog[0].showModal();
});
callbackFunction();
}
};
TABS.motors.cleanup = function (callback) {

View file

@ -0,0 +1,15 @@
'use strict';
class CommonUtils
{
static GetMixerImageSrc(mixerIndex, reverseMotorDir, apiVersion)
{
let reverse = "";
if (semver.gte(apiVersion, API_VERSION_1_36)) {
reverse = reverseMotorDir ? "_reversed" : "";
}
return `./resources/motor_order/${mixerList[mixerIndex - 1].image}${reverse}.svg`;
}
}

View file

@ -0,0 +1,40 @@
'use strict';
class DshotCommand
{
static get ALL_MOTORS() { return 255; }
}
DshotCommand.dshotCommands_e = {
DSHOT_CMD_MOTOR_STOP: 0,
DSHOT_CMD_BEACON1: 1,
DSHOT_CMD_BEACON2: 2,
DSHOT_CMD_BEACON3: 3,
DSHOT_CMD_BEACON4: 4,
DSHOT_CMD_BEACON5: 5,
DSHOT_CMD_ESC_INFO: 6, // V2 includes settings
DSHOT_CMD_SPIN_DIRECTION_1: 7,
DSHOT_CMD_SPIN_DIRECTION_2: 8,
DSHOT_CMD_3D_MODE_OFF: 9,
DSHOT_CMD_3D_MODE_ON: 10,
DSHOT_CMD_SETTINGS_REQUEST: 11, // Currently not implemented
DSHOT_CMD_SAVE_SETTINGS: 12,
DSHOT_CMD_SPIN_DIRECTION_NORMAL: 20,
DSHOT_CMD_SPIN_DIRECTION_REVERSED: 21,
DSHOT_CMD_LED0_ON: 22, // BLHeli32 only
DSHOT_CMD_LED1_ON: 23, // BLHeli32 only
DSHOT_CMD_LED2_ON: 24, // BLHeli32 only
DSHOT_CMD_LED3_ON: 25, // BLHeli32 only
DSHOT_CMD_LED0_OFF: 26, // BLHeli32 only
DSHOT_CMD_LED1_OFF: 27, // BLHeli32 only
DSHOT_CMD_LED2_OFF: 28, // BLHeli32 only
DSHOT_CMD_LED3_OFF: 29, // BLHeli32 only
DSHOT_CMD_AUDIO_STREAM_MODE_ON_OFF: 30, // KISS audio Stream mode on/Off
DSHOT_CMD_SILENT_MODE_ON_OFF: 31, // KISS silent Mode on/Off
DSHOT_CMD_MAX: 47,
};
DshotCommand.dshotCommandType_e = {
DSHOT_CMD_TYPE_INLINE: 0, // dshot commands sent inline with motor signal (motors must be enabled)
DSHOT_CMD_TYPE_BLOCKING: 1, // dshot commands sent in blocking method (motors must be disabled)
};

View file

@ -0,0 +1,95 @@
'use strict';
class EscProtocols
{
static get PROTOCOL_PWM() { return "PWM"; }
static get PROTOCOL_ONESHOT125() { return "ONESHOT125"; }
static get PROTOCOL_ONESHOT42() { return "ONESHOT42"; }
static get PROTOCOL_MULTISHOT() { return "MULTISHOT"; }
static get PROTOCOL_BRUSHED() { return "BRUSHED"; }
static get PROTOCOL_DSHOT150() { return "DSHOT150"; }
static get PROTOCOL_DSHOT300() { return "DSHOT300"; }
static get PROTOCOL_DSHOT600() { return "DSHOT600"; }
static get PROTOCOL_DSHOT1200() { return "DSHOT1200"; }
static get PROTOCOL_PROSHOT1000() { return "PROSHOT1000"; }
static get PROTOCOL_DISABLED() { return "DISABLED"; }
static get DSHOT_PROTOCOLS_SET()
{
return [
EscProtocols.PROTOCOL_DSHOT150,
EscProtocols.PROTOCOL_DSHOT300,
EscProtocols.PROTOCOL_DSHOT600,
EscProtocols.PROTOCOL_DSHOT1200,
EscProtocols.PROTOCOL_PROSHOT1000,
];
}
static GetProtocolName(apiVersion, protocolIndex)
{
const escProtocols = EscProtocols.GetAvailableProtocols(apiVersion);
return escProtocols[protocolIndex];
}
static IsProtocolDshot(apiVersion, protocolIndex)
{
const protocolName = EscProtocols.GetProtocolName(apiVersion, protocolIndex);
return EscProtocols.DSHOT_PROTOCOLS_SET.includes(protocolName);
}
static GetAvailableProtocols(apiVersion)
{
const escProtocols = [
EscProtocols.PROTOCOL_PWM,
EscProtocols.PROTOCOL_ONESHOT125,
EscProtocols.PROTOCOL_ONESHOT42,
EscProtocols.PROTOCOL_MULTISHOT,
];
if (semver.gte(apiVersion, "1.20.0")) {
escProtocols.push(EscProtocols.PROTOCOL_BRUSHED);
}
if (semver.gte(apiVersion, API_VERSION_1_31)) {
escProtocols.push(EscProtocols.PROTOCOL_DSHOT150);
escProtocols.push(EscProtocols.PROTOCOL_DSHOT300);
escProtocols.push(EscProtocols.PROTOCOL_DSHOT600);
if (semver.lt(apiVersion, API_VERSION_1_42)) {
escProtocols.push(EscProtocols.PROTOCOL_DSHOT1200);
}
}
if (semver.gte(apiVersion, API_VERSION_1_36)) {
escProtocols.push(EscProtocols.PROTOCOL_PROSHOT1000);
}
if (semver.gte(apiVersion, API_VERSION_1_43)) {
escProtocols.push(EscProtocols.PROTOCOL_DISABLED);
}
return escProtocols;
}
static ReorderPwmProtocols(apiVersion, protocolIndex)
{
let result = protocolIndex;
if (semver.lt(apiVersion, "1.26.0")) {
switch (protocolIndex) {
case 5:
result = 7;
break;
case 7:
result = 5;
break;
default:
break;
}
}
return result;
}
}