January 23, 2026

Capitalizations Index – B ∞/21M

Reading a VGA monitor’s configuration data with I2C and a PocketBeagle

Ken Shirriff’s blog
Reading a VGA monitor’s configuration data with I2C and a PocketBeagle

pre {border:none;background-color:#eee;min-width:40em;padding:4px;display:inline-block;font-size:80%;line-height:120%;}
code {background-color:#eee;}

Have you ever wondered how your computer knows all the characteristics of your monitor—
the supported resolutions, the model, and even the serial number?
Most monitors use a system called DDC to communicate this information to the computer.1 This information is transmitted using the I2C communication protocol—a protocol also popular for connecting hobbyist devices. In this post, I look inside a VGA monitor cable, use a tiny PocketBeagle (a single-board computer in the BeagleBone family) to read the I2C data from an LCD monitor, and then analyze this data.

Inside a vga cable. The cable is more complex than i expected, with multiple layers of shields. The green, red, white (sync) and blue wires are thicker and have their own shielding.

Inside a VGA cable. The cable is more complex than I expected, with multiple layers of shields. The green, red, white (sync) and blue wires are thicker and have their own shielding.

To connect to the monitor, I cut a VGA cable in half and figured out which wire goes to which pin.3
The wire (above) is constructed in an interesting way, more complicated than I expected. The red, green, blue and horizontal sync signals are transmitted over
coaxial-like cables formed by wrapping a wire a spiral of thin copper wires for shielding.2
The remaining signals travel over thinner plain wires. Several strands of string form the structural center of the VGA cable,
and the ten internal wires are wrapped in a foil shield and woven outer shield.

The vga connector consists of 3 rows of 5 pins. Pins are simply numbered left-to-right with 1 through 5 in the first row, 6-10 in the second, and 11-15 in the third. (click image for a closeup. )

The VGA connector consists of 3 rows of 5 pins.
Pins are simply numbered left-to-right with 1 through 5 in the first row, 6-10 in the second, and 11-15 in the third.
(Click image for a closeup.)

The photo above shows the male VGA connector on each end of the cable.
The function assigned to each pin is shown in the table below. The I2C clock (SCL) and data (SDA) are the important pins for this project.
The wire colors are not standardized; they refer to my VGA cable and may be different for a different cable.

table#vga {border-collapse: collapse;font-size: 90%;}
table#vga th {text-align: center; border-bottom: 1px solid #333}
table#vga td {text-align: center; padding: 0 8px;}
table#vga tr.ul {border-bottom: 1px solid #888;}

PinFunctionWire color
1 Red Red coax
2 Green Green coax
3 Blue Blue coax
4 Reserved Shield
5 Ground Black
6 Red Ground Shield
7 Green Ground Shield
8 Blue Ground Shield
9 5V Yellow
10 Ground White
11 Reserved Shield
12 SDA Green
13 HSync White coax
14 VSync Brown
15 SCL Red

The 5 volt wire in the cable has a clever purpose.
This wire allows the computer to power the EEPROM chip that provides the configuration data.
Thus, the computer can query the display’s characteristics even if the display is turned off or even unplugged from the wall.

Reading the configuration data

To read the data over I2C,
I used the PocketBeagle, a tiny Linux computer that
I had handy.
(You could use a different system that supports I2C, such as the Raspberry Pi,
Beaglebone
or Arduino.)
I simply connected the I2C clock (SCL), data (SDA) and ground wires from the VGA cable to the PocketBeagle’s I2C pins as shown below.

Connecting a vga cable to the pocketbeagle allows the configuration data to be read over i2c. The black wire is ground, the green wire is i2c data (sda) and the red wire is i2c clock (scl).

Connecting a VGA cable to the PocketBeagle allows the configuration data to be read over I2C. The black wire is ground, the green wire is I2C data (SDA) and the red wire is I2C clock (SCL).

Simple Linux commands let me access I2C.
First, I probed the I2C bus to see what devices were present, using the i2cdetect command.
(Many devices can be connected to an I2C bus, each assigned a different address.)
The output below shows that devices 30, 37, 4a, 4b and 50 responded on I2C bus 1.
Device 50 is the relevant I2C device, assigned to the configuration information. Device 37 is DDC/CI, allowing monitor settings to be controlled by the computer, but I’ll ignore it for this post. Devices 30, 4a, and 4b are a mystery to me so leave a comment if you know what they are.

$ i2cdetect -y -r 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — — — — — — — — — — — — —
10: — — — — — — — — — — — — — — — —
20: — — — — — — — — — — — — — — — —
30: 30 — — — — — — 37 — — — — — — — —
40: — — — — — — — — — — 4a 4b — — — —
50: 50 — — — — — — — — — — — — — — —
60: — — — — — — — — — — — — — — — —
70: — — — — — — — —

Next, I used the i2cdump command to read 128 bytes from device 50’s registers, providing the raw VGA information.
The hex values are on the left and ASCII is on the right.

$ i2cdump -y -r 0-127 1 0x50 b
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 00 ff ff ff ff ff ff 00 04 69 fa 22 01 01 01 01 ……..?i?”????
10: 12 19 01 03 1e 30 1b 78 ea 3d 25 a3 59 51 a0 25 ?????0?x?=%?YQ?%
20: 0f 50 54 bf ef 00 71 4f 81 80 81 40 95 00 a9 40 ?PT??.qO???@?.?@
30: b3 00 d1 c0 01 01 02 3a 80 18 71 38 2d 40 58 2c ?.?????:??q8-@X,
40: 45 00 dd 0c 11 00 00 1e 00 00 00 fd 00 32 4c 1e E.???..?…?.2L?
50: 53 11 00 0a 20 20 20 20 20 20 00 00 00 fc 00 56 S?.? …?.V
60: 45 32 32 38 0a 20 20 20 20 20 20 20 00 00 00 ff E228? ….
70: 00 46 34 4c 4d 51 53 31 32 38 35 34 36 0a 00 bb .F4LMQS128546?.?

Understanding the monitor’s EDID data

The configuration data is encoded in the EDID (Extended Display Identification Data) format, so it’s not immediately obvious what the data means.
But the format is well-documented, so it’s not too hard to figure out.
For instance, the first 8 bytes 00 ff ff ff ff ff ff 00 are the header.
The next two bytes 04 69 encode three 5-bit characters for the manufacturer ID, in this case “ACI” – Asus Computer International.
(The data format uses a lot of annoying bit manipulations like these to make the data compact.)
Near the end of the output, the ASCII strings “VE228” and “F4LMQS128546” are clearly visible; these are the monitor’s model number and serial number.

I made a simple Python program to decode the data, giving the following results:

Header:
Manufacturer: ACI
Product code: 8954
Week: 18
Year: 2008
Edid version 1, revision 3
Analog input
Levels: +0.7/-.03
Blank-to-black setup (pedestal) expected
Separate sync supported
Composite sync supported
Sync on green supported
Horizontal screen size: 48cm
Vertical screen size: 27cm
Display gamma: 2.200
DPMS standby supported
DPMS suspend supported
DPMS active-off supported
Display type (analog): RGB color
Preferred timing mode in descriptor block 1
Chromaticity coordinates: r: (0.637, 0.351), g: (0.319, 0.626), b: (0.145, 0.061), w: (0.313, 0.329)
Established timings:
720×400 @ 70 Hz
640×480 @ 60 Hz
640×480 @ 67 Hz
640×480 @ 72 Hz
640×480 @ 75 Hz
800×600 @ 56 Hz
800×600 @ 60 Hz
800×600 @ 72 Hz
800×600 @ 75 Hz
832×624 @ 75 Hz
1024×768 @ 60 Hz
1024×768 @ 72 Hz
1024×768 @ 75 Hz
1280×1024 @ 75 Hz
Standard timing information:
X res: 1152, aspect 4:3, Y res (derived): 864), vertical frequency: 75
X res: 1280, aspect 5:4, Y res (derived): 1024), vertical frequency: 60
X res: 1280, aspect 4:3, Y res (derived): 960), vertical frequency: 60
X res: 1440, aspect 16:10, Y res (derived): 900), vertical frequency: 60
X res: 1600, aspect 4:3, Y res (derived): 1200), vertical frequency: 60
X res: 1680, aspect 16:10, Y res (derived): 1050), vertical frequency: 60
X res: 1920, aspect 16:9, Y res (derived): 1080), vertical frequency: 60
Descriptor 1: Detailed timing descriptor:
Pixel clock: 148500kHz
Horizontal active pixels: 1920
Horizontal blanking pixels: 280
Vertical active lines: 1080
Vertical blanking lines: 45
Horizontal front porch pixels: 88
Horizontal sync pulse pixels: 44
Vertical front porch lines: 4
Vertical sync pulse lines: 5
Horizontal image size: 477mm
Vertical image size: 268mm
Horizontal border pixels: 0
Vertical border lines: 0
Digital separate sync
VSync serration
Positive horizontal sync polarity
Descriptor 2: Display range limits
Minimum vertical field rate 50Hz
Maximum vertical field rate 76Hz
Minimum horizontal field rate 30Hz
Maximum horizontal field rate 83Hz
Maximum pixel clock rate: 170Mhz
Default GTF
Descriptor 3: Display name VE228
Descriptor 4: Display serial number F4LMQS128546

As you can see, the EDID format crams a lot of configuration information into 128 bytes.
The output starts off with some basic data about the monitor’s characteristics and inputs.
The VGA standard doesn’t nail down as many things as you’d hope. For instance the sync signals can be provided on one wire (separate), two wires (composite), or on the green wire.
The output above shows my monitor supports all three sync types.

The monitor then provides a long list of supported resolutions, which is how your computer knows what the monitor supports.
The “detailed timing descriptor” provides more information on signal voltage levels and timings.
The timing of VGA signals contains some strange features (e.g. blanking and “front porch”) inherited from
obsolete CRT (Cathode Ray Tube) displays.
The values in the configuration provide the information necessary for the computer’s graphics board to synthesize a proper VGA signal that the monitor can understand.

The CIE chromaticity coordinates provided by the monitor are interesting, but need a bit of background to understand.
A CIE chromaticity diagram (below), shows all the colors in the real world.
(Brightness is factored out, so grays and browns don’t appear.)
Individual wavelengths of light (i.e. the spectrum) curve around the outside of the diagram.
The colors inside the curve are combinations of the pure spectral colors, with white in the middle.

Cie diagram showing the color gamut and white point of my monitor.

CIE diagram showing the color gamut and white point of my monitor.

A display, however, generates its colors by combining red, green, and blue. The result is that a display can only show the colors inside the triangle above with red, green, and blue at the corners.
A display doesn’t generate the light wavelengths necessary to display colors outside the triangle.
Like most monitors, this monitor can only show a surprisingly small fraction of the possible colors.
(A wide-gamut display uses different phosphors to expand the triangle and get more vivid colors.)
The triangle vertices and white point4 in the diagram above come from the x,y chromaticity coordinates in the configuration data.

You might wonder how you can see the whole CIE diagram on your display if only the colors inside the triangle can be displayed.
The answer is the diagram “cheats”—the colors are scaled to fit into RGB values, so you’re not seeing the exact colors but just an approximate representation.
If you look at the spectrum through a prism, for instance, the colors will be more intense than what you see in the CIE diagram.

Inside I2C

The I2C protocol (Inter-Integrated Circuit) was invented in 1982 by Philips Semiconductor to connect a CPU to peripheral chips inside televisions.
It’s now a popular protocol for many purposes, including connecting sensors, small LED displays, and other devices to microcontrollers.
Many I2C products are available from Adafruit and Sparkfun for instance.

The I2C protocol provides a simple, medium-speed way to connect multiple devices on a bus using just two wires—one for a clock and one for data.
I2C is a serial protocol, but it differs from serial protocols like RS-232 in a couple ways.
First, I2C is synchronous (using a clock), unlike RS-232 which is asynchronous (no clock).
Second, I2C is a bus and can connect dozens of devices, while RS-232 connects two devices.5

The oscilloscope trace below shows what an I2C communication with the monitor looks like on the wire.
The top line (cyan) shows the clock. Note that the clock only runs while data is transmitted.) The yellow line is the binary data. At the bottom, the oscilloscope decoded the data (green).
In this trace, register number 0x26 is being read from device 0x50.
The I2C protocol is rather peculiar since a read is performed by doing a write followed by a read.
That is, to read a byte, the master first does a write to the device of the desired register number: the master first sends 0x50 (the device ID) the write flag bit (indicated with “W:50”), and 0x26 (the register number, ASCII “&”).
Then, the master does a read; it sends 0x50 and the read flag bit (“R:50”). The device responds with the value in the register, 0x71 (ASCII “q”).6

I2c trace: clock (scl) in cyan and data (sda) in yellow. Green shows decoded data. Oscilloscope was set to 20µs/division and 2v/division.

I2C trace: clock (SCL) in cyan and data (SDA) in yellow. Green shows decoded data. Oscilloscope was set to 20µs/division and 2V/division.

Devices on the I2C bus can only pull a line low; pull-up resistors keeps the lines high by default.7
As a result, the traces above drop low sharply, but climb back up slowly.8
Even though the transitions look sloppy, the I2C bus worked fine.
I couldn’t find a source to tell me if VGA monitors included pull-up resistors, or if I needed to add them externally.
However, I measured voltage on the lines coming from the monitor and everything worked without external resistors, so there must be pull-up resistors inside the monitor.

Conclusion

The VGA specification includes a data link that allows a computer to learn about a monitor and configure it appropriately.
It is straightforward to read this configuration data using the I2C protocol and a board with an I2C port.
While VGA is mostly obsolete now, the same data protocol is used with DVI and HDMI displays.
My goal in reading the monitor’s config data was so I could use the timing data in an FPGA to generate a VGA video signal.
(That project is yet to come.)
Follow me on Twitter
or RSS
to find out about my latest blog posts.

Notes and references

DDC (Display Data Channel) is used by VGA, DVI and HDMI connections, which transmit the data over two I2C pins.
The data it sends is in the EDID (Extended Display Identification Data) format.
Everything changed with the DisplayPort interface. It transmits configuration data over a differential AUX channel using the DisplayID format, which extends EDID to supports newer features such as 3D displays. Thus, the techniques I describe in this article should work with DVI or HTMI interfaces, but won’t work with DisplayPort. 

Looking at other VGA cables on the web, most VGA cables don’t have the fourth coax for horizontal sync that my cable does. So my cable seems a bit unusual. 

Instead of cutting a VGA cable in half, I could have simply plugged a cable into a VGA connector, but that’s less interesting. 

The white point for my monitor matches a standard called D65

For more information on I2C, good explanations are on SparkFun and Wikipedia

I’m leaving out some of the complications of I2C. For example, the master generates the clock, but the device can do “clock stretching” by holding the clock low until it is ready. Also, the device sends an ACK bit after each request.
The device address is 7 bits, while the data is 8 bits.
See protocol documentation for details. 

Using a pull-up resistor on the I2C bus avoids the risk of short circuits. If, alternatively, devices could actively pull the line high, it would be a problem if one device tried to pull a line high at the same time another pulled it low. 

The oscilloscope traces show exponential R-C charging curves when the line is pulled high. This is due to the wire capacitance being charged through the pull-up resistor. The signals only reach about 3V, making them suitable for the PocketBeagle’s 3.3V inputs. (If you try this with a different monitor, check the voltage levels to avoid damaging the PocketBeagle’s inputs.) 

BTC-ECHO
Fujitsu öffnet blockchain-innovationszentrum in belgien

Fujitsu öffnet Blockchain-Innovationszentrum in Belgien
Reading a vga monitor's configuration data with i2c and a pocketbeagle
Reading a vga monitor's configuration data with i2c and a pocketbeagleFujitsu hat die Errichtung eines eigenen Zentrums für Blockchain-Innovationen angekündigt. In Gemeinschaftsprojekten will der japanische Technologiekonzern hier an potenziellen Anwendungen der Technologie forschen. Ein Fokus wird auf Smart Cities liegen. In einer Pressemitteilung hat Fujitsu bekannt gegeben, dass der Großkonzern seine Forschung an der Blockchain-Technologie in einem speziell eingerichteten „Internationalen Blockchain Innovationszentrum“ weiterführen wird. In…
 
Source: BTC-ECHO

Der Beitrag Fujitsu öffnet Blockchain-Innovationszentrum in Belgien erschien zuerst auf BTC-ECHO.

Reading a vga monitor's configuration data with i2c and a pocketbeagle Reading a vga monitor's configuration data with i2c and a pocketbeagle Reading a vga monitor's configuration data with i2c and a pocketbeagle Reading a vga monitor's configuration data with i2c and a pocketbeagle Reading a vga monitor's configuration data with i2c and a pocketbeagle Reading a vga monitor's configuration data with i2c and a pocketbeagle Reading a vga monitor's configuration data with i2c and a pocketbeagle Reading a vga monitor's configuration data with i2c and a pocketbeagle Reading a vga monitor's configuration data with i2c and a pocketbeagle Reading a vga monitor's configuration data with i2c and a pocketbeagle

Previous Article

Going to War: Monero Sticks to Anti-ASIC Guns with Emergency Software Update

Next Article

Wall Street Analyst Lowers Price Targets Of AMD, Nvidia Shares In Reaction To Bitmain Competition

You might be interested in …