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

**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**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*and

bitsToInt(raw, 24, 16) = 13124

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*and

bytesToInt(raw, 3, 2) = 13124

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*17459

bytesToUintLe(raw, 3, 2) = 0x4433 =**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*17459

bytesToIntLe(raw, 3, 2) =and09

raw = 0x00112233C4556677

bytesToIntLe(raw, 3, 2) = -153**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

**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**2018 KTM 790 Duke engine RPM**

CAN-Bus PID: 288

Source data: 0x23A0223344556677

Equation: bitsToUInt(raw, 0, 16)

= 9120 RPM