OBD-II Software.pdf

(91 KB) Pobierz
OBD-II Software
Main Menu
Changes last made on: 07 November 2002 13:01 -0500
Context Menu
OBD-II Software
When I first owned a car with an "electronic brain", I was always curious about how this computer worked.
The curiosity was borne out of the fact that my profession deals with embedded computers. Subsequently, I
have the hardware and software tools at my disposal to act on my curiosity.
So, after cracking ALDL on my Lotus Esprit, the next stage was to investigate this mysterious OBD-II that
everybody is talking about.
Flavours
OBD-II, although it's a standard, has three distinct interfaces:
Variable Pulse Width - VPW
Pulse Coded Modulation - PCM
Standard Serial - ISO
VPW (usually found on American GM vehicles) and PCM (usually found on Fords) unfortunately need a
dedicated piece of communications hardware to act as a gateway between the PC's communication port and
the ECU. The reason for this is because a standard PC is just not equipped to handle these hardware
formats.
You could probably use a serial port or a pin from the parallel port to emulate these interface formats but
the PC will spend most of its time polling the port due to lack of dedicated hardware. This means that your
http://www.andywhittaker.com/ecu/obdii_software.htm (1 of 8)4/21/2005 3:55:13 AM
929395647.030.png 929395647.031.png 929395647.032.png 929395647.033.png 929395647.001.png 929395647.002.png 929395647.003.png 929395647.004.png 929395647.005.png 929395647.006.png 929395647.007.png 929395647.008.png 929395647.009.png 929395647.010.png 929395647.011.png 929395647.012.png 929395647.013.png 929395647.014.png 929395647.015.png 929395647.016.png 929395647.017.png 929395647.018.png 929395647.019.png 929395647.020.png 929395647.021.png 929395647.022.png 929395647.023.png
OBD-II Software
brand-new 2GHz Pentium 4 PC will be sitting there wasting billions of instruction cycles dealing with the
interface.
ISO, however, is a Godsend. This is because it uses a data-format that a standard PC UART can deal with,
the only thing you need to do is to convert the RS232 voltage levels of the PC into the 12V OBD-II levels of
the ECU interface.
There are a few interfaces available on the market, including mine OBD-II Hardware .
K and L Lines
Whenever I read specifications, I wonder what the people were smoking when they were writing them. A
typical example is the naming of the ISO part of the OBD-II interface; the K and L lines.
Well, the line that you use to communicate with the ECU is the K line. Most newer ECUs allow you to wake-
up the ECU with this line too (i.e. the 5 baud, 0x33 transmission).
Older ECUs need to be woken-up by transmitting 0x33 at 5 baud on the L line. To the best of my
knowledge, the L line is then redundant and not used.
So, that's it. K line is the ISO data to and from the ECU and the L line is sometimes needed to wake-up the
ECU.
Any suggestions to where K and L came from, please put your answers on a postcard to.....
Software
The OBD-II software is the bit where the trouble starts. Lots of people want it, a few people know how to
initiate an ECU conversation.... and about 3 people know how to code it!
If you want to speak to an OBD-II device you have to do the following:
Set your serial port to 5 baud
Send out 0x33 to the ECU
Set your serial port to 10400 baud
Listen for the 0x33 echo because the interface is half-duplex
Listen for 0x55 from the ECU.
Send all sorts of commands to the ECU to get its data....
So what's the problem with that?
http://www.andywhittaker.com/ecu/obdii_software.htm (2 of 8)4/21/2005 3:55:13 AM
929395647.024.png 929395647.025.png 929395647.026.png 929395647.027.png 929395647.028.png 929395647.029.png
OBD-II Software
Unfortunately, if you want to be a good little programmer on 32-bit Windows platforms, Microsoft likes you
to use its File I/O to communicate with the serial port. You can have no direct contact with the serial
hardware.
Another problem you'll encounter is that Windows is a message based, multitasking operating system. You
cannot hog the machine, you must co-operate with the other programs running on the system. You are
almost forced to follow this programming paradigm because, if you don't, your user interface (GUI) will not
function (due to the lack of messages being sent).
Allowing Windows To Multitask
This is easy...
void ISO_L0::PumpMessages()
{
MSG msg;
// if there is a message on the queue, then dispatch it
if (::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ))
{
::GetMessage(&msg, NULL, NULL, NULL);
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
We just need to periodically call PumpMessages() to allow Windows to switch to other tasks and dispatch its
own messages.
Accurate Waiting
You'll see later that we need an accurate waiting function. Windows supplies high-resolution timers within
its API. To wait, we need to glue the functions together like this:
// Waits for specified time in milliseconds.
void ISO_L0::TimerWait( unsigned int mSeconds)
{
BOOL bResult=FALSE;
LARGE_INTEGER liFirst, liSecond, liElasped, liTarget;
if (m_liPerfFreq.QuadPart == 0)
{ //first time we're calling this
// current timer frequency in counts per second
http://www.andywhittaker.com/ecu/obdii_software.htm (3 of 8)4/21/2005 3:55:13 AM
 
OBD-II Software
bResult = QueryPerformanceFrequency(&m_liPerfFreq);
if (!bResult)
{
TRACE("TimerWait failed on call to QueryPerformanceFrequency\n");
AfxMessageBox("TimerWait failed on call to QueryPerformanceFrequency");
return ;
}
CString csTemp;
csTemp.Format("Timer resolution %ld%ld counts per second\n", m_liPerfFreq.HighPart, m_liPerfFreq.
LowPart);
TRACE(csTemp);
}
liTarget.QuadPart = m_liPerfFreq.QuadPart * (ULONGLONG) mSeconds;
liTarget.QuadPart = liTarget.QuadPart / (ULONGLONG) 1000; // convert counts per mSecond
// liTarget is now our target time
// Query the current counter for start point.
bResult = QueryPerformanceCounter(&liFirst);
if (!bResult)
{
TRACE("TimerWait failed on call to QueryPerformanceCounter\n");
return ;
}
liElasped.QuadPart = (ULONGLONG) 0;
while (liElasped.QuadPart < liTarget.QuadPart)
{
// Greatly reduce the processing time while waiting,
// as we near 5 ms of our target time, use full CPU
// Thanks for Uwe Ross for this one.
if ((liTarget.QuadPart - liElasped.QuadPart) < (ULONGLONG) 5)
{ // we're very close to target time
}
else
{ // we're a long way off target time
Sleep(1); // less processor intensive
}
bResult = QueryPerformanceCounter(&liSecond);
if (!bResult)
{
TRACE("TimerWait failed on call to QueryPerformanceCounter\n");
http://www.andywhittaker.com/ecu/obdii_software.htm (4 of 8)4/21/2005 3:55:13 AM
 
OBD-II Software
break ;
}
liElasped.QuadPart = liSecond.QuadPart - liFirst.QuadPart;
}
}
This has been modified since I first published it on the recommendations of Uwe Ross. The routine uses
Sleep(1) which greatly reduces the processing time while it's being called; as the delay loop sees the target
time approaching i.e. within 5 miliseconds, it reverts back to Sleep(0).
I also only call the QueryPerformanceFrequency() function once and store its result in a member variable.
Serial Communications
What an absolute pig serial communications are in Win32! Just when you think you know what you're
doing.... something doesn't work and you spend days scratching your head wondering why a seemingly
simple procedure doesn't work.
You need a Device Control Structure (DCB) to set up the COM ports. This is what you require:
dcb.BaudRate = DWORD(eBaudrate);
dcb.ByteSize = BYTE(eDataBits);
dcb.Parity = BYTE(eParity);
dcb.StopBits = BYTE(eStopBits);
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
dcb.fDsrSensitivity = FALSE;
dcb.fNull = FALSE;
dcb.fAbortOnError = FALSE;
dcb.fOutxCtsFlow = false; // Disable CTS monitoring
dcb.fOutxDsrFlow = false; // Disable DSR monitoring
dcb.fDtrControl = DTR_CONTROL_ENABLE; // Enable DTR control (for self-powered interfaces)
dcb.fOutX = false; // Disable XON/XOFF for transmission
dcb.fInX = false; // Disable XON/XOFF for receiving
dcb.fRtsControl = RTS_CONTROL_ENABLE; // Enable RTS to go high
You'll also need to set-up some overlapped structures.... don't even contemplate trying to understand and
code from scratch. There are a few serial classes out there in the wild that can be downloaded. I used
Ramon's class http://home.ict.nl/~ramklein/Projects/Serial.html which I found out that I needed to make a
few modifications to.
Next, because we're message based, we need a message handler to react to any characters entering the
http://www.andywhittaker.com/ecu/obdii_software.htm (5 of 8)4/21/2005 3:55:13 AM
 
Zgłoś jeśli naruszono regulamin