Protocol

Creating Protocols

Step-by-step guide to creating CAN Bus protocol definitions.

What is a Protocol?

A protocol definition describes the CAN Bus messages and signals broadcast by an ECU. This allows tools to decode real-time CAN data into human-readable values like RPM, temperatures, and pressures.

Protocols Include:

  • CAN message IDs and lengths
  • Signal bit positions and sizes
  • Scaling factors and offsets
  • Units and value ranges

Use Cases:

  • Real-time CAN data logging
  • Digital dashboards
  • Data acquisition systems
  • CANalyzer / PCAN-View integration

Before You Start

  • Get official documentation - Find the vendor's CAN protocol specification document if available.
  • Test with real hardware - Verify signals using a CAN interface and the actual ECU.
  • Check existing protocols - Ensure a protocol doesn't already exist for your ECU.
  • Understand CAN basics - Familiarity with message IDs, byte order, and bit packing helps.

Step-by-Step Guide

1

Fork and Clone

bash
git clone https://github.com/YOUR-USERNAME/OpenECUAlliance.git
cd OpenECUAlliance
2

Create Vendor Directory

bash
mkdir -p specs/protocols/vendorname

Use lowercase vendor names: haltech, link, motec, aem, etc.

All protocol files go in specs/protocols/[vendor]/ within this repository.

3

Create Protocol File

bash
touch specs/protocols/vendorname/vendorname-protocol.protocol.yaml

Naming convention: {vendor}-{protocol}.protocol.yaml

Examples: haltech-elite-broadcast.protocol.yaml, link-g4x-broadcast.protocol.yaml
4

Write the Protocol

yaml
openecualliance: "1.0"
type: protocol
id: vendorname-broadcast
name: "VendorName CAN Broadcast Protocol"
version: "1.0.0"
vendor: vendorname
description: |
  CAN broadcast protocol for VendorName ECU series.
  Supports Model A, Model B, and Model C.
website: "https://vendor-website.com/can-protocol"

protocol:
  type: can           # can | canfd | lin | k-line
  baudrate: 1000000   # 1Mbps
  extended_id: false  # Standard 11-bit IDs

messages:
  - id: 0x360
    name: "Engine Data 1"
    length: 8         # Bytes
    interval_ms: 10   # Broadcast rate
    signals:
      - name: "RPM"
        start_bit: 0
        length: 16
        byte_order: little_endian
        data_type: unsigned
        scale: 1.0
        offset: 0
        unit: "rpm"
        min: 0
        max: 20000
        description: "Engine speed"

      - name: "Manifold_Pressure"
        start_bit: 16
        length: 16
        byte_order: little_endian
        data_type: unsigned
        scale: 0.1
        offset: 0
        unit: "kPa"
        min: 0
        max: 400
        description: "Manifold absolute pressure"

  - id: 0x361
    name: "Engine Data 2"
    length: 8
    interval_ms: 10
    signals:
      - name: "Throttle_Position"
        start_bit: 0
        length: 16
        byte_order: little_endian
        data_type: unsigned
        scale: 0.1
        offset: 0
        unit: "%"
        min: 0
        max: 100

      - name: "Coolant_Temp"
        start_bit: 16
        length: 16
        byte_order: little_endian
        data_type: signed
        scale: 0.1
        offset: 0
        unit: "celsius"
        min: -40
        max: 200

# Optional: Enumeration definitions for discrete signals
enums:
  - name: "GearPosition"
    values:
      0: "Neutral"
      1: "First"
      2: "Second"
      3: "Third"
      4: "Fourth"
      5: "Fifth"
      6: "Reverse"

metadata:
  author: "Your Name"
  license: "MIT"
  tested_with:
    - "VendorName Model A"
    - "VendorName Model B"
  compatible_tools:
    - "CANalyzer"
    - "PCAN-View"
    - "SavvyCAN"
  changelog:
    - version: "1.0.0"
      date: "2025-01-06"
      changes:
        - "Initial release with core engine messages"
5

Validate Your Protocol

bash
# Install validation tool (one-time)
npm install -g ajv-cli

# Validate
ajv validate -s specs/schema/protocol.schema.json -d specs/protocols/vendorname/vendorname-broadcast.protocol.yaml
6

Submit Pull Request

bash
git checkout -b add-vendorname-protocol
git add specs/protocols/vendorname/
git commit -m "protocol: Add CAN protocol for VendorName Broadcast"
git push origin add-vendorname-protocol

Then create a Pull Request on GitHub. Once merged, your protocol is instantly available via the public API!

Understanding Signal Bits

CAN signals are packed into messages at specific bit positions. Each signal has a start bit and length.

yaml
# Signal position is defined by:
# - start_bit: The first bit of the signal (0-63 for 8-byte messages)
# - length: Number of bits in the signal

# Example: 16-bit RPM starting at bit 0
- name: "RPM"
  start_bit: 0
  length: 16
  # This occupies bits 0-15 (bytes 0-1)

# Example: 8-bit status starting at bit 16
- name: "Status"
  start_bit: 16
  length: 8
  # This occupies bits 16-23 (byte 2)

Scaling and Offsets

Raw CAN values are converted to engineering units using scale and offset:

yaml
# Raw value to engineering value formula:
# engineering_value = (raw_value * scale) + offset

# Example: Temperature in 0.1 degree resolution
- name: "Coolant_Temp"
  scale: 0.1      # Raw 250 = 25.0 degrees
  offset: 0
  unit: "celsius"

# Example: Pressure with offset
- name: "Fuel_Pressure"
  scale: 0.01     # Raw 10000 = 100.00
  offset: -100    # Offset for vacuum reading
  unit: "kPa"

Quality Checklist

Before submitting, verify:

  • Protocol validates against JSON Schema
  • All required fields are present
  • Message IDs are in hexadecimal format
  • Signal bit positions don't overlap
  • Byte order matches ECU documentation
  • Scale and offset values are correct
  • metadata.tested_with lists ECUs tested
  • Protocol has been verified with real CAN data

DBC Export

Protocols in the OpenECU Alliance can be exported to DBC format for use with industry-standard tools like CANalyzer, PCAN-View, and SavvyCAN.

CANalyzer compatible
PCAN-View compatible
SavvyCAN compatible