Lutz S. schrieb:
Sind die weitgehend kompatibel
Weitgehend, aber ganz ohne Codeänderung wird es nicht gehen. Beide Controller kann man gleich initialisieren, aber die Datenübertragung ins Display-RAM geht etwas anders.
Ich zeige dir das relevante Fragment aus meinem Arduino Code. Ich habe Feedback erhalten, dass er mit SH1106 funktioniert, selbst aber nur mit SSD1306 getestet.
1 |
void OLED::display()
|
2 |
{
|
3 |
size_t index = 0;
|
4 |
for (uint_fast8_t page = 0; page < pages; page++)
|
5 |
{
|
6 |
// Set memory address to fill
|
7 |
i2c.beginTransmission(i2c_address);
|
8 |
i2c.write(0x00); // command
|
9 |
if (isSH1106)
|
10 |
{
|
11 |
i2c.write(0xB0 + page); // set page
|
12 |
i2c.write(0x00); // lower columns address =0 // Some displays might need 0x02 here
|
13 |
i2c.write(0x10); // upper columns address =0
|
14 |
}
|
15 |
else
|
16 |
{
|
17 |
i2c.write(0xB0 + page); // set page
|
18 |
i2c.write(0x21); // column address
|
19 |
i2c.write(0x00); // first column =0
|
20 |
i2c.write(width - 1); // last column
|
21 |
}
|
22 |
i2c.endTransmission();
|
23 |
|
24 |
// send one page of buffer to the display
|
25 |
i2c.beginTransmission(i2c_address);
|
26 |
i2c.write(0x40); // data
|
27 |
for (uint_fast8_t column = 0; column < width; column++)
|
28 |
{
|
29 |
// Split the transaction into chunks of 32 bytes because that is a limitation of Arduino
|
30 |
if (column>0 && (column % 31 == 0) )
|
31 |
{
|
32 |
i2c.endTransmission();
|
33 |
i2c.beginTransmission(i2c_address);
|
34 |
i2c.write(0x40); // data
|
35 |
}
|
36 |
|
37 |
i2c.write(buffer[index++]);
|
38 |
}
|
39 |
i2c.endTransmission();
|
40 |
yield(); // to avoid that the watchdog triggers
|
41 |
}
|
42 |
}
|
Der Buffer wird hier verwendet, um das ganze Bild im RAM aufzubauen und es danach mit der oben gezeigten Funktion an das Display zu senden. Die Struktur entspricht dem Display.
1 |
width and height = Anzahl der Pixel vom Display
|
2 |
pages = (height + 7) / 8
|
3 |
bufsize = pages * width (Größe vom Buffer in Bytes)
|
Eine Page ist ein Balken, der 8 Pixel hoch ist und die ganze Breite des Display abdeckt. Jedes Byte steht für 8 untereinander liegende Pixel. Also wenn das Display 128 Pixel breit ist, dann ist jede Page 8 * 128 Pixel groß, also 128 Bytes. Wenn das Display 32 Pixel hoch ist, dann hat es 4 Pages (vier Balken jeweils 8 Pixel hoch).
Die Stelle mit
if (isSH1106) ...
ist für die Unterschiede zwischen den beiden Chips wichtig.
Der Kommentar
Some displays might need 0x02 here
bezieht sich auf folgendes Fehlerbild: Das ganze Bild erscheint horizontal um zwei Pixel verschoben und am Rand erscheint ein zwei Pixel schmaler vertikaler Balken mit zufälligen Inhalt.
Die Zeilen 29-36 könnte man weg lassen, wenn Arduino nicht dieses blöde Limit auf maximal 32 Bytes pro I2C Transaktion hätte.