Hi All !
New member here, got my M2 a number of months back and have been quietly perusing the forum to learn bits and pieces of information about the M2, SavvyCan and overall the “theory” behind CAN, UDS etc. Lots of things to learn but its been interesting, feels like im back in my Assembler (X86) class with all of these Hex bytes.
I wanted to share a little bit about my project and perhaps get a little bit of feedback.
First thing is first, setting up the M2 was pretty straightforward although it did take me a few attempts. I have not worked with an Arduino before so there was a bit of a learning curve to figure out how Sketches work (probably a lot more to learn here but it seemed that once GVRET was flashed, I wont be needing to flash anything for a while). Getting the SuperB+ working is still on my list of things because im still a little confused on the process but I haven’t had an immediate need to ditch the USB cable for now.
Now back to the project. I have an older Nissan Altima hybrid, which I have brought back to life with reconditioning the battery modules etc – so yay it runs ! After installing an aftermarket double din unit into it – it now feels like a modern-ish car. The thought was, what if I could find a way to display the battery module information (voltage) on the screen of the headunit so we can look out for when the battery starts to get weak again, kind of like a Prius? Alas my little project was born.
The big picture here is that I wanted to use a rasperyPi running something like OBDPi to be able to retrieve battery module voltages and then output those onto the screen of the radio via a RCA output which the Pi supports. So far so good? So now I had to figure out how the heck can I get the voltages since it is not a standard PID but rather some proprietary BS. This is where the M2 comes to play. I was able to huck up the M2 inline with a cheap scan tool that can actually get to that data.
This is where I learned more about the UDS protocol, multi-frame messages, flow control and the rest – thought I still don’t understand it perfectly, just rudimentary. The point where I am at now is that ive been able to isolate the frames/communication of what happens once I hit “go” on the scan tool to pull that data. Since it’s a multi-frame message, after some seeming back and forth requests/denials, eventually I see the output I was looking for (in a sequence). Doing a little of reverse hex math I was able to figure out where the data is in the payload and the formula for offsetting and scaling it (it was actually easier than I thought it would be, but certainly took some time manually go through it and decipher what actually made sense).
Im going to annotate a little bit of what I understand from the above. Whenever there is an 03 in D1, this is a flow control frame that basically gives us that its flow control, status, and separation time.
For the 02 im actually not so sure because I thought 02 means its consecutive frames, but there would be no sequence, unlike later down below with actual data-data. I did notice that on line 11 in D2 we see x13, and in the subsequent frame on like 12 in D2 we see x53 so by some UDS rules that x53 means that it is successful because x13 +x40 = x53 (works out in decimal too). So I think that means something was successful.
Then there are a number of other frames that happen which frankly I don’t know what they do, but the meat and potatoes really happens on line 20. This is the true multi-message UDS right here that even has a sequence number of 0->5 (second 4 bits of D1). Within that I knew I was looking for 17 data points (the car has 34 battery modules, which are reported in groups of 2). The “x27” in blue is supposed to tell us how many bytes of data are part of this series of frame which turns out to be 39. I was looking for 17 data points which would be represented as two bytes each, so that’s 34, so I knew there would be some extra I didn’t need (i.e. have 39, need 34). A little staring at it and there was a pattern. A lot of x86! This is because the battery module voltages were all 15.XX volts. So now I knew that each 86XX was exactly that and there were a correct number of tuples (green/red) I needed.
Tinkering with some hex math, it ends up working out that ex: x86x36 = 34358 (decimal), so there had to be extra things to normalize it. I happened to try the lower range value of an int16 (-32768). 34358- 32768 = 1590. This is starting to look like my voltage ! except the decimal is off. Dividing by 100 I got 15.90V which was spot on with the scan tool, Eurica !
The next step I am on now is figuring out how I can “replicate” this data retrieval behavior without a scan tool inline. This is really where im looking for a little feedback.
Whats confusing me is the seemingly multi-request, and some seemingly resulting in failures. I was also expecting that things would generally be in the same sequence as you see with the “final data” (line 20-25, is usually very consistent as it should be) but the rest sometimes comes back a bit inconsistently, flip-flopped etc. I also notice that everything in Savvy can is showing up on Can Bus 0, I have all 3 enabled but unless I got the baud rate wrong im not seeing anything to come in on those. Also to note, everything I see in SavvyCan is usually in one direction only Rx (not Tx). Problem?
Also I have tried the Playback feature of SavvyCan but it feels like the filters are not being applied, so cant verify if anything is actually happening (too many frames!)
Anyways, thanks for getting this far.
Hopefully someone else can part benefit from my findings and or discussion thereafter.
M2 inline with Scan tool that request data
Relevant frames isolated
Trying to figure out how to replicate this behavior without scan tool in line
UDS messages are confusing