Skip to content

Commit c14adf9

Browse files
frankiearzupfeerick
authored andcommitted
fix(telemetry): process DSM LIPO Cells Monitor sensor correctly (#4720)
1 parent 72a71c8 commit c14adf9

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

radio/src/telemetry/spektrum.cpp

+38-14
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#define I2C_PSEUDO_TX_RSSI (I2C_PSEUDO_TX << 8 | 0)
5050
#define I2C_PSEUDO_TX_BIND (I2C_PSEUDO_TX << 8 | 4)
5151
#define I2C_PSEUDO_TX_FM (I2C_PSEUDO_TX << 8 | 8)
52+
#define I2C_PSEUDO_TX_CELLS (I2C_PSEUDO_TX << 8 | 10)
5253

5354
#define SPEKTRUM_TELEMETRY_LENGTH 18
5455
#define DSM_BIND_PACKET_LENGTH 12
@@ -142,6 +143,7 @@ struct SpektrumSensor {
142143

143144
#define SS(i2caddress,startByte,dataType,name,unit,precision) {i2caddress,startByte,dataType,precision,unit,name}
144145

146+
// IMPORTANT: Keep the sensor table incremtally sorted by i2caddress
145147
const SpektrumSensor spektrumSensors[] = {
146148
// 0x01 High voltage internal sensor
147149
SS(I2C_VOLTAGE, 0, int16, STR_SENSOR_A1, UNIT_VOLTS, 2), // 0.01V increments
@@ -268,13 +270,13 @@ const SpektrumSensor spektrumSensors[] = {
268270
//SS(0x38, 0, uint16, STR_SENSOR_PRESSSURE, UNIT_PSI, 1),
269271

270272
// 0x3A Lipo 6s Monitor Cells
271-
SS(I2C_CELLS, 0, uint16, STR_SENSOR_CELLS, UNIT_VOLTS, 2), // Voltage across cell 1, .01V steps
272-
SS(I2C_CELLS, 2, uint16, STR_SENSOR_CELLS, UNIT_VOLTS, 2),
273-
SS(I2C_CELLS, 4, uint16, STR_SENSOR_CELLS, UNIT_VOLTS, 2),
274-
SS(I2C_CELLS, 6, uint16, STR_SENSOR_CELLS, UNIT_VOLTS, 2),
275-
SS(I2C_CELLS, 8, uint16, STR_SENSOR_CELLS, UNIT_VOLTS, 2),
276-
SS(I2C_CELLS, 10, uint16, STR_SENSOR_CELLS, UNIT_VOLTS, 2),
277-
SS(I2C_CELLS, 12, uint16, STR_SENSOR_TEMP2, UNIT_CELSIUS, 2), // Temperature, 0.1C (0-655.34C)
273+
SS(I2C_CELLS, 0, uint16, STR_SENSOR_CL01, UNIT_VOLTS, 2), // Voltage across cell 1, .01V steps
274+
SS(I2C_CELLS, 2, uint16, STR_SENSOR_CL02, UNIT_VOLTS, 2),
275+
SS(I2C_CELLS, 4, uint16, STR_SENSOR_CL03, UNIT_VOLTS, 2),
276+
SS(I2C_CELLS, 6, uint16, STR_SENSOR_CL04, UNIT_VOLTS, 2),
277+
SS(I2C_CELLS, 8, uint16, STR_SENSOR_CL05, UNIT_VOLTS, 2),
278+
SS(I2C_CELLS, 10, uint16, STR_SENSOR_CL06, UNIT_VOLTS, 2),
279+
SS(I2C_CELLS, 12, uint16, STR_SENSOR_TEMP2, UNIT_CELSIUS, 1), // Temperature, 0.1C (0-655.34C)
278280

279281
// 0x40 Vario-S
280282
SS(I2C_VARIO, 0, int16, STR_SENSOR_ALT, UNIT_METERS, 1),
@@ -350,6 +352,7 @@ const SpektrumSensor spektrumSensors[] = {
350352
SS(I2C_PSEUDO_TX, 0, uint8, STR_SENSOR_TX_RSSI, UNIT_RAW, 0),
351353
SS(I2C_PSEUDO_TX, 4, uint32, STR_SENSOR_BIND, UNIT_RAW, 0),
352354
SS(I2C_PSEUDO_TX, 8, uint32, STR_SENSOR_FLIGHT_MODE, UNIT_TEXT, 0),
355+
SS(I2C_PSEUDO_TX, 10, uint32, STR_SENSOR_CELLS, UNIT_CELLS, 2),
353356
SS(0, 0, int16, NULL, UNIT_RAW, 0) //sentinel
354357
};
355358

@@ -625,11 +628,13 @@ void processSpektrumPacket(const uint8_t *packet)
625628

626629
bool handled = false;
627630
for (const SpektrumSensor * sensor = spektrumSensors; sensor->i2caddress; sensor++) {
628-
uint16_t pseudoId = (sensor->i2caddress << 8 | sensor->startByte);
629-
630-
if (i2cAddress != sensor->i2caddress) // Not the sensor for current packet
631+
// Optimization... the sensor table is sorted incrementally by i2cAddress
632+
if (sensor->i2caddress < i2cAddress) // haven't reach the sesnor def. keep going
631633
continue;
632-
634+
if (sensor->i2caddress > i2cAddress) // We past it, done
635+
break;
636+
637+
uint16_t pseudoId = (sensor->i2caddress << 8 | sensor->startByte);
633638
handled = true;
634639

635640
// Extract value, skip header
@@ -666,9 +671,14 @@ void processSpektrumPacket(const uint8_t *packet)
666671
} // I2C_ESC
667672

668673
else if (i2cAddress == I2C_CELLS && sensor->unit == UNIT_VOLTS) {
669-
// Map to FrSky style cell values
674+
if (value == 0x7FFF) continue; // ignore NO-DATA
675+
676+
// Map to FrSky style cell values (All Cells in a single Sensor)
670677
int cellIndex = (sensor->startByte / 2) << 16;
671-
value = value | cellIndex;
678+
uint32_t valueCells = cellIndex | value;
679+
setTelemetryValue(PROTOCOL_TELEMETRY_SPEKTRUM, I2C_PSEUDO_TX_CELLS, 0, instance, valueCells, UNIT_CELLS, 2);
680+
681+
// Continue to process regular Single Cell value
672682
} // I2C_CELLS
673683

674684
else if (sensor->i2caddress == I2C_HIGH_CURRENT && sensor->unit == UNIT_AMPS) {
@@ -1081,6 +1091,7 @@ static int testStep = 0;
10811091
static bool real0x16 = false;
10821092
static bool real0x17 = false;
10831093
static bool real0x34 = false;
1094+
static bool real0x3A = false;
10841095

10851096
// *********** GPS LOC (BCD) ******************************
10861097
// Example 0x16: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
@@ -1106,6 +1117,15 @@ static char test17data[] = {0x17, 0x00, 0x25, 0x00, 0x00,
11061117
static char test34data[] = {0x34, 0x00, 0x2F, 0x00, 0x30, 0x09, 0x85, 0x01,
11071118
0x2B, 0x00, 0x07, 0x0A, 0x81, 0x01 };
11081119

1120+
// *********** Lipo monitor (Big-Endian)***************
1121+
// Example 0x3A: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
1122+
// 3A 00 | 01 9A | 01 9B | 01 9C | 01 9D | 7F FF | 7F FF | 0F AC
1123+
// 4.10V 4.11V 4.12V 4.12v -- -- 40.1C
1124+
static char test3Adata[] = {0x3A, 0x00, 0x01, 0x9A, 0x01, 0x9B, 0x01, 0x9C,
1125+
0x01, 0x9D, 0x7F, 0xFF, 0x7F, 0xFF,
1126+
0x01, 0x91 };
1127+
1128+
11091129
static uint8_t replaceForTestingPackage(const uint8_t *packet)
11101130
{
11111131
uint8_t i2cAddress = packet[2] & 0x7f;
@@ -1114,6 +1134,7 @@ static uint8_t replaceForTestingPackage(const uint8_t *packet)
11141134
if (i2cAddress == I2C_GPS_LOC) real0x16 = true;
11151135
else if (i2cAddress == I2C_GPS_STAT) real0x17 = true;
11161136
else if (i2cAddress == I2C_FP_BATT) real0x34 = true;
1137+
else if (i2cAddress == I2C_CELLS) real0x3A = true;
11171138

11181139
// Only Substiture AS3X/SAFE I2C_FLITECTRL packages, since they are constantly brodcast
11191140
if (i2cAddress != I2C_FLITECTRL) {
@@ -1137,9 +1158,12 @@ static uint8_t replaceForTestingPackage(const uint8_t *packet)
11371158
case 3: // Return Dual Bat monitor
11381159
if (!real0x34) memcpy((char *)packet + 2, test34data, 14);
11391160
break;
1161+
case 4: // Return LIPO monitor
1162+
if (!real0x3A) memcpy((char *)packet + 2, test3Adata, 16);
1163+
break;
11401164
}
11411165

1142-
testStep = (testStep + 1) % 4;
1166+
testStep = (testStep + 1) % 5;
11431167

11441168

11451169
return packet[2] & 0x7f;

0 commit comments

Comments
 (0)