iwanders / OBD9141

A class to read an ISO 9141-2 port found in car diagnostic OBD-II ports.
MIT License
237 stars 72 forks source link

readerKWP not working for me #32

Open jwdsoft opened 3 years ago

jwdsoft commented 3 years ago

I'm using the readerKWP example which have initKWP and i'm setting init_success = true; so that in order for a request to be sent but on the logic analyzer nothing happens after the initKWP. I also tried requestKWP and request but nothing work except the init.even if I make a request without the init it doesn't send anything.

I should mention that I'm only using a logic analyzer on the TX pin only I'm not using any tranceiver still waiting for them to come.


UPDATE: Solved the problem now it works without a problem. can you suggest how can I receive without sending any request just keep receiving the frames.

iwanders commented 3 years ago

UPDATE: Solved the problem now it works without a problem.

Great news! :tada:

can you suggest how can I receive without sending any request just keep receiving the frames.

Normally, the OBD9141 protocol doesn't support that. As far as I know the ECU is always the slave, and you have to actively request information and then listen for the response. I've not heard of any ECU that proactively sends information.

If this answers your question, please close this issue. :)

jwdsoft commented 3 years ago

Thanks for your reply. I didn't clarify it enough for you. I know that the ISO9141 protocol doesn't support that.I don't mean to connect the arduino to the ECU and wait for it to send something since it will not send anything. what I meant is to connect a diagnostic tool to the ECU to let it talk and connect the arduino to see the communication between the DiagTool and the ECU (just like the Scope or the logic analyzer) so is that possible. the arduino will be only listening without interfering with the communication

iwanders commented 3 years ago

so is that possible. the arduino will be only listening without interfering with the communication

Yeah, should be possible. Not sure if you need this library for that... it may help with the parsing though.

Just enable the serial port with the right baud rate as set_port(true) would do. Then you can just read bytes from the serial port and those will be the bytes going over the kline. Depending on the timing of your particular vehicle you can probably just do a readBytes on the serial port with an appropriate timeout, the standard request method has the read code here.

In short; set up the Rx line and serial port (see begin). Then use readBytes on the serial port to read whatever goes over the bus.

Ashok12698 commented 1 year ago

Hi @iwanders @jwdsoft, Thanks for posting this discussion. I am following the readerKWP script to test KWP2000 fast with my ECU simulator. I am following the script as it is, but it gets me init_success=false. so I tried.... -sending request message as C1 33 F1 81 -checking buffer[4] = 0xC1 instead of buff[3] which is by default defined in script. and it reads 0xC1 and I get init_success=true and able to read RPM value. Thats good. BUT............... when I add other PIDs to read like 0x0C and 0x0D, I don't get any other. Should I send different request message for every ECU every time? or missing something in here....? In getPID my message is uint8_t message[5] = {0xC1, 0x33, 0xF1, mode, pid}; Please suggest~ Thanks.

iwanders commented 1 year ago

I don't think you're guaranteed to have 0xC1 in the message, in these examples, the start is 0xc2, but that is not anywhere in the response?

Ashok12698 commented 1 year ago

@iwanders I tried 0xC2 but it didn't work. Let me brief you, what I am trying.....

IninitKWP(), I am trying to send request message as uint8_t message[4] = {0xC1, 0x33, 0xF1, 0x81}; and then checking the buffer[4] == 0xC1 if if(this->requestKWP(&message, 4) == 7) In requestKWP(void* request, uint8_t request_len) I am reading the request_len and add checksum as buf[request_len] = this->checksum(&buf, request_len);. The buf gives me buf: 193 51 241 129 and checksum is 102 and buffer[0] is 128, later while calculating const uint8_t msg_len = (this->buffer[0]) & 0b111111; which gives '0' and seems the problem continues from here since the msg_len comes '0'. Intensely, if I set the msg_len = 4 ("message length") it works for reading ECU only for RPM as my getPID(uint8_t pid, uint8_t mode, uint8_t return_length) is defined as:

bool OBD9141::getPID(uint8_t pid, uint8_t mode, uint8_t return_length){
uint8_t message[5] = {0xC1, 0x33, 0xF1, mode, pid};
    // header of request is 5 long, first three are always constant.
    bool res = this->request(&message, 5, return_length+5);
    // checksum is already checked, verify the PID. 
    if (this->buffer[4] != pid){
        return false;
    } return res;
}

Please correct me. Thanks.

iwanders commented 1 year ago

The buf gives me buf: 193 51 241 129 and checksum is 102 and buffer[0] is 128, later while calculating const uint8_t msg_len = (this->buffer[0]) & 0b111111; which gives '0' and seems the problem continues from here since the msg_len comes '0'.

But... 193 51 241 129 is 'C1', '33', 'F1', '81', so the exact request that was sent? It looks like the echo of the request itself? Curiously, only the request method has the logic to read the echo?

So; you may need to read the length + 1 bytes to account for the echo occuring on your serial port. Though I'm not fully sure why request has handling for the echo and requestKWP doesn't.

Ashok12698 commented 1 year ago

Hi @iwanders yes, that the exact request that was sent. I just logged it to confirm what requesting is actually sending. well, please have a look on my log below and suggest, what I am missing....

This is when I am considering const uint8_t remainder = msg_len + 2 + 1; _(getting msglen from buffer[0] & 0b111111)

Looping
Before 25 ms / 25 ms startup.
Enable port.
Request Message: 193 51 241 129 -----> C1 33 F1 81 (Request)
requestKWP() starts.....
request_len: 4
CheckSum: 102
REQ: 193 51 241 129 ----> C1 33 F1 81  (Request)
buffer[0]:128
msg_len:0
Rem: 3
ret_len: 4
RSP: 128 241 16 3 0   ---> 80 F1 10 3 0 (Response)
init_success:0

This is when I consider const uint8_t remainder = 4 + 2 + 1; _(forcibly set msglen=4)

Looping
Before 25 ms / 25 ms startup.
Enable port.
Request Message: 193 51 241 129 ----> C1 33 F1 81  (Request)
requestKWP function starts.....
request_len: 4
CheckSum: 102
REQ: 193 51 241 129 ---> C1 33 F1 81 (Request)
buffer[0]:128
msg_len:0
Rem: 7
ret_len: 8
RSP: 128 241 16 3 193 234 143 190 0  ----> 80 F1 10 3 C1 EA 8F BE 0   (Response)
buffer[4]=0xC1 OK...
init_success:1

even though, in both the cases the buffer[0] comes same 128, but while reading msg_len from buffer[0], it gives '0'.

iwanders commented 1 year ago

Hmm, so the request you are sending is the start communication request; this one. But then for your system it returns more bytes than the expected 6 from here

Searching for that 80 F1 10 3 C1 EA 8F BE 0 sequence, I find: this txt file.

Which implies that the length is the 4th bytes buffer[3] for this response? Which is very different from the implementation followed in my library.

If we look at that url carefully, it's a txt from this wiki; perhaps Suzuki Diagnostic System requests aren't the same as KWP even though the physical bus is the same?

That entire project could be of great help to you, given that it looks like you are dealing with this particular flavour?