Skip to content

3. Data handling

Nathan zhou edited this page Nov 10, 2025 · 5 revisions

CAN 2.0 have maximum payload size of eight bytes. It is necessary to plan ahead for your variable placement. Each variable you send over CAN must be carefully packed into the limited data space, especially when sending multiple values in one frame.

For example:

  • A uint8_t (unsigned 8-bit integer) takes 1 byte.
  • A uint16_t (unsigned 16-bit integer) takes 2 bytes.
  • A uint32_t (unsigned 32-bit integer or float) takes 4 bytes.
  • A float (IEEE 754 single precision) also takes 4 bytes.
  • A bool or bit-flag can take 1 bit, but typically occupies 1 byte unless bit-packed manually.
  • An ASCII character takes 1 byte, and since each CAN message can carry up to 8 bytes of data, a single CAN frame can hold 8 ASCII characters at most.

When composing a CAN message, your total data must not exceed 8 bytes. If you attempt to send, for instance, two floats (2 × 4 bytes = 8 bytes), you’ve already reached the limit. Adding even one more uint8_t would overflow the frame. If more data space is needed, it is necessary to do another CAN message on a different API ID.

Begin with a basic schematic

Screenshot 2025-07-11 at 15 55 24

This is probably the most basic schematic of any CAN device you are designing.

In the setup shown above, the Sensor communicates with a Microcontroller Unit (MCU), which acts as a translator and relay between the sensor and the roboRIO over the CAN bus. The MCU collects data from the sensor (such as distance, color, or motion), packages it into a compact CAN message, and transmits it to the roboRIO. Communication isn’t just one-way. The roboRIO can also send commands or settings to the sensor via the MCU. This allows the robot code to configure or control the sensor during runtime.

Example: ToF CAN

ESP32 → roboRIO

Per-sensor API IDs:

  • Sensor 0: 0x0301
  • Sensor 1: 0x0302
  • Sensor 2: 0x0303
  • Sensor 3: 0x0304

Data Payload for each sensor, note that we actually send back current setting of the sensor to roboRIO:

Byte Field Type Description
0-1 Distance (mm) uint16_t Raw distance measurement (0–8191 mm)
2 Ranging mode uint8_t 0 = Short, 1 = Medium, 2 = Long
3 ROI center uint8_t Region of interest center (0–255)
4 ROI size X uint8_t ROI width (4–16, even)
5 ROI size Y uint8_t ROI height (4–16, even)
6-7 Timing budget (µs / 1e3) uint16_t Measurement timing budget (up to ~65ms)

roboRIO → ESP32

Per-sensor API IDs:

  • Sensor 0: 0x0305
  • Sensor 1: 0x0306
  • Sensor 2: 0x0307
  • Sensor 3: 0x0308
Byte Field Type Description
0 Ranging mode uint8_t 0 = Short, 1 = Medium, 2 = Long
1 ROI center uint8_t Center of ROI (0–255)
2 ROI size X uint8_t ROI width (4–16, must be even)
3 ROI size Y uint8_t ROI height (4–16, must be even)

Clone this wiki locally