Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

more on custom PIDs - splitting response #38

Closed
miguelos6 opened this issue Jul 7, 2020 · 17 comments
Closed

more on custom PIDs - splitting response #38

miguelos6 opened this issue Jul 7, 2020 · 17 comments
Assignees
Labels
enhancement New feature or request

Comments

@miguelos6
Copy link

miguelos6 commented Jul 7, 2020

This is continuation of issue 4
some custom PIDs return values and suggested calculation for result is divided in two parts A and B (all examples for Torque app)
see example of calculations suggested -> here
if A256+B makes all sense as it's simply conversion of longer response to decimal (I guess)
such a calculation :
(A
33.55/255+B*0.13/255)-12
is impossible to get with current findResponse()

Would it be possible to return A and B separately so calculation could be done on them ?

currently the most complex query & response for me is
Distance Since Last DPF Regeneration Dist. DPF 223039 A*256+B 0 65535 km 7E0
myELM327.queryPID(34, 12345) //0x22 and 0x3039 => 34 and 12345

@miguelos6 miguelos6 added the enhancement New feature or request label Jul 7, 2020
@PowerBroker2
Copy link
Owner

While bit masking/shifting the output of findResponse() would relatively easily provide the A and B values you're looking for, I can add 2 class member variables a and b to make things even easier.

PowerBroker2 added a commit that referenced this issue Jul 8, 2020
@PowerBroker2
Copy link
Owner

I opted not to use class variables a and b, but rather broke out the 64-bit response into 8 individual bytes that you can then use as your application sees fit.

Changes implemented in 2.3.0.

@miguelos6
Copy link
Author

Hi @PowerBroker2, sorry for re-opening this.
Could you please give an example how to apply such calculations on A & B returned separately ?
Will old sketches work with this change ?

@PowerBroker2
Copy link
Owner

No worries!

Some standard PIDs return a single byte - in this case, the LSB of the response is the A value and B is undefined. Other standard PIDs return 2 bytes - in this case, the 2nd LSB is the A value and the LSB is the B value. Custom PIDs sometimes return even more than 2 bytes of data.

Because there is no set byte for the A value and B value, I can't easily/automatically interpret which byte in the response is A or B. This is why I didn't implment class variables a and b. Instead I implemented the following:

byte responseByte_0;
byte responseByte_1;
byte responseByte_2;
byte responseByte_3;
byte responseByte_4;
byte responseByte_5;
byte responseByte_6;
byte responseByte_7;

Where responseByte_0 is the response LSB, responseByte_1 is the 2nd LSB, ..., and responseByte_7 is the response MSB.

For your application, if you get a valid response from getResponse(), you can then use responseByte_1 and responseByte_0 as your A and B values, respectively.

Does that help?

@miguelos6
Copy link
Author

miguelos6 commented Jul 12, 2020

Thank you for reply, but again I'm sorry for not understanding (I'm not a programmer, just using the lib to do small work for me)
I guess I need to change my code (pre 2.3.0) in order to know how to interpret returned values?
that is - now more significant bytes may contain garbage data & simply doing sth like this :
int16_t Tpid1a6d = myELM327.findResponse()
will give unpredicted results ?

So far I used only A and A+B values. Only recently found a value that need to be split into separate calculations on A and B

Maybe it's an option to zero out more significant bytes and just filling A or A+B on query ?
Could you please provide an option on how to read A, B (or more) separately in sketch after findresponse? (as mentioned - I'm not a programmer:/)

@PowerBroker2
Copy link
Owner

Any non-valid bytes are already zeroed out, so it's fully backwards compatible with previous sketches. The difference is now you have more flexibility when calculating complex PID responses. For your case:

myELM327.findResponse();
byte B = myELM327.responseByte_0;
byte A = myELM327.responseByte_1;
// do things with A and B

@cyberelectronics
Copy link

cyberelectronics commented Jul 30, 2020

Hi,
I'm trying to implement some Extended PIDs for a Hyundai Kona EV (the car not yet arrived, so I can't test it right now. I'm more a HW guy, so implementing any SW is not an easy task for me).
Your library works great with my old car and BT adapter (checked the RPM data).

I found some examples/sniff and description on the net, but it looks like for a query (PID 220100), the response can be 6x 8bytes or even 9x 8bytes long or maybe I just misunderstand something. (Source)
example_hexdump

pid 220100 @ 2019-03-23T10:50:56.868873
7BB 10 26 62 01 00 7E 50 07
7BB 21 C8 FF 7C 67 66 0E E5 [?=200] [?=255] [INDOORTEMP=22] [OUTDOORTEMP=11.5] [EVAPORATORTEMP?=11] [?=14] [?=229]
7BB 22 8F FF FF 8F FF 11 FF [?=143] [?=255] [?=255] [?=143] [?=255] [?=17] [?=255]
7BB 23 FF FF FF FF FF FF FF [?=255] [?=255] [?=255] [?=255] [?=255] [?=255] [?=255]
7BB 24 FF 3A D6 8F 90 43 FF [?=255] [?=58] [?=214] [?=143] [?=144] [speed?=41.6407706650093] [?=255]
7BB 25 FF 00 FF FF 00 00 00 [?=255] [?=0] [?=255] [?=255] [?=0] [?=0] [?=0]

Is there a way to parse and check a specific "responseByte_X"?
Can you give me an example code?
Thank you!

@PowerBroker2
Copy link
Owner

I'm curious, what is the 7BB section for? Usually when you query for a PID, the response will begin a slightly modified PID as a sort of "preamble". Is this the case for your PID?

Once you do get the car, use one of the test sketches to manually query the vehicle for this custom PID. Then, record the exact response and post it here.

@cyberelectronics
Copy link

cyberelectronics commented Jul 31, 2020

I think Header / Module ID. (end of this page)
Here on the first page you can find 7BB (Aircon).
Ok. I will try to record the exact response (in 2-3 weeks :( )

@cyberelectronics
Copy link

cyberelectronics commented Aug 5, 2020

Just found this example with more info.
So from the "our dump" response, where request ID was 7B3, we can identify:
7BB _10_ _26_ _62 01 00_ 7E 50 07
7BBh = request ID 7B3 + 0x8 (added to response)
10h = first frame (sequence 0) from a multiframe packet (20h means consecutive frame and 00h means single frame packet)
26h= number of bytes (len) = 38 - 3bytes (Mode&PID)
62h 01h 00h = Mode&PID, where 62 => Mode 22h + 40h ("OK" added to response)) and PID 01 00
Aprox. 10ms between sequences

Another crazy example about VESS - CAN mod explained

ATcommands (init, protocol 6) for OBD adapter ( screenshot from OBD2 Simulator, found on the net) :
ISO15765_example

@cyberelectronics
Copy link

cyberelectronics commented Aug 26, 2020

Here is the response, using your demo sketch:

  1. Sending command 220101 (from Battery Management System BMS module):
    Connected to ELM327
    220101
    SEARCHING...
    7F2212
    7F2212
    7F2212
    03E - I think this should be at the beginning of frame 0:
    0: ?3E? 620101FFF7E7 // ?3E? = missing byte from frame 0
    1:FF 98 0000000080 // State Of Charge SOC = 98h / 2 = 76% -> correct!
    2:0000 0F2B 1F1D1D // represents Main Battery voltage (0F*256 + 2B)/10 = 388V which is correct! = according to this file
    3:1D1F1D0000 1B C6 // BATT Inlet Temp 1B = 27C -> correct
    4:03C5280000 7A 00 // AUX Batt Voltage 7A * 0.1 = 12.2V -> correct
    5:0009FF00000888
    6:00 00 03 D0 00 00 03 // Cummulative Energy Charged CEC = ((00<24)+(00<16)+(03<8)+D0)/10.0 = 97.6 kWh -> correct
    7: 1D 000615A30900 // Cummulative Energy Discharged CED = ((00<24)+(00<16)+(03<8)+1D)/10.0 = 77.1 kWh -> correct
    8:030000000003E8

  2. Sending command 220100 (AirCon module, I think it was OFF)
    220100 SEARCHING... 7F2212 7F2212 7F2212

  3. Sending command P:
    Print supported PIDs *** Turn engine ON ***
    Turning ECU filter off ATCRA
    Turning headers ON ATH1
    Turning line feeds ON ATL1Turning spaces ON ATS1
    =================================
    Supported PIDs: 01007EB064100800000017EC06410080000001
    Supported PIDs: 01207EB064120800180007EC06412080018001
    Supported PIDs: 01407EC06414000000020
    Supported PIDs: 0160NODATA
    Supported PIDs: 0180NODATASupported PIDs: 01A0NODATA
    =================================
    Disconnecting bluetooth connectionHalting program ...

@PowerBroker2
Copy link
Owner

This is all a little confusing - all I need is the query and the exact response. Most likely, however, you will have to send and parse this particular PID response yourself since the output of the library's parser is 64bit max. You can still find utility in the library for setting up the ELM327 and polling less eccentric PIDs

@cyberelectronics
Copy link

cyberelectronics commented Aug 27, 2020

I combined 2 demo sketches, but basically I just sent the "220101" thru Arduino Serial Monitor (using this OBD adapter + this ESP32 TTGO board).

void loop()
{
  if(DEBUG_PORT.available())
  {
    char c = DEBUG_PORT.read();
    DEBUG_PORT.write(c);
    ELM_PORT.write(c);
  }
 if(ELM_PORT.available())
  {
    char c = ELM_PORT.read();
    if(c == '>')
      DEBUG_PORT.println();
    DEBUG_PORT.write(c);
  }
}

and the exact response was this (where 03E = 62 bytes length and 620101 = 40h + PID):

Connected to ELM327
220101
SEARCHING...
7F2212
7F2212
7F2212
03E
0:620101FFF7E7
1:FF980000000080
2:00000F2B1F1D1D
3:1D1F1D00001BC6
4:03C52800007A00
5:0009FF00000888
6:000003D0000003
7:1D000615A30900
8:030000000003E8
> 

Today I will try this:

if (myELM327.queryPID(34, 257))   // Kona PID = 22 01 01 = 34, 257
              {
                 Serial.print("Payload received: ");
                 for (int i=0; i<myELM327.recBytes; i++) Serial.print(myELM327.payload[i]);
                 Serial.println();
              }

@cyberelectronics
Copy link

So here is the results for queryPID(34, 257) =>PID 22 0101 at every 2 seconds
OBD protocol was modified from '0' (Auto) to '6' (otherwise 'Searching...' will appear).
Original payloadLen = 40 in elmduino.h (line 300)
Here the car was turned ON

Connected to ELM327
Payload received: 03E0:620101FFF7E77F22127F2212
Payload received: 7F22127F22127F221203E0:620101FFF7E71:FF6E
Payload received: 7F22127F22127F221203E0:620101FFF7E71:FF6E
Payload received: 7F221203E0:620101FFF7E77F22127F22121:FF6E
Payload received: 7F221203E0:620101FFF7E77F22127F22121:FF6E

Modified payloadLen = 200 in elmduino.h (line 300)
Now all frames, from 0: to 8: appears correctly
The car was turned OFF

Connected to ELM327
Payload received: 03E0:620101FFF7E71:FF6E00000000802:00000E3B1C191B3:19191B00001CB94:46B92D00007C005:000AF100000AFF6:000004270000047:040007684400008:000000000003E8
Payload received: 03E0:620101FFF7E71:FF6E00000000802:00000E3B1C191B3:19191B00001CB94:0DB92800007C005:000AF100000AFF6:000004270000047:040007684600008:000000000003E8

From here the car was turned ON ( 7F2212 was sent 3 times for each query, I don't know what is this)

Payload received: 7F22127F22127F221203E0:620101FFF7E71:FF6E00000000832:00010E3B1B191B3:19191B00001CB94:49B92800007A005:000AF100000AFF6:000004270000047:040007685F0D018:6B0000000003E8
Payload received: 7F22127F22127F221203E0:620101FFF7E71:FF6E00000000832:000C0E3A1B191B3:19191B00001CB94:0FB928000080005:000AF100000AFF6:000004270000047:04000768610D018:6B0000000003E8

Strange: sometimes 7F2212 appears later in the packet, between frame 0: and frame 1:

Payload received: 7F22127F221203E0:620101FFF7E77F22121:FF6E00000000832:000C0E3A1B191B3:19191B00001CB94:2CB92D000092005:000AF100000AFF6:000004270000047:04000768750D018:6B0000000003E8
Payload received: 7F221203E0:620101FFF7E77F22127F22121:FF6E00000000832:000F0E3A1B191B3:19191B00001CB94:01B928000084005:000AF100000AFF6:000004270000047:04000768630D018:6B0000000003E8

@Erictric
Copy link

Erictric commented Dec 6, 2020

I combined 2 demo sketches, but basically I just sent the "220101" thru Arduino Serial Monitor (using this OBD adapter + this ESP32 TTGO board).

void loop()
{
  if(DEBUG_PORT.available())
  {
    char c = DEBUG_PORT.read();
    DEBUG_PORT.write(c);
    ELM_PORT.write(c);
  }
 if(ELM_PORT.available())
  {
    char c = ELM_PORT.read();
    if(c == '>')
      DEBUG_PORT.println();
    DEBUG_PORT.write(c);
  }
}

and the exact response was this (where 03E = 62 bytes length and 620101 = 40h + PID):

Connected to ELM327
220101
SEARCHING...
7F2212
7F2212
7F2212
03E
0:620101FFF7E7
1:FF980000000080
2:00000F2B1F1D1D
3:1D1F1D00001BC6
4:03C52800007A00
5:0009FF00000888
6:000003D0000003
7:1D000615A30900
8:030000000003E8
> 

Today I will try this:

if (myELM327.queryPID(34, 257))   // Kona PID = 22 01 01 = 34, 257
              {
                 Serial.print("Payload received: ");
                 for (int i=0; i<myELM327.recBytes; i++) Serial.print(myELM327.payload[i]);
                 Serial.println();
              }

Is this a snipet of your code?

Should I had:
myELM327.sendCommand("AT SH 7E4");

To set the Header first?

Thanks

@cyberelectronics
Copy link

cyberelectronics commented Dec 7, 2020

@herode10 It's from the demo code, but yes you should set the Header first, using this command, otherwise more ECUs will respond with the same message.
Just finished my project ( Konassist v1.0 ) so you can check the full code/description here also

@Erictric
Copy link

Erictric commented Dec 7, 2020

@herode10 It's from the demo code, but yes you should set the Header first, using this command, otherwise more ECUs will respond with the same message.
Just finished my project ( Konassist v1.0 ) so you can check the full code/description here also

Wow! Impressive work! Thanks for the response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants