Hi,
I'm in the processo of reverse engineering can-bus on my Mazda MX5 NC, my goal is to record data for RPM, Speed, % Accelerator, Brake Pedal position and Steering wheel from direct CAN-bus reading instead of OBD2. I'm almost there! I will show you what I found as soon as I manage to go on the road and do a full test.
In the meantime, I'm having a little bit of trouble with the steering anlge. I found the ID, it is 0x81, baud rate 500 kHz. It is a 4 byte long frame.

What I did is rotating the steering wheel from nearly neutral position to right, stopping for a while at 90°, 180°, 270°, 360° etc, then quickly back to 0 and repeating to left, then again quicky back to 0.
Byte 0 is not interesting and then not plotted
Byte 1 has 2 status: EF or 6F, depending on if the steering is at the 360° angle, in both direction of turning, starting from the neutral position (I've plotted the decimal value)
Byte 2 has 4 status: 00 or 01 or FE or FF depending on value of Byte 3 and direction of turning. If the angle is in the "positive" field, meaning from neutral position turning to right, Byte 2 equals 0 for angles up to 255°, then it swithches to 01 for angles above 255°. In the "negative" field, meaning from 0 turning to left, Byte 2 equals FF for angles from 0 to -255°, then it equals FE for anlges exceeding -255 (again I've plotted the decimal value)
Byte 3: the decimal value is ranging from 0 to 255, with a direct correspondance between decimal value and degree of rotation (0 = 0°, 90 = 90°, etc). Above 255°, it is resetting to 0. From the neutral postition 0° turning to left it starts from 255 and decrease to 0 while the steering wheel is reaching -255°, then it resets to 255
I came up with this equation, using the "less than/greater than" condition
=(BytesToUint(raw,3,1)+(BytesToUint(raw,2,1)-256)*256)*(BytesToUint(raw,2,1)>253)+(BytesToUint(raw,2,1)*256+BytesToUint(raw,3,1))*(BytesToUint(raw,2,1)

I'm quite satisfied of the result, except for following consideration:
- I didn't use the Byte 1 information. Is there any way to use that information and smooth the equation?
- The values are not "symmetric". I got a -486° and +455°, it doesn't feel right
Any suggestion from a fresh set of eyes would be very much appreciated. Thank you!
Data collected using PiCan2
Comments
Sorry, the equation was incomplete:
(BytesToUint(raw,3,1)+(BytesToUint(raw,2,1)-256)*256)*(BytesToUint(raw,2,1)>253)+(BytesToUint(raw,2,1)*256+BytesToUint(raw,3,1))*(BytesToUint(raw,2,1)<253)
- Zero position
- 90 degrees to left position
- 90 degrees to right position
- Max left position
- Max right position
With the data I can write up how to figure it out.
(bytestouint(raw,1,2)-32768)/20.00
To answer your question, position and full raw data including ID# and byte 0, I've also added 360° left and 360° right
0° position: 081# 76 EF 00 00 90° left: 081# 8D 6F FF A6 90° right: 081# 17 6F 00 5A Max left (486): 081# 12 6F FE 1A Max right (455): 081# DE 6F 01 C7 360° left: 081# FE EF FE 98 360° right: 081# D3 EF 01 68
The negative values are being represented in two's complement: https://en.wikipedia.org/wiki/Two's_complement When you know about two's complement it's rather easy to eyeball it from negative values starting from maximum unsigned integer value, in this case -1 is FF FF, and going down as the negative value grows.
Byte order is Big-Endian: https://en.wikipedia.org/wiki/Endianness , it's obvious in this case that third byte is more significant than the fourth byte.
The bytesToInt (notice not bytesToUint) can extract a signed integer, with two's complement and big-endian byte order. So just "bytesToInt(raw, 2, 2)" will solve your steering angle in degrees!
Use the reference guide to pick the correct function: https://racechrono.com/support/equations