Decode S300 tail payload RPM

This commit is contained in:
HVBT Dev 2026-07-28 01:31:10 +05:30
parent 80167fd9e5
commit ba578a0b69
2 changed files with 46 additions and 5 deletions

View File

@ -39,11 +39,14 @@ SensorState parseS300(Uint8List frame, {bool validateChecksum = true}) {
throw ArgumentError('S300 frame NEG8 checksum failed');
}
// RPM: bytes 2..3 uint16 BE, used directly.
// The S300 live frame starts its sensor payload at byte 2; byte 0..1 are
// the protocol header. Reading from byte 3 shifts all high-rate values.
final int rpmRaw = _readUint16BE(frame, 2);
final double rpm = (rpmRaw - 256).clamp(0, 12000).toDouble();
// Some S300 Bluetooth frames carry live RPM in the tail payload at 82..83,
// while the header bytes stay fixed at 1b 00 14 00 and decode to a bogus
// 4864 rpm. Prefer the tail value when it looks like real engine speed.
final bool hasTailPayload = _hasS300TailPayload(frame);
final int rpmRaw =
hasTailPayload ? _readUint16LE(frame, 82) : _readUint16BE(frame, 2);
final double rpm =
(hasTailPayload ? rpmRaw : rpmRaw - 256).clamp(0, 12000).toDouble();
// VSS: bytes 5..6 little-endian pulse period.
final int vssRaw = _readUint16LE(frame, 5);
@ -180,3 +183,9 @@ int _readUint16BE(Uint8List frame, int offset) {
int _readUint16LE(Uint8List frame, int offset) {
return frame[offset] | (frame[offset + 1] << 8);
}
bool _hasS300TailPayload(Uint8List frame) {
if (!isS300PlaceholderFrame(frame)) return false;
final rpm = _readUint16LE(frame, 82);
return rpm > 300 && rpm < 12000;
}

View File

@ -189,5 +189,37 @@ void main() {
expect(isS300PlaceholderFrame(frame), isTrue);
});
test('uses tail payload RPM for S300 Bluetooth prefix frames', () {
final frame = Uint8List(128);
final prefix = [
0x1B,
0x00,
0x14,
0x00,
0x00,
0xFF,
0xFF,
0xF2,
0x03,
0x18,
0x00,
0x00,
0x10,
0x00,
0x00,
0x00,
0xC4,
];
for (var i = 0; i < prefix.length; i++) {
frame[i] = prefix[i];
}
frame[82] = 0x32;
frame[83] = 0x0C;
frame[127] = calculateNeg8(frame.sublist(0, 127));
final state = parseS300(frame);
expect(state.rpm, equals(3122.0));
});
});
}