J1939Spn Class¶
Static helpers for extracting SAE J1939-71 SPN (Suspect Parameter Number) values from a PGN payload using configurable scale/offset (SRS FR-J1939-002).
Inheritance Object → J1939Spn
Remarks¶
SAE J1939-71 encodes each SPN as an integer field of 1..64 bits — unsigned, or two's
complement for a signed SLOT — at a fixed byte (and bit) offset inside its PGN payload, with
a linear transform to physical units: physical = raw * resolution + offset.
Not every bit pattern is a measurement. §5.1.1 reserves the top of each SPN's raw range for
indicators — "not available", "error", reserved and parameter-specific codes — so
Extract(ReadOnlySpan<byte>, int, int, int, double, double, bool) returns a
J1939SpnValue that reports which of the two it found, rather than a bare
Double that would turn a 16-bit 0xFFFF ("not available") into a
plausible-looking 8191.875 rpm. Classify(ulong, int, bool) exposes the range check on its own.
Byte order is little-endian, matching SAE J1939-71 §5.1.3. Bit fields that start at an offset within a byte are read across byte boundaries with the low bits coming from the low-indexed byte, in line with the standard.
Methods¶
J1939Spn.Classify(ulong, int, bool) Method¶
Classifies a raw SPN field against the SAE J1939-71 §5.1.1 indicator ranges, which occupy the top of every SPN's raw range and must not be scaled into physical values.
public static CanKit.Pro.J1939.J1939SpnValueKind Classify(ulong raw, int bitLength, bool isSigned=false);
Parameters¶
raw UInt64
The field's raw bits, right-aligned and zero-extended (as returned by ExtractRaw(ReadOnlySpan<byte>, int, int, int)) — for a signed SPN the two's-complement pattern, not the sign-extended number.
bitLength Int32
Field size in bits (1..64).
isSigned Boolean
Whether the SPN is a two's-complement signed parameter.
Returns¶
Exceptions¶
ArgumentOutOfRangeException
bitLength is outside
1..64.
Remarks¶
J1939-71 defines the ranges on the field's leading byte for parameters of one byte
or wider — unsigned 0xFB parameter-specific, 0xFC..0xFD reserved,
0xFE error, 0xFF not available — so a two-byte SPN is "not available" over
0xFF00..0xFFFF and a four-byte one over 0xFF000000..0xFFFFFFFF.
For a signed parameter the same codes sit at the top of the signed range, i.e. with the
sign bit clear: 0x7B, 0x7C..0x7D, 0x7E, 0x7F.
Sub-byte parameters use the same code pattern scaled to the field: the leading nibble for
4..7 bits (0xB, 0xC..0xD, 0xE, 0xF) and the leading two
bits for 2..3 bits (0b10 error, 0b11 not available), matching the 4-bit and
2-bit tables in §5.1.1. Widths the standard does not tabulate (3, 5..7, and anything that
is not 8/16/32 above a byte) are handled by that same leading-group rule. A 1-bit field
has no room for an indicator and is always Valid, as is a
signed field narrower than a byte — J1939-71 defines no indicator codes there, and
inventing some would report real measurements as missing.
Because the leading group is a fixed size per width class, the indicator fraction of the range is whatever the tabulated width of that class already spends: about 2% for a byte or wider, five sixteenths for 4..7 bits, and one half for 2..3 bits. That last one is the widest reading here — a 3-bit field classifies raw 4..7 as indicators, so a parameter genuinely carrying eight states would see half of them reported as "no reading". Scaling by value instead of by leading group would cost such a field two states rather than four; J1939-71 tabulates neither, and the choice is open as issue #99. Every width above, inferred ones included, is pinned by known-answer tests so it cannot drift silently.
J1939Spn.Extract(ReadOnlySpan<byte>, int, int, double, double, bool) Method¶
Extracts an SPN and applies the linear transform
physical = raw * +
(SRS FR-J1939-002, SAE J1939-71 §5.1.3).
public static CanKit.Pro.J1939.J1939SpnValue Extract(System.ReadOnlySpan<byte> payload, int byteOffset, int bitLength, double resolution, double offset, bool isSigned=false);
Parameters¶
payload ReadOnlySpan<Byte>
The PGN payload bytes.
byteOffset Int32
Zero-based byte position of the first bit.
bitLength Int32
Number of bits (1..64).
resolution Double
Physical units per raw increment.
offset Double
Physical value at raw 0.
isSigned Boolean
Whether the SPN is a two's-complement signed parameter.
Returns¶
J1939SpnValue
A J1939SpnValue that is either a measurement or one of the J1939-71 §5.1.1
indicators. It is <b>not</b> a Double: a field reading 0xFFFF is
"not available", and reporting it as 8191.875 rpm was the defect this return type exists
to prevent.
Exceptions¶
ArgumentOutOfRangeException
Any argument is out of range or the
requested field extends past payload.
J1939Spn.Extract(ReadOnlySpan<byte>, int, int, int, double, double, bool) Method¶
Extracts an SPN and applies the linear transform
physical = raw * +
(SRS FR-J1939-002, SAE J1939-71 §5.1.3).
public static CanKit.Pro.J1939.J1939SpnValue Extract(System.ReadOnlySpan<byte> payload, int byteOffset, int startBit, int bitLength, double resolution, double offset, bool isSigned=false);
Parameters¶
payload ReadOnlySpan<Byte>
The PGN payload bytes.
byteOffset Int32
Zero-based byte position of the first bit.
startBit Int32
Zero-based bit index within byteOffset byte (0..7). 0 = least-significant bit of the byte, as in SAE J1939-71 §5.1.3.
bitLength Int32
Number of bits (1..64).
resolution Double
Physical units per raw increment.
offset Double
Physical value at raw 0.
isSigned Boolean
Whether the SPN is a two's-complement signed parameter.
Returns¶
J1939SpnValue
A J1939SpnValue that is either a measurement or one of the J1939-71 §5.1.1
indicators. It is <b>not</b> a Double: a field reading 0xFFFF is
"not available", and reporting it as 8191.875 rpm was the defect this return type exists
to prevent.
Exceptions¶
ArgumentOutOfRangeException
Any argument is out of range or the
requested field extends past payload.
J1939Spn.ExtractRaw(ReadOnlySpan<byte>, int, int, int) Method¶
Extracts an unsigned SPN raw value from payload at byteOffset starting at bit startBit (0..7) and spanning bitLength bits (1..64), little-endian.
public static ulong ExtractRaw(System.ReadOnlySpan<byte> payload, int byteOffset, int startBit, int bitLength);
Parameters¶
payload ReadOnlySpan<Byte>
The PGN payload bytes.
byteOffset Int32
Zero-based byte position of the first bit.
startBit Int32
Zero-based bit index within byteOffset byte (0..7). 0 = least-significant bit of the byte, as in SAE J1939-71 §5.1.3.
bitLength Int32
Number of bits (1..64).
Returns¶
Exceptions¶
ArgumentOutOfRangeException
Any argument is out of range or the
requested field extends past payload.
J1939Spn.ExtractRawSigned(ReadOnlySpan<byte>, int, int, int) Method¶
Extracts an unsigned SPN raw value from payload at byteOffset starting at bit startBit (0..7) and spanning bitLength bits (1..64), little-endian.
public static long ExtractRawSigned(System.ReadOnlySpan<byte> payload, int byteOffset, int startBit, int bitLength);
Parameters¶
payload ReadOnlySpan<Byte>
The PGN payload bytes.
byteOffset Int32
Zero-based byte position of the first bit.
startBit Int32
Zero-based bit index within byteOffset byte (0..7). 0 = least-significant bit of the byte, as in SAE J1939-71 §5.1.3.
bitLength Int32
Number of bits (1..64).
Returns¶
Exceptions¶
ArgumentOutOfRangeException
Any argument is out of range or the
requested field extends past payload.
J1939Spn.FromRaw(ulong, int, double, double, bool) Method¶
Applies the SAE J1939-71 §5.1.1 range check and, for a measurement, the linear transform
physical = raw * +
to an already-extracted raw field.
public static CanKit.Pro.J1939.J1939SpnValue FromRaw(ulong raw, int bitLength, double resolution, double offset, bool isSigned=false);
Parameters¶
raw UInt64
The field's raw bits, right-aligned and zero-extended.
bitLength Int32
Field size in bits (1..64).
resolution Double
Physical units per raw increment.
offset Double
Physical value at raw 0.
isSigned Boolean
Whether the SPN is a two's-complement signed parameter; when true the raw bits are sign-extended before scaling.
Returns¶
J1939Spn.WriteRaw(Span<byte>, int, int, int, ulong) Method¶
Encodes an SPN raw value back into a payload buffer, little-endian. Useful for tests and for round-tripping simulated PGN payloads.
public static void WriteRaw(System.Span<byte> payload, int byteOffset, int startBit, int bitLength, ulong rawValue);
Parameters¶
byteOffset Int32
startBit Int32
bitLength Int32
rawValue UInt64
Exceptions¶
ArgumentOutOfRangeException
The requested field extends past
payload.