Page 3 of 4 FirstFirst 1234 LastLast
Results 21 to 30 of 31

Thread: How to begin OBD development?

  1. #21
    Newbie
    Join Date
    Jun 2008
    Posts
    6
    Would be really happy about any sample code The C# Emulator would be also really great!

  2. #22
    North of the land of Hey Huns
    Auto Apps:loading...

    Join Date
    Jun 2004
    Location
    Westminster, MD
    Posts
    2,144
    Here ya go:

    Code:
    int openPort()
    {
    	portHandle=CreateFileA("\\\\.\\COM1", GENERIC_READ|GENERIC_WRITE,0, NULL, OPEN_EXISTING, 0, NULL);
    	if (portHandle == INVALID_HANDLE_VALUE)
    	{
    		return -1;
    	}
    	COMMCONFIG Win_CommConfig;
    	COMMTIMEOUTS Win_CommTimeouts;
    	unsigned long confSize = sizeof(COMMCONFIG);
    	Win_CommConfig.dwSize = confSize;
    	GetCommConfig(portHandle, &Win_CommConfig, &confSize);
    	Win_CommConfig.dcb.Parity = 0;
    	Win_CommConfig.dcb.fRtsControl = RTS_CONTROL_DISABLE;
    	Win_CommConfig.dcb.fOutxCtsFlow = FALSE;
    	Win_CommConfig.dcb.fOutxDsrFlow = FALSE;
    	Win_CommConfig.dcb.fDtrControl = DTR_CONTROL_DISABLE;
    	Win_CommConfig.dcb.fDsrSensitivity = FALSE;
    	Win_CommConfig.dcb.fNull=FALSE;
    	Win_CommConfig.dcb.fTXContinueOnXoff = FALSE;
    	Win_CommConfig.dcb.fInX=FALSE;
    	Win_CommConfig.dcb.fOutX=FALSE;
    	Win_CommConfig.dcb.fBinary=TRUE;
    	Win_CommConfig.dcb.DCBlength = sizeof(DCB);
    	Win_CommConfig.dcb.BaudRate = 9600;
    	Win_CommConfig.dcb.ByteSize = 8;
    	Win_CommTimeouts.ReadIntervalTimeout = 50;
    	Win_CommTimeouts.ReadTotalTimeoutMultiplier = 0;
    	Win_CommTimeouts.ReadTotalTimeoutConstant = 110;
    	Win_CommTimeouts.WriteTotalTimeoutMultiplier = 0;
    	Win_CommTimeouts.WriteTotalTimeoutConstant = 110;
    	SetCommConfig(portHandle, &Win_CommConfig, sizeof(COMMCONFIG));
    	SetCommTimeouts(portHandle,&Win_CommTimeouts);
    	return 0;
    }
    //bytesRead is an int passed by reference so you knwo how many bytes have been read
    //numBytesToRead is how many bytes the pid you requested should return. 
    //Eg: RPM returns 2 bytes, Load Value returns 1.
    byte* readBytes(int* bytesRead,int numBytesToRead)
    {
    	byte *rcvdBuffer = new byte[100];
    	int charPnt = 0;
    	int bufferSize;
    
    	//So the function can timeout. 0.2 means 200 milliseconds.
    	clock_t time = clock() + (0.2 * CLOCKS_PER_SEC); 
    	
    	//the "(7 + (numBytesToRead * 3)) + 1" value is ELM327 specific, you HAVE to turn off echo, headers, and linefeeds.
    	//This makes sure to read the proper number of bytes
    	byte *tmpBuf = new byte[(7 + (numBytesToRead * 3)) + 1]; 
    	
    	while ((charPnt<= (7 + (numBytesToRead * 3))) && (clock() < time))
    	{
    		DWORD Win_BytesRead=0;
    		if (::ReadFile(portHandle,(void*)tmpBuf,(7 + (numBytesToRead * 3)),&Win_BytesRead,NULL))
    		{
    			for (int i=0;i<Win_BytesRead;i++)
    				rcvdBuffer[charPnt++] = tmpBuf[i];			
    		}
    		else
    		{
    			//An error happened, I should probably handle this sometime.
    		}
    	}
    	*bytesRead = charPnt;
    	return rcvdBuffer;
    }
    
    //sendBuffer is a byte array, of size bufferSize. bytesWritten is an int passed to the 
    //function by reference so you can know how many bytes were actually written
    void writeBytes(byte *sendBuffer,int bufferSize,int *bytesWritten)
    {
    	DWORD Win_BytesWritten=0;
    	if (!::WriteFile(portHandle, (void*)sendBuffer, (DWORD)bufferSize, &Win_BytesWritten, NULL)) {
    		//An error happened, I should probably handle this soemtime.
        }
    	*bytesWritten = ((int)Win_BytesWritten);
    	
    }

    the openPort function opens the port, and stores the handle (HANDLE type in windows) in portHandle. This allows the read and write functions to access it.

    readBytes and writeBytes take a couple arguments which are explained above the functions

    One of the unfortunate things about the ELM327, is that it returns Ascii representations of hexadecimal figures. To get around this I wrote a function which takes two bytes, each is an ascii hex charachter.

    Code:
    byte byteArrayToByte(byte b1, byte b2)
    {
    	byte newB1 = 0;
    	byte newB2 = 0;
    	if ((b1 >= 48) && (b1 <= 57))
    	{
    		newB1 = ((b1 - 48) * 16);
    	}
    	else
    	{
    		//55
    		newB1 = ((b1 - 55) * 16);
    	}
    	if ((b2 >= 48) && (b2 <= 57))
    	{
    		newB2 = (b2 - 48);
    	}
    	else
    	{
    		newB2 = (b2 - 55);
    	}
    	byte retVal = (newB1 + newB2);
    	return retVal;
    }
    if b1 == "0"(actual value 48) and b2 == "F"(actual value 70) then the function would return 15.

    Typical implimentation:
    Code:
    	byte *rcvdBuffer;
    	int *bytesWritten = new int;
    	writeBytes("010C\r",5,bytesWritten);
    	if (*bytesWritten == 0) return;
    	int *bytesRead = new int;
    	rcvdBuffer = readBytes(bytesRead,2);
    	if (*bytesRead == 0) return;
    	//rcvdBuffer now contains 14 bytes or so:
    	//"41 0C 0B C3\r>\r"
    	//To retrieve our RPM we need to get the last two "ascii" hex bytes.
    	byte rpmByteOne = byteArrayToByte(rcvdBuffer[6],rcvdBuffer[7]);
    	byte rpmByteTwo = byteArrayToByte(rcvdBuffer[9],rcvdBuffer[10]);
    	
    	//Then going by the OBD2 standard:
    	int myRpm = (((rpmByteOne * 256) + rpmByteTwo) / 4);
    
    	//myRpm is now your current RPM. yay!


    I know my code is ugly, but this will hopefully be of some help to someone. It took me a couple weeks to get this working but thus far it seems to work well. Keep in mind, my read and write functions are blocking, you need to thread them otherwise your GUI program will lock.

    As for damaging your car... As long as you stick to MODE 01 pids, (the 01 in the 010C request I sent), then you should be fine. This is a list of the different mode/pid combonations: http://en.wikipedia.org/wiki/OBD-II_PIDs

    I'm working on getting the c# emulator program working to an extent where I can send it to someone, right now it'll only work here on my development machine.

  3. #23
    Newbie
    Join Date
    Jun 2008
    Posts
    6
    Sorry I haven't posted any source code yet. I'm working on a version to post that is just the OBD-II reading parts. Otherwise you have to weed through all of my other code for graphics, smoothing, etc. I should have something in a day or two.

    @Malcolm: I'm glad I use VB! C++ confuses the crap out of me! I like my managed code too much

  4. #24
    Newbie
    Join Date
    Jan 2009
    Posts
    2

    Hi guys, just know that i'm waIting.. :)

    i'm waiting for your sample for a long time!!
    i want to start write a c# app to work with the elm scan...

    what i need is to read all the current info (temp, air, bla bla bla...),
    clear codes (MIL LAMP?)
    And to.. show if there a problam and to show a description in english.

    mm.. what i did for now is just to download all the codes (P0201 etc..)
    and thats it, im too lazy to begin!!

    i wait for your sample to start with it.. HELP ME PLS!

    (C# OR VB.NET WILL BE EXCELLENT!!!)

    THAKNS AGAIN!

  5. #25
    Newbie
    Join Date
    Jan 2009
    Posts
    1

    Wink Re-programming the ECU

    I might be wrong but ODB-II is only for diagnostic purposes and can not access the ECU directly. ODB and ODB-II are incapable since it can not rewrite to ECU memory. But ODB-III changes this completely. With ODB-III you can access the ECU and read and write I think. There are special codes released by the manufacture which cost money. These updates can help the car drive better or use gas more efficiently. The EPA put into law a new way to communicate with vehicles from sensors therefor helping to lower emissions. Newer vehicles which have ODB-3 ports are able to write to ECU directly without the need of any other ports. ODB-3 is suppose to be easy but car manufactures are charging us to update our own ECU which can potentially help the environment.. I'm sorry but that does not make sense. Potentially you can tune your car with out the need of taking out the chip and fitting another one in... Their are ODB2 emulators and ECU emulators out there on the internet somewhere you just have to look.. Most of the emulators I've seen are hardware based. I think there is a Turkish company that sales them cheap. Maybe $100 bucks. They sale a ODB 2 reader as well for $15, but shipping costs alot.. I believe there is an encryption on most of the ports for the ECU's in older vehicles which use ODB-2 ports. you should try to find a cheap ECU out there on EBAY and test with it. I thinks its crazy how the auto manufactures try to keep their computers encrypted oh well someone will break it..

  6. #26
    Constant Bitrate
    Join Date
    Dec 2008
    Posts
    167
    Hi, I am starting to write a OBD plugin using VB.NET. Is there a ELM327 interface(DLL)?

  7. #27
    Mod - Driveline forum
    Auto Apps:loading...
    ClockWorK's Avatar
    Join Date
    Oct 2003
    Location
    Michigan
    Posts
    703

    VB.Net 2008

    Here's my ELM/OBD2 module from my FrontEnd (DriveLine). For anyone who wants to play with it.

    Technically, I think you should be able to peform writes and not just queries with OBD2 if you access the Manufactureer-Specific PIDs, which involves contructing your own OBD2/CAN headers instead of letting the ELM device do it. I could be wrong on that though.

  8. #28
    Mod - Driveline forum
    Auto Apps:loading...
    ClockWorK's Avatar
    Join Date
    Oct 2003
    Location
    Michigan
    Posts
    703
    Hey. I completely forgot to include the supporting modules in the file, so I removed it from the above post. I hate writing modules with dependencies, but this one needed a lot of things (port communication for example). If you want all the code and supporting modules, just grab the entire source from the DriveLine forum.

    Sorry for not thinking that one through a little more.. my bad.

  9. #29
    Newbie
    Join Date
    Jun 2009
    Posts
    3
    Quote Originally Posted by Mork0075 View Post
    Thanks a lot for your reply My concern is, that i'am doing something wrong, sending wrong bytes through the channel, which causes a damage. I've done some socket programming in Java, which is really close to what you've described (sending some bytes, waiting for the answer, adjusting the program). But writing your own test environement makes a lot of assumptions, which are perhaps wrong. So a pre build car emulator would give me the confidence, to not damage my car.

    do as i did; buy the same type of ecu on a scrap yard. Then interfacing it will
    simulate almost the real thing. The biggest problem is having the electrics compatible, a wrong interface CAN damage your ECU. you could even connect a resistor to the colling water input to simulate some values.
    I ended up with a correctly designed interface, with a 100mA fuse added in the K line (to be sure) and stable harmless software before trying it on the car itself.

  10. #30
    Newbie
    Join Date
    Jun 2008
    Posts
    6

    DreamSpeed

    Sorry to revive an ancient thread, but I thought the original information in my earlier post on this thread helps explain the source code a little.

    I meant to post this ages ago, but failed to do so. Sorry about that.

    This is the source code for a VB.NET application I was/am developing. The idea is to read the current vehicle speed, engine RPM, etc. from the OBD-II port to make a digital gauge cluster for my car pc. Most of the code in the project is related to the graphics and can be ignored. The meat of the raw OBD-II reading can be found in the Form1_Load sub (initializing the connection with the OBD-II reader) and the Serial_recieved sub (reading the data and then asking for more).

    It currently only reads two values; Vehicle Speed and Engine RPM. Getting more info is as simple as adding a new "case" statement with the correct value. For a list of common OBD-II PIDs and the formula to decode them, see this Wikipedia article.

    Without further ado: DreamSpeed.zip

    Some notes: If you run it, ESC is to exit, ENTER is to toggle fullscreen/windowed modes. There's a boolean value at the top of the code for Form1 called "DemoMode" and it's currently set to "True". Set it to false to read from the OBD-II reader, otherwise it generates random values to test the graphics.

    If you have questions, ask me on my website at http://www.lcarsx32.com. I probably won't be checking back here very often.

    Also on my site, for those interested, is a Star Trek LCARS shell that I'm actively developing.

    Thanks and sorry for the looooong delay is posting the source code.

    -Ray

Page 3 of 4 FirstFirst 1234 LastLast

Similar Threads

  1. OBD II connector on an OBD I car
    By HearseNurse in forum Engine Management, OBD-II, Engine Diagnostics, etc.
    Replies: 6
    Last Post: 03-23-2009, 09:52 AM
  2. 1999 Saab 9-5 OBD, and more
    By nblracer in forum Newbie
    Replies: 1
    Last Post: 05-08-2008, 10:52 PM
  3. OBD or special hardware?
    By Jirka Jirout in forum General Hardware Discussion
    Replies: 2
    Last Post: 03-04-2007, 05:01 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •