CAN Bus Input

Applies to: IOcan · Standalone controller. What this means

Overview

A CAN Bus Input decodes a single signal out of a raw incoming CAN frame, using a layout you enter by hand. Use it for a device that has no CAN preset and whose frame layout you know — from a DBC, a data sheet, or your own reverse engineering.

For a supported device, use a CAN Object Input instead and let the preset own the decoding.

⚠️ Firmware 2.1 changed what Enable interpolation does, and it affects configurations you already have. Before 2.1 the raw → out scaling was applied whether the box was ticked or not. From 2.1 it is honoured, and a configuration where it was never ticked reports the raw frame value instead of your scaled one. What to do.

One field still does not behave the way its name suggests — see the one field that does not mean what it says.

If the device with no preset is your engine ECU, my ECU isn't listed walks the same job end to end — which signals you have to map, and how to find them in the stream.

Prerequisites

  • A CAN bus defined on the channel the frame arrives on — see Working with the CAN bus.
  • The frame's message ID and the signal's position, width, signedness and endianness.

Add it in the app

  1. Add a new input and choose CAN Bus Input as the type.
  2. Give it a clear name (e.g. Engine RPM).
  3. Enter the message ID and ID type.
  4. Enter the decoding type, length and offset that locate the signal in the frame.
  5. Tick Enable interpolation and set the raw → out scaling. From 2.1 the scaling is not applied unless you do.
  6. Set a timeout — the default if you leave it at zero is 500 ms, which is too slow for anything the transmission depends on.

Settings reference

Setting Meaning Unit Range / values Notes
Message ID Frame identifier to match hex fixed32 The arbitration ID of the frame carrying the signal.
Message ID type Identifier width Extended (29-bit), Standard (11-bit) Must match how the sender addresses the frame.
Decoding type How the bits are interpreted UnsignedBigEndian, UnsignedLittleEndian, SignedBigEndian, SignedLittleEndian, BitField, BitFieldBigEndian, SignedBitField, SignedBitFieldBigEndian, FloatLittleEndian, FloatBigEndian All ten are implemented.
Length Signal width bytes / bits uint32 Bytes for the integer and float types, bits for the four bitfield types.
Offset Where the signal starts in the frame bytes / bits uint32 Same units as Length.
Enable interpolation Applies the raw → out scaling on / off Off means no scaling at all — the input reports the decoded frame value. Changed in 2.1; see below.
Raw min / Raw max Decoded range to scale from raw sint32 The raw low and high points. Interpolation only.
Out min / Out max Value range to scale to your unit sint32 Both left at zero gives 0…1024, not 0…0. Interpolation only.
Saturate Clamps the raw value into Raw min…Raw max on / off Off, a value past either end extrapolates beyond your Out range. Interpolation only.
Default value Reported before the first frame arrives raw sint32 Also the substitute in UseDefault. In raw units — see below.
Fault value The substitute in UseFault raw sint32 In raw units — see below.
Timeout Longest acceptable gap between frames ms uint32 Zero means 500 ms, not "no timeout".
Timeout mode What to report after a timeout UsePrevious, UseDefault, UseFault All three implemented from 2.1.
Fault min / Fault max Out-of-range window on the decoded value sint32 Labelled Allowed Range Min / Max in the configuration app and Fault Min / Max Value in the transmission-configuration editor. Both zero disables the check. Reversed values are swapped automatically.

Enable interpolation, and the 2.1 migration

Before firmware 2.1 the two-point scaling was applied unconditionally — the setting was read into an empty branch and had no effect. From 2.1 it does what it says: with it off, the input reports the decoded frame value and Raw min/max, Out min/max and Saturate are unused.

That is the behaviour you want when a Map Input is going to do the scaling, or when the frame already carries the value in the units you work in.

⚠️ Existing configurations need attention. The setting defaults to off and the transmission-configuration editor never wrote it, so a CAN input made before 2.1 is scaling today and will report the raw frame value once the device is flashed with 2.1. Tick Enable interpolation on every CAN bus input that has a raw → out scaling, and re-save the configuration.

The symptom if you miss one is a channel reading in raw frame units — often a large number where you expected a small one, occasionally the reverse. It does not fault. Check every CAN input in the datalogger after the update.

Timeouts

A frame that stops arriving does not raise anything on its own. What the input reports afterwards is decided entirely by the timeout mode:

Mode After the timeout elapses
UsePrevious Holds the last received value, indefinitely
UseDefault Substitutes Default value
UseFault Substitutes Fault value

All three are implemented from firmware 2.1; before that UseFault had no case in the firmware and left the mode undefined.

Three details that matter in practice:

  • UseFault does not raise a fault. The name is misleading: it substitutes a second, separate value and nothing else happens. Its usefulness is that you can distinguish "this signal dropped out" from "this signal is at its default" — give Default and Fault different values and the datalogger tells you which happened.
  • Default value and Fault value are in raw units, not your scaled ones. They are substituted on the decoded side, before the raw → out scaling, so they go through it exactly like a received frame value. With Raw 0…65535 mapped to Out 0…8191, a Fault value of 0 reports as 0, but a Fault value of 65535 reports as 8191.
  • The substitution happens once, when the timeout elapses, and the value returns to the frame contents on the first frame after the dropout. From 2.1 the datalogger shows the substituted value too — before that the log kept showing the last received value while the control path used the substitute, so the two disagreed exactly when you needed them to agree.

On anything the transmission depends on, use UseDefault or UseFault. UsePrevious holds a stale value forever and nothing indicates it is stale — see If an input drops out.

The one field that does not mean what it says

Timeout of zero means 500 ms, not "no timeout". There is no way to disable the timeout — only to make it long. Set it deliberately on anything the transmission depends on.

The fault window

Fault min and Fault max are checked against the decoded value and raise the same watchdog faults as an analog input — 0x0101 below the minimum, 0x0102 above the maximum. The same inhibit applies: the check does not run until ignition is on and the battery is above about 8 V, so it is invisible on a USB-only bench. See the fault window.

Identifying which CAN input raised one takes more work than for an analog input. These faults carry an input identifier that the configuration does not set for a CAN input, so it does not point back at the channel the way it does elsewhere. Narrow it down from the fault window you configured and the value the datalogger was showing when it tripped.

Common settings

CAN Bus Input uses the shared Name setting, and the Pin field selects which CAN channel to listen on rather than a physical pin. A correct frame definition pointed at the wrong channel reads nothing, and looks exactly like a wrong message ID. See Common IO settings.

Example — engine speed from a J1939-style frame

  1. Type CAN Bus Input, name Engine RPM.
  2. Message ID 0x0CF00400, ID type Extended (29-bit).
  3. Decoding type UnsignedLittleEndian, Length 2 bytes, Offset 3 bytes.
  4. Enable interpolation on, Raw min/max 0/65535Out min/max 0/8191, Saturate on.
  5. Timeout 100 ms, Timeout mode UseFault, Default value 0, Fault value 0.

Both substitutes are raw, and raw 0 scales to 0 rpm. A lost ECU now reports zero rather than holding the last live value — which is detectable, where a frozen reading is not.

To tell a dropout apart from a genuine zero, give Fault value a raw value that cannot occur — 65535 here, which scales to 8191 rpm — and watch for that number in the log. Do this only where a wildly wrong value is safe; on a torque-critical signal it is not, and 0 is the right answer.

Troubleshooting

  • Value is garbage: check the decoding type first — signedness and endianness. Then check that Length and Offset are in the right units: bytes for the integer and float types, bits for the bitfield types.
  • Reads zero and never updates: wrong message ID or ID type, or a bitrate mismatch on the bus. CAN bus diagnostics.
  • A channel that used to be scaled now reads in raw frame units: the 2.1 change to Enable interpolation. Tick it and re-save — see above.
  • Reads 0–1024 instead of your range: Out min and Out max were both left at zero, so Out max defaulted to 1024.
  • Value holds after the sender drops off: the timeout mode is UsePrevious. Use UseDefault or UseFault.
  • The substituted value is not what you entered: Default and Fault values are in raw units and go through the raw → out scaling. Work backwards from the value you want to see.
  • Timeout seems far too slow: the timeout was left at zero, which means 500 ms.