GM OBD-I (OBD1) ALDL Microcontroller LCD Interface \ Scan Tool

Project status: Project Completed
Project first started: February 2007
Project finished: Late April 2007
Project Scope: 2007 Senior Design Engineering Project @ Old Dominion University

GM OBD-I ALDL AVR LCD interface pulling data off a 7730 $8D ECU
GM OBD-I ALDL Atmel AVR LCD interface pulling data off a 7730 $8D ECU

1. Project Overview

1.1 Heads-up:

This project was done for my 2007 Senor design project class in college.  I have copied and pasted a lot of the description out of the project formal report.  Much of this information was written in a formal technical writing manor,  I have since gone back and added some for more in-depth information others might find useful who have more background knowledge on GM engine control systems then my professor who read the report at the time.  That is also why you will see two distinct writing styles, the more formal style used in the report and my more laid back personal how-to style of the added information sections.

1.2 Abstract:

A microcontroller based automotive computer interface is described. The device utilizes a propriety serial interface to connect to an automotive engine control computer and retrieve current engine conditions. This information is then processed and output to a LCD. The hardware, software, and interface details are described.

1.3 Project Overview:

In this project an interface and display was designed to retrieve automotive diagnostic data from a late 1980’s to early 1990’s General Motors automotive engine control unit / computer known as an ECU. This interface utilizes an Atmel AVR 8-bit microcontroller to perform serial communication over a one wire serial interface with the ECU. This diagnostic data is then processed by the AVR microcontroller and outputted to a LCD in an easy to read format for the user to view.

1.4 Background on Project:

This project will focus on interfacing with an onboard automotive computer using the GM later 8192 baud OBD-I interface. GM started using the 8192 baud OBD-I interface in 1986 and continued using it widely until 1995 when a universal interface and protocol was mandated by SAE (OBD-II). The OBD-I interface on GM cars is a proprietary GM interface.

The ECU chosen for this project is one found is many late 1980’s and early 1990’s GM vehicles and is know by its part number, 1227730 (or 1227727 which is the under hood version). The ECU has a customized version of the Motorola 6811 processor and runs code written in Assembly. The processor runs at 8.388 Mhz’s, has 2 kilobytes of RAM, and a 32 kilobyte UV EPROM for code and calibration data. This code has since been disassembled and commented by auto hobbyists for the general public use. GM has platform dependent code which is vehicle specific and is called code “masks”. The specific code mask a vehicle runs is determined by engine type, transmission configuration, which ECU is used in the vehicle, and other vehicle features. The code mask used in this project is $8d, which is used on the 1990-1992 Pontiac Firebird, 1990-1992 Chevrolet Camaro, and the 1990-1991 Chevrolet Corvette. ECU code along with engine specific data such as fuel maps are hard coded into a removable EPROM chip inside the ECU, which is called the “MemCal”, which stands for Memory Calibration Unit. This made it easy for GM to use the same ECU across different platforms and for technicians to upgrade the calibration in case a problem was found after production.


2. GM OBD-I ECU \ ECM Test Bench

2.1 ECU \ ECM Test Bench Overview:

In order to make this project feasible during software development a method for running the automotive ECU on a bench had to be created. Each critical engine sensor the ECU reads is simulated so the ECU will not go into an error running state. Some sensors are simply variable resistors such as the temperature sensors and throttle position sensors, so these could be simulated with a potentiometer. The ECU outputs a 5 volt reference for all the resistance based sensor circuits. For the temperature sensors and throttle position sensors, potentiometer resistance values were selected based on the resistance range of the original sensor the potentiometer was replacing. Two variable frequency square wave pulse generation circuits had to be designed to simulate the vehicle speed sensor and the engine RPM input. The frequency of each square wave is directly proportional to the speed in MPH and engine revolutions in RPM the ECU reads.

Designing the circuits to simulate the vehicle speed sensor and engine RPM output required more then just a potentiometer. Experimentation was done with using a 555 Timer circuit and using a set capacitance value with a potentiometer in the RC section of the 555 Timer circuit. The result was the inability to produce a wide enough frequency output range and the inability to bring the output down to zero hertz for an off state. So a Voltage Controlled Oscillator (VCO) IC was selected to perform the task. A low cost CMOS 4046 Phase-Locked Loop with VCO IC was selected for the job. The inputs for the phase-locked loop portion of the IC are tied to an inactive state and effectively disabled. On CMOS IC’s it is recommended to tie all inactive inputs low to avoid damage to the IC and to produce reliable results. The VCO portion of the IC was used to achieve the desired square wave output. Since the IC was CMOS and can only output small output currents in the 1-5mA range, the output was run through a TTL 74LS04 inverter which can provide up to 20mA output which is more suitable for the ignition module signal load. An inverter was selected due to easy availability. A TTL buffer or many other chips could be used to achieve the same affect.

ECU Test Bench RPM & MPH Square Wave Generator Circuit Schematic
Figure 1: ECU Test Bench RPM & MPH Square Wave Generator Circuit Schematic

The circuit seen in Figure 1 is the square wave generator circuit. It consists of two variable square wave outputs, one for the RPM input and one for the MPH input on the ECU. The output frequency is determined by the capacitance between pin 6 (Cx) and 7 (Cx), the resistance on pin 11 (R1) and 12 (R2), and the voltage present on pin 9 (VCOin). Before determining the correct values to be placed on these pins the desired frequency range to be inputted into the ECU must first be determined.

The maximum RPM the ECU can read is 6375 RPM’s. This is because the engine RPM is stored in one byte of memory with a multiplier of 25. This results in 255 multiplied by 25 which equals 6375 RPM. The engine the ECU operates is only capable of 6000 RPM’s so this limit is not a problem. Some ECU’s and or code masks can read up to 9000 RPM’s so it was decided to make the RPM generator circuit output a maximum frequency equivalent to 9000 RPM’s for future uses. The distributor which generates the RPM signal for the ECU is connected to a camshaft which rotates at half the speed of the engine output crankshaft. The distributor outputs one pulse per cylinder fired. So the distributor is outputting 4 pulses per engine rotation on a V8 engine. The maximum frequency desired for the circuit to produce is calculated below:

ECU Test Bench calculate RPM Frequency150 Rotation per seconds x 4 pulses per revolution = 600Hz

The maximum speed the ECU can read is 255 MPH since it the speed variable is stored in one byte of memory. The vehicle speed sensor outputs 2000 pulses per minute at a speed of one mile per minute. A speed of one mile per minute is 60 miles per hour (MPH). So the pulse per second (Hz) at 60 miles per house is 2000 divided by 60 which equals 33.3 Hz. Using this ratio it can be determined that a pulse of 141.6 Hz is needed to max out the ECU’s MPH reading of 255 MPH. Of course this speed would never be achieved in real life but for testing purposes the full range of the ECU is utilized. It was chosen to round up the MPH pulse to a max of 150Hz for simplicity.

To calculate what resistor and capacitor values were needed to achieve these desired frequencies a bench testing of the circuit method was used. The circuit was built on a bread board and an oscilloscope was used to measure the output frequency. The starting test values where chosen from the 4046 datasheets graphs and final values where chosen after tweaking the values to produce frequency results of the above calculations.

ECU Test Bench VCO MPH & RPM Squarewave Generation Circuit
Figure 2: VCO MPH & RPM Squarewave Generation Circuit
ECU Test Bench
Figure 3: ECU Test Bench



3. GM OBD-I ALDL LCD Microcontroller Interface

3.1 Proprietary General Motors Assembly Line Diagnostic Link (ALDL):

GM used its own proprietary communication method for communicating with its ECU’s. Each GM OBD-I automobile has a connector that is called the Assembly Line Diagnostic Link (ALDL) connector seen in Figure 4 which is wired to the ECU. Mechanics can plug their shop diagnostic computer into this connector to communicate with the onboard ECU and retrieve engine sensor data and ECU error codes. During the period of the proprietary GM OBD-I standard; GM used two interfaces, the first of which was a 160 baud interface which was later replaced by an 8192 baud interface. The 8192 baud interface will be utilized in this project. The term interface refers to the communication as a whole including communication hardware, the physical communication method / protocol, and the software protocol. The protocol is the set of standards that must be followed when designing the hardware and software to communicate with the ECU properly and reliably.

GM OBD-I ALDL Connector
Figure 4: GM OBD-I ALDL connector

The GM 160 baud OBD-I ALDL interface was the first of two GM OBD-I interfaces and uses synchronous serial communication utilizing one data line. This interface and data protocol does not allow for two way commutation with the ECU. The ECU constantly outputs diagnostic data at a rate of 160 baud over one wire on pin A of the ALDL connector. The receiver must be synced to receive at 160 baud in order to correctly receive the data bits at the “Sample Point” in Figure 5. Each data bit is synced with a falling start edge on the wave form before the data bit is sent. The drawbacks of this interface are the slow data speed and the inability for the diagnostic machine to send data to the ECU.

GM OBD-I ALDL 160-Baud protocol
Figure 5: GM OBD-I ALDL 160-Baud protocol (7)

The GM 8192 baud OBD-I ALDL interface was the second and last of the two OBD-I interfaces. The 8192 baud interface communicates over pin M of the ALDL connector. The 8192 baud interface is more complex, faster, allows for more control of diagnostic data, and more diagnostic data to be retrieved from the ECU. The 8192 baud interface only uses one wire like the 160 baud interface but uses an asynchronous serial communication method and allows for two way communications over a single data line. The 8192 baud interface protocol is also a master/slave protocol and allows for multiple devices internal and external to the automobile to be connected to it. The ECUs that implement a 8192 baud interface do not constantly output data like the 160 baud interface; instead the attached device must send a short message requesting data from the ECU and the ECU will respond with a 60+ byte burst of data depending on the model of automobile, ECU, and code mask running on the ECU.

The 8192 baud ALDL interface uses an asynchronous serial communication method as a means to transfer data over the data line. The 8192 baud interface also has a predetermined software communication procedure which can be considered the 8192 baud protocol. The 8192 baud interface uses asynchronous serial communication to perform the physical task of transmitting and receiving data. Asynchronous serial communication uses a start signal prior to each byte and a stop signal after each byte of data sent. This is the same method a serial RS-232 port on a computer uses with the difference that a RS-232 port has a separate transmit and receive line. In asynchronous serial communication the number of bits to be transmitted between start and stop bits, number of stop bits, parity options, and baud rate must be defined prior to any communication. The 8192 baud ALDL interface uses eight bits with one stop bit and no parity as seen in the timing diagram of Figure 6 below. The 8192 baud protocol uses an off standard baud rate of 8192 samples per second as the name implies. The closest standardized baud rate is 9600, this requires more effort in the hardware and software design to accommodate this off standard baud rate which is discussed later in this document.

RS232 Asynchronous Serial Communication
Figure 6: RS232 Asynchronous Serial Communication (1)

The data line is held high when inactive (idle). The transmission device pulls the data line low before transmitting data to trigger the receiving device to start sampling the data. The receiving device starts sampling the data line at the preset sample (baud) rate until it detects the stop bit. The connection is then resynchronized at the next start bit.

The ECU has six documented interface modes; each mode has a different command set, performs a different operation on the ECU, and receives different responses from the ECU. The six modes are mode 0, mode 1, mode 2, mode 3, mode 4, and mode 10. The function of these modes is discussed in detail later in this document. The modes are triggered by sending the ECU a specific command set.

For reference, refer to Appendix A for the list of commands each ECU mode is activated by. The most basic command set will include in this order: a message ID byte, message length byte, mode byte, and a checksum byte. The more complex commands will have other data bytes transmitted after the mode byte and before the checksum byte. The first command in the command set is the message ID byte which lets the ECU know what category of command it is receiving. Since all the commands listed above and in Appendix A are diagnostic commands they all have the same message ID byte of 0xF4. The next command in the command set is the message length byte. The most basic command set has a base message length byte of 0x56 and any other commands or data transmitted increments the message length number per extra byte transmitted. The mode byte is simply the desired ECU operation mode number. Other data bytes must be transmitted in the more complex data modes which are: mode 2, mode 3, and mode 4. The last byte to be transmitted is the checksum byte. The checksum byte is the one’s complement of the sum of all bytes transmitted.

Mode 0 is used by diagnostic equipment attached to the ALDL port to stop any communication on the data line. This would include in-car systems such as a body (suspension) computer and dash board modules which retrieve data from the ECU constantly over the diagnostic line. This communication must be stopped for the diagnostic equipment to accesses data from the ECU at full speed and constantly.

Mode 1 is used to retrieve all diagnostic data from the ECU. This operation mode is used in the field by test equipment; it is also used in this project. In this mode the diagnostic equipment or device will send the mode 1 commands over the data line and the ECU will reply with 64 bytes of diagnostic data. The bytes of data returned is dependent on the ECU and the code mask General Motors is running on the ECU, but the ECU chosen in this project returns 64 bytes of diagnostic data.

Mode 2 is used to dump 60 bytes of memory from the ECU to the ALDL data line starting with a user or device defined address. This is used mainly for debugging purposes and has little or no use for the average mechanic or technician. The most significant byte (MSB) of the desired memory start address and least significant byte (LSB) is transmitted after the mode 2 byte to tell the ECU which address to start the memory dump at. The ECU will then reply with the mode 2 command set and the desired 60 bytes of data.

Mode 3 will perform a dump of any eight defined addresses. The eight desired addresses are transmitted after the mode 3 command. These addresses are transmitted with the most significant byte first followed by the least significant byte. The ECU will then reply with the mode 3 command set and the desired 8 bytes of data. These addresses can be any addresses in the whole system including registers, RAM, and ROM. Mode 3 is also used in debugging and had little or no use for the average mechanic or technician.

Mode 4 is a controller mode where the user may change engine fuel, spark, and other engine parameters. This is a partially implemented feature and does not work on the production code mask used in this project. For this reason little is known how to operate this mode or how this mode is supposed to be commanded. It seems to be a GM development feature that was deactivated on the production code to avoid engine damage by untrained users.

Mode 10 is used to clear any trouble codes the ECU has stored. A trouble code is a code stored in the ECU memory when it detects a fault or error in any of its sensor readings. This is commonly seen by the end user as a “service engine soon” light on the dash board. The ECU code mask used in the project has 64 trouble codes stored in 8 bytes, each bit representing a trouble code. After a mechanic or technician has retrieved these codes from the ALDL diagnostic port and repaired the problem the mode 10 command set can be transmitted to the ECU to clear stored trouble codes. This task can also be accomplished by removing battery power to the ECU.

3.2 Circuit Design:

An Atmel Mega324P AVR microcontroller was selected in this project to communicate and process the ECU data. This data is then output to a Hitachi 44780 controller based 4×20 LCD. The details of the AVR microcontroller and why it was chosen over similar microcontrollers, like a Microchip PIC microcontroller, is discussed below because is it outside the scope of this section. The Mega324P AVR is the most powerful AVR in a 40 pin DIP package, in production at the time of this report.
The Universal Asynchronous Receiver/Transmitter (UART) built into the Mega324P is designed to work with serial communication methods that use separate transmit and receive data lines such as SCI and SPI. The Mega324P, as with most microprocessors, is not designed to work with the off standard one wire interface used in this project. An interface circuit is needed to convert the one ALDL serial line to two data lines: a transmit line and a receive line.

One design issue with the microcontroller UART is that the transmit pin on the microcontroller is held high when inactive.  Holding the serial line high when inactive is extremely common and used in many serial communication methods. If the transmit pin of the microprocessor was connected directly to the ECU serial line it would be held high when the ECU was trying to bring the line low for communication. A transistor is used on pin PD1 of the microcontroller, as seen in Figure 7, to isolate the transmit line. The ALDL serial line is held high by the ECU, the PNP transistor only brings the serial data line low when the transmit pin on the microcontroller is brought low.

GM ALDL UART 1-wire ALDL AVR UART Interface Circuit
Figure 7: 1-wire ALDL AVR UART Interface Circuit

In order to prevent the receive UART from being filled with data that is being transmitted from the AVR microcontroller a transistor is use to isolate the receive line. The microcontroller sets pin PD5 high when transmitting so the receive UART on pin PD0 does not see the data being transmitted. When the microcontroller brings pin PD5 low the transistor is able to pull the receive UART pin, PD0, low when the ALDL line is low. An ALDL serial activity LED was added for debugging purposes. The LED comes on when the ALDL serial line is pulled low and remains off when there is no activity on the line, since the inactive state of a serial line is high.

To accommodate for the off standard baud rate of 8192 a crystal oscillator of 19.6608 Mhz was selected. At this clock rate the divider in the UART baud rate register, defined as UBRR, works out to zero percent error. As seen in the equation below an exact baud rate of 8192 is achieved with a UBRR register setting of 149 and a crystal oscillator of 19.6608 Mhz.

GM ALDL Microcontroller BaudRate CalcualtionAccording to the microcontroller data sheet a percentage of error up to two percent is acceptable in most situations but in this project unnecessary error was eliminated for completeness and to reduce potential problems.

3.3 Complete Schematic:

Check appendix D of my senior final report for a rough schematic without proper bypass caps, etc

3.4 Firmware:

The code for this project was written in C and compiled with a free open source compiler named WinAVR. WinAVR is a part of AVR studio, Atmel’s development software.

The entire code for this project can be download below. The code is split up into a few functions to perform specific tasks. There are four main tasks accomplished by the code. The first is to initialize the command registers of the microcontroller and initialize the LCD. Secondly the car and diagnostic data is retrieved from the ECU and stored in the AVR’s memory. Third the stored car data is processed and calculations are made to convert the raw values to the real world units the sensors are reading. Fourth the processed data is outputted to the LCD. The second through the fourth task are looped continually so the LCD will always have the most up to date information from the ECU.

The initialization process of the code is used to configure the microprocessor and the LCD before use. The I/O ports of the microcontroller are configured for their proper function either input or output. The UART is configured for the proper baud rate, bit size, and number of stop bits. The 8-bit operation mode command is transmitted to the LCD along with commands to reset the display and place the cursor at the being of the display.

The second main task of the code operation is retrieving car and diagnostic data from the ECU which is comprised of a few functions. The first thing the code must do in this task is send out the ALDL mode 1 command set to the ECU which commands the ECU to return a dump of the diagnostic data. This data is then stored one byte at a time in an array to be used at a later. Timeout detection is also built into the receive routine so if a transmission error occurs the code will timeout instead of getting hung up in the receive loop.

The third main task of the code operation is to process the stored diagnostic data from the previous task. The diagnostic data received from the ECU is in a raw, unprocessed format, and must be processed to produce data that makes sense to the end user. The data has set dividers and multipliers that must be performed to the raw values to produce the real world value the sensor is truly reading. These values are then converted to ASCII for output to the LCD.

The forth and final step is to output the processed ASCII data to the LCD. This includes putting headings in front of values so the users can identify what value they are reading. The data outputted to the user are: engine RPM, vehicle MPH, fuel block value know as BLM, coolant temperature (CTS), intake manifold air pressure (MAP), throttle position percent (TPS), battery voltage, and ECU trouble codes.

C Source code & WinAVR make file: GM OBD-I ALDL uC Interface Sourcecode


4. College Senior Project Final Report

If you want take a look of my full 2007 Senior class project report you can download the PDF below.  It goes into more detail on some background information about GM ECU’s etc so the professor who was grading my project can understand the context better.  Since making this report I have worked in the industry and have learned a great deal on how I could improve the circuit design, etc.  I have updated a few of these things in this web project report from time to time.

Senior final design project formal report: Senior Project 2007 Automotive Diagnostic LCD Interface



$8d 8192 Baud Asynchronous Communications Data Stream Modes
$8d ECU Diagnostic Data Stream Returned in Mode 1

References \ Sources:

1) Asynchronous serial communication. (n.d.). Wikipedia. Retrieved March 24, 2007, from
2) Atmel AVR. (n.d.). Wikipedia. Retrieved February 25, 2007, from
3) AVR 8-Bit RISC. (n.d.). Atmel. Retrieved February 25, 2007, from
4) Barnett, R., O’Cull, L., & Cox, S. (2007). Embedded C Programming and the Atmel AVR (2nd ed.). Clifton Park, NY: Thomson Delmar Learning.
5) Error Codes from Service Engine Light. (n.d.). Retrieved April 14, 2007, from
6) Gadre, D. V. (2001). Programming and Customizing the AVR Microcontroller. New York, NY: McGraw-Hill.
7) GM Diagnostics. (n.d.). ECM Guy. Retrieved March 10, 2007, from
8) Mitchell. (2006). Automotive Shop Manuals. Mitchell.
9) Morton, J. (2002). AVR an Introductory Course. Woburn, MA: Newnes.
10) On-Board Diagnostics. (n.d.). Wikipedia. Retrieved March 10, 2007, from
11) Pardue, J. (2005). C Programming for Microcontrollers. Knoxville, TN: Smiley Micros.
12) Win AVR Compiler. (n.d.). Retrieved February 25, 2007, from

Page content created on: Spring 2007
Page content last updated: September 2009

6 thoughts on “GM OBD-I (OBD1) ALDL Microcontroller LCD Interface \ Scan Tool”

  1. My atmel 8515 to PC didn’t work until i added your 3 transistor interface.
    That stoped the echo, and the 8515 hit the 8192 baud at divisor clk set to 30.
    No framing or Overrun Errors were generated.
    Changed baud back to 9600 to RS232 back to PC (WinXP)

  2. Thanks God there are people who share knowledge. How else could we learn? I hop I get the error code out of my clients Airstream with OBD1.

Leave a Reply

Luke's past and current projects…

%d bloggers like this: