# FT86 cars (Subaru BRZ, Toyota 86, Scion FR-S) Here is information on some of the PIDs that you're most likely to use with RaceChrono and equations to get the right scale, etc. ## PID 0x18 Update frequency: 100 times per second. `0x18` is a strange PID. Judging by the low PID number (which in CAN networks implies higher priority) and the high update frequency, one would expect it to have some important data, like data for ABS or ESC systems. But based on what is currently known, it only has one the steering angle as a useful data channel. The steering angle graphs are usually relatively smooth, and this data is also available over `0xD0`, along with some much more important data, such as accelerometers. Channel name | Equation | Notes ------------ | -------- | ----- Steering angle | `bytesToIntLe(raw, 0, 2) * 0.1` | Also available in `0xD0` ??? | `C` or `bytesToIntLe(raw, 2, 1)` | The value is 112 most of the time for me ??? | `D` or `bytesToIntLe(raw, 3, 1)` | 0–14 sawtooth ??? | `E` or `bytesToIntLe(raw, 4, 1)` | The value is 0 most of the time for me ??? | `F` or `bytesToIntLe(raw, 5, 1)` | The value is 0 most of the time for me ??? | `G` or `bytesToIntLe(raw, 6, 1)` | The value is 0 most of the time for me ??? | `H` or `bytesToIntLe(raw, 7, 1)` | Strange data channel. It changes in a strange way when the car turns. It also has a 0-14 sawtooth over some otherwise smooth curve. ## PID 0xD0 Update frequency: 50 times per second. Channel name | Equation | Notes ------------ | -------- | ----- Steering angle | `bytesToIntLe(raw, 0, 2) * 0.1` | Also available in 0x18 Z rate of rotation | `bytesToIntLe(raw, 2, 2) * -0.286478897` | The multiplier for ΒΊ/sec appears to be ((90 / pi) * 100) ??? | bytes 4, 5 | Lateral acceleration | `bytesToIntLe(raw, 6, 1) * 0.2` | Not 100% sure about the multiplier, but looks about right Longitudinal acceleration | `bytesToIntLe(raw, 7, 1) * -0.1` | Not 100% sure about the multiplier, but looks about right Combined acceleration | `sqrt(pow2(bytesToIntLe(raw, 6, 1) * 0.2) + pow2(bytesToIntLe(raw, 7, 1) * 0.1))` | ## PID 0xD1 Update frequency: 50 times per second. Channel name | Equation | Notes ------------ | -------- | ----- Speed | `bytesToIntLe(raw, 0, 2) * 0.015694` | May want to check the multiplier against an external GPS device Brake position | `min(C / 0.7, 100)` | The third byte is the pressure in the brake system, in Bars. The 0.7 divider seems to be a good value to get 100% at pressure slightly higher than those you're likely to use on the track for cars with no aero. You can use 0.8 or 0.9 if you see 100% too often. ## PID 0xD4 Update frequency: 50 times per second. Channel name | Equation | Notes ------------ | -------- | ----- Wheel speed FL | `bytesToIntLe(raw, 0, 2) * 0.015694` | Use same multiplier as for speed in 0xD1 Wheel speed FR | `bytesToIntLe(raw, 2, 2) * 0.015694` | Use same multiplier as for speed in 0xD1 Wheel speed RL | `bytesToIntLe(raw, 4, 2) * 0.015694` | Use same multiplier as for speed in 0xD1 Wheel speed RR | `bytesToIntLe(raw, 6, 2) * 0.015694` | Use same multiplier as for speed in 0xD1 ## PID 0x140 Update frequency: 100 times per second. Channel name | Equation | Notes ------------ | -------- | ----- Accelerator position | `A / 2.55` Clutch position | `(B & 0x80) / 1.28` | On/off only Engine RPM | `C + (D & 0x3f) * 256` ??? | `D & 0xc0` ??? | byte 4 Throttle position | `F / 2.55` | Not tested ??? | bytes 6, 7 ## PID 0x141 Update frequency: 100 times per second. Channel name | Equation | Notes ------------ | -------- | ----- Accelerator pedal position? | `bytesToIntLe(raw, 0, 2)` | Follows `A` from `0x140` closely with ~9860 for 0% and ~11625 for 42%. Needs more testing. Throttle position? | `bytesToIntLe(raw, 2, 2)` | Follows the accelerator pedal position with some smoothness, but is independent at idle revs, and when inching in traffic by modulating the clutch. Scale is unknown. ??? | `bytesToIntLe(raw, 4, 2)` | Goes up on acceleration, jumps down when coasting. Might be intake pressure, fuel pressure, etc. Gear | `(G & 0xF) * (1 - (min(G & 0xF, 7)) / 7)` | It's basically just `G & 0xF` but neutral is reported as `7`, hence the complex math to turn it into a 0. The reverse gear is reported as `1`. The value can be wrong when the clutch pedal is depressed. ??? | `G & 0xF0` | I saw values of 128, 160, 192 here. ??? | `H` | Equals to 16 when I lift off the accelerator, then turns to 8, then 0. ## PID 0x360 Update frequency: 20 times per second. Channel name | Equation | Notes ------------ | -------- | ----- Engine oil temperature | `C - 40` Coolant temperature | `D - 40` Cruise control ON | `(F & 16) / 16` | Means the mode is "On", but not necessarily "Set". Not tested much. Cruise control set | `(F & 32) / 32` | Not tested much. Cruise control speed | `H` | In the same unit as the current speed display units? Not tested much. TODO: would be great to find how to read the ambient temperature, and maybe the intake temperature. TODO: find how to log the fuel remaining. ## Connections Besides the CAN pins in the OBD-II port, there is a CAN bus male port hidden behind the car multimedia head unit: ![Hidden CAN port](../images/ft86_hidden_can_connector.jpg) It's very close to the glovebox, which makes it great for putting your CAN reader in the glovebox. Such a placement makes sure it's out of the way and you won't accidentally hit it with your leg while on the track, and also allows quick access for troubleshooting and experimenting. There's also a second 12V port inside the glovebox, which makes it easy to use a 12V-to-USB adapter instead of adding a 12V-to-5V converter to your hardware design. You can use the two middle pins of a [Toyota radio harness](https://www.amazon.com/gp/product/B0002BEQJ8) to connect to the CAN bus in a reliable way. ![CAN socket wiring](../images/ft86_socket_wiring.jpg) It's recommended to use a ~60–90 cm (2–3') twisted pair cable between that port and your CAN reader. I would strongly discourage you from using the screw terminals on the MCP2515 board, as if the cable comes loose it can cause a short circuit in the CAN bus (ask me how I know), which will throw a MIL at best, and who knows what at worst if it happens on the track. Instead, I attached a female JST SM connector to the cable. ![Assembled device in the glovebox](../images/ft86_glovebox.jpg) ## Typical histogram of PIDs Here's what the distribution of PIDs looks like in the CAN bus while idling in a parking lot: PID | Decimal PID | Number of packets received over a 10 second period ---- | --- | --- 0x18 | 24 | 1000 0xD0 | 208 | 500 0xD1 | 209 | 500 0xD2 | 210 | 500 0xD3 | 211 | 500 0xD4 | 212 | 500 0x140 | 320 | 1000 0x141 | 321 | 1000 0x142 | 322 | 1000 0x144 | 324 | 500 0x152 | 338 | 500 0x156 | 342 | 500 0x280 | 640 | 500 0x282 | 642 | 167 0x284 | 644 | 100 0x360 | 864 | 200 0x361 | 865 | 200 0x370 | 880 | 200 0x372 | 882 | 100 0x374 | 884 | 10 0x375 | 885 | 10 0x37A | 890 | 10 0x3D1 | 977 | 84 0x440 | 1088 | 25 0x442 | 1090 | 25 0x44D | 1101 | 25 0x46C | 1132 | 25 0x4C1 | 1217 | 10 0x4C3 | 1219 | 10 0x4C6 | 1222 | 10 0x4C8 | 1224 | 10 0x4DC | 1244 | 10 0x4DD | 1245 | 10 0x63B | 1595 | 20 0x6E1 | 1761 | 10 0x6E2 | 1762 | 10