Basics

RaceChrono Pro (v6.0 and later) allows users to enter freely typed equations for custom OBD-II channels and CAN-Bus channels.

  • Case insensitive: Variables and functions in equations are case insensitive. It doesn’t matter if you write POW(2) , Pow(2) or pow(2).
  • Decimal floating point values: 64-bit floating point value. A dot ( . ) is used as decimal separator. Comma ( , ) is reserved as function parameter separator. Constants are interpreted as floating point values only when decimal separator is included ( . ). Example: 12494.0
  • Decimal integer values: 64-bit integer value. Example: 12494
  • Hexadecimal integer values: 64-bit integer value. Denoted by 0x at start. Example: 0x30CE = 12494
  • Spaces: Spaces can be used to make equations more readable, but they are not required anywhere.
  • Brackets: Brackets can be used to mark precedence. For example:
    (4 + 2) * 10 = 60
    4 + (2 * 10) = 24
  • Definition of true and false: In logical operations and functions, zero is always considered as false. Anything else is considered as true.

Operators

Normal C / C++ / Java style operators work, and the operator precedence is same as in these languages.

  • Add
    5 + 2 = 7
  • Subtract
    5 – 2 = 3
  • Multiplication
    5 * 2 = 10
  • Division
    5 / 2 = 2
    5.0 / 2 = 2.5
    5 / 2.0 = 2.5

    Notice when dividing two integers, an integer rounded down will be returned.
  • Modulo
    10 % 3 = 1
    -10 % 3 = -1
    10 % 3.5 = 3.0
  • Equal to
    11 == 12 = 0 (false)
    11 == 11 = 1 (true)
  • Not equal to
    11 != 12 = 1 (true)
    11 != 11 = 0 (false)
  • Less than
    11 < 12 = 1 (true)
    11 < 11 = 0 (false)
  • Greater than
    12 > 11 = 1 (true)
    11 > 11 = 0 (false)
  • Less or equal to
    11 <= 11 = 1 (true)
    11 <= 10 = 0 (false)
  • Greater or equal to
    11 >= 11 = 1 (true)
    11 >= 12 = 0 (false)
  • Logical or
    0 || 100 = 1 (true)
    0 || 0 = 0 (false)
  • Logical and
    10 && 100 = 1 (true)
    10 && 0 = 0 (false)
  • Bitwise shift left
    1 << 3 = 8
  • Bitwise shift right
    8 >> 3 = 1
  • Bitwise and
    15 & 8 = 8
  • Bitwise or
    8 | 4 = 12
  • Bitwise xor
    15 ^ 8 = 7

Variables and constants

  • NaN
    Not-a-number. Floating point value that will not be displayed in gauges and graphs. Can be used in place of an invalid value.
  • raw
    Raw data output by the OBD-II PID or CAN-Bus PID. Usually you’ll extract bytes (or bits) from the raw variable to an integer, and then apply some maths over it. The following will extract first two bytes to an unsigned integer, and divides that by 100:
    bytesToUint(raw, 0, 2) / 100.0
    bytesToUint(0x0101FFFFFFFFFFFF, 0, 2) / 100.0
    257 / 100.0 = 2.57
  • A and R2
    1st byte of variable raw. Same as bytesToUInt(raw, 0, 1)
  • B and R3
    2nd byte of variable raw. Same as bytesToUInt(raw, 1, 1)
  • C and R4
    3rd byte of variable raw. Same as bytesToUInt(raw, 2, 1)
  • D and R5
    4th byte of variable raw. Same as bytesToUInt(raw, 3, 1)
  • E and R6
    5th byte of variable raw. Same as bytesToUInt(raw, 4, 1)
  • F and R7
    6th byte of variable raw. Same as bytesToUInt(raw, 5, 1)
  • G and R8
    7th byte of variable raw. Same as bytesToUInt(raw, 6, 1)
  • H and R9
    8th byte of variable raw. Same as bytesToUInt(raw, 7, 1)

Functions

  • bitsToUint(source, bitOffset, bitLength)
    Returns unsigned integer value, extracted from the source value. Bit offset 0 is the bit with most significance (msb-0 and big-endian).
    raw = 0x 00 11 22 33 44 55 66 77
    raw = 00000000 00010001 00100010 00110011 01000100 01010101 01100110 0111 0111 (binary)
    bitsToUint(raw, 24, 16) = 0011 0011 0100 0100 (binary) = 0x3344 = 13124
  • bitsToInt(source, bitOffset, bitLength)
    Returns signed integer value, extracted from the source value. Negative values are determined by the most significant bit (two’s complement). Bit offset 0 is the bit with most significance (msb-0 and big-endian).
    raw = 0x00 11 22 33 44 55 66 77
    bitsToInt(raw, 24, 16) = 0x3344 = 13124
    and
    raw = 0x001122B344556677
    bitsToInt(raw, 24, 16) = 0x3344 – 0x8000 = -19644
  • bitsToUintLe(source, bitOffset, bitLength)
    This function is coming to v7.1. Little-endian version of bitsToUInt. Returns unsigned integer value, extracted from the source value. Bit offset 0 is the bit with least significance (lsb-0 and little-endian).
    raw = 0x01 23 45 67 89 AB CD EF
    bitsToUintLe(raw, 28, 16) = 0xB896 = 47254
  • bitsToIntLe(source, bitOffset, bitLength)
    This function is coming to v7.1. Little-endian version of bytesToInt. Returns signed integer value, extracted from the source value. Negative values are determined by the most significant bit (two’s complement). Bit offset 0 is the bit with least significance (lsb-0 and little-endian).
    raw = 0x01 23 45 67 89 AB CD EF
    bitsToIntLe(raw, 28, 16) = 0xB896 = 47254
    and
    raw = 0x01 23 45 67 89 AB CD EF
    bitsToIntLe(raw, 28, 16) = 0x3896
    – 0x8000 = -18282
  • bytesToUint(source, byteOffset, byteLength)
    Returns unsigned integer value, extracted from the source value. Byte offset 0 is the byte with most significance (big-endian).
    raw = 0x0011223344556677
    bytesToUint(raw, 3, 2) = 0x3344 = 13124
  • bytesToInt(source, byteOffset, byteLength)
    Returns signed integer value, extracted from the source value. Negative values are determined by the most significant bit (two’s complement). Byte offset 0 is the byte with most significance (big-endian).
    raw = 0x0011223344556677
    bytesToInt(raw, 3, 2) = 0x3344 = 13124
    and
    raw = 0x001122B344556677
    bytesToInt(raw, 3, 2) = 0x3344 – 0x8000 = -19644
  • bytesToUintLe(source, byteOffset, byteLength)
    Little-endian version of bytesToUint. Returns unsigned integer value, extracted from the source value. Byte offset 0 is the byte with least significance (little-endian).
    raw = 0x0011223344556677
    bytesToUintLe(raw, 3, 2) = 0x4433 = 17459
  • bytesToIntLe(source, byteOffset, byteLength)
    Little-endian version of bytesToInt. Returns signed integer value, extracted from the source value. Negative values are determined by the most significant bit (two’s complement). Byte offset 0 is the byte with least significance (little-endian).
    raw = 0x0011223344556677
    bytesToIntLe(raw, 3, 2) = 0x4433 = 17459
    and
    raw = 0x00112233C4556677
    bytesToIntLe(raw, 3, 2) = 0x4433 – 0x8000 = -15309
  • float(arg)
    Converts the argument to floating point. Examples: float(4) = 4.0, float(5) / 2 = 2.5
  • int(arg)
    Converts the argument to integer. Examples: int(4.0) = 4, int(5.0) / 2 = 2
  • pow(base, power)
    The first argument is a base value and second argument is a power raised to the base value. Examples: pow(x, y) = x y, pow(3, 2) = 3 2 = 9
  • pow2(base)
    The base argument is raised to power of 2. Examples: pow2(x) = x 2, pow2(3) = 3 2 = 9
  • sqrt(arg)
    Returns the square root of the argument. Examples: sqrt(x) = √x, sqrt(4) = 2
  • lowPass(source, limit)
    Returns source when source <= limit, otherwise NaN.
    lowPass(100.0, 99.9) = NaN
    lowPass(99.9, 99.9) = 99.9
    lowPass(99.8, 99.9) = 99.9
  • highPass(source, limit)
    Returns source when source >= limit, otherwise NaN.
    highPass(100.0, 99.9) = 99.9
    highPass(99.9, 99.9) = 99.9
    highPass(99.8, 99.9) = NaN
  • min(a, b)
    Returns minimum value of the two arguments.
    max(100.0, 99.9) = 99.9
  • max(a, b)
    Returns maximum value of the two arguments.
    max(100.0, 99.9) = 100.0
  • if(a, b, c)
    Returns argument c if argument a is 0 (false), otherwise returns argument b.
    if(1, 100, 101) = 100
    if(0, 100, 101) = 101
  • abs(source)
    Returns absolute value of source.
    abs(-10) = 10
    abs(10) = 10
  • scale(source, oldA, oldB, newA, newB)
    Scales source value from range [oldA, oldB] to [newA, newB].
    scale(50, 0, 100, 0, 200) = 100
    scale(50, 0, 100, 1000, 2000) = 1500
    scale(source, oldA, oldB, newA, newB) = ((value – oldA) / (oldB – oldA)) * (newB – newA) + newA
  • isNaN(source)
    Returns 1 (true) if the argument is not a number (NaN), otherwise returns 0 (false)
    isNaN(100) = 0
    isNaN(NaN) = 1

Examples

  1. 2009 BMW 320d oil temperature
    OBD-II PID: 0x2C100458
    Source data: 0x49D4
    Equation: bytesToUInt(raw, 0, 2) * 0.01 – 100.0
    = bytesToUInt(0x49D4, 0, 2) * 0.01 – 100.0
    = 18900 * 0.01 – 100.0
    = 189.0 – 100.0
    = 89.0 celsius
  2. 2018 KTM 790 Duke engine RPM
    CAN-Bus PID: 288
    Source data: 0x23A0223344556677
    Equation: bitsToUInt(raw, 0, 16)
    = 9120 RPM