diff --git a/companion/src/eeprominterface.h b/companion/src/eeprominterface.h
index 43ef03a5a..eab2588d3 100644
--- a/companion/src/eeprominterface.h
+++ b/companion/src/eeprominterface.h
@@ -51,7 +51,8 @@ enum BoardEnum {
BOARD_TARANIS_REV4a
};
-#define IS_STOCK(board) (board==BOARD_STOCK || board==BOARD_M128)
+#define IS_9X(board) (board==BOARD_STOCK || board==BOARD_M128)
+#define IS_STOCK(board) (board==BOARD_STOCK)
#define IS_2560(board) (board==BOARD_GRUVIN9X || board==BOARD_MEGA2560)
#define IS_ARM(board) (board==BOARD_SKY9X || board==BOARD_TARANIS || board==BOARD_TARANIS_REV4a)
#define IS_TARANIS(board) (board==BOARD_TARANIS || board==BOARD_TARANIS_REV4a)
@@ -758,6 +759,9 @@ class FrSkyData {
int varioCenterMin; // if increment in 0.2m/s = 3.0m/s max
int varioCenterMax;
int varioMax;
+ bool mAhPersistent;
+ unsigned int storedMah;
+ int fasOffset;
void clear() { memset(this, 0, sizeof(FrSkyData)); rssiAlarms[0].clear(2, 45); rssiAlarms[1].clear(3, 42); varioSource = 2/*VARIO*/; }
};
@@ -1015,7 +1019,9 @@ enum Capability {
LuaInputs,
LimitsPer1000,
EnhancedCurves,
- TelemetryInternalAlarms
+ TelemetryInternalAlarms,
+ HasFasOffset,
+ HasMahPersistent
};
enum UseContext {
diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp
index 672400fe1..005ebe684 100644
--- a/companion/src/firmwares/opentx/opentxeeprom.cpp
+++ b/companion/src/firmwares/opentx/opentxeeprom.cpp
@@ -1717,10 +1717,9 @@ class FrskyField: public StructField {
Append(new ConversionField< SignedField<6> >(frsky.rssiAlarms[i].value, -45+i*3));
}
if (version >= 216) {
- // TODO uint16_t mAhPersistent:1;
- // uint16_t storedMah:15;
- // int8_t fasOffset;
- Append(new SpareBitsField<24>());
+ Append(new BoolField<1>(frsky.mAhPersistent));
+ Append(new UnsignedField<15>(frsky.storedMah));
+ Append(new SignedField<8>(frsky.fasOffset));
}
}
else {
@@ -2044,7 +2043,7 @@ Open9xGeneralDataNew::Open9xGeneralDataNew(GeneralSettings & generalData, BoardE
internalField.Append(new SpareBitsField<1>());
internalField.Append(new UnsignedField<8>(generalData.inactivityTimer));
- if (IS_STOCK(board) && version >= 215) {
+ if (IS_9X(board) && version >= 215) {
internalField.Append(new UnsignedField<3>(generalData.mavbaud));
}
else {
diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp
index 47ac1b8a8..392a062b4 100644
--- a/companion/src/firmwares/opentx/opentxinterface.cpp
+++ b/companion/src/firmwares/opentx/opentxinterface.cpp
@@ -690,6 +690,10 @@ int Open9xInterface::getCapability(const Capability capability)
case EnhancedCurves:
case TelemetryInternalAlarms:
return IS_TARANIS(board);
+ case HasFasOffset:
+ return (IS_STOCK(board) ? false : true);
+ case HasMahPersistent:
+ return (IS_ARM(board) ? true : false);
default:
return 0;
}
@@ -1050,6 +1054,7 @@ void RegisterOpen9xFirmwares()
open9x->addOption("novario", QObject::tr("No vario support"));
open9x->addOption("nogps", QObject::tr("No GPS support"));
open9x->addOption("nogauges", QObject::tr("No gauges in the custom telemetry screen"));
+ open9x->addOption("fasoffset", QObject::tr("Allow compensating for offset errors in FrSky FAS current sensors"));
open9x->addOptions(fai_options);
firmwares.push_back(open9x);
diff --git a/companion/src/modeledit/telemetry.cpp b/companion/src/modeledit/telemetry.cpp
index 5a429b8b1..fe6241015 100644
--- a/companion/src/modeledit/telemetry.cpp
+++ b/companion/src/modeledit/telemetry.cpp
@@ -375,7 +375,7 @@ void TelemetryPanel::setup()
else {
ui->AltitudeGPS_ChkB->setChecked(model.frsky.FrSkyGpsAlt);
}
-
+
if (IS_TARANIS(GetEepromInterface()->getBoard())) {
ui->AltitudeToolbar_ChkB->setChecked(model.frsky.altitudeDisplayed);
}
@@ -484,6 +484,32 @@ void TelemetryPanel::setup()
} else {
ui->frskyProtoCB->addItem(tr("Winged Shadow How High (not supported)"));
}
+
+ ui->variousGB->hide();
+ if (!(GetEepromInterface()->getCapability(HasFasOffset)) && !(firmware_id.contains("fasoffset"))) {
+ ui->fasOffset_label->hide();
+ ui->fasOffset_DSB->hide();
+ }
+ else {
+ ui->fasOffset_DSB->setValue(model.frsky.fasOffset/10.0);
+ ui->variousGB->show();
+ }
+
+ if (!(GetEepromInterface()->getCapability(HasMahPersistent))) {
+ ui->mahCount_label->hide();
+ ui->mahCount_SB->hide();
+ ui->mahCount_ChkB->hide();
+ }
+ else {
+ if (model.frsky.mAhPersistent) {
+ ui->mahCount_ChkB->setChecked(true);
+ ui->mahCount_SB->setValue(model.frsky.storedMah);
+ }
+ else {
+ ui->mahCount_SB->setDisabled(true);
+ }
+ ui->variousGB->show();
+ }
ui->frskyProtoCB->setCurrentIndex(model.frsky.usrProto);
ui->frskyUnitsCB->setCurrentIndex(model.frsky.imperial);
@@ -717,6 +743,25 @@ void TelemetryPanel::on_varioLimitCenterMax_DSB_editingFinished()
emit modified();
}
+void TelemetryPanel::on_fasOffset_DSB_editingFinished()
+{
+ model.frsky.fasOffset = ui->fasOffset_DSB->value()*10;
+ emit modified();
+}
+
+void TelemetryPanel::on_mahCount_SB_editingFinished()
+{
+ model.frsky.storedMah = ui->mahCount_SB->value();
+ emit modified();
+}
+
+void TelemetryPanel::on_mahCount_ChkB_toggled(bool checked)
+{
+ model.frsky.mAhPersistent = checked;
+ ui->mahCount_SB->setDisabled(!checked);
+ emit modified();
+}
+
void TelemetryPanel::telBarUpdate()
{
int index;
diff --git a/companion/src/modeledit/telemetry.h b/companion/src/modeledit/telemetry.h
index 6984a9f51..e8f634463 100644
--- a/companion/src/modeledit/telemetry.h
+++ b/companion/src/modeledit/telemetry.h
@@ -74,6 +74,9 @@ class TelemetryPanel : public ModelPanel
void on_varioLimitCenterMin_DSB_editingFinished();
void on_varioLimitMinOff_ChkB_toggled(bool checked);
void on_varioLimitCenterMax_DSB_editingFinished();
+ void on_fasOffset_DSB_editingFinished();
+ void on_mahCount_SB_editingFinished();
+ void on_mahCount_ChkB_toggled(bool checked);
void telBarCBcurrentIndexChanged(int index);
void ScreenTypeCBcurrentIndexChanged(int index);
void telMaxSBeditingFinished();
diff --git a/companion/src/modeledit/telemetry.ui b/companion/src/modeledit/telemetry.ui
index b03ab1091..bb6bae9c9 100644
--- a/companion/src/modeledit/telemetry.ui
+++ b/companion/src/modeledit/telemetry.ui
@@ -7,13 +7,13 @@
0
0
692
- 540
+ 568
Form
-
+
-
@@ -770,6 +770,106 @@
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Various
+
+
+
+ 1
+
+
+ 1
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ 32767
+
+
+
+ -
+
+
+ mAh count
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ FAS Offset
+
+
+
+ -
+
+
+ Persistent mAh
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 1
+
+
+ -1.500000000000000
+
+
+ 1.500000000000000
+
+
+ 0.100000000000000
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
-
-
diff --git a/radio/src/Makefile b/radio/src/Makefile
index 2c9ddc635..7765bcbdb 100644
--- a/radio/src/Makefile
+++ b/radio/src/Makefile
@@ -159,6 +159,10 @@ PPM_UNIT = PERCENT_PREC1
# Values = YES, NO
FRSKY_HUB = YES
+# FrSky FAS current sensor offset compensation
+# Values = YES, NO
+FAS_OFFSET = NO
+
# WS HowHigh
# Values = YES, NO
WS_HOW_HIGH = YES
@@ -332,6 +336,10 @@ ifeq ($(PCB), $(filter $(PCB), STD 9X 9XR))
ifeq ($(SP22), YES)
CPPDEFS += -DSP22
endif
+
+ ifeq ($(FAS_OFFSET), YES)
+ CPPDEFS += -DFAS_OFFSET
+ endif
endif
ifeq ($(PCB), $(filter $(PCB), STD128 9X128 9XR128))
diff --git a/radio/src/gui/menu_model.cpp b/radio/src/gui/menu_model.cpp
index 325dca789..dcab928a7 100644
--- a/radio/src/gui/menu_model.cpp
+++ b/radio/src/gui/menu_model.cpp
@@ -5167,6 +5167,9 @@ enum menuModelTelemetryItems {
#endif
ITEM_TELEMETRY_USR_VOLTAGE_SOURCE,
ITEM_TELEMETRY_USR_CURRENT_SOURCE,
+#if defined(FAS_OFFSET) || !defined(CPUM64)
+ ITEM_TELEMETRY_FAS_OFFSET,
+#endif
#if defined(CPUARM)
ITEM_TELEMTETRY_PERSISTENT_MAH,
#endif
@@ -5247,9 +5250,15 @@ enum menuModelTelemetryItems {
#define VARIO_RANGE_ROWS 3
#endif
+#if defined(FAS_OFFSET) || !defined(CPUM64)
+ #define IF_FAS_OFFSET(x) x,
+#else
+ #define IF_FAS_OFFSET(x)
+#endif
+
void menuModelTelemetry(uint8_t event)
{
- MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, ITEM_TELEMETRY_MAX+1, {0, CHANNEL_ROWS CHANNEL_ROWS RSSI_ROWS USRDATA_LINES 0, 0, IF_CPUARM(0) IF_VARIO(LABEL(Vario)) IF_VARIO(0) IF_VARIO(VARIO_RANGE_ROWS) CASE_PCBTARANIS(LABEL(TopBar)) CASE_PCBTARANIS(0) SCREEN_TYPE_ROWS, 2, 2, 2, 2, SCREEN_TYPE_ROWS, 2, 2, 2, 2, IF_CPUARM(SCREEN_TYPE_ROWS) IF_CPUARM(2) IF_CPUARM(2) IF_CPUARM(2) IF_CPUARM(2) });
+ MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, ITEM_TELEMETRY_MAX+1, {0, CHANNEL_ROWS CHANNEL_ROWS RSSI_ROWS USRDATA_LINES 0, 0, IF_FAS_OFFSET(0) IF_CPUARM(0) IF_VARIO(LABEL(Vario)) IF_VARIO(0) IF_VARIO(VARIO_RANGE_ROWS) CASE_PCBTARANIS(LABEL(TopBar)) CASE_PCBTARANIS(0) SCREEN_TYPE_ROWS, 2, 2, 2, 2, SCREEN_TYPE_ROWS, 2, 2, 2, 2, IF_CPUARM(SCREEN_TYPE_ROWS) IF_CPUARM(2) IF_CPUARM(2) IF_CPUARM(2) IF_CPUARM(2) });
uint8_t sub = m_posVert - 1;
@@ -5419,6 +5428,16 @@ void menuModelTelemetry(uint8_t event)
lcd_putsiAtt(TELEM_COL2, y, STR_VOLTSRC, g_model.frsky.currentSource, attr);
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.frsky.currentSource, 3);
break;
+
+#if defined(FAS_OFFSET) || !defined(CPUM64)
+ case ITEM_TELEMETRY_FAS_OFFSET:
+ lcd_putsLeft(y, STR_FAS_OFFSET);
+ lcd_outdezAtt(TELEM_COL2, y, g_model.frsky.fasOffset, attr|LEFT|PREC1);
+ lcd_outdezAtt(TELEM_COL2+6*FW, y, frskyData.hub.current, LEFT|PREC1);
+ lcd_putc(TELEM_COL2+8*FW, y, 'A');
+ if (attr) g_model.frsky.fasOffset = checkIncDec(event, g_model.frsky.fasOffset, -15, 15, EE_MODEL);
+ break;
+#endif
#if defined(CPUARM)
case ITEM_TELEMTETRY_PERSISTENT_MAH:
diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp
index f2e7f7905..8e2a4bda2 100644
--- a/radio/src/telemetry/frsky.cpp
+++ b/radio/src/telemetry/frsky.cpp
@@ -191,6 +191,12 @@ void parseTelemHubByte(uint8_t byte)
break;
case offsetof(FrskySerialData, current):
+#if defined(FAS_OFFSET) || !defined(CPUM64)
+ if(((int16_t)frskyData.hub.current + g_model.frsky.fasOffset)>0)
+ frskyData.hub.current += g_model.frsky.fasOffset;
+ else
+ frskyData.hub.current = 0;
+#endif
if (frskyData.hub.current > frskyData.hub.maxCurrent)
frskyData.hub.maxCurrent = frskyData.hub.current;
break;
diff --git a/radio/src/telemetry/frsky_sport.cpp b/radio/src/telemetry/frsky_sport.cpp
index 8499cb5f8..9b8055d13 100644
--- a/radio/src/telemetry/frsky_sport.cpp
+++ b/radio/src/telemetry/frsky_sport.cpp
@@ -200,6 +200,10 @@ void processHubPacket(uint8_t id, uint16_t value)
break;
case CURRENT_ID:
+ if(((int16_t)frskyData.hub.current + g_model.frsky.fasOffset)>0)
+ frskyData.hub.current += g_model.frsky.fasOffset;
+ else
+ frskyData.hub.current = 0;
if (frskyData.hub.current > frskyData.hub.maxCurrent)
frskyData.hub.maxCurrent = frskyData.hub.current;
break;
@@ -382,6 +386,10 @@ void processSportPacket(uint8_t *packet)
}
else if (appId >= CURR_FIRST_ID && appId <= CURR_LAST_ID) {
frskyData.hub.current = SPORT_DATA_U32(packet);
+ if(((int16_t)frskyData.hub.current + g_model.frsky.fasOffset)>0)
+ frskyData.hub.current += g_model.frsky.fasOffset;
+ else
+ frskyData.hub.current = 0;
if (frskyData.hub.current > frskyData.hub.maxCurrent)
frskyData.hub.maxCurrent = frskyData.hub.current;
}
diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp
index 98d62ab7b..1c5c07f2a 100644
--- a/radio/src/translations.cpp
+++ b/radio/src/translations.cpp
@@ -267,6 +267,10 @@ const pm_char STR_EEPROMOVERFLOW[] PROGMEM = TR_EEPROMOVERFLOW;
const pm_char STR_TRIMS2OFFSETS[] PROGMEM = TR_TRIMS2OFFSETS;
const pm_char STR_MENURADIOSETUP[] PROGMEM = TR_MENURADIOSETUP;
+#if defined(FAS_OFFSET) || !defined(CPUM64)
+const pm_char STR_FAS_OFFSET[] PROGMEM = TR_FAS_OFFSET;
+#endif
+
#if defined(CPUM2560) || defined(CPUARM)
const pm_char STR_MENUDATEANDTIME[] PROGMEM = TR_MENUDATEANDTIME;
#endif
diff --git a/radio/src/translations.h b/radio/src/translations.h
index 4a3e0600a..09f83bd54 100644
--- a/radio/src/translations.h
+++ b/radio/src/translations.h
@@ -448,6 +448,10 @@ extern const pm_char STR_INVERT_THR[];
extern const pm_char STR_AND_SWITCH[];
extern const pm_char STR_CF[];
+#if defined(FAS_OFFSET) || !defined(CPUM64)
+extern const pm_char STR_FAS_OFFSET[];
+#endif
+
#if defined(DSM2) || defined(PXX)
extern const pm_char STR_RXNUM[];
#endif
diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt
index 145783ff3..724434f84 100644
--- a/radio/src/translations/cz.h.txt
+++ b/radio/src/translations/cz.h.txt
@@ -660,6 +660,7 @@
#define TR_LOWALARM INDENT "Nízký Alarm"
#define TR_CRITICALALARM INDENT "Kritický Alarm"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#if defined(MAVLINK)
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"
diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt
index 8023eaf06..8edd60158 100644
--- a/radio/src/translations/de.h.txt
+++ b/radio/src/translations/de.h.txt
@@ -663,6 +663,7 @@
#define TR_LOWALARM INDENT "Low Alarm"
#define TR_CRITICALALARM INDENT "Kritisch Alarm"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#if defined(MAVLINK)
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"
diff --git a/radio/src/translations/en.h b/radio/src/translations/en.h
index 62876daf9..e87b5f7c6 100644
--- a/radio/src/translations/en.h
+++ b/radio/src/translations/en.h
@@ -667,6 +667,7 @@
#define TR_LOWALARM INDENT "Low Alarm"
#define TR_CRITICALALARM INDENT "Critical Alarm"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#if defined(MAVLINK)
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"
diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt
index 652776e6e..700e2643f 100644
--- a/radio/src/translations/fr.h.txt
+++ b/radio/src/translations/fr.h.txt
@@ -660,6 +660,7 @@
#define TR_LOWALARM INDENT "Alarme basse"
#define TR_CRITICALALARM INDENT "Alarme critique"
#define TR_PERSISTENT_MAH TR(INDENT "Enr. mAh",INDENT "Enregistrer mAh")
+#define TR_FAS_OFFSET TR(INDENT "Corr FAS", INDENT "Correction FAS")
#if defined(MAVLINK)
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"
diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt
index 3a2c62fca..8c1229ac7 100644
--- a/radio/src/translations/it.h.txt
+++ b/radio/src/translations/it.h.txt
@@ -660,6 +660,7 @@
#define TR_LOWALARM INDENT "Allarme Basso"
#define TR_CRITICALALARM INDENT "Allarme Critico"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#if defined(MAVLINK)
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"
diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt
index 5525754ed..8a2caf86c 100644
--- a/radio/src/translations/pl.h.txt
+++ b/radio/src/translations/pl.h.txt
@@ -661,6 +661,7 @@
#define TR_LOWALARM INDENT "Alarm niski"
#define TR_CRITICALALARM INDENT "Alarm krytyczny"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#if defined(MAVLINK)
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"
diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt
index 691c840af..022579f74 100644
--- a/radio/src/translations/pt.h.txt
+++ b/radio/src/translations/pt.h.txt
@@ -660,6 +660,7 @@
#define TR_LOWALARM INDENT "Low Alarm"
#define TR_CRITICALALARM INDENT "Critical Alarm"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#if defined(MAVLINK)
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"
diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt
index 68de29549..1aaf93273 100644
--- a/radio/src/translations/se.h.txt
+++ b/radio/src/translations/se.h.txt
@@ -663,6 +663,7 @@
#define TR_LOWALARM INDENT "Låg-alarm"
#define TR_CRITICALALARM INDENT "Kritiskt alarm"
#define TR_PERSISTENT_MAH INDENT "Store mAh"
+#define TR_FAS_OFFSET TR(INDENT "FAS Ofs", INDENT "FAS Offset")
#if defined(MAVLINK)
#define TR_MAVLINK_RC_RSSI_SCALE_LABEL "Max RSSI"