I'm trying to write a program in C that will request data through the CN2 port. I currently have a ROM with John Cui's QuickDatalogger, and I am able to datalog with Cuddle and Freelog, so my hardware is setup properly.

I don't know a whole lot about doing serial communications with windows, so I found some prewritten code to get me started. Here is what I have:

Ive written some datalogging code in C and Objective-C but my serial communication was much simpler as I'm on a BSD base (Mac OS X) so I can't pffer you help in your serial configuration, but I see what might be a problem.

Maybe its cause its late and ive been drinking, but, it looks like your sending the integer 'code' to the ECU. You have code set to 22, in integer format. I believe you want 22 in hexidecmal format which is 34 in base 10. Also, I think you only send 1 byte to the ecu to and then wait for 1 byte to be returned. I haven't written C for Windows in a while, but I'm going to guess that an integer is 16 or 32 bits. Try sending something with sizeof(1) like a single char.

Everything I said could be wrong as I haven't played in C on Win32 in almost 4 years, and I never did RS232 during my Win32 days, but it might help you narrow down your issue.

Also, when you say it gets caught in the Readfile function, what do you mean? Does the program crash, does it hang? Give us some details.

I found the attached file on the forum sometime ago, its not complete, but it might help. (If you have a more updated version, or competing information please post it so I can combine all the data).

You do not have the required permissions to view the files attached to this post.

When I say it gets stuck in there, the program gets into that function and just hangs indefinitely. I know it is there because I put a little printf statement above it and below it, and it only prints the one above, so that's where it is stuck. I suppose it is possible that I am sending the wrong code aswell and the ECU may not recognize it. I'll set it to 0x22 tommorow and see what happens. I'll do that sizeof thing and see how many bytes that int takes up aswell. But now that I'm thinking about it, there is no reason why 0x22 couldn't fit into one byte, so I'm probably giving the ReadFile and WriteFile the wrong parameters aswell.

The communication with the ECU is not foolproof. I have a timeout on my code to read data from the ecu. Basically, I send a byte, and then poll the ecu for X amount of times to get data. If no data is returned then I send the byte again and poll X amount more times. If this happens say 100 times and nothing then I return an error saying that the connection is broken.

I ran into a problem with that method, so be sure to read/clear the rx buffer before you output the next command. also you may wish to check if the tx buffer is empty before starting your rx timeout in case it isn't done sending. most trouble will be when you deal with multi byte commands, however, so don't be too concerned. I found the best method to deal with the serial commands is to convert your decimal/hex to ascii characters asociated with the value. ie val(0x22) if c has a similar command... then send it as a one character string at a time. make sure you enable null characters as a valid response, some defaults are set up to ignore it.

What I do in my code (C based) is send it as a single char (ie: char msg[1]; and just send write( pipe, msg[0] ); ) To set the appropriate byte in the array you can do something like msg[0] = 0x22, or msg[0] = (char)32;

Don't know how much help this will be since its *nix based and objective-c (if youve done any C++ or Java objective-c shouldn't be a problem, slightly different syntax) but here is my datalogging code. If any of it confuses you send me a PM or IM.

Correct me if I am wrong, but it seems to me that the function you use to send the data, in my case the WriteFile, is expecting me pass the address of a string to it instead of the address of an int. I looked at your code and I notice that you put the codes into the 1 position of a string, and then pass that string to the GetData function, which then has a write command like so:

Code:

write( fd, string, 1 );

what are the parameters for the write function? is the 1 telling the write function which position in the string to find the data you want it to send? Or are you telling it how many bytes you want it to send and the function automatically starts at the 1 position?

I have lots of things to discuss based on your last post. First, almost all C commands for linux are documented in whats known as the Man pages (as in manual). Google any C command and the word 'man' to get an explanation.

write expects the file descriptor (the port we are using, com1, com2... etc), the data to be sent as a pointer, and the amount of bytes we wish to send from the data. It does not care what format the data is in, (void *). It will simply send the amount of bytes given in the last parameter starting from the begginning.

Also, some symatics, I am not placing the hex number in the 1 position of the string. The commands at the top are creating char arrays (not strings) that are one char long, and placing command in the 0 position. In C (and its derived language) arrays of size X have locations 0 through X-1. The 1 location is actually the second.

Second thing. Check the result - if there's an error, check the code. FOr example, you can get ERROR_IO_PENDING - not really any error, just meaning 'no data yet'.

Third thing, it's a good idea to make sure the PC and ECU are in 'sync' as far as the comms goes. Send a handshake byte '0xab', and reading anything that comes back until you get the '0xcd' handshake reply. When you do, you've actually a pretty good chance of getting back what you expect from the ECU when you send it something. As ltdannear's said already, watch out for multi-byte commands - it's annoying common for a byte to be lost part way through. When that happens, the ECU can try interpret the rest of the bytes in a multibyte command, as commands... which generally means you'll get something back, but not what you expect.

I have good Windows serial code, but it's not something I can release. I ended up using an extra thread along with the Windows event's system to handle the synchronisation. That approach works very well - but it's far from trivial. If you're just experimenting, it's better using another language on Windows that has a decent serial library so you're spared the pain of fighting the stupid Windows comms api, and can just get on with what you want to write.

Who is online

Users browsing this forum: No registered users and 3 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum