Car Scanner allows you add custom sensors (also known as “custom PIDs”) to get data, defined by your car manufacturer.
To create custom sensor you need to know at least 2 things:
1. How to make a request to ECU to get the data you need:
Command = Mode + PID, e.g. 010C for engine RPM
Header = address where to send request, e.g. 7E0 for CAN 11bit protocol. You can leave header blank. In that case default functional header for current protocol would be used. Most of custom PIDs requires correct header!
2. How to decode received data: Formula (Equation).
To point at certain bytes in response use latin letters: A, B, C, D .. Z, AA, AB, .. AZ, BA, BB, .. BZ, … etc. , where letter A stands for 1st byte in response, letter B stands for second byte in response, etc.
Attention! Formula is case sensitive!
To determine first byte, Car Scanner skips some bytes in response from ECU: header bytes, data length, response to certain mode marker (e.g. mode 01 -> response marker 41) and PID id.
Example: request 010C (engine RPM) would give you response: 7E804410C0C9C, where Car Scanner would skip 7E804410C.
So we have only 0C9C data left.
Letter A would mean 0C, letter B would mean 9C
You can use mathematical operators like *, /, –, +. Example: A+B
To change calculation order use brakets ( ), like: (A*256+B)/4
You can use floating point numbers in formula using dot “.”: e.g. A+13.54
Bitwise functions supported:
Bitwise unary complement: @~
Bitwise AND: @&
Bitwise exclusive OR: @^
Shift left: @<<
Shift right: @>>
Examples: A@<<16, C&7, etc.
Additional functions (funtion arguments should be always separated by “,“):
GetBit(A,N), where A – byte number, N – bit number, from 0 to 7
SIGNED(A), signed(A), Signed(A) – treat byte as signed (-128 .. 127)
ShortSigned(A,B) – treat 2 bytes as 16-bit signed value
And(A,B) – bitwise AND, same as A@&B
Shr(A,B) – bitwise shift right, same as A@>>B
Shl(A,B) – bitwise shift left, same as A@<<B
MAX(A,B) – returns maximum value from A and B
MIN(A,B) – return minimum value from A and B
abs(A) – return unsigned value, e.g. abs(-1)=1, abs(-123456)=123456, abs(123456)=123456
FLOAT32(A,B,C,D), float32(A,B,C,D) – returns IEEE 754 floating point value from 4 given bytes.
FLOAT64(A,B,C,D,E,F,G,H), float64(A,B,C,D,E,F,G,H) – returns IEEE 754 floating point value from 8 given bytes.
if(A,B,C) – logic function, if A=1, returns B, else returns C. You can use “=” or “<” or “>” for comparison.
Example: if(A>5;5;A). If A greater than 5, return 5, else return A. With A=6 this would return 5. With A=3 this would return 3.
SetVar(key,value) – store in memory some value. Car Scanner has a key-value dictionary, that is shared for all pids. Key – any integer number, e.g. 0, 1, 2, 3, 9999. Value – any value, e.g. 45.24. Returns the same value.
SetVarOnce(key,value) – store in memory some value, ONLY if it is not stored there yet (with the same key). Returns the same value.
GetVar(key,default_value) – get value from dictionary previously set by SetVar or SetVarOnce. If value doesn’t exist in shared dictionary yet, returns default value. Example: GetVar(123,789.244) – returns value, stored in key 123, but if there’s no value with such key it returns 789.244
You can refer other sensors by 2 ways:
1) PID(ID) or pid(ID) – get other sensor value, where ID is sensor ID (you can check ID in Settings -> Sensors). Example: PID(5)
2) {name}, where name – is exact pid full name (case sensitive). Example: {Fuel temperature}
You can add commands, that would be executed BEFORE and after requesting PID (Start diagnostic command and stop diagnostic commands). This commands should be fully qualified ELM327 commands, separated by “;” or “,” or “\”. Example: ATCRA7E8,ATFCSH7E0,ATFCSD300000
Action PIDs.
Action PIDs are executed when you tap on them. Response is not decoded.
Example of usage: create custom action pid for some command, that starts a routine, like forced DPF regeneration.
Don’t forget, you still need to know header and command for that.
Name and Short name fields can be entered as you wish.
Minimum and maximum fields can be skipped.