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/OECUASpecs.git
cd OECUASpecs
2

Create Vendor Directory

bash
mkdir -p protocols/vendorname

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

3

Create Protocol File

bash
touch 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 schema/protocol.schema.json -d protocols/vendorname/vendorname-broadcast.protocol.yaml
6

Submit Pull Request

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

Then create a Pull Request on GitHub.

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