Project

General

Profile

CAN Bus Output » History » Version 1

Adam Klama, 06/21/2026 03:29 PM

1 1 Adam Klama
# CAN Bus Output
2
3
## Overview
4
A **CAN Bus Output** packs a single **CANbus signal** into a raw outgoing CAN
5
frame, using a byte/bit layout you define by hand. Use it when you know the frame
6
layout (e.g. from a DBC) for an arbitrary or custom device and there is no
7
[CAN Preset](Working_with_the_CAN_Bus#can-presets) for it.
8
9
This is the **raw frame signal** approach: you give the message ID, say how the
10
bits are encoded and where they sit, then scale your source value into the raw
11
signal. To write a named object on a supported device instead, use a
12
[CAN Object Output](CAN_Object_Output).
13
14
## Prerequisites & hardware
15
- A **defined CAN bus** for the channel the frame is sent on — see
16
  [Working with the CAN Bus](Working_with_the_CAN_Bus).
17
- The frame's **message ID** and **bit layout** for the signal you want to write
18
  (length, offset, encoding).
19
- A source value (a map, driver or input) to drive the signal.
20
21
## Add it in the app
22
1. Add a new output and choose **CAN Bus Output** as the type.
23
2. Give it a clear **alias** (e.g. `Requested Torque`).
24
3. Enter the **Message ID** and its **ID type**, then the **encoding type**,
25
   **length** and **offset** that place the signal in the frame.
26
4. Set the **in → raw** scaling and a **default value**, then drive it from a
27
   map/driver.
28
29
## Settings reference
30
> Schema: `config/CanbusOutputConfiguration.proto`.
31
32
| Setting | Meaning | Unit | Range / values | Notes |
33
|---|---|---|---|---|
34
| **Message ID** | CAN frame identifier to send | hex | fixed32 | The arbitration ID of the outgoing frame. |
35
| **Message ID type** | Identifier width | — | `Extended (29-bit)`, `Standard (11-bit)` | Must match what the receiving device expects. |
36
| **Encoding type** | How the value is packed into the bits | — | `UnsignedBigEndian`, `UnsignedLittleEndian`, `SignedBigEndian`, `SignedLittleEndian`, `BitField`, `CounterField`, `BitCounterField` | Selects signedness/endianness/bitfield. `CounterField` / `BitCounterField` auto-generate a rolling message counter. |
37
| **Length** | Signal length | bytes / bits | uint32 | In **bytes** for the integer types and `CounterField`; in **bits** for the bitfield types (`BitField`, `BitCounterField`). |
38
| **Offset** | Position of the signal in the frame | bytes / bits | uint32 | Same units as Length: **bytes** for integer/`CounterField` types, **bits** for bitfield types. |
39
| **In min / In max** | Input (engineering) range to scale **from** | source unit | sint32 | The source low/high points. |
40
| **Raw min / Raw max** | Raw signal range to scale **to** | — | sint32 | The packed value at In min / In max. |
41
| **Default value** | Value packed before a source value is available | source unit | sint32 | Sent until the source provides a value. |
42
43
**Scaling:** the source value is mapped from `In min…In max` to `Raw min…Raw max`
44
using [two-point interpolation](Scaling_and_Maps#two-point-interpolation).
45
46
**Rolling counter:** choose `CounterField` or `BitCounterField` for keep-alive /
47
rolling-counter bytes — the controller increments the value each frame for you, so
48
no source is needed.
49
50
## Common settings
51
CAN Bus Output also uses the shared settings — alias and pin. See [Common IO Settings](Common_IO_Settings).
52
53
## Example — requested torque to an inverter
54
1. Type **CAN Bus Output**, alias `Requested Torque`.
55
2. **Message ID** `0x100`, **ID type** `Standard (11-bit)`.
56
3. **Encoding type** `UnsignedLittleEndian`, **Length** `2` (bytes), **Offset** `1`
57
   (starts at byte 1) — a 16-bit value. (A bitfield type would use bits here.)
58
4. **In min/max** `0`/`500` (Nm) → **Raw min/max** `0`/`5000` (0.1 Nm/bit).
59
5. **Default value** `0` so no torque is requested until the strategy drives it.
60
6. Add a second output on the same ID with **Encoding type** `CounterField` for the
61
   inverter's rolling-counter byte.
62
63
## Troubleshooting
64
- **Receiver ignores the frame:** check the **Message ID** and **ID type**, and the
65
  CAN bus baud rate.
66
- **Value lands wrong / sign flipped:** check the **encoding type**, **Length** and
67
  **Offset** — they are in **bytes** for integer/`CounterField` types and **bits**
68
  for bitfield types.
69
- **Receiver reports a counter/checksum fault:** add a `CounterField` /
70
  `BitCounterField` output for the rolling-counter byte.
71
- **Sends an unexpected value at start-up:** set a sensible **Default value**.
72
73
## Related
74
- [CAN Object Output](CAN_Object_Output) — write a named object to a CAN Preset
75
  instead of packing bytes by hand.
76
- [CAN Bus Input](CAN_Bus_Input) — decode a signal from an incoming
77
  frame.
78
- [Working with the CAN Bus](Working_with_the_CAN_Bus)