Ich habe hier ein 1.3" OLED das wohl einen SH1106 Controller verbaut
hat.
Testweise an einen Arduino angeklemmt und mit einem Sketch aus dem Netz
zeigt das Display auch was an.
Nun möchte ich da gerne mit eigener Software drauf und finde im
Datenblatt vom SH1106 keine Initialisierungs-Sequenz.
Gefunden habe ich diverse Varianten von dem Datenblatt, der letzte Stand
den ich habe ist die V2.3 von Juni 2013.
Im Netz wird teilweise mit Preliminary Ständen 0.1 und 0.2 hantiert.
Okay, Copy-Paste und anpassen, das Arduino Sketch läuft ja.
Tja, das Init sieht dort so aus:
1
_Send_Command(SETMUXRATIO); //Set MUX ratio
2
_Send_Command(0x3F);
3
4
_Send_Command(CHARGEPUMP); //Enable charge pump
5
_Send_Command(ENABLECHARGEPUMP);
6
7
/* Set memory addressing mode to horizontal addressing */
8
_Send_Command(MEMORYADDRESSMODE);
9
_Send_Command(HORIZONTALADDRESSMODE);
SETMUXRATIO = 0xA8
Das passt zum Datenblatt, der dann gesendete Wert entspricht dann aber
überflüssigerweise dem Default-Wert.
CHARGEPUMP = 0x8D
ENABLECHARGEPUMP = 0x14
Das Kommando 0x8D gibt es laut Datenblatt gar nicht, falls der
Controller das ignoriert wird mit dem folgenden 0x14 das High-Nibble der
Spalten-Adresse auf 4 eingestellt.
MEMORYADDRESSMODE = 0x20
HORIZONTALADDRESSMODE = 0x00
Das Kommando 0x20 gibt es laut Datenblatt gar nicht, falls der
Controller das ignoriert wird mit dem folgenden 0x00 das Low-Nibble der
Spalten-Adresse auf 0 eingestellt.
Also eigentlich macht diese Init-Sequenz rein gar nichts.
Ich gehe im Moment davon aus, dass das eher Zufall ist, dass das Display
überhaupt was anzeigt.
Zudem habe ich noch andere Quellen gefunden in denen ebenfalls
mindestens die 0x8D im Init zu finden sind, unreflektiert kopiert würde
mal vermuten.
Jetzt bin ich auf der Suche nach der vorgesehenen Init-Sequenz für die
SH1106, vorzugsweise noch mit Erklärung dazu, warum das so richtig ist.
Meinetwegen auch als Magie-Cookie Liste oder Ablauf-Diagramm vom
Hersteller.
Ein Hinweis darauf wo ein aktuelleres Datenblatt zu finden wäre hätte
auch was.
Harry L. schrieb:> static const uint8_t OledInit[] =
Hmm, was ist das genau?
Ein Datenstrom welcher per I2C geschickt wird?
Oder was soll das 0x80 was da drin immer wieder auftaucht bedeuten?
Auf jeden Fall ist das ohne Erläuterung dazu und ohne Quellen-Angabe
wertlos.
Ich verwende SPI, was für die Daten an sich ja nicht wichtig ist.
>0x80, 0x8d, 0x80, 0x14, // set Charge Pump enable/disable
Damit ist die Sequenz an sich doch gleich wieder disqualifiziert, es
gibt kein 0x8d Kommando im SH1106...
Harry L. schrieb:> Steht doch alles im Datenblatt.
Eben nicht, den Rest kontrolliere ich jetzt gar nicht, aber 0x8d ist
ganz sicher kein Kommando vom SH1106.
> 0x80 ist das Prefix für Commands, und 0x40 signalisiert Zugriff auf den> Framebuffer.
Davon finde ich im Datenblatt ebenfalls nichts.
Das mag bei I2C so sein, direkt raus lese ich das spontan aber nicht und
interessieren tut es mich auch nicht wirklich da ich SPI benutze.
Ach ja:
http://www.sinowealth.com/en/softtype.asp?cat_id=33&class_id=100
Da gibt es nur leider gar keine Datenblätter.
Rudolph R. schrieb:> Damit ist die Sequenz an sich doch gleich wieder disqualifiziert, es> gibt kein 0x8d Kommando im SH1106...
Komisch, das man dieses Komanndo in allen SPI-sources wiederfindet.
Woher weißt Du das ohne Datenblatt?
Also wenn da schon irgendwelche Kommandos autauchen die es gar nicht
gibt hätte ich bitte schön gerne mal eine Erklärung dafür, warum das
trotzdem gut und richtig sein soll den vermeintlichen Datenmüll zu
schicken.
Tippgeber schrieb:> Komisch, das man dieses Komanndo in allen SPI-sources wiederfindet.> Woher weißt Du das ohne Datenblatt?
Datenblatt hängt an, siehe oben.
Wenn Du was neueres hast, bitte anhängen, danke.
Rudolph R. schrieb:> Also wenn da schon irgendwelche Kommandos autauchen die es gar> nicht> gibt hätte ich bitte schön gerne mal eine Erklärung dafür, warum das> trotzdem gut und richtig sein soll den vermeintlichen Datenmüll zu> schicken.
Das ist einfach, weil es mir selbst auch passiert ist:
https://github.com/olikraus/u8g2/blob/master/csrc/u8x8_d_ssd1306_128x64_noname.c#L42
Der SH1106 ist nämlich 90% kompatibel zum weit verbreiteten (und
älteren?) SSD1306. Für den SH1106 wurde dann einfach oft der init code
vom SSD1306 übernommen, der scheinbar tatsächlich erstaunlich gut
funktioniert (der SH1106 scheint den charge pump Befehl zu ignorieren).
Spannender finde ich übrigens die Befehle 0x0d9 (charge) und 0x0db
(vcomh deselect). Für diese Werte braucht man eigentlich zwingend das
Datenblatt des OLED Herstellers. Ok, das gilt natürlich auch für viele
andere Befehle der Fall (beispielsweise wie das OLED am SH1106
angeschlossen ist). All dieses Wissen fließt ja gerade in die init
sequenz rein. Es nützt also nichts nur das SH1106 Datenblatt zu lesen.
Hier noch ein interessantes Beispiel: Der SH1106 besitzt einen Buffer
mit 132x64 Pixel. Meistens ist aber ein 128x64 Pixel OLED am SH1106
angeschlossen. Aber: Wie ist das 128x64 Fenster des OLEDs in den 132x64
Buffer des SH1106 hineingemapped?
Gibt es nur einen Hersteller oder ist es Zufall, dass alle SH1106, die
mir bisher untergekommen sind, das 128x64 Fenster genau im 132x164
Buffer zentriert ist?
Wie auch immer, man sollte mal eine SSD1306/SH1106 Vergleichstabelle
mache...
Grüße Oliver (u8g2lib)
Hmm, also eigentlich funktionieren die Dinger doch nur zufällig weil die
ähnlich genug zu den SSD1306 sind?
Und belastbare Daten zu OLEDs mit SH1106 scheinen soweit nicht zu
existieren?
Gefällt mir nicht so wirklich.
Datenblätter zu den OLEDs aus China muss man nicht wirklich suchen.
Wobei ja schon mal interessant wäre, wie genau die Platine bestückt ist
auf welcher die OLEDs so daher kommen.
Okay, also wer stellt sowas denn her?
Eine Firma die ich finden konnte ist Raystar aus Taiwan, ein
"Datenblatt" zu einem 1.0" OLED von denen mit SH1106G von denen hängt
an.
Was da drin steht ist aber erstmal ein Witz.
Genau wie das "Datenblatt" von Winstar.
Wenn man dann so die üblichen Verdächtigen abklappert findet man zum
Beispiel bei Display Elektronik OLED Module mit SH1106.
Da steht nur ebenfalls erschreckend wenig im Datenblatt drin und
wesentliche Teile weisen erstaunliche Ähnlichkeiten zu den Datenblätter
von Raystar auf.
Wenn man nach dem WEO012864L von Winstar sucht findet man ein Datenblatt
bei Texim dazu das wiederrum verdächtig nach Raystar aussieht.
Natürlich ist auch dieses frei von überflüssigen Daten wie einer
Init-Sequenz.
Rudolph schrieb:> Hmm, also eigentlich funktionieren die Dinger doch nur zufällig weil die> ähnlich genug zu den SSD1306 sind?
Wenn ich mich recht entsinne (ist schon ein paar Tage her, dass ich die
Lib für SSD1306 und SH1106 schrieb) unterscheiden sich SSD1306 und
SH1106 nur dadurch, dass SSD1306 einen automatischen Zeilenumbruch hat
während die SH1106 links und rechts einer Zeile des sichtbaren
Displaybereichs zwei nicht sichtbare Columns haben. Alles andere ist bei
den Dingern eigentlich identisch.
Schau dir mal meine Lib an, wenn du da Probleme hast, vielleicht hilft
es dir: Beitrag "Re: SSD1306 Library zum Darstellen von Text auf OLED Displays"
Naja, das eigentliche "Problem" was ich habe ist einfach belastbare
Informationen zu finden.
Das Init aus meinem Eingangspost "funktioniert" ja.
Ist zwar totaler Murks in dem Sinne das dem Controller Kommandos
geschickt werden die er nicht mal versteht, aber es wird ja was
angezeigt.
Wenn ich nach der Sequenz gehe müsste das auch funktionieren wenn ich
dem gar nichts zur Initialisierung schicke.
Bis auf Hören-Sagen und Copy-Paste gab es in diesem Thread ja auch noch
keine weitere Resonanz zur Initalisierung eines SH1106 basierten OLED.
Der Hinweis auf den anders organisierten Speicher ist gut und richtig,
aber im Grunde die Antwort auf eine andere Frage.
Also von einem echten Problem bin ich weit entfernt, ich würde das nur
gerne mal richtig machen und nicht wie ich das in diversen Quellen
finden konnte offenbar falsch aber zufällig doch funktionierend.
Der SH1106 hat zum Beispiel sehr wohl ein Kommando für die
Ladungs-Pumpe.
Das wird aber auch im dem Schnipsel oben aus der u8g2 Lib nicht benutzt.
Der Power-On Wert scheint ja zu passen, es gibt aber auch noch andere.
Copy-Paste ist mir ja nur zu langweilig, der Weg ist das Ziel, aber wenn
ich da nichts finde benutze ich das Ding halt einfach so das es läuft.
Hallo Rudolph,
der Sh1106 wird von der u8glib gut unterstützt. Da habe ich mich auch
durchgegraben um die Init-Sequenz zu finden. Der SH1106 ist bis auf ein
Detail mit dem SSD1306 kompatibel, also auch die Initialisierung. Der
SH1106 hat 132 Spalten, der SSD nur 128. Das findest Du in Kommentaren
in der u8glib... wenn Du lange genug suchst. Ich kann heute Abend mal
meine Sequenz reinstellen. Da initialisiere ich aber auch quer Beet,
ohne Rücksicht auf Default Werte. Besser ist besser und der ARM, den ich
einsetze hat die paar Bytes übrig. Dabei benutze ich SPI. I²C braucht
halt ein paar ms länger um das Display aufzufrischen, reicht aber auch.
Grüße Lothar
Ich bin mir nicht ganz sicher, ob es überhaupt Sinn macht nach der
"richtigen" Init-Sequenz zu suchen. Bisher bin ich "Ausprobieren" ganz
gut gefahren. Hier aber noch eine Info.
Ich hatte einmal zwei HelTec OLEDs bestellt, eines davon war ein SH1106.
Dazu gibt es dieses Dokument:
http://www.heltec.cn
/wp-content/uploads/2014/03/OLED%E5%B8%B8%E8%A7%81%E6%8A%80%E6%9C%AF%E9%
97%AE%E9%A2%98%E6%B1%87%E6%80%BB-V0.1.pdf
(Das Leerzeichen nach cn noch rauslöschen, weil das Forum keine .cn
Domain akzeptiert)
Ich kann zwar kein Chinesish, aber auf Seite 1 ist vom SH1106 die Rede,
wärend auf Seite 7 dann doch der 0x8d Charge Pump Befehl verwendet wird.
Es wäre mal interessant am funktionierenden SH1106 OLED die Charge-Pump
mit diesem Befehl ein und auszuschalten.
Oliver
u8g2 schrieb:> Ich kann zwar kein Chinesish, aber auf Seite 1 ist vom SH1106 die Rede,> wärend auf Seite 7 dann doch der 0x8d Charge Pump Befehl verwendet wird.
Tja nun, steht ja überall im Internet, muss ja richtig sein...
> Es wäre mal interessant am funktionierenden SH1106 OLED die Charge-Pump> mit diesem Befehl ein und auszuschalten.
Würde mich echt wundern wenn das funktionieren sollte, da es ja sehr
wohl ein Kommando für die Ladungs-Pumpe gibt im SH1106.
Mit 0x30/0x31/0x32/0x33 stellt man die Spannung ein auf
6,4V/7,4V/8,0V/9,0V.
Wobei 8,0V per Default beim Power-On voreingestellt wird.
Und über 0xad 0x8b wird die Ladungspumpe aktiviert, was ebenfalls
Default Einstellung ist.
Beides taucht auch in dem Schnipsel der u8g2 Lib nicht auf.
Wenn das nicht zufällig Default wäre und die OLEDs nicht typischerweise
auf den Betrieb mit Ladungspumpe bestückt wären, dann würde da gar
nichts angezeigt werden.
Wenn das Teil im Betrieb abstürzen sollte, "aus Gründen", dann dürfte
nur ein Power-Cycle helfen das da raus zu holen.
Rudolph R. schrieb:> Beides taucht auch in dem Schnipsel der u8g2 Lib nicht auf.> Wenn das nicht zufällig Default wäre und die OLEDs nicht typischerweise> auf den Betrieb mit Ladungspumpe bestückt wären, dann würde da gar> nichts angezeigt werden.
Nun ja, aus 3 Jahren Betreuung der U8glib/U8g2 würde ich sagen, die
Probleme der Arduino User liegen da an anderer Stelle ;-)
Wie ich schon schrieb, ich bin lange davon ausgegangen, dass SSD1306 und
SH1106 praktisch gleich sind. Tatsächlich sind mir Probleme bezüglich
der Init-Sequenz des SH1106 noch nie untergekommen.
Insofern verfolge ich diesen Thread auch mit besonderem Interesse.
Grüße,
Oliver
Rudolph schrieb:> Naja, das eigentliche "Problem" was ich habe ist einfach belastbare> Informationen zu finden.
Was gefällt dir an z.B. diesem Datenblatt hier nicht?
u8g2 schrieb:> Tatsächlich sind mir Probleme bezüglich> der Init-Sequenz des SH1106 noch nie untergekommen.
Funktioniert soweit ja auch, so an sich, nur scheinbar auf Basis von
Default-Werten. :-)
M. K. schrieb:> Was gefällt dir an z.B. diesem Datenblatt hier nicht?
Was verstehst Du an "Preliminary" und "V0.1" nicht? :-)
Weiter oben habe ich ja bereits Version 2.3 davon angehängt.
Jetzt finde ich nur gerade das "V0.2" nicht wieder.
Allerdings ist in dem 0.1 "Power On an Initialization", Kapitel 1.1.
Seite 31 deutlich ausführlicher als in der 2.3.
So könnte man das mal umsetzen, ja.
Wobei "belastbar", wenn das gut und richtig ist, warum wurde das später
wieder aus dem Datenblatt entfernt?
Die Revisions-History vom 2.3 fängt bei 1.0 an.
Ich habe gestern auch mal Winstar angeschrieben, die bieten
Beispiel-Code, mal schauen ob da was kommt.
Rudolph schrieb:> Allerdings ist in dem 0.1 "Power On an Initialization", Kapitel 1.1.> Seite 31 deutlich ausführlicher als in der 2.3.
Deshalb hab ich ja das "alte" Datasheet angehangen ;)
Rudolph schrieb:> Wobei "belastbar", wenn das gut und richtig ist, warum wurde das später> wieder aus dem Datenblatt entfernt?
Ob wir sowas erfahren werden? Auf jeden Fall funktioniert es problemlos.
Rudolph schrieb:> Ich habe gestern auch mal Winstar angeschrieben, die bieten> Beispiel-Code, mal schauen ob da was kommt.
Das könnte in der Tat interessant sein.
Mahlzeit.
Angehängt mal ein erster kleiner Test-Sketch.
Wie vermutet, dreisterweise funktioniert das Display auch komplett ohne
die Zeilen die man in anderen Quellen so findet.
Im Grunde bediene ich da gerade mal den Reset und schalte die Anzeige
ein mit dem 0xaf Kommando.
Die Ladungs-Pumpe funktioniert einfach so.
Die erste sichtbare Spalte ist so 2 statt 0, steht ja auch oben, 132
Spalten im Speicher, 128 Spalten in der Anzeige.
Rudolph schrieb:> dreisterweise funktioniert das Display
Das stimmt so nicht. Das DB gilt für den Controller, aber da gibt es ja
noch das Display. Und je nach Display muss der Controller passend
eingestellt werden. Du hast vielleicht Glück und die Voreinstellungen
nach Reset passen gerade, muss aber nicht. Oder die Einstellung der
Charge Pump ist falsch und man sieht was auf dem Display, beschädigt es
aber auf Dauer.
Und wenn man sich das Setzen einiger Page Startadressen spart kann es
passieren das nach einem Programmstart ohne HW Reset des Displays Müll
angezeigt wird. Z.B. geteilte Bilder weil die Ausgaberoutine
unterbrochen wurde und die Startadressen verstellt hat.
Die paar Bytes für das Init zu sparen kann funktionieren, ist aber keine
robuste Lösung.
Johannes S. schrieb:> Das stimmt so nicht.
Siehe oben, das ist doch genau das warum ich den Thread erstellt habe.
:-)
Die ursprüngliche Initialisierung die ich hatte hat nichts bewirkt.
Wobei ich sowieso keine Hoffnung habe das Datenblatt der Displays zu
bekommen, nicht bei China-Ware.
Okay, ich habe mal die Spannungen gemessen und mit der
Default-Einstellung welche die Ladungs-Pumpe auf 8,0V setzen sollte kann
ich 8,1V auf der Platine finden.
Dann habe ich mal die Sequenz von oben eingebaut die übrigens konkret
aus der "HCuOLED" Library stammt.
Die Spannung bleibt bei 8,1V.
Dann habe ich mal mit 0x8d 0x10 gemäß des Datenblattes des SSD1306 die
Ladungspumpe abgeschaltet.
Die Spannung bleibt bei 8,1V.
So viel spannende Dinge, so wenig Zeit...
Winstar hat mir den Demo-Code geschickt für ein bestimmtes OLED.
Auf den ersten Blick sehr ausführlich, ich melde mich wieder.
Ich habe gerade mal sowohl die Init-Sequenz aus der u8g2 Library als
auch den Init-Code den ich von Winstar für das WEO012864L erhalten habe
initialisiert und ausprobiert.
Die Sequenz der u8g2 macht ein bisschen was das nicht funktioniert und
ein bisschen was anders das sich nicht offensichtlich auswirkt.
Der Kontrast wird auf 0xcf gestellt - wofür auch immer die
Kontrast-Einstellung bei einem OLED überhaupt gut ist.
Die Frequenz wird auf +15% gestellt.
Pre-Charge/Dis-Charge wird auf 1/15 gestellt.
VCOM wird auf 1V gestellt.
Wofür auch immer, einen Unterschied konnte ich in der Anzeige jedenfalls
spontan nicht feststellen.
Das Winstar setup ist für ein WEO012864L.
Kontast wird auf Max gedreht, Frequenz mit Default-Wert geschrieben,
Pre-Charge/Dis-Charge wird auf 1/1 gestellt.
VCOM auf 0,770V gestellt was ebenfalls Default-Wert ist.
Winstar wird schon wissen warum, hoffe ich, das öffentlich verfügbare
Datenblatt zu dem OLED verrät mir nicht, warum die das verdrehen.
Die Einstellung der Ladungs-Pumpe fassen die auch nicht an.
Mein Vorschlag dazu ist jetzt das hier:
1
SPI.transfer(0xae); // Display OFF/ON: off (POR = 0xae)
2
SPI.transfer(0xa4); // Set Entire Display OFF/ON: off (POR = 0xa4)
3
SPI.transfer(0xd5); // Divide Ratio/Oscillator Frequency Mode Set:
SPI.transfer(0xa6); // Set Normal/Reverse Display: normal (POR = 0xa6)
20
SPI.transfer(0xda); // Common Pads Hardware Configuration Mode Set:
21
SPI.transfer(0x12); // Sequential/Alternative Mode Set: alternative (POR = 0x12)
22
23
// flip display
24
SPI.transfer(0xa1); // Set Segment Re-map: reverse direction (POR = 0xa0, normal direction)
25
SPI.transfer(0xc8); // Set CommonOutput Scan Direction: flipped (POR = 0xc0)
Das sind so im wesentlichen Default-Werte, bis auf den Kontrast der auf
Max gesetzt ist.
Das "passt" auch nur wenn das OLED für das man kein Datenblatt hat damit
läuft.
Das meiste davon könnte man auch weg lassen, mit der Sequenz müsste man
aber auch ein "aus Gründen" gecrashtes OLED Re-Initialisieren können,
nur dafür ist das so ausführlich.
Macht was Ihr wollt damit, ich werde das dann so benutzen, wenn auch
nicht per Arduino. :-)
Servus,
vielen vielen Dank, seit Tagen suche wie du auch (Rudolph R.) und finde
nichts. vor allem kam es mir verdächtigt vor das im Datenblatt
(mittlerweile 2.6 No.2015) bei D0 ein D steht und eing. mit D folgendes
gemeint ist
"When D = “L”, DC-DC is disable.
When D = “H”, DC-DC will be turned on when display on. (POR)"
habe vermutet das es sich um ein tipp Fehler handelt der sich per
Copy/Paste noch viral verbreitet hat.
Ich konnte ohne die Info wo es drinsteht auch nicht weiterleben.
Vielen Dank.