#### 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

#### Operators

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

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
• 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

• 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 highest significance (big-endian).
raw = 0x0011223344556677
bitsToUint(raw, 24, 16) = 0x3344 = 13124
• bitsToInt(source, bitOffset, bitLength)
Returns signed integer value, extracted from the source value. Negative values are determined by the first bit of the extracted bytes (two’s complement). Bit offset 0 is the bit with highest significance (big-endian).
raw = 0x0011223344556677
bitsToInt(raw, 24, 16) = 13124
and
raw = 0x001122B344556677
bitsToInt(raw, 24, 16) = -19644
• bytesToUint(source, byteOffset, byteLength)
Returns unsigned integer value, extracted from the source value. Byte offset 0 is the byte with highest 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 first bit of the extracted bytes (two’s complement). Byte offset 0 is the byte with highest significance (big-endian).
raw = 0x0011223344556677
bytesToInt(raw, 3, 2) = 13124
and
raw = 0x001122B344556677
bytesToInt(raw, 3, 2) = -19644
• bytesToUintLe(source, byteOffset, byteLength)
RaceChrono v6.0.9 and later. Little-endian version of bytesToUint. Returns unsigned integer value, extracted from the source value. Byte offset 0 is the byte with lowest significance (little-endian).
raw = 0x0011223344556677
bytesToUintLe(raw, 3, 2) = 0x4433 =
17459
• bytesToIntLe(source, byteOffset, byteLength)
RaceChrono v6.0.9 and later. Little-endian version of bytesToInt. Returns signed integer value, extracted from the source value. Negative values are determined by the first bit of the extracted bytes (two’s complement). Byte offset 0 is the byte with lowest significance (little-endian).
raw = 0x0011223344556677
bytesToIntLe(raw, 3, 2) =
17459
and
raw = 0x00112233C4556677
bytesToIntLe(raw, 3, 2) = -153
09
• 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

#### 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