Jump to content
Jason-ABRP

Decoding the i3's PIDs

Recommended Posts

Hi,

I'm making reasonable progress in understanding the i3 PIDs with help from the decompiled .PRG files from inside Deep OBD and by looking at Bluetooth traces in Wireshark.

22 D1 07: Returns current speed (STAT_GESCHWINDIGKEIT_WERT - Speed Value)

22 DD BC: Returns state of charge (22 DD C4 also state of charge - one is the displayed one and the other I think is the absolute SOC)

22 63 35: Returns 2 part reply - second part (the 607 F1 21 part) contains the battery State of Health in percent

22 DD 68: Returns high voltage battery voltage in 1/100th of a volt (DD B4 seems to return similar as above)

22 DD 69: 2 part reply: 607 F1 21 part contains the current high voltage battery and a 2s complement signal 16 bit value in 1/100th of an amp. -ve is discharging.

22 DD C0: 2 part reply containing 3 battery temps - is it three sensors, or a low/high/average?

22 F1 90: 4 part reply containing the 17 digit vin with each byte returned as 2 hex digits, eg 30 for "0", 39 for "9".

22 DE 86: 3 part reply - in the first part is the AC charge voltage in volts.  There are more values in the reply but I don't know what they mean

22 DE 87: 2 part reply - in the first part is the AC current in 1/10ths of an amp.  There are more values in the reply but I don't know what they mean

22 D1 12: reply has 2 temp values (STAT_A_TEMP_ANZEIGE_WERT (display) and STAT_A_TEMP_ROHWERT_WERT (raw)) - real temp is (value / 2 - 40).  External temp I think

22 42 0C: 2 part reply which has what looks like range in the various driving modes.  I have an i3s and get 4 numbers that look credibly like range in the 4 modes
(but which mode are we in?  Don't know where to get that)

Still trying to understand this one :

22 DE 84: "AE_BETRIEBSZUSTAND_SLE" (Operating condition?) returns 4 parts but don't know what the values mean - more experiments needed

Still looking for mileage, range.  

  • Like 1
Link to comment
Share on other sites

Hello,

could you please explain to me how did you decode the current response ?

I got these frames : 607F1100762DD69FFFF 607F121FE44FFFFFFFF

I know that the current value is in the FE44 of the second frame but I didn't know how to get the decimal value ( I'm supossed to find -4,19 A).

Thanks 

On 11/17/2020 at 2:55 PM, Steve Davies said:

Hi,

I'm making reasonable progress in understanding the i3 PIDs with help from the decompiled .PRG files from inside Deep OBD and by looking at Bluetooth traces in Wireshark.

22 D1 07: Returns current speed (STAT_GESCHWINDIGKEIT_WERT - Speed Value)

22 DD BC: Returns state of charge (22 DD C4 also state of charge - one is the displayed one and the other I think is the absolute SOC)

22 63 35: Returns 2 part reply - second part (the 607 F1 21 part) contains the battery State of Health in percent

22 DD 68: Returns high voltage battery voltage in 1/100th of a volt (DD B4 seems to return similar as above)

22 DD 69: 2 part reply: 607 F1 21 part contains the current high voltage battery and a 2s complement signal 16 bit value in 1/100th of an amp. -ve is discharging.

22 DD C0: 2 part reply containing 3 battery temps - is it three sensors, or a low/high/average?

22 F1 90: 4 part reply containing the 17 digit vin with each byte returned as 2 hex digits, eg 30 for "0", 39 for "9".

22 DE 86: 3 part reply - in the first part is the AC charge voltage in volts.  There are more values in the reply but I don't know what they mean

22 DE 87: 2 part reply - in the first part is the AC current in 1/10ths of an amp.  There are more values in the reply but I don't know what they mean

22 D1 12: reply has 2 temp values (STAT_A_TEMP_ANZEIGE_WERT (display) and STAT_A_TEMP_ROHWERT_WERT (raw)) - real temp is (value / 2 - 40).  External temp I think

22 42 0C: 2 part reply which has what looks like range in the various driving modes.  I have an i3s and get 4 numbers that look credibly like range in the 4 modes
(but which mode are we in?  Don't know where to get that)

Still trying to understand this one :

22 DE 84: "AE_BETRIEBSZUSTAND_SLE" (Operating condition?) returns 4 parts but don't know what the values mean - more experiments needed

Still looking for mileage, range.  

 

Link to comment
Share on other sites

On 12/17/2020 at 3:56 PM, Zackbk said:

Hello,

could you please explain to me how did you decode the current response ?

I got these frames : 607F1100762DD69FFFF 607F121FE44FFFFFFFF

I know that the current value is in the FE44 of the second frame but I didn't know how to get the decimal value ( I'm supossed to find -4,19 A).

Thanks 

 

Sure.

So you are seeing a reply sent in two frames.  The returned value is 0xfffffe44.  The first 2 bytes are in the first reply (after the 62DD69 which is the extended PID being sent in the reply) ie that is the FFFF.  And the second 2 bytes are in the second reply after the 21 - ie FE44.

This is actually a signed long (32 bit) integer.  It's in what is called 2s complement format.

You can tell that its a negative number because it is larger than 0x80000000.

If you ask your calculator to turn that into decimal it will probably say 4294966852 - that is what you get it you treat it as unsigned.

But to get the real number do 0xfffffe44 - 0x100000000 (or in decimal 4294966852 - 4294967296 = -444.  So the value is -4,44A.

For signed short (16 bit) values the idea is the same, except that numbers >= 0x8000 are negative and to get the true negative value you need to subtract 65536.

Not sure if signed 8 bit values are used but for that 0x00 to 0x7F are 0 to +127 and 0x80 to 0xFF are -128 to -1.

Regards,

 

Link to comment
Share on other sites

On 12/19/2020 at 3:38 PM, Steve Davies said:

Sure.

So you are seeing a reply sent in two frames.  The returned value is 0xfffffe44.  The first 2 bytes are in the first reply (after the 62DD69 which is the extended PID being sent in the reply) ie that is the FFFF.  And the second 2 bytes are in the second reply after the 21 - ie FE44.

This is actually a signed long (32 bit) integer.  It's in what is called 2s complement format.

You can tell that its a negative number because it is larger than 0x80000000.

If you ask your calculator to turn that into decimal it will probably say 4294966852 - that is what you get it you treat it as unsigned.

But to get the real number do 0xfffffe44 - 0x100000000 (or in decimal 4294966852 - 4294967296 = -444.  So the value is -4,44A.

For signed short (16 bit) values the idea is the same, except that numbers >= 0x8000 are negative and to get the true negative value you need to subtract 65536.

Not sure if signed 8 bit values are used but for that 0x00 to 0x7F are 0 to +127 and 0x80 to 0xFF are -128 to -1.

Regards,

 

Thank you very much, that's very helpful 

Link to comment
Share on other sites

Hi,

My project to add BMW i3 support to OpenVehicles' OVMS box is going along quite well.

Here's a snapshot of metrics that I'm collecting at this point (I removed the OVMS "system" ones):

v.b.12v.current                          -6.48A
v.b.12v.voltage                          14.57V
v.b.12v.voltage.alert
v.b.12v.voltage.ref                      12.6V
v.b.c.temp
v.b.c.temp.alert
v.b.c.temp.dev.max
v.b.c.temp.max
v.b.c.temp.min
v.b.c.voltage
v.b.c.voltage.alert
v.b.c.voltage.dev.max
v.b.c.voltage.max
v.b.c.voltage.min
v.b.cac                                  121.54Ah
v.b.consumption                          0Wh/km
v.b.coulomb.recd
v.b.coulomb.recd.total
v.b.coulomb.used
v.b.coulomb.used.total
v.b.current                              0.72A
v.b.energy.recd
v.b.energy.recd.total
v.b.energy.used                          -978.297kWh
v.b.energy.used.total
v.b.health                               Excellent
v.b.p.level.avg                          93.83%
v.b.p.level.max                          94.53%
v.b.p.level.min                          93.23%
v.b.p.level.stddev
v.b.p.temp.avg                           21.72°C
v.b.p.temp.max                           22°C
v.b.p.temp.min                           21°C
v.b.p.temp.stddev
v.b.p.temp.stddev.max
v.b.p.voltage.avg                        4.1868V
v.b.p.voltage.max                        4.189V
v.b.p.voltage.min                        4.185V
v.b.p.voltage.stddev
v.b.p.voltage.stddev.max
v.b.power                                0.285kW
v.b.range.est                            250km
v.b.range.full                           250km
v.b.range.ideal                          250km
v.b.soc                                  100%
v.b.soh                                  96%
v.b.temp                                 21.72°C
v.b.voltage                              401.93V
v.c.charging                             no
v.c.climit                               3.2A
v.c.current                              0A
v.c.duration.full
v.c.duration.range
v.c.duration.soc
v.c.efficiency                           0%
v.c.kwh
v.c.limit.range
v.c.limit.soc
v.c.mode
v.c.pilot                                yes
v.c.power
v.c.state                                done
v.c.substate
v.c.temp                                 22.7916°C
v.c.time                                 0Sec
v.c.timermode
v.c.timerstart
v.c.type
v.c.voltage                              0V
v.d.cp                                   yes
v.d.fl                                   no
v.d.fr                                   no
v.d.hood                                 no
v.d.rl                                   no
v.d.rr                                   no
v.d.trunk                                no
v.e.alarm
v.e.aux12v
v.e.awake                                yes
v.e.c.config
v.e.c.login
v.e.cabinfan
v.e.cabinintake
v.e.cabinsetpoint
v.e.cabintemp
v.e.cabinvent
v.e.charging12v                          yes
v.e.cooling
v.e.drivemode
v.e.drivetime                            0Sec
v.e.footbrake
v.e.gear                                 0
v.e.handbrake
v.e.headlights
v.e.heating
v.e.hvac
v.e.locked                               yes
v.e.on                                   no
v.e.parktime                             1059Sec
v.e.regenbrake
v.e.temp                                 20.5°C
v.e.throttle
v.e.valet
v.i.efficiency
v.i.power
v.i.temp                                 35.0064°C
v.m.rpm                                  0
v.m.temp                                 21.4344°C
v.p.acceleration
v.p.altitude                             10.6m
v.p.direction                            0°
v.p.gpshdop                              0.9
v.p.gpslock                              yes
v.p.gpsmode                              AN
v.p.gpsspeed                             0km/h
v.p.latitude                             -34.xxx
v.p.location                             Home
v.p.longitude                            18.xxx
v.p.odometer                             14534km
v.p.satcount                             9
v.p.speed                                0km/h
v.p.trip
v.tp.fl.p
v.tp.fl.t
v.tp.fr.p
v.tp.fr.t
v.tp.rl.p
v.tp.rl.t
v.tp.rr.p
v.tp.rr.t
v.type                                   I3
v.vin
xi3.s.pollermode                         1
xi3.v.b.p.ocv.avg                        4.1898V
xi3.v.b.p.ocv.max                        4.192V
xi3.v.b.p.ocv.min                        4.188V
xi3.v.b.range.bc                         250km
xi3.v.b.range.comfort                    250km
xi3.v.b.range.ecopro                     253km
xi3.v.b.range.ecoproplus                 262km
xi3.v.b.soc.actual                       93.2%
xi3.v.b.soc.actual.highlimit             93.3%
xi3.v.b.soc.actual.lowlimit              10.5%
xi3.v.c.chargecablecapacity              32A
xi3.v.c.chargeledstate                   0
xi3.v.c.chargeplugstatus                 Connected
xi3.v.c.current.dc                       0A
xi3.v.c.current.dc.limit                 1.8A
xi3.v.c.current.dc.maxlimit              16A
xi3.v.c.current.phase1                   0A
xi3.v.c.current.phase2                   0A
xi3.v.c.current.phase3                   0A
xi3.v.c.db.plugconnected                 no
xi3.v.c.dc.chargevoltage                 0V
xi3.v.c.dc.contactorstatus               0
xi3.v.c.dc.controlsignals                0
xi3.v.c.deratingreasons                  0
xi3.v.c.error                            0
xi3.v.c.failsafetriggers                 0
xi3.v.c.interruptionreasons              0
xi3.v.c.pilotsignal                      6A
xi3.v.c.readytocharge                    yes
xi3.v.c.voltage.dc                       402.4V
xi3.v.c.voltage.dc.limit                 420V
xi3.v.c.voltage.phase1                   0V
xi3.v.c.voltage.phase2                   0V
xi3.v.c.voltage.phase3                   0V
xi3.v.d.chargeport.dc                    no
xi3.v.e.obdtraffic                       yes
xi3.v.gps_speed                          0km/h
xi3.v.wheel1_speed                       0km/h
xi3.v.wheel2_speed                       0km/h
xi3.v.wheel3_speed                       0km/h
xi3.v.wheel4_speed                       0km/h
xi3.v.wheel_speed                        0km/h

A few I need to debug (energy used -977kWh - well that would be nice!)

I need to test 3-phase and DC charging.

If possible get the TPMS tyre pressure info.

And work on the remaining metrics - the ones above with no values.

My main remaining problem is to try to get data while the car is charging - it turns off the OBD gateway.  There are hints for other cars that show some tricks that might work.

To stay on topic OVMS can feed ABRP and its nice that the box is dedicated so always up and running and providing info on the SOC etc.

As you can see OVMS captures much more info which is of interest to anyone who really wants to know what is going on with their car.

 

  • Like 3
Link to comment
Share on other sites

I’m working on similar project evDash  https://github.com/nickn17/evDash - helping with integration of BMW i3 support. We plan to integrate ABRP support in the future as well.

The problem I’m having is that some PIDs stops responding, mostly from BMS (SOC, current, voltage). Other PIDs continue to work. This happens after 30min to 90min. Then it helps to turn the car off for some time, approx 30min. No other car brands we are working with does not show this issue, so it seems to be bmw specific. Does anyone have similar experience?

Btw I’m happy to exchange information about bmw PIDs I already have if anyone is interested. You can also check evDash Github repo for more details.

 

  • Like 1
Link to comment
Share on other sites

Here some info on how to get HV battery information out of a BMW i3 or a Mini Cooper SE Electric. Maybe even more electric BMW models.


First send out commands to the BT dongle to prepare the dongle to send and receive the correct data (initialization of the dongle, first part for all module ID's)
sendATCommand("ATD");         // set to all defaults
sendATCommand("ATE0");        // Echo off
sendATCommand("ATH1");        // Headers On
sendATCommand("ATAL");        // Allow long messages (> 7 bytes)
sendATCommand("ATPBE101");    // Set protocol B options and baud rate
sendATCommand("ATSPB");       // set protocol to B
sendATCommand("ATBI");        // bypass the initialisation sequence
sendATCommand("ATSH6F1");     // set header 6F1
sendATCommand("ATAT0");       // adaptive timing off
sendATCommand("ATSTFF");      // set timeout to FF x4 msec = 1024 msec = 1 sec

(additional settings for access to the SME module = module id 607)

sendATCommand("ATCRA607");      // set can receive address to 607 (= SME module, battery management module, SME = Storage Management electronics)
sendATCommand("ATCEA07");       // use can extended address 07
sendATCommand("ATFCSH6F1");     // flow control set the header to 6F1
sendATCommand("ATFCSD07300800");// flow control set data to 07 30 08 00
sendATCommand("ATFCSM1");       //Can silent mode on

After the initialization (needs to be only once) send out request for extended PID's and interpret the response. All responses are in HEX, conversion to decimal is provided in the explanation


sendATCommand("22DDBC"); // SOC
Example Response is : 607F1100962DDBC01A6607F12103E50091FFFF
1) Relevant data 1 = 01A6 (from position 15, length 4 bytes) = State Of Charge * 10 => 0x01A6 HEX = 422 dec = 42.2% SOC = indicated SOC to driver
2) Relevant data 2 = 03E5 (from position 26, length 4 bytes) = SOC HV Max * 10 => 0x03E5 HEX = 997 dec = 99.7% SOCHVmax = Top buffer limit of real SOC
3) Relevant data 3 = 0091 (from position 30, length 4 bytes) = SOC HV min * 10 => 0x0091 HEX = 145 dec = 14.5% SOCHVmin = bottom buffer limit of real SOC


sendATCommand("22DD68"); // Battery Voltage
Example Response is : 607F10562DD688AF8
1) relevant data = 8AF8 (from position 13, length 4 bytes) = Battery Voltage * 100 => 0x8AF8 HEX = 35576 dec = 355,76 Volt = battery Voltage


sendATCommand("22DD69"); // Battery Current
Example Response is : 607F1100762DD690000607F121011AFFFFFFFF
Relevant data = 011A (from position 26, length 4 bytes) = Battery Current * 100 => 0x011A HEX = 282 dec = 2,82 Amps
SPECIAL CASE FOR NEGATIVE VALUES. The highest bit the the negative sign. Any Value above 32768 is negative current : example below
Example Response is : 607F1100762DD69FFFF607F121FFAFFFFFFFFF
Relevant data = FFAF (from position 26, length 4 bytes) = Battery Current * 100 => 0xFFAF HEX = 65455 => 65455 - 65535 = -80 => -0,80 Amps

Battery Power is to be calculated from Battery Voltage * battery Current


sendATCommand("22DDBF"); // Cell voltages (min, max, avg)
Example response is : 607F1100762DDBF0E73607F1210E81FFFFFFFF
1) Relevant data 1 = 0E73 (from position 15, length 4 bytes) = Lowest Cell Voltage => 0x0E73 HEX = 3699 dec = 3,699 Volt
2) Relevant data 2 = 0E81 (from position 26, length 4 bytes) = highest Cell Voltage => 0x0E81 HEX = 3717 dec = 3,717 Volt 
Calculated value : cell balance is 3,717 Volt - 3,699 Volt = 0,018 Volt = 18 milliVolt


sendATCommand("22DDC0"); // Battery temperatures (min, max, avg)
Example response is : 607F1100962DDC009C4607F1210C1C0AF4FFFF
1) relevant data 1 = 09C4 (from position 15, length 4 bytes) = Battery lowest temperature in Celsius => 0x09C4 HEX = 2500 dec = 25,00 degrees Celcius
2) relevant data 2 = 0C1C (from position 26, length 4 bytes) = Battery highest temperature in Celsius => 0x0C1C HEX = 3100 dec = 31,00 degrees Celcius
3) relevant data 3 = 0AF4 (from position 30, length 4 bytes) = Battery middle or average temperature in Celsius => 0x0AF4 HEX = 2804 dec = 28,04 degrees Celcius


sendATCommand("22DDC4"); // RAW SOC
Example response is : 607F10662DDC413F601
1) relevant data 1 = 13F6 (from position 13, length 4 bytes) = Real SOC * 100 => 0x13F6 HEX = 5110 dec = 51,10% real State Of Charge


sendATCommand("22DFA0"); // Amp hours and average cell voltage
Example response is : 607F1102962DFA025D2607F121274B26B09082607F122910E90C309C4607F1230C1C0AF4FFFF607F124FFFF285513FE607F125155F14BCA1CC607F126A1EAA1DB2855
1) relevant data 1 = 25D2 (from position 15, length 4 bytes) = Battery amp hours * 100 => 0x25D2 HEX = 9682 dec = 96,82 AmpHours
2) relevant data 2 = 910E (from position 45, length 4 bytes) = Average Battery Cell voltage * 10000 Volt => 0x910E HEX = 37134 dec = 3,7134 Volt


sendATCommand("226335"); // SOH State Of Health
Example response is : 607F110076263350000607F1210064FFFFFFFF
1) relevant data = 0064 (from position 26, length 4 bytes) = State of Health (SOH) in percent => 0x0064 HEX = 100 dec = 100% SOH
 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


×
×
  • Create New...