Decyphering iMiEV and iON CAR-CAN message data

Mitsubishi i-MiEV Forum

Help Support Mitsubishi i-MiEV Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
Edit: i will need to redo this scan so disregard all this guess work. Even though the Saleae Logic analyzer is a nicely packaged tool, easy to use, etc., and their website claims that it can be used to read CAN data--i have found that it is not working on the mitsubishi CAN buss...
______________________________________________
i made a scan to record what happens when you start heating/defrost using the Remote while plugged in the EVSE, and i made another scan during the heating session just to catch more data for comparison.

Surprisingly, in both scans none of the PIDs that were previously reported to be related to heater control settings or operation were used or found, e.g. 0x384, 385, 3A4.

What was found were some Extended ID codes, both requesting data and sending data?-- So there's another can of worms to decode...

The EV Remote-ECU located under the dash is the antenna receiver for the remote commands. It must be powered up all the time at least while the EVSE is connected. My guess is that it uses the Extended CAN ID parameters for communication and override of the AC/Heater Switch settings.
 
Here are some graphs from a 6-second acceleration run i made while capturing the CAN buss with the logic analyzer. Shifted from N to D (green trace), then you can see the torque command go into creep mode (blue) right before i stomped the accelerator pedal (orange) up to WOT, then let off and you can see the regen torque. The next chart shows the pack voltage and current for this run, along with power (calculated).


wU49LDm.png


G0EQ4KD.png
 
There is now another software to analyze iMiev CAN messages see:

http://can4eve.bitplan.com/index.php/Main_Page
The OBD PID information is gathered at:
http://can4eve.bitplan.com/index.php/Cantriplet
and also in the source code at
https://github.com/BITPlan/can4eve/tree/master/obdii/src/main/java/com/bitplan/triplet
 
Howdy seppl, Welcome and thanks for sharing the links and info, that is a very interesting project and should greatly help with identifying and understanding of the CAN ids and functions.
 
I’d like to add some PIDs that I found. If I repeat early finds I apologize.

Parameter PID (hex)Bytes Computation (integers) Units Remark

Steering 236 0,1 (byte0*256+byte1-4096)/2 degrees centered = 0 degrees
Gear 285 6 if byte6 = 12 then park or neutral
285 6,7 if byte6 = 14 and byte7 = 16 then drive
285 6,7 if byte6 = 14 and byte7 <> 16 then reverse

Windshield wipers 424 1 if bit5 = 1 then on else off
Rear window defrost 424 6 if bit5 = 1 then on else off

Motor 696 2,3 (byte2*256+byte3-500)/20 amps not certain about the computation
Regeneration 696 6,7 (byte6*256+byte7-10000)/10 negative amps not certain about the computation

Chademo 697 0 if byte0 = 1 then on else off
697 1 byte1 procent not certain about the meaning
697 2 byte2 amps no decimal

byte0 is the first byte after the PID and byte7 is the last byte after the PID.
bit0 is the least significant bit and bit7 is the most significant bit.


I am fairly sure that 696 2 and 3 is the motor amps and that 696 6 and 7 is the regeneration amps but I’m not sure that the computations are correct. With respect to the Chademo procent, I’m not sure of its significance. It seems that this is less than 100% when the current is limited by the charger and 100% when the current is limited by the car or the battery.
These PIDs are included in my free app, OBDZero, which is available on Google Play. The app was developed on two inexpensive Bluetooth dongles, the INTEY OBDII and the Vgate Scan. The Vgate seems to run a bit better than the INTEY. The app didn’t work with my OBDLink LX dongle but I’m pretty sure that this is because of outdated firmware in the OBDLink. I will try it with newer firmware soon.
In order to work on inexpensive dongles the OBDZero app runs more slowly than other apps. A data collection cycle takes between 4 and 5 seconds.
 
I can see that I haven’t followed the standard set by garygid at the start of this tread. Here are the PIDs again using the standard
236 (D1*256+D2-4096)/2= steering in degress where 0=centered
285 if D7 = 12 then gear = park or neutral
285 if D7 = 14 and D8 = 16 then gear = drive
285 if D7 = 14 and D8 <> 16 then gear = reverse
424 D2[5] = windshield wipers on
424 D7[5] = rear window defrost on
696 (D3*256+D4-500)/20=motor amps
696 (D7*256+D8-10000)/10=regeneration amps (negative)
697 D1[0] = Chademo in operation
697 D2 = Chademo percent
697 D3 = Chademo amps
 
Howdy CZeroOwner and welcome to the forum, thanks for sharing your findings--every little bit helps. My car is in the shop to have the pack replaced and haven't been keeping up with the PID work.
 
This is probably the most complete doc that exists, you can check out all existing DTC, but unfortunately you do not know how to get them

http://mmc-manuals.ru/manuals/i-miev/online/Service_Manual/2013/index_M1.htm
 
Presumably Mitsubishi isn't prepared to provide the necessary information, even though the Minicab is the only comparable vehicle still in production ?

Can anyone advise how much information is provided to Mitsubishi dealers and authorized service agents ?

If perchance a service agent was prepared to spill the beans, would he have sufficient knowledge to advance the state of play to the extent that the missing pieces aren't so inaccessible ?

From another perspective. if it is completely unrealistic to get a handle on controlling how the existing software works, how crazy is the concept of generating a totally new operating system ? When its all said and done, its difficult to imagine a more basic EV than an iMiEV, consequently developing a replacement operating system must be a lot more do-able than it would be in the case of a Tesla. Is this idea pie in the sky ?
 
praxidice said:
From another perspective. if it is completely unrealistic to get a handle on controlling how the existing software works, how crazy is the concept of generating a totally new operating system ? When its all said and done, its difficult to imagine a more basic EV than an iMiEV, consequently developing a replacement operating system must be a lot more do-able than it would be in the case of a Tesla. Is this idea pie in the sky ?
It's a different set of reverse engineering problems, plus a lot of forward engineering.

You still have to reverse engineer what general purpose inputs and outputs connect to what functionality, for example. Some microcontrollers have of the order of 80 such I/O lines. Then you need the details of any extra-controller hardware, like the gain of every op-amp.

If we could get hold of the firmware, even in binary form, then patching to overcome things like VIN locking becomes possible, though hard. I can help with that. But getting hold of the firmware is often difficult. In two projects that I've been involved with, Elcon/TC chargers and PIP/Axpert inverter-chargers, I got lucky. Ways were found to read the firmware; in the case of Elcon chargers, this was done by two users on this very forum. But I don't think that they can do the same trick with the microcontrollers used in the iMievs (but I'd be very pleased to be proved wrong).

I'm not saying it's impossible or even too hard; it depends on the skill sets of the people available to get the work done.
 
coulomb said:
praxidice said:
If we could get hold of the firmware, even in binary form, then patching to overcome things like VIN locking becomes possible, though hard. I can help with that. .

In your opinion, do you feel that getting hold of the firmware is the most straightforward way to proceed ? I agree that its most likely to be get-able in binary form ... however .....

I have a few ideas bumping around and will pursue those,
 
praxidice said:
In your opinion, do you feel that getting hold of the firmware is the most straightforward way to proceed ?
I'm very new at iMievs; I don't have one myself. My only connection is a friend of a friend is trying to transplant a complete iMiev drive train into a Citroën, and there are problems. I've always enjoyed reverse engineering binary software (disassembling, even decompiling at times). So I'm a bit naive and also biased. In my biased opinion, yes, disassembling the firmware is a good method. If you can get a binary image to me, I'll likely be able to extract useful information from it, and may even be able to prepare patched images to do various things. But it might take a long time, and it may prove hopeless in the end.
 
I have noticed that my CZero seems to use more amps while discharging than it stores in the battery while charging. This must be wrong because it would eventually lead to negative values for the Ah remaining in the battery. At the same time, a possible error in the amps measurement is mentioned on the forum. I found what I believe is the amps error using a continuous data set for a trip involving driving, slow charging and fast charging. This trip is shown in the figure below.



Figure: A trip of about 200 km with both slow and fast charging.

The data shown in the figure was collected with the OBDZero app. The app computed the battery amps at 4 to 5 second intervals using the formula provided on the forum by garygid:

PID 373 D3,D4 as (((D3 * 256) + D4) - 32768) * 0.01 = pack amps In
Note that I chose amps in rather than amps out with a corresponding change from -0.01 to 0.01

In Excel the data was sorted by date and time then the precise time step in hours between each measure¬ment set was computed. The amps were multiplied by the time step to obtain the Ah for each time step using this formula:

Ah = (Amps0 + Amps1)*h/2

Where Amp0 is the amps in one measurement and Amp1 is the amps in the next measurement, the time step h later. Then the accumulated Ah were computed as a running sum starting with 100% = 37.3 Ah. 37.3 Ah was the battery capacity shown by the EvBatMon on that day. The result is shown as the blue line in the figure. The downward trend in Ah compared to the SoC is easy to see.
By simply adding 0.66 amps to each measurement I was able to move the blue line so the two lines were on top of each other.



Figure: The accumulated Ah after adding 0.66 amps to each amps measurement

As the amps are negative while discharging and positive while charging adding 0.66 effectively reduces the amps used while discharging and increases the amps stored. This balances the budget. Therefore adding 0.66 amps calibrates the amps measurement at least on my CZero.
 
I’d like to add two more PID values that I found.

374 (D1 -10)/2 = SoC1
374 D7/2 = C the car’s estimate of the battery’s present capacity in Ah.

We have known for some time that 374 (D2 -10)/2 is the SoC. I believe that this SoC, SoC2, is based on the battery voltage. When the battery is close to fully charged or discharged this can be an accurate measure of the SoC. In this way SoC2 is never greater than 100 or less than 0. On the other hand, the SoC1 shown here may be based on an internal accounting of Ah to and from the battery. That is:
SoC 1 = 100* Ah/C
Where Ah is the car's sum of Ah to and from the battery. If C is a bit less than the true capacity of the battery then SoC1 can be slightly greater than SoC2 and the opposite is also the case.

C as shown above is given in increments of 0.5 Ah. A more precise measure of the present battery capacity, C12, may be given by e.g.:
C12 = C * (1 + (SoC1 - SoC2)/100)

I think the car uses the difference between SoC1 and SoC2 to adjust C. if e.g. SoC1 is some amount less than SoC2 then C is reduced by 0.5 Ah. Then SoC1 is recomputed using the new C.
 
dear sirs, i'm reading the post and i´d like to read the can-bus data with a raspberry pi in python.
At this time i can connect via bluetooth and seria port profile the raspberry with the obdlink lx.
Also i try the following python script, but i´m not sure what protocol use the imiev/psa car.
i´d like to use this can-bus data to make a power control of the batery charge.
F.e.: read the actual soc when the car is in the garage, program a ssd relay to start charge at a time, and when the SOC reach a input value, the raspberry stop the charge.
Many thanks in advance.
this is the python code i try:

import obd_io
import serial
import platform
import obd_sensors
from datetime import datetime
import time

from obd_utils import scanSerial

class OBD_Capture():
def __init__(self):
self.supportedSensorList = []
self.port = None
localtime = time.localtime(time.time())

def connect(self):
portnames = scanSerial()
print portnames
for port in portnames:
self.port = obd_io_OBDPort(port, None, 2, 2)
if(self.port.State == 0):
self.port.close()
self.port = None
else:
break

if(self.port):
print "Connected to "+self.port.port.name

def is_connected(self):
return self.port

def getSupportedSensorList(self):
return self.supportedSensorList

def capture_data(self):

text = ""
#Find supported sensors - by getting PIDs from OBD
# its a string of binary 01010101010101
# 1 means the sensor is supported
self.supp = self.port.sensor(0)[1]
self.supportedSensorList = []
self.unsupportedSensorList = []

# loop through PIDs binary
for i in range(0, len(self.supp)):
if self.supp == "1":
# store index of sensor and sensor object
self.supportedSensorList.append([i+1, obd_sensors.SENSORS[i+1]])
else:
self.unsupportedSensorList.append([i+1, obd_sensors.SENSORS[i+1]])

for supportedSensor in self.supportedSensorList:
text += "supported sensor index = " + str(supportedSensor[0]) + " " + str(supportedSensor[1].shortname) + "\n"

time.sleep(3)

if(self.port is None):
return None

#Loop until Ctrl C is pressed
localtime = datetime.now()
current_time = str(localtime.hour)+":"+str(localtime.minute)+":"+str(localtime.second)+"."+str(localtime.microsecond)
#log_string = current_time + "\n"
text = current_time + "\n"
results = {}
for supportedSensor in self.supportedSensorList:
sensorIndex = supportedSensor[0]
(name, value, unit) = self.port.sensor(sensorIndex)
text += name + " = " + str(value) + " " + str(unit) + "\n"

return text

if __name__ == "__main__":

o = OBD_Capture()
o.connect()
time.sleep(3)
if not o.is_connected():
print "Not connected"
else:
o.capture_data()
 
i can't help with the python code, but here is the CAN buss frame format, if that would help you. The PID is found in the arbitration field, the number of data bytes is 4 bits in the control frame, followed by the actual data bytes and a checksum.

Mu626eg.png
 
Back
Top