Skip to content

Instantly share code, notes, and snippets.

@hovsep
Created January 9, 2026 16:06
Show Gist options
  • Select an option

  • Save hovsep/68412cf7834d8b47c4f3ecf6faa6834a to your computer and use it in GitHub Desktop.

Select an option

Save hovsep/68412cf7834d8b47c4f3ecf6faa6834a to your computer and use it in GitHub Desktop.
ISO-tp frames
func main() {
fm := getMesh()
// Initialize the mesh: set diagnostic frames to USB port, so the laptop will send them
laptopInstance.SendDataToUSB(
diagnostics.FrameGetEngineDTCs,
diagnostics.FrameGetSpeed,
diagnostics.FrameGetRPM,
diagnostics.FrameGetCoolantTemperature,
diagnostics.FrameGetCalibrationID,
diagnostics.FrameGetVIN,
diagnostics.FrameGetTransmissionFluidTemperature,
)
runResult, err := fm.Run()
if err != nil {
fmt.Println("The mesh finished with error: ", err)
os.Exit(1)
}
fmt.Printf("Mesh stopped after %d cycles and %s", runResult.Cycles.Len(), runResult.Duration)
}
// FrameGetRPM is an ISO-TP Single Frame encoded inside one CAN frame.
// It requests the current Engine RPM via OBD-II (Mode 01, PID 0x0C).
FrameGetRPM = &codec.Frame{
// 0x7DF is the functional OBD-II request ID.
// "Functional" means all ECUs that support this service may respond.
Id: 0x7DF,
// DLC = 8 because classic CAN always sends 8 data bytes.
// Even if the payload is shorter, the frame must be padded.
DLC: 8,
Data: [8]byte{
// ISO-TP Protocol Control Information (PCI)
// High nibble: frame type (0 = Single Frame)
// Low nibble: payload length in bytes
// 0x02 means: Single Frame, 2 bytes of actual data follow
0x02,
// OBD-II Service ID (Mode)
// 0x01 = "Show Current Data"
0x01,
// OBD-II Parameter ID (PID)
// 0x0C = Engine RPM
0x0C,
// Padding bytes.
// ISO-TP requires unused bytes in a CAN frame to be padded.
// They have no meaning but must be present to fill all 8 bytes.
0x00, 0x00, 0x00, 0x00, 0x00,
},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment