Decode S300 tail payload RPM
This commit is contained in:
parent
80167fd9e5
commit
ba578a0b69
@ -39,11 +39,14 @@ SensorState parseS300(Uint8List frame, {bool validateChecksum = true}) {
|
|||||||
throw ArgumentError('S300 frame NEG8 checksum failed');
|
throw ArgumentError('S300 frame NEG8 checksum failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
// RPM: bytes 2..3 uint16 BE, used directly.
|
// Some S300 Bluetooth frames carry live RPM in the tail payload at 82..83,
|
||||||
// The S300 live frame starts its sensor payload at byte 2; byte 0..1 are
|
// while the header bytes stay fixed at 1b 00 14 00 and decode to a bogus
|
||||||
// the protocol header. Reading from byte 3 shifts all high-rate values.
|
// 4864 rpm. Prefer the tail value when it looks like real engine speed.
|
||||||
final int rpmRaw = _readUint16BE(frame, 2);
|
final bool hasTailPayload = _hasS300TailPayload(frame);
|
||||||
final double rpm = (rpmRaw - 256).clamp(0, 12000).toDouble();
|
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.
|
// VSS: bytes 5..6 little-endian pulse period.
|
||||||
final int vssRaw = _readUint16LE(frame, 5);
|
final int vssRaw = _readUint16LE(frame, 5);
|
||||||
@ -180,3 +183,9 @@ int _readUint16BE(Uint8List frame, int offset) {
|
|||||||
int _readUint16LE(Uint8List frame, int offset) {
|
int _readUint16LE(Uint8List frame, int offset) {
|
||||||
return frame[offset] | (frame[offset + 1] << 8);
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -189,5 +189,37 @@ void main() {
|
|||||||
|
|
||||||
expect(isS300PlaceholderFrame(frame), isTrue);
|
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));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user