I2c row / collumn dot matrix display controller PCF8578/9

Hy, I would like to control dot matrix display on BMW e39 business radio (Becker BE 3350), that uses 1 PCF8579 and 2 PCF8578 row /column drivers.


I want to add usb playback to the radio. I sorted out ibus interface with arduino, but I cannot send messages to lcd via ibus.


On the frontplate I had traced i2c wires, i2c scanner finds adress of PCF8578 (0x3c), PCF8579s are controlled with PCF8578.

Now that I know I have connection and adress, I would need a code / library for it. There is nothing online.

I would need to make my own code, I have the datasheet that explains the i2c part, but I don't understand it.


PCF8578 is a row driver and PCF8579s are column drivers. I still need for count rows and columns of display.

I will study it and try to make it work, I would be grateful for any explanation on how to do it.

So if you know anything about it please let me know.

When finished I will post whole project, wiring, schematics, library and code, etc... so others can make this mod within few hours.

What part of it don't you understand? We can't really explain an entire datasheet... Can you reference page and paragraph numbers, with specific questions?

What is your level of embedded software experience? To code this from scratch (since you couldn't find pre-existing code), is an advanced project.

Hy. My ebmedded software experience is hard to describe. I'm a type of guy that will want to make something and will eventualy make it happen with zero experience. I learn as I go. As a kid I started to repair computers. Back in a day I was writing programs in Visual Basic 6, GTA San Andreas multiplayer maps, websites... I made car stereo with android tablet, lock unlock controlled by arduino on key contact, dab, modified launcher.... Diy sound bar controlled with ir remote and bluetooth and android app for it with eq pressets... hardware side is not problem at all I builded lots of sound amplifiers, I also worked as car electrician.
Thats some of the things, it's a long description, hope you get a feel.
I know it's an advanced project, but I want to make it. Soundbar project for example took me 3 months to complete as I learned along, oh man, those were some long nights.

I dont know where to start, if I would have some example I would start modifying it.
I don't know how to form a messages based on what is shown in the datasheet.

What I know is that I need to count rows and columns to know the multiplex rate and define it, that I need to define the ram access mode. I dont know how to form the code to define that and after that I'm lost.

You didn't answer post #2.

I don't know how to form a i2c code. Currenly I'm reading the datasheet and watching some tutorials to get an idea.

In the Arduino system, you use the 'wire' library for I2C. There are examples that come with the IDE.

I am aware of that. My problem is this:

I dont know how to put this together. And then convert those bits into hex.

Those are just bytes, sent consecutively to the device. The device doesn't understand hex. Only binary (bytes).

1 Like

+1. You sound like a self starter, so start yourself looking at some simple I2C examples.

The how to say things over I2C is easy, you will find. All the pesky dets are hidden by the library.

The what to say part is harder. It sounds like you need to know more or tell us more anyway about the display you hacking.


1 Like

This is my problem... to take info from datasheet and convert it into something usefull for wire.write.
I imagine that I need to tell the IC for example "Go to column 30, row 1 and light that pixel up, then go to column 30, row 2 and light this one too", and so on and so on to get stripe shown on lcd.

#include <Wire.h>

byte val = 0;

void setup()

void loop()
  Wire.beginTransmission(0x3c); //adress is 0x3c
  Wire.write(val);             // I dont know what to write here, what format, if I do need to make array or something.... 

  Wire.endTransmission();     // stop 

If I understand correctly I dont need the marked section because wire sends start bit, first byte (the adress) gets send by Wire.beginTransmission and write bit gets send by Wire.write?
Then I write the command byte with wire.write, followed by display data with wire.write.

What do I do with bits A, C and P
A is ack i think and P is equal to Wire.endTransmission?

You are looking way too closely. You no gonna need to worry about ACKs and NAKs and such.

I think if you find an I2C example for something similar, you will see the light, so to speak.

You have the right idea, the data sent will no doubt be like what you describe, specific display dimensions and other beginning setup (hint) commands.

You may find only very low level abilities, like turn on or off a single pixel to a single color. Without reading the data sheet it isn’t clear that the driver chips will give you much more. So anything more sophisticated will be slogging it out at a higher level in the code.

With luck you may be able to use one of several general and comprehensive display libraries. Code for a simple small TFT will show this typically.

Gotta jet, breakfast time here. In the meantime google

 i2c lcd library 8579 8578

and do or don’t add “Arduino”. Poke around a bit, you on a well trod path I think and you will find help or misery (company) and at the very least see a little real I2C in action.



Well this kind of thing is no use

  Domino's General Manager(03821) - 8578 Palm Parkway

but a bit of my own poking around confirms that you will need to know more about the display that the chipset is controlling.

Do you have the display in any original working circuit or device? I ask in anticipation of the need to reverse engineer some things. Vastly preferred woukd be the specs on the display itself ahead of its having been hooked to the control chips.

And the libraries don’t seem, at a glance, to offer direct support even if you had a detailed idea of exactly what the display is. Here it may be necessary or easiest to use an existing library and modify it at the lowest levels to handle the 8578/8578 chipset.

Sounds like a certain kind of what some ppl would call fun. :expressionless:


Hy, thank you for all the info...
I managed to turn all segments on with a set-mode, found out that it uses 1:8 multiplex mode and that PCF8578 is running in row mode (not mixed).
There is no info on lcd or the pcb. It`s a Becker BE3350 radio for BMW e39, Becker is notorious for not releasing any schematics, some of ICs on the board are not even labeled.

Well that's major progress. Dare I say it's all downhill from here? :expressionless:


Sadly no... I dont know what I need to do from there...
I think that I need to define x and y, do I need device select also?
Datasheet says that RAM operations are only possible when 8578 in mixed mode, but I`m running it in row mode...

Do I need to load-X-address and the tell the 8578 to tell to 8579 to specify Y address or something?

After specifying x and y will that pixel lit up or do I need to do something more?

Ok, so it's progress, perhaps just not major.

Now it is crawling through the data sheet(s) time. I think you have an idea of what to look for, but it will be necessary to come to an idea of just how the 8578/9 set works.

More like total mastery than merely an idea. Like I said, fun for a certain type. Big bucks for anyone getting paid to do this kind of work.

I appreciate that there is a dearth of info coming from ppl who know very well exactly how this thing works and could probably hand you some code that would make everything else you do way easier.

I don't know how far the "right to repair" movement would get if it asked that this information be made available...


I think that this is my anwser.

1 Like

I think that I have figured something out, but I dont know how to write / send it....

  Wire.write(0xcd);             // set_mode  -blank

Wire.write(0xE4);             // device select
Wire.write(0X8F);             // load X address
Wire.write(0X70);             // RAM access
Wire.write(0xc4);             // DATA

Set mode works, but I don`t know how to send all other bytes at once. I think that my problem is that Every Wire.write sends the slave address and WRITE bit... I need that only before "device select" after that I only need ACK bit between the bytes...
SLAVE ADDRESS > WRITE BIT> ACK BIT> device select> ACK BIT> load-x-address> ACK BIT> RAM access> ACK BIT>DATA>ACK BIT....

Also I hope that this is the way to do it (light up a pixel). I have subaddresses for both 8579s.