Harry L. schrieb:> Der Code sollte auf jedem System mit jeder Codepage zum selben Ergebnis> führen.
Die Zeit von „Codepages“ ist (zumindest in meiner Welt) vorbei. Der
einzige Nachteil von UTF-8 an dieser Stelle ist es eben, dass dort die
Umlaute dann Multibyte-Zeichen werden, sodass man sie nicht mehr in
einem einfachen "char" abspeichern und verarbeiten kann. Für ein kleines
Werkzeug auf einem Controller ist sowas natürlich lästig, da hätte man
gern alle Zeichen in 8 Bit passend.
Wenn der Compiler UTF-8 als host character set akzeptiert, dann geht
allerdings obiges auch so zu schreiben:
1
#define ä "\xe4"
2
#define ß "\xdf"
3
4
...
5
printf("Verl"äß"lich");
Bekomme ich mit dem GCC aber gerade nicht akzeptiert, während der Clang
es klaglos schluckt. Vorgeblich sollte GCC es zumindest mit -std=c99
(oder höher) auch akzeptieren.
M. K. schrieb:> Würde nur mit deinem Font nicht funktionieren da da ä als 0x84 definiert> ist und ß mit 0xe1.
Dass diese Definitionen mit dem Font zusammenpassen müssen, sollte
sonnenklar sein.
Jörg W. schrieb:> Bei dieser Variante ist man halt komplett unabhängig vom host und> execution charset.
Nö, ist man nicht. Ist das charset so eingestellt dass ein ä als 0x84
dargestellt wird, wie das beim verwendeten Font von Harry der Fall ist,
führt das zu einer fehlerhaften Ausgabe da sein Font kein Zeichen mit
dem Code 0xe4 kennt ;)
Man kann natürlich Glück haben, dass die Defaulteinstellungen vom input
so sind, dass ein ä ein 0xe4 ist und vom exec so, dass ein ä ein 0x84
ist aber das wäre schlicht purer Zufall. Aber hat man Pech wird aus
einem 0xe4 ein 0xe4 und dann sagt der Mikrocontroller nur "Das Zeichen
ist im Font nicht enthalten."
Jörg W. schrieb:> Dass diese Definitionen mit dem Font zusammenpassen müssen, sollte> sonnenklar sein.
Eben das ist aber dem Harry nicht klar. Deshalb diskutieren wir ja
darüber. Er meint ja, dass es besser wäre dem Compiler im Font besser
den Hexcode zu geben als das Zeichen. In der main aber, so meine
Meinung, wird man weniger mit hexcode den Font schreiben wollen als mit
Zeichen. Daher ist es IMO sinniger im Font auch die Zeichen anzugeben
und dem Compiler eben das korrekte Charset mitzuteilen. Dafür gibts ja
extra flags beim gcc. Warum also sie nicht nutzen und sich somit das
Leben leichter machen?
M. K. schrieb:> Eben das ist aber dem Harry nicht klar. Deshalb diskutieren wir ja> darüber. Er meint ja, dass es besser wäre dem Compiler im Font besser> den Hexcode zu geben als das Zeichen. In der main aber, so meine> Meinung, wird man weniger mit hexcode den Font schreiben wollen als mit> Zeichen. Daher ist es IMO sinniger im Font auch die Zeichen anzugeben> und dem Compiler eben das korrekte Charset mitzuteilen. Dafür gibts ja> extra flags beim gcc. Warum also sie nicht nutzen und sich somit das> Leben leichter machen?
Natürlich ist mir der Zusammenhang klar, aber meine IDE verwendet UTF-8
- und jetzt?
Harry L. schrieb:> Natürlich ist mir der Zusammenhang klar, aber meine IDE verwendet UTF-8> - und jetzt?
Ja, deine IDE. Und wenn sich nun jemand dein Projekt im Github runter
läd und seine IDE benutzt nicht UTF-8 sondern z.B. Ansi (Windows
Standard-Charset) oder Latin-1? Wie gesagt, der GCC kennt ja Flags zur
Vorgabe der Charsets, warum also sie nicht benutzen wenn sie schon da
sind? ;)
Ihr beiden dreht euch schon wieder im Kreise. Lasst's doch mal gut
sein. Dass die Optionen für die Umwandlung der Zeichen offenbar nicht
in jeder Umgebung funktionieren, ist ja nun auch klar geworden, damit
sind auch die Kommandozeilenoptionen kein „Allheilmittel“. Wichtig ist
daher, dass sich jeder dessen gewahr ist, um sich mit seinem Sourcecode
passend drauf einstellen zu können.
M. K. schrieb:> Joachim B. schrieb:>> freut mich, ich habe auch noch 2 nachbestellt>> So, ich hab meine SH1106er nun auch endlich bekommen und konnte heute> experimentieren. Library ist angepasst, Fehler möglich ;).> Es werden nun OLED-Displays mit SSD1306 und SH1106 Controller> unterstützt, entsprechend einzustellen in der jeweiligen Header-Datei.
Funktioniert diese Library auch mit einem Atmega2560 ohne Arduino mit
Atmelstudio 7 ? oder was für Anpassungen müsste man vornehmen, damit es
funktionieren würde?
Danke im Voraus
Simon X. schrieb:> Funktioniert diese Library auch mit einem Atmega2560 ohne Arduino mit> Atmelstudio 7 ? oder was für Anpassungen müsste man vornehmen, damit es> funktionieren würde?
Es müsste auch auf einem Atmega2560 funktionieren. Dazu muss lediglich
in der i2c.h die Prozessorinformation ergänzt werden (gehört also ein
(_defined_ATmega2560_) zum entsprechenden #if dazu). Das habe ich
grade mal bei der Library ergänzt und sollte nun gehen.
Die Library kannst du mit der Arduino IDE, dem Atmel Studio oder auch
jeder anderen IDE benutzen. Denke nur daran, dass es eine C-Library ist.
Willst du sie in einem C++ Projekt verwenden musst du sie mit
[c]extern "C" {
#include "lcd.h"
}
includieren ;)
Habe heute ein kleines Update aufgespielt.
Man kann nun in der Header-Datei (lcd.h) ein #define BIGCHAR setzen
wodurch die Schriftgröße verdoppelt wird.
Bisher funktioniert das fehlerfrei auf SSD1306 und SH1106 Displays im
Grafik- und Textmode. Lediglich die Displaygröße wird noch nicht bei
Verwendung der BIGCHARs mit berücksichtigt (man kann also quasi über den
Displayrand schreiben...mit allen Konsequenzen, die das jeweilige
Display dabei bedingt).
Noch eine kleine Änderung eingefügt, es lässt sich nun der Font in
normaler Größe und doppelter Größe gleichzeitig nutzen.
Lib liegt unter
https://github.com/Sylaina/oled-display
zum Download bereit.
Sehr gute Arbeit M. K., ich danke dafür.
Hab noch eine Frage dazu, da ich noch nicht so gut programmieren kann:
Köntest Du eine Beispielzeile für die Verwendung von Sonderzeichen wie
Ä, Ü
geben?
Was mir noch aufgefallen ist:
Auf Github in der readme.md sind zwei Beispiele. Im zweiten Beispiel
liegt die Ausgabe in der main loop. Im ersten Beispiel vor der main
loop?
Das erste Beispiel ist richtig, oder?
Es sind beide Beispiele richtig wenn auch der Code im zweite Beispiel
nicht zwingend im Mainloop liegen muss.
Ob Code für das Display im Mainloop liegen muss oder nicht hängt
letztendlich vom konkreten Programm ab. Als Regel kann man aber sagen:
Text des Displays, der sich zur Programmlaufzeit nicht ändert, muss
nicht im Mainloop liegen.
Ich hab den Code mal aus dem Mainloop raus genommen damit es nicht
weiter zu Verwirrung führt.
Tillmaier schrieb:> Köntest Du eine Beispielzeile für die Verwendung von Sonderzeichen wie> Ä, Ü> geben?
Einfach im Code benutzen und beachten, dass der Compiler entsprechend
eingestellt ist (vergleiche Makefile Line 114, angegebene Compiler-Flags
setzen).
1
...
2
// irgendwo im Code, bei dem Text gedruckt werden soll
M. K. schrieb:
Ich habe den code mal hinein kopiert. Jedoch beim compilieren auf
(ATMega2560) kommen mehrere gleiche Fehler wie auf dem Bild (F_CPU
undeclared) obwohl definiert oder fehlt da noch was?
Wie lautet deine Fehlermeldung genau? Auf den ersten Blick würde ich
sagen 1 MHz System-Clock und 100 kHz I2C-Clock passen nicht zusammen, da
müsste das TWBR out of Range gehen.
Vom Atmel Studio hab ich zudem wenig Ahnung, es könnte auch sein, dass
F_CPU an dieser Stelle noch unbekannt ist, wird da aber gebraucht.
M. K. schrieb:> Wie lautet deine Fehlermeldung genau? Auf den ersten Blick würde> ich> sagen 1 MHz System-Clock und 100 kHz I2C-Clock passen nicht zusammen, da> müsste das TWBR out of Range gehen.> Vom Atmel Studio hab ich zudem wenig Ahnung, es könnte auch sein, dass> F_CPU an dieser Stelle noch unbekannt ist, wird da aber gebraucht.
Hier die genaue Fehlermeldung: in jedem File sozusagen
Wie ich mir schon dachte, TWBR ist außerhalb des zulässigen Bereiches.
Du musst die erste Fehlermeldung erst mal bearbeiten. Dass F_CPU nicht
definiert ist, ist ein Folgefehler.
Reduziere einmal F_I2C auf z.B. 40000
Dann liegt es wohl doch daran, dass er F_CPU an dieser Stelle nicht
kennt. Ich kenne mich mit dem Studio leider zu wenig aus, ich arbeite
mit einem Macintosh.
Was sagt den Google dazu wie man im Studio ein Symbol dem gesamten
Projekt bekannt machen kann?
EDIT: Schau mal hier, vielleicht hilft es:
Beitrag "define F_CPU in AVR Studio 5, nur wo?"
M. K. schrieb:> Dann liegt es wohl doch daran, dass er F_CPU an dieser Stelle nicht> kennt.
Projekt - Properties - AVR/GNU C Compiler - Symbols - "F_CPU=16000000UL"
Das habe ich versucht die Fehler sind nicht mehr da compiliert auch so
wie sollte. Jedoch bleibt das Display schwarz (Prozessor ATMeaga2560
16Mhz)
SDA und SCL Pins richtig angeschlossen mit Pull up.
Simon schrieb:> Das habe ich versucht die Fehler sind nicht mehr da compiliert auch so> wie sollte. Jedoch bleibt das Display schwarz (Prozessor ATMeaga2560> 16Mhz)
Stell mal bitte Dein Projekt (komplett) ein.
Dieter F. schrieb:> Simon schrieb:>> Das habe ich versucht die Fehler sind nicht mehr da compiliert auch so>> wie sollte. Jedoch bleibt das Display schwarz (Prozessor ATMeaga2560>> 16Mhz)>> Stell mal bitte Dein Projekt (komplett) ein.
Ich konnte das Problem mit einem neuen Display losen. Weiss nicht wie
dies so gekommen ist, dass es nicht mehr geht. Sieht super aus und lässt
sich einiges darstellen. Doch wie schreibt man einen Parameter auf das
Display z.B. eine sich hochzählende Zahl oder eine Temperatur.
Simon schrieb:> Doch wie schreibt man einen Parameter auf das> Display z.B. eine sich hochzählende Zahl oder eine Temperatur.
itoa
ltoa
utoa
ultoa
sprintf
oder etwas selbst gebautes. Man muss dabei nur den ASCII Zeichensatz
anwenden.
1
inti=5;
2
charc='0'+i;// ergibt "5"
Auf alles Weitere müsstest du mit Nachdenken, Divisionen und Modulus
Operator kommen.
Stefanus F. schrieb:> Divisionen und Modulus Operator
Da Division und Modulus eigentlich immer gemeinsam berechnet werden,
spart man sich eine zusätzliche Operation, wenn man gleich die
(Standard-)Funktion div() benutzt.
Aber wenn mich nicht Platzgründe dazu zwingen, würde ich nicht ohne Not
etwas anderes als sprintf() benutzen … das ist schlicht die bequemste
(und flexibelste) Variante.
Simon schrieb:> Doch wie schreibt man einen Parameter auf das> Display z.B. eine sich hochzählende Zahl oder eine Temperatur.
Du musst dir im vorfeld überlegen, wieviele Stellen wird die Zahl wohl
maximal haben. Um einen Wert auf dem Display auszugeben musst du die
Zahl in eine Zeichenfolge umwandeln, dafür musst du ein char-Array zur
Verfügung stellen. Je nachdem ob du einen Integer darstellen möchtest
oder einen Float-Wert gibt es zur Umwandlung unterschiedliche
Funktionen. Hier mal ein Beispiel wie das in C aussehen kann:
1
#include<stdlib.h>
2
#include"lcd.h"
3
4
intmain(void){
5
charvalueToPrint[5];// char-Array das später die darzustellende Zahl enthalten soll, es muss mindestens so lang sein wie die darzustellenden Stellen plus dem String-Ende-Zeichen \0
6
uint8_tmyInteger=123;
7
floatmyFloat=1.23;
8
9
lcd_init(LCD_DISP_ON);
10
lcd_clrscr();
11
itoa(myInterger,// Zahl, die umgewandelt werden soll
12
valueToPrint,// char-Array, dass die Umwandlung aufnehmen soll
13
10);// Zahlenbasis, die zur Darstellung benutzt werden soll, hier dezimales System, oktal (8) und hexadezimal (16) ginge auch wenn ich mich recht entsinne
14
lcd_puts_p(PSTR("Integer: "));
15
lcd_puts(valueToPrint);
16
lcd_puts_p(PSTR("\r\n"));
17
dtostrf(myFloat,// Zahl, die umgewandelt werden soll, kann auch ein Interger sein
18
4,// Anzahl der darzustellenden Stellen incl. Komma, Komma ist auch eine Stelle ;)
19
2,// Anzahl der Nachkommastellen
20
valueToPrint);// char-Array, der die Umwandlung aufnehmen soll
21
22
lcd_puts_p(PSTR("Float: "));
23
lcd_puts(valueToPrint);
24
for(;;){
25
// main-loop
26
}
27
return0;
28
}
Hoffe, ich hab in dem Code jetzt keinen Fehler drin, schreib das grade
vom iPad aus von unterwegs.
Auf dem Diplay sollte dann stehen:
Integer: 123
Float: 1.23
Also ich finde möglichst schnellen und kleinen Code optimal, da ich
meistens auf einem Controller auch noch andere Dinge tute, als nur das
Display zu bespaßen...aber das beisst sich mit der Bequemlichkeit,
welche eine flexible und voller Funktionen steckende Libray bietet. Hier
einen Kompromiss zu finden ist sicherlich schwer. Ich orientiere mich
meistens nur daran, was ich konkret an Funktionalität benötige, um die
Komplexität zu reduzieren, und werfe überflässigen Overhead raus!
Peter schrieb:> Also ich finde möglichst schnellen und kleinen Code optimal, da ich> meistens auf einem Controller auch noch andere Dinge tute, als nur das> Display zu bespaßen
Das macht ja wohl so ziemlich jeder, wer baut schon ein reines serielles
Terminal oder sowas?
Meist bringen aber ohnehin andere Randbedingungen (nötige Peripherie
etc.) einen Controller mit sich, bei dem es gar auf das letzte Kilobyte
an Flashverbrauch ankommt, weil am Ende noch genügend frei bleibt. Für
nicht benutzten Flash bekommt man ja kein Geld zurück. ;-)
Allerdings habe ich die genannten OLED-Displays bislang immer (zumindest
teilweise) grafisch benutzt, da braucht man dann ohnehin die im
Eingangspost genannten 1 KiB an Display-Puffer (shadow buffer) und damit
mindestens sowas wie einen ATmega328. Flashnutzung ist dann oft nur bei
10 oder 20 %.
Wenn man mit einem ATtiny2313 auskommen möchte, sieht das anders aus.
Andererseits ist der Preisunterschied zwischen einem ATtiny2313 und
einem ATmega328 so verschwindend gering, dass man schon ziemliche
Stückzahlen braucht, damit sich der höhere Aufwand lohnt im Vergleich zu
„Komfort-Funktionen“ mit etwas mehr Flashverbrauch …
Hallo M. K.
Ich hab mal ne Frage wegen Bitmaps.
Hatte vor ein paar Monaten diese Library ausprobiert, welche nebenbei
gesagt mal richtig gut ist, und hatte auch ein paar Bitmaps mit dem
weiter oben geposteten Programm Oledbm.exe generiert und das
funktionierte ganz gut, auch für dieses Progi ein herzlichen Dank.
Jetzt habe ich die neueste Version der Library compiliert und musste
feststellen, das sich die draw_bitmaps Funktion um 3 weitere Variablen
erweitert hat und meine Bitmaps nun nicht mehr korrekt angezeigt werden.
Hab hier ein Bitmap mit 64x64 Pixeln und wenn ich bei Width und Height
64, 64 angebe gibts nur ein komplett verpixeltes Bild mit der Grösse.
Für einen guten Tip wäre ich sehr dankbar.
Bernd
Besitzt jemand das Font-Array für die längere Version des SSD1306-OLEDs
(das 128x32 Pixel misst)?
Auf dem 128x64 funktioniert das aktuelle einwandfrei, nur bei dem
längeren ist die Schrift nicht gut erkennbar.
Ich dachte, der Font wäre an das Seitenverhältnis des 128x64-Displays
angepasst.
Welche Gründe könnte es noch haben, dass der Font abgeschnitten
aussieht?
Das soll "HALLO" heißen.
Ich schätze dass du hier versuchst, Text zwischen zwei Zeilen auszugeben
und das kann diese Library wohl nicht.
Schreibe den Text mal ganz oben in die äusserste Ecke (ab Position 0,0).
Wenn das auch nicht geht, wurde der Display Controller wohl falsch
initialisiert. Da gleiche Problem müsste dann auch mit Linien erkennbar
sein. Zeichne mal einfach ein großes X quer über das gesamte Display.
Wird das auch Lückenhaft dargestellt?
Die richtige Initialisierungs-Sequenz kannst du meinem (anderen)
Quelltext entnehmen: http://stefanfrings.de/esp8266/WIFI-Kit-8-OLED.zip
Max M. schrieb:> Welche Gründe könnte es noch haben, dass der Font abgeschnitten> aussieht?
Mir sind schon mal Displays mit gebrochenen Ecken geliefert worden. Dort
sah die Schrift dann ähnlich aus wie bei dir.
Stefanus F. schrieb:> Da gleiche Problem müsste dann auch mit Linien erkennbar> sein. Zeichne mal einfach ein großes X quer über das gesamte Display.> Wird das auch Lückenhaft dargestellt?
Ich weiß nicht?
Daniel B. schrieb:> Mir sind schon mal Displays mit gebrochenen Ecken geliefert worden.
Also die Ecken sind nicht gebrochen, aber im angehängten Foto erkennt
man, dass das silber Reflektierende im Display gebrochen aussieht. Keine
Ahnung, ob das so etwas verursachen kann.
Bernd schrieb:> Hallo M. K.>> Ich hab mal ne Frage wegen Bitmaps.>> Hatte vor ein paar Monaten diese Library ausprobiert, welche nebenbei> gesagt mal richtig gut ist, und hatte auch ein paar Bitmaps mit dem> weiter oben geposteten Programm Oledbm.exe generiert und das> funktionierte ganz gut, auch für dieses Progi ein herzlichen Dank.>> Jetzt habe ich die neueste Version der Library compiliert und musste> feststellen, das sich die draw_bitmaps Funktion um 3 weitere Variablen> erweitert hat und meine Bitmaps nun nicht mehr korrekt angezeigt werden.>> Hab hier ein Bitmap mit 64x64 Pixeln und wenn ich bei Width und Height> 64, 64 angebe gibts nur ein komplett verpixeltes Bild mit der Grösse.>> Für einen guten Tip wäre ich sehr dankbar.> Bernd
Hm, das muss ich mir mal anschaun, da schau ich morgen mal. Eigentlich
müsste es funktionieren. Hast du vielleicht etwas Beispielcode?
Max M. schrieb:> Besitzt jemand das Font-Array für die längere Version des SSD1306-OLEDs> (das 128x32 Pixel misst)?> Auf dem 128x64 funktioniert das aktuelle einwandfrei, nur bei dem> längeren ist die Schrift nicht gut erkennbar.
Hm, wie schon gesagt wurde ist der Font nicht vom Display abhängig. Es
sieht in der Tat so aus als stimmt irgend etwas mit deinem Display
nicht. Bei dem "Hallo-Beispiel" sieht es so aus als würde die ein und
andere Zeile fehlen, bei dem "X-Beispiel" sieht es so aus als würde jede
zweite Spalte fehlen.
Bernd schrieb:> Hab hier ein Bitmap mit 64x64 Pixeln und wenn ich bei Width und Height> 64, 64 angebe gibts nur ein komplett verpixeltes Bild mit der Grösse.
Ich habs mir nun mal angeschaut und habe eine Vermutung:
Hast du deinem Bitmap auch das Attribut mitgegeben, dass es im Flash
liegen bleiben soll? Über den "Fehler" bin ich grad bei mir gestolpert,
viel mir aber sofort auf weil sich der Pixelsalat unabhängig vom Bild
nicht änderte ;)
Die lcd_drawBitmap() erwartet das Bitmap nämlich im Flash ;)
Folgender Code sollte mit der aktuellen Library einen Pacmen aufs
Display malen:
lcd_drawBitmap(0,0,PacMen,127,64,WHITE);// draw bitmap to buffer
84
lcd_display();// send buffer to display
85
#endif
86
for(;;){
87
//main loop
88
}
89
return0;
90
}
Einzige Änderung, die ich heute an der lcd_drawBitmap() gemacht habe
ist, dass nun Bitmaps auch invertiert gezeichnet werden wenn als Color
nicht WHITE sondern BLACK angegeben wird.
Bei mir spuckt der Compiler immer folgende Fehlermeldungen aus. Im
TEXTMODE funktioniert die Ansteuerung trotzdem. Im GRAPHICMODE nicht.
Was hat das zu bedeuten?
1
lcd.c:91:0: warning: ignoring #pragma mark LCD [-Wunknown-pragmas]
2
#pragma mark LCD COMMUNICATION
3
^
4
Makefile:405: die Regel für Ziel „lcd.o“ scheiterte
5
lcd.c:108:0: warning: ignoring #pragma mark [-Wunknown-pragmas]
6
#pragma mark -
7
^
8
lcd.c:109:0: warning: ignoring #pragma mark GENERAL [-Wunknown-pragmas]
9
#pragma mark GENERAL FUNCTIONS
10
^
11
lcd.c:252:0: warning: ignoring #pragma mark [-Wunknown-pragmas]
12
#pragma mark -
13
^
14
lcd.c:253:0: warning: ignoring #pragma mark GRAPHIC [-Wunknown-pragmas]
15
#pragma mark GRAPHIC FUNCTIONS
16
^
17
lcd.c: In function ‘lcd_display’:
18
lcd.c:356:5: error: expected declaration or statement at end of input
Zeilen dienen der Strukturierung in Xcode, sie erleichtern mir ein wenig
das Navigieren.
Die Fehlermeldung ist merkwürdig, hast die die Library
verändert/modifiziert? Ein Beispiel wäre sicher gut. Ich hab grade die
aktuelle Library herunter geladen und in allen Variationen kompiliert
(nur Graikmode, für SSD1306 und SH1106) und es wird bei mir immer
fehlerfrei kompiliert. Der AVR-GCC 4.8.1 warnt bei mir nur wegen der
#pragma marks.
Ich habe die Library noch mal frisch heruntergeladen, nur das minimalste
konfiguriert und jetzt kompiliert sie ohne Probleme.
Ich muss nochmal schauen was ich beim letzten Mal falsch gemacht habe..
Danke trotzdem :)
Moin,
ich habe in der i2c.c heute den Atmega16 hinzugefügt. Im Textmode hat
das ohne Probleme funktioniert. (Von 1 - 16 MHz) Der Graphicmode spuckt
allerdings nur einen Block gequirlte Zeichen aus.
Hat jemand eine Idee, wo man da ansetzen müsste?
Liebe Grüße,
Adrian
Stefanus F. schrieb:> Signalqualität messen.
Alle Einstellungen bis auf F_CPU = 16 MHz und die Erlaubnis, für
Atmega16 zu kompilieren unverändert zum original Code
Die Signale steigen im Graphic Mode wesentlich langsamer an, als im Text
Mode. Man beachte die Form der oberen Spitzen vom SCL Signal. Das ist
aber komisch.
Normalerwesie hängt das von den Pull-Up Widerständen ab, nicht vom
Programm. Welche Werte haben deine Pull-Up Widerstände? Ich würde
ungefähr 2,2k Ohm Empfehlen.
Stefanus F. schrieb:> Die Signale steigen im Graphic Mode wesentlich langsamer an, als im Text> Mode. Man beachte die Form der oberen Spitzen vom SCL Signal. Das ist> aber komisch.
SORRY! Ich habe einen Flüchtigkeitsfehler gemacht. Ich wollte kürzere
Kabel verwenden, habe dabei so umgesteckt dass es keine Pull-Ups mehr
gab.
Ich verwende 10k Pull-Ups. Screenshots tausche ich in einer Minute aus.
Jetzt sehen die Signale qualitativ gleich aus.
Adrian E. schrieb:> Im Textmode wird ein einziges mal der Bildschirminhalt gesendet, im> Graphicmode resettet er sich kontinuierlich..
Öhm...das liegt dann aber an deinem Aufbau/Programm. Im Textmode wird
jedes Zeichen direkt an das Display gesendet, im Graphicmode wird der
komplette Displayinhalt nur bei Aufruf von lcd_display(); ans Display
gesendet (dann die kompletten 1024 Bytes).
Adrian E. schrieb:> Im Textmode wird ein einziges mal der Bildschirminhalt gesendet, im> Graphicmode resettet er sich kontinuierlich..
Reicht denn die RAM-Grösse des Atmega16 aus?
Einfach mal nach dem Kompilieren die Grösse kontrollieren.
RAM Prüfer schrieb:> Reicht denn die RAM-Grösse des Atmega16 aus?> Einfach mal nach dem Kompilieren die Grösse kontrollieren.
Nur wenn getrickst wird. Ich bin jetzt davon ausgegangen, dass er die
Lib ein wenig geändert hat. Ist natürlich auch denkbar, dass er gar nix
an der Lib verändert hat, dann passt das mit dem Graphicmode aber gar
nicht da man mindestens 1027 Bytes RAM braucht, der Atmega16 aber nur
1024 Bytes besitzt. Ich muss das mal ändern bei Zeiten sodass man
zumindest ein Warning erhält.
M. K. schrieb:> Nur wenn getrickst wird.
Ist sowieso Schwachsinn auf so einem kleinen Controller
graphische Dinge zu machen. Was soll das Sinnvolles bringen?
Mir fällt da nix ein ....
RAM Prüfer schrieb:> Ist sowieso Schwachsinn auf so einem kleinen Controller> graphische Dinge zu machen. Was soll das Sinnvolles bringen?
Wenn er genügend RAM hat, warum denn nicht? Zur Visualisierung? Fiktives
Beispiel: Multimeter. Man kann eine Digitalanzeige machen, klar. Manch
einem gefällt aber eine Zeigeranzeige besser. Schwachsinn würde ich das
also nicht nennen wollen. Da kann es schon ganz schicke Projekte für
geben.
RAM Prüfer schrieb:> M. K. schrieb:>> Da kann es schon ganz schicke Projekte für geben.>> Ja, is doch schick wenn der Stack in den Framebuffer reinschreibt.
Ist noch ausbaufähig: welche Stackbelegung liefert einen schönen
QR-Code? :.)
M. K. schrieb:> RAM Prüfer schrieb:>> Reicht denn die RAM-Grösse des Atmega16 aus?>> Einfach mal nach dem Kompilieren die Grösse kontrollieren.>> Nur wenn getrickst wird. Ich bin jetzt davon ausgegangen, dass er die> Lib ein wenig geändert hat. Ist natürlich auch denkbar, dass er gar nix> an der Lib verändert hat, dann passt das mit dem Graphicmode aber gar> nicht da man mindestens 1027 Bytes RAM braucht, der Atmega16 aber nur> 1024 Bytes besitzt. Ich muss das mal ändern bei Zeiten sodass man> zumindest ein Warning erhält.
Danke für die Antworten! Nein ich gebe zu, ich habe erst mal gar nichts
an der Library geändert. Mir war nicht bewusst dass der ATMega16
aufgrund des zu kleinen RAM gar nicht dafür geeignet ist. Dann werde ich
auf diesem Controller nur den Textmode verwenden.
Adrian E. schrieb:> Danke für die Antworten! Nein ich gebe zu, ich habe erst mal gar nichts> an der Library geändert. Mir war nicht bewusst dass der ATMega16> aufgrund des zu kleinen RAM gar nicht dafür geeignet ist. Dann werde ich> auf diesem Controller nur den Textmode verwenden.
Der Atmega32 hätte wieder genug RAM auch für den Graphicmode und ist IMO
pinkompatibel zum Atmega16 ;)
M. K. schrieb:> Der Atmega32 hätte wieder genug RAM auch für den Graphicmode und ist IMO> pinkompatibel zum Atmega16 ;)
ATmega644 und 1284 sind auch pinkompatibel, allerdings nicht mehr
Code-kompatibel (nicht einmal auf Sourcecodeebene komplett).
M. K. schrieb:> Noch eine kleine Änderung eingefügt ..> normaler Größe und doppelter Größe gleichzeitig ...> .. Lib .. zum Download bereit.
Perfekt, prima, vielen Danke, vor allem für die saubere Bereitstellung
des Codes. Es klappte bei mir auf Anhieb auf nem 1306 (NEIN :-/ - erst
nachdem ich die richtige Adresse eingefügt hatte), siehe unten. Ich bin
begeistert. Bisher hatte ich das als lausiger C(äh)Programmierer nur
sehr bescheiden mit veröffentlichten Codes in cpp hinbekommen. Aber nun
:
https://dl.dropbox.com/s/igqyyhpnnvajayz/oled_4217-50%25.jpg?dl=0
Nun war ich zwei Tage dran den Code von DoubleSize auf 4fachSize zu
bemühen - wegen drei, vier Zahlen irgendwo mittendrin in meinem archie.
Aber da finde ich mich nicht wirklich zurecht. Gibts so etwas, jetzt
oder zukünftig?
Nochmal herzlichen Dank für Dein Projekt
grüßt der
oberallgeier
(aus dem obern Allgäu)
Zukünftig gibts sowas vielleicht mal, derzeit mangelt es mir aber ein
wenig an der Zeit. Ich hab einfach zu viele andere Projekte noch am
laufen die erst mal fertig werden müssen ;)
M. K. schrieb:> .. vielleicht mal .. zu viele andere Projekte ..> .. die erst mal fertig werden müssen ;)
Ach ja, kenne ich. Sowas gibt sich wohl nie (nicht mal bei mir als
Rentner).
Danke für die schnelle Antwort.
Moin,
ich klinke mich hier mal mit ein..
Hat jemand schon mal den "Effekt" gehabt das sich der Bildschirminhalt
nach unbestimmter Zeit einfach mal um 180° dreht? Oder das die oberste
Zeile einfach mal ein Stück weit unten wieder raus kommt?
Wahrscheinlich ist der Text, den du auf das Display ausgeben willst, zu
groß so dass der Speicher quasi überläuft. Diesbezüglich sind in der
Library nur wenig Überprüfungen implementiert.
Hast du vielleicht Beispiel-Code der die Fehler zeigt? Dann kann ich mal
schauen ob ich das raus gefixt bekomme.
M. K. schrieb:> Wahrscheinlich ist der Text, den du auf das Display ausgeben willst, zu> groß so dass der Speicher quasi überläuft. Diesbezüglich sind in der> Library nur wenig Überprüfungen implementiert.>> Hast du vielleicht Beispiel-Code der die Fehler zeigt? Dann kann ich mal> schauen ob ich das raus gefixt bekomme.
Also der Fehler ist nach wie vor noch da.. :(
Anbei mal meine Lib für den "SSD1306"..
Vielleicht findest Du ja was.
Ach, das ist ja gar nicht meine Lib. Ich dachte du benutzt meine Lib.
Was mir bei deiner verwendeten Lib auffällt ist z.B. dass es egal ist wo
x und y liegt, so ein Display hat ja idR 128*64 Pixel Größe, bei der Lib
hindert mich aber nichts daran auch bei x > 128 und y > 64 was zu
zeichnen.
Ist hier im Thread etwas OT aber wie schon gesagt, es kommt einfach auch
drauf an wohin du im RAM des Displays was reinschreibst und wie sich
dann die Displays verhalten. Genaueres steht im Datenblatt, das ist echt
etwas umfangreich, z.B. kennt das SSD1306 einen automatischen
Zeilenumbruch, man muss also nichts dazu tun um einen Zeilenumbruch zu
erwirken. Meine Lib ist allerdings so aufgebaut dass man hierbei nicht
vom automatischen Zeilenumbruch des SSD1306 profitieren kann. Sinn
dahinter war/ist dass die Befehle dann für das SH1106, dass keinen
automatischen Zeilenumbruch kennt, die selben sind. ;)
Hallo Gemeinde
habe den Artikel gelesen, tolle Sachen dabei. Habe aber ein Problem
damit. Ihr geht vom SSD1306 und einem Display von 0,96`` aus. Moderne
bzw. andere Displays haben den SSD1309 drin. Der kling ähnlich. Wie weit
ist er ähnlich? Kann ich die Libs einfach für ein grösseres Display
nutzen? Sicher muss ich was dazu anpassen. Die Displays haben 128x64.
LG Paul
Paul schrieb:> Das sieht nicht so gut aus mit deinem Hinweis.
Das sieht nicht so gut aus mit deinem Vorhaben. Du bist
zu faul zum Lesen des Datenblatts.
Das hat doch mit der Programmiersprache nicht zu tun. Zur
Initialisierung muss eine Folge von Kommandos (das sind einfache Zahlen,
teils mit Pausen dazwischen) an den Controller gesendet werden.
Diese Sequenzen sind im Datenblatt des Displays in Form von
Flussdiagrammen dargestellt. Jedes einzelne Kommando ist im Datenblatt
des Controllers beschrieben.
Zu prüfen wäre aber auch, ob der Bildspeicher anders organisiert ist.
Ich habe mal die Doku von einem 0,96" SSD1306 Display angehängt.
Heinzi(Gast) schrieb:> Der gute Paul(Gast) will eine mundgerechte Lösung in C und hat> keine> Lust, sich durch den Datenblattwust zu kämpfen ;-)
Wer hat schon Lust sich durch den Datenblattwust zu kämpfen. Ich würde
auch erstmal schaun obs nicht was Mundgerechtes gibt ;)
Mit der Faulheit kann man geteilter Meinung sein. Habe das Datenblatt
angeschaut und versucht es zu verstehen. Ab einem Punkt bin ich
gescheitert, war zu viel für mich.
Das mit Flussdiagramm habe ich gesehen. Habe auch schon versucht etwas
umzusetzen. Es gibt einige Anfänge dazu. Sind zu kaotisch um sie zu
zeigen. Leider ohne Erfolg. Im Datenblatt des Herstellers ist auch eine
Routine dazu drin. Bin am entschlüsseln was wozu ist.
Beim SSD1306 ist ja auf eine andere Grösse bezogen. Wollte es eigentlich
als Grundstein für des SDD1309 nehmen. Einiges scheint zu passen anderes
nicht.
Paul schrieb:> Mit der Faulheit kann man geteilter Meinung sein. Habe das Datenblatt
In der Tat; wenn ein Display nur Mittel zum Zweck sein soll, täte ich
mich „sogar“ nach was Vorhandenem umschauen, z.B. die Uglib2, oder
Sparkfun
https://github.com/sparkfun/HyperDisplay_SSD1309_ArduinoLibrary.
Würde ich eine Lib erweitern oder ergänzen wollen, würde ich mir
sicherlich zuerst die Init-Routinen vorhandener Libs (s.o.) anschauen...
> angeschaut und versucht es zu verstehen. Ab einem Punkt bin ich> gescheitert, war zu viel für mich.> Das mit Flussdiagramm habe ich gesehen. Habe auch schon versucht etwas> umzusetzen. Es gibt einige Anfänge dazu. Sind zu kaotisch um sie zu> zeigen. Leider ohne Erfolg. Im Datenblatt des Herstellers ist auch eine> Routine dazu drin. Bin am entschlüsseln was wozu ist.> Beim SSD1306 ist ja auf eine andere Grösse bezogen. Wollte es eigentlich> als Grundstein für des SDD1309 nehmen. Einiges scheint zu passen anderes> nicht.
Wer hat schon Lust sich durch den Datenblattwust zu kämpfen. Ich würde
auch erstmal schaun obs nicht was Mundgerechtes gibt ;)
Niemand muß doch einen Beitrag schreiben, wenn er es nicht möchte, lässt
er es eben. Wenn er etwas anfängt, wäere es schön, es zu vollenden (ohne
dass das in Stress ausartet, natürlich). Nicht jeder ist in der Lage,
das Datenblatt umzusetzen. Die Lebenszeit ist endlich. Wenn jeder
Erdenbürger bei Null, in der Urzeit anfangen wollte, alles dagewesene
neu zu erfinden, wird nichts fertig oder besser wie das dagewesene. So
eine Lib ist eben meist nur Teil eines Ganzen. Ein Baubetrieb setzt auch
Fertigzement ein und brennt ihn nicht selber. Der Baumensch ist deshalb
nicht faul. So geht eben Fortschritt.
Der Autor der Lib sollte natürlich immer genannt werden. Sein Lohn ist
es, als Berühmtheit in die Geschichte einzugehen.
Gruß
Reinhard
Paul schrieb:> Hallo Gemeinde> habe den Artikel gelesen, tolle Sachen dabei. Habe aber ein Problem> damit. Ihr geht vom SSD1306 und einem Display von 0,96`` aus. Moderne> bzw. andere Displays haben den SSD1309 drin. Der kling ähnlich. Wie weit> ist er ähnlich? Kann ich die Libs einfach für ein grösseres Display> nutzen? Sicher muss ich was dazu anpassen. Die Displays haben 128x64.> LG Paul
Ich hab mich jetzt ein wenig damit beschäftigt und mir auch mal ein
SSD1309-Display beschafft. Das erste, dass mir auffiel ist, dass das
Display standard-mäßig für SPI konfiguriert ist. Meine Library geht aber
von einem I2C-Bus aus, an dem das Display klemmt.
Ich hab mal noch ein wenig aufgeräumt im Code, will nun mal schaun wie
ich das Ganze umschreiben kann sodass es auch mit SPI läuft. Man kann
die SSD1309-Displays anscheinend auch an I2C betreiben, ich bekomme
meins da aber nicht an den Start. Das Suchen nach der I2C-Adresse
schlägt bei mir immer wieder fehl. Und ja, ich hab auch die Widerstände
umgelötet, das Reset-Signal geschickt und CS auf GND gepinnt.
Vom Programmaufruf/-ablauf an sich scheinen SSD1306 und SSD1309
identisch zu sein, ich konnte beim Überfliegen der Datenblätter
diesbezüglich keine Unterschiede feststellen, d.h. wenn man die
Kommunikation auf SPI umschreibt müsste auch ein SSD1309-Display mit der
Library funktionieren.
Ich bin dazu gekommen zu testen und hab meine Library mal von I2C auf
SPI umgeschrieben (nur rudimentär zum testen). Damit lässt sich dann,
wenn die Library auf SSD1306-Displays eingestellt ist, auch ein
SSD1309-Display ansteuern. Das funktioniert. Mal schaun ob ich die Tage
dazu komme, die Library ganz allgemein auf SPI umzuschreiben sodass man
zwischen I2C und SPI wählen kann.
Jörg W. schrieb:> M. K. schrieb:>> unterstützt nun auch SSD1309-Displaycontroller>> Soll ich dir das mal in der Überschrift ergänzen?
Oh, das wäre sehr gut. Danke dir, Jörg ;)
Hallo Sylaina,
herzlichen Dank, wirklich eine tolle Arbeit.
Ist die Lib auch für ESP32 verwendbar? Bzw., wird es eine Anpassung
geben?
Aktuell verwende ich die U8g2lib.h, aber ich bekomme es nicht in den
Griff, dass immer beim Überschreiben die Zeichen nicht komplett
überschrieben werden (z.b. wenn 0 mit 1 überschrieben wird, bleiben am
linken Rand des Zeichens Punkte stehen). Dies tritt z.B. bei einer
Uhrzeitausgabe auf.
Erhoffe mir, dass das Problem bei deinem Verfahren nicht auftritt.
MfG.
Äd
Hallo Äd Franzis,
die Library kann mit Anpassungen auch beim ESP verwendet werden. Hierzu
musst du lediglich die Kommunikations-Funktionen in lcd_data,
lcd_command und lcd_init anpassen.
Ich selbst habe noch keinen ESP und es wird bei mir dieses Jahr auch
kein ESP mehr ins Haus kommen. Grund dafür ist, dass ich noch einige
andere Baustellen habe und mir keine weitere aufmachen will. Es liegt
also nicht daran, dass ich den ESP doof finde, mir fehlt es schlicht nur
an Zeit. ;)
Zu deinem Problem:
Die U8G2lib ist eigentlich sehr gut (leider auch sehr umfangreich
weshalb ich diese Lib nur für SSD1306/SSD1309/SH1106 schrieb). Ich denke
also, dass dein beobachteter Fehler nicht von der Lib herrührt sondern
von deinem Code. Ich kann dir daher empfehlen, dir deinen Code noch mal
genau anzuschaun und auf einem Blatt Karo-Papier und Bleistift mal die
Zeichenfunktionen gemäß dem Code durchzuspielen. Ich denke dann wirst du
den Fehler entdecken ;)
Grüße
Michael
Vielen Dank, Michael, für deine Informationen.
Viel Code ist da ja nicht, da ich ausschließlich Text ausgeben. Habe
mich an einem "Hallo Welt"-Beispiel orientiert.
Ich verwende das Board "WIFI_Kit_32 HTIT-WB32" von Heltec. Darauf
enthalten ist ein 0.96'' 128*64 Display, das über I2C angeschlossen ist.
Hier mal die relevanten Code-Fagmente (alles, was mit dem OLED zu tun
hat):
u8g2.setFont(u8g2_font_ncenB08_tr);// choose a suitable font oder u8g2_font_helvB08_tr
78
u8g2.setFontMode(0);
79
u8g2.drawStr(0,10,pSW_Version);// write something to the internal memory
80
u8g2.sendBuffer();// transfer internal memory to the display
81
/*
82
* END OF SETUP() from 0.92'' OLED
83
*/
84
85
86
//[... ... ... ...]
87
88
Strings0=WiFi.localIP().toString();
89
90
u8g2.drawStr(0,21,s0.c_str());
91
u8g2.sendBuffer();
92
93
//[... ... ... ...]
94
95
}
Problem: Wenn z.B. 1 auf 0 und 7 auf 6 folgt bleiben bei der 1 links
Punkte von der 0 und bei der 7 rechts Punkte von der 6 über. Ganz wild
sieht es aus, wenn die Wochentage überschrieben werden. Das ist dann gar
nicht mehr lesbar.
Vielen Dank.
MfG.
Äd
Wenn ich das richtig sehe löschst du nie den Zeichenbuffer sondern
überschreibst ihn einfach. Das ist dein Problem: Wenn im neuen String
ein Pixel aus sein soll, im alten aber ein Pixel an ist dann wird dieser
Pixel nicht ausgeschaltet. Am besten immer erst mal den Zeichenbuffer
löschen und dann neu reinschreiben, so wie das im Setup ja auch gemacht
wird ;)
Hallo Sylaina,
herzlichen Dank, das ist ein ganz wichtiger Hinweis.
Das heißt dann aber auch, ich kann immer nur den kompletten
Display-Bereich schreiben, oder wie? Ich habe jezt SW-Version und IP in
der initialisierung Datumsangaben nur um Mitternacht und die Uhrzeit
halt alle 500ms geschrieben. Ich dachte, es ist effizienter, als immer
alles zu beschreiben. So habe ich es immer beim LCD-Display gemacht.
Oder kann ich auch einen Teil des Buffers löschen, also immer die Zeile,
die ich auch neu beschreibe will.
Oder anders gefragt: Wird eh jedesmal mit u8g2.sendBuffer() der gesamte
Buffer geschickt, d.h. immer die gleiche Datenmenge. Dann würde ich
natürlich durch mein vorgehen eh nichts sparen.
MfG.
Äd
Äd Franzis schrieb:> Wird eh jedesmal mit u8g2.sendBuffer() der gesamte> Buffer geschickt, d.h. immer die gleiche Datenmenge.
Ja, wird es. u.a. deshalb habe ich die Library entwickelt, im Textmode
ist meine Library erheblich schneller als die u8g-Library da ich im
Textmode nur an der Stelle ins Display schreibe, in der ich Daten ändern
will, und nicht den gesamten Displayinhalt neu beschreiben muss.
Hallo Sylaina,
vielen Dank. Dann schließt sich jetzt der Kreis und ich komme wieder zu
der Frage:
Äd schrieb:> Ist die Lib auch für ESP32 verwendbar? Bzw., wird es eine Anpassung geben?
und:
Äd schrieb:> Erhoffe mir, dass das Problem bei deinem Verfahren nicht auftritt.
Ist denn bei deiner Lib auch das Problem, dass ich trotzdem den ganzen
Buffer vor dem Überschreiben löschen muss? Oder kann ich auch
zeilenweise löschen und nicht nur schreiben.
MfG.
Äd
Äd Franzis schrieb:> Oder kann ich auch> zeilenweise löschen und nicht nur schreiben
Jein - Du kannst zeilenweise Leerzeichen reinschreiben und dann das, was
Du dort sehen willst.
Äd Franzis schrieb:> Dann schließt sich jetzt der Kreis und ich komme wieder zu> der Frage:
Die hatte ich schon beantwortet: Ja, du musst nur die lcd_command,
lcd_data und lcd_init bzgl. der Kommunikation für den ESP anpassen ;)
Äd Franzis schrieb:> Ist denn bei deiner Lib auch das Problem, dass ich trotzdem den ganzen> Buffer vor dem Überschreiben löschen muss?
Im Grafikmode: Jain (du müsstest mit meiner Lib den Bereich löschen, der
neu beschrieben werden soll).
Im Textmode: Nein, da gibts keinen Buffer, da wird direkt ins Display
geschrieben.
Hallo,
ich hoffe hier kann mir jemand bei meinem Anliegen helfen, ich möchte
ein OLED-Display als Statusanzeige (wie die serielle Console von
Arduino) benutzen und würde immer gerne die letzen 7 Zeilen anzeigen.
Mit folgendem Code werden die ersten 7-Zeilen angezeigt, aber der Rest
wird nicht mehr angezeigt!
Bob H. schrieb:> Bitte um dringende Hilfe!
Bitte einen eigenen Thread in "Microcontroller + Elektronik" öffnen.
Bitte Netiquette beachten, insbesondere viel mehr Details zu deinem
Problem schreiben.
Hallo M.K.
M. K. schrieb:> Die hatte ich schon beantwortet: Ja, du musst nur die lcd_command, lcd_data und
lcd_init bzgl. der Kommunikation für den ESP anpassen ;)
ups, stimmt, hattest du schon beantwortet. Vor lauter, lauter...
Werde mir das später mal anschauen, ob ich das anpassen kann. Bin auch
erst Einsteiger. Wenn nur die digitalen Ausgänge anzupassen, wäre das ja
schnell gemacht, aber I2C direkt ansteuern habe ich bisher noch nicht
gemach. Würde dann schon gerne deine schlanke lib verwenden.
Hallo Hugo
Hugo H. schrieb:> Jein - Du kannst zeilenweise Leerzeichen reinschreiben und dann das, was Du dort
sehen willst.
Bei der U8g2lib genügt das leider nicht. Ich hab's probiert; Ergebnis
ist unverändert. Es bleiben also immer noch einzelne Pixel stehen.
Vermute, auch das Leerzeichen ist quasi transparent. Man müsste ein
schwarzen Leerzeichen haben.
Habe nun auf die U8x8lib gewechselt, da funzt es genau so, wie du sagst.
Aber dann passen immer nur 16 Zeichen in einer Zeile. Schade, aber OK.
Im Moment läuft die OLED-Ausgabe mal zufriedenstellend. Wäre schön, wenn
ich die LIB aus diesem Thread hier für ESP umschreiben kann. Ansonsten
werde ich später doch wieder zur U8g2lib zurückkehren, und dann jeweils
vor'm Schreiben einer Zeile die Pixel mit einem schwarzen Rechteck
"löschen".
Ich lasse es euch wissen, wird aber etwas dauern.
Herzlichen Dank euch allen.
Liebe Grüße,
Äd.
Äd Franzis schrieb:> lcd_init bzgl. der Kommunikation für den ESP anpassen ;)> ups, stimmt, hattest du schon beantwortet. Vor lauter, lauter...> Werde mir das später mal anschauen, ob ich das anpassen kann. Bin auch> erst Einsteiger. Wenn nur die digitalen Ausgänge anzupassen, wäre das ja> schnell gemacht, aber I2C direkt ansteuern habe ich bisher noch nicht> gemach. Würde dann schon gerne deine schlanke lib verwenden.
Das muss man sich nur einmal an einem ruhigen Nachmittag anschaun, dann
sieht man recht zügig, dass I2C doch eigentlich schon mega einfach ist
was u.a. den Charme von dieser Schnittstelle aus macht. Also keine
Furcht davor ;)
Hallo M. K.
M. K. schrieb:> Also keine Furcht davor ;)
Danke für's Mutmachen. :)
Ja, schaue es mir gerne an. Habe vorher noch ein paar andere Steine aus
dem Weg zu rollen (das OLED ist nicht die einzige Baustelle), aber dann
wird dieser Nachmittag mal kommen. Vielleicht komme ich dann aber auch
nochmal mit 'ner Frage hierher. Denke, dass dann dein LIB auch für
andere ESP-User von Nutzen sein wird.
Liebe Grüße,
Äd.
Beitrag "Re: SSD1306 Library zum Darstellen von Text auf OLED Displays"
Wegen einer Nachfrage habe ich das OledBm-Tool zum Generieren des
C-Codes noch erweitert. Es kann jetzt zusätzlich auch noch den Binärcode
als Datei rausschreiben. Für eine 128x64 Bitmap wird also eine 1.024
Byte große Datei erstellt.
Zudem noch der Sourcecode dazu, ist C# und z.B. mit VS 2019
kompilierbar.
Hallo Sylaina,
Diese Library ist der Hammer. Ich bin Anfänger und fand mich gut
zurecht! Wirklich ausgezeichnete Arbeit. Was mich sehr freuen würde,
wäre eine Funktion für das Ausgeben von einer Zahl und Zahlen mit
Kommastellen. Ich dachte zuerst das ich einfach anstelle einen Text auch
eine Variabel nehemen könnte. Aber dies funktionierte nur ein mal
leider. Dan wird die Zahl nicht mehr aktualisiert. Dan habe ich ein
wenig herumprobiert aber musste schlussendlich aufgebe. Mit meinen
Kentnissen konnte ich das nicht bewältigen. Wäre somit der Hammer wen
die Library um diese Funkton erweitert werden könnte.
Mit freundlichen Grüssen
Daniel
Daniel I. schrieb:> Was mich sehr freuen würde,> wäre eine Funktion für das Ausgeben von einer Zahl und Zahlen mit> Kommastellen.
1
charpuffer[5];
2
sprintf(puffer,"%0.2f",0.99);
3
lcd_puts(puffer);
https://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm
Achtung: Der Puffer muss mindestens ein Zeichen größer sein, als die
längste erwartete Textausgabe. Das heisst in diesem Fall, dass die Zahl
im Bereich 0.00 bis 9.99 liegen muss, sonst gibt es einen
Speicher-Überlauf.
Hallo!
Frage zum Verwenden von 128 X 32 Oleds (also die Kleinen).
funktioniert das mit der gegebenen Library schon (Wenn ja einfach diesen
Beitrag ignorieren)? Ansonsten habe ich da eine sehr einfache Lösung. Es
muss lediglich in der Initalisierung was geändert werden, ansonsten
bleibt alles gleich...
Hier kurz die Änderung:
In der Initialiserungssequenz muss folgendes abgeändert werden:
Von derzeit:
0xDA, 0x12, // Set com pins hardware configuration
Auf:
0xDA, 0x02, // Set com pins hardware configuration
zudem muss dann natürlich noch in den DEFINES der Wert für
DISPLAY_HEIGHT entsprechend auf 32 geändert werden.
Begeisterter schrieb:> Hier kurz die Änderung:>> In der Initialiserungssequenz muss folgendes abgeändert werden:>> Von derzeit:> 0xDA, 0x12, // Set com pins hardware configuration>> Auf:>> 0xDA, 0x02, // Set com pins hardware configuration>> zudem muss dann natürlich noch in den DEFINES der Wert für> DISPLAY_HEIGHT entsprechend auf 32 geändert werden.
So schaut es aus ;)
Hallo Sylaina,
ich möchte dir zuerst mal Danken für die tolle Lib und zweites noch eine
Rückmeldung zur Verwendung mit einem OLED 0,91" 128x32 Display geben.
Angeschlossen habe ich das ganze an einem Arduino Nano zuerst mit der
bekannten Adafruit_SSD1306 und der Adafruit-GFX-Library.
Das Display funktioniert da ja soweit ganz gut jedoch 'fressen' mir die
beiden Lib's in meinem Projekt den restlichen Speicher auf.
Da ich aber eh nur Textausgaben machen will, würde mir deine Lib sehr
helfen.
Jedoch ist die Darstellung so nicht zu gebrauchen (siehe Image1). Sieht
alles irgendwie zu klein aus und in die untere Hälfte verschoben.
In der LCD.h habe ich folgende Werte angepasst:
1
/* TODO: define bus */
2
#define I2C // I2C or SPI
3
#define SSD1306 // SH1106 or SSD1306, check datasheet of your display
4
#define TEXTMODE // TEXTMODE for only text to display,
5
#define FONT ssd1306oled_font // set font here, refer font-name at font.h/font.c
6
#define LCD_I2C_ADR (0x78 >> 1) // 7 bit slave-adress without r/w-bit
Als kleines Testprogramm habe ich nur folgende Zeilen:
1
#include<font.h>
2
#include<i2c.h>
3
#include<lcd.h>
4
5
voidsetup(){
6
7
lcd_init(LCD_DISP_ON);
8
lcd_clrscr();
9
lcd_set_contrast(0x00);
10
lcd_charMode(NORMALSIZE);
11
lcd_gotoxy(0,0);
12
lcd_puts("Normal Size");
13
lcd_charMode(DOUBLESIZE);
14
lcd_gotoxy(0,1);
15
lcd_puts("DoubleSize");
16
}
17
18
voidloop(){
19
// put your main code here, to run repeatedly:
20
21
}
Da das Display und die Ausgaben in den Adafruit-Libs richtig
funktioniert, hab ich mal auf die Suche gemacht, warum es mit deiner Lib
nicht gehen soll.
Aufgefallen ist mir dabei ein Unterschied in der Init-Sequenz:
In der Adafruit_SSD1306.cpp steht beim Init u.A. folgendes:
D.h.: Bei einem Display mit 32 Pixel Höhe wird comPins mit 0x02
initalisiert und bei 64 Pixels mit 0x12.
In deiner LCD.c hab ich dann die Init-Sequenz mal geändert
1
0x02,// Set com pins hardware configuration for Display 128x32
2
//0x12, // Set com pins hardware configuration for Display 128x64
Und siehe da, die Ausgabe passt jetzt (siehe Image 2).
Event. hilft die Info ja jemanden weiter bzw. kannst du in einem Update
das mal einpflegen.
Danke und Gruß,
Bernardo
Das scheint eine Besonderheit bei deinem Display zu sein.
Meine 128x32 Displays funktionieren richtig, wenn ich mit 0x12
initialisieren.
Ich habe deinen Hinweis mal als Kommentar in meine (das ist eine andere)
Bibliothek eingebaut, dann findet man es später schneller.
Ob das ein bessonderes Display ist kann ich nicht sagen, aber in der
Library von Adadfruit SSD1306 (Adafruit_SSD1306.cpp s.o.), ist das fest
für 128x32 Displays eingestellt (wenn ich das richtig Überblicke).
Und diese Library wird von sehr vielen verwendet.
Event. geht dein Display ja auch mit der Einstellung comPins 0x02 ?
Stefan ⛄ F. schrieb:> Meine 128x32 Displays funktionieren richtig, wenn ich mit 0x12> initialisieren.
Sorry ich habe das etwas verwechselt. Ich habe auch mit 0x02
initialisiert.
Hallo Bernhard,
ich muss mich unbedingt noch mal hinsetzen und meine Lib überarbeiten.
Sie ist, wie schon einigen aufgefallen ist, für die 128x64er Displays
geschrieben, für Displays mit anderer Auflösung muss die Library
angepasst werden und das fängt schon in der Init-Routine an aber auch in
den Zeichenroutinen und Co muss z.B. die Abfragen der Art
1
...
2
if((WIDTH==128)&&(HEIGHT==64)){
3
...
angepasst werden. Ich danke dir für deine Rückmeldung, ich werde mal
schaun dieser Tage die Ergänzung für die Init-Sequence einfließen zu
lassen.
Oh, das muss ich mal ausprobieren. Passt das dann immer noch mit den
Zeilen und Spalten Abfragen (also diese Teile: if( x > DISPLAY_WIDTH-1
|| y > (DISPLAY_HEIGHT-1)) return; // out of Display)? Ich denke nicht,
oder? Ich schätze mal WIDTH und HEIGHT muss man dann auch tauschen.
Nö, die Drehung ist doch 180°.
DISPLAY_WIDTH und DISPLAY_HEIGHT werden nur bei 90° bzw. 270°
vertauscht.
Das ist dann aber komplizierter.
Edit:
Ist nicht auf meinem Mist gewachsen, sondern stammt aus der
u8g2/u8x8-Lib.
Ich konnte auf dieser Weise mein Layout retten.
Edit2:
Ich habe nur den TEXTMODE benutzt
Jörg F. schrieb:> Nö, die Drehung ist doch 180°.
Achja, stimmt ja, ist ja Flip...war schon zu spät gestern für mich.
Jörg F. schrieb:> Ich habe nur den TEXTMODE benutzt
Sollte im Graphicsmode auch gehen denn die Funktion dreht am RAM-Inhalt
des Displays ;)
Der Text steht nach dem Flip zwar auf dem Kopf ist aber in
Spiegelschrift.
Nach einem lcd_clear und der neuen Ausgabe des Textes ist aber wieder
alles OK. Ich denke den Flip benutzt man ähnlich den init nur ein
einziges Mal im Programm, da das Display ja nicht auf einem
Rotationteller ist.
M. K. schrieb:> Wie soll das funktionieren also ohne Puffer funktionieren?
Ich könnte mir einen FIFO mit Zeichenbefehlen vorstellen. Hierbei könnte
eine Scanline gepuffert werden und alle Zeichenkommandos dann Scanline
für Scanline abgearbeitet und zeilenweise an's Display übertragen
werden. Hierfür muss man nur die übliche y-Schleife der Zeichenbefehle
in eine finale Zeichnen & Senden-Funktion auslagern.
Da hier im Flash gespeicherte Bitmaps und Fonts einfach per Adresse
referenziert werden können und für Linien und Formen einfach die
Eckkoordinaten gespeichert werden können, kann solch eine Vorgehensweise
recht effizient sein. Hier muss jedoch bei jeder Änderung eines
Bildschirmbereiches dieser Teil neu gezeichnet werden. Die Erzeugung des
Zeichenbefehlspuffers muss also in jedem Frame passieren. Die
Übertragungssoftware könnte dann immer den kleinstmöglichen Bereich
rendern und zeilenweise übertragen.
Benedikt M. schrieb:> Hier muss jedoch bei jeder Änderung eines> Bildschirmbereiches dieser Teil neu gezeichnet werden.
Und genau das ist ja der Knackpunkt. Wenn man den Displayinhalt nicht
löschen will ist man gezwungen mit dem Puffer zu arbeiten da man die
Displays typischerweise nicht auslesen kann (könnte man sie auslesen
wäre es einfach ;)).
M. K. schrieb:> Und genau das ist ja der Knackpunkt. Wenn man den Displayinhalt nicht> löschen will ist man gezwungen mit dem Puffer zu arbeiten
Doch, das Problem ist damit ja auch adressiert. Wenn man den
Bildschirminhalt nur teilweise verändert, kann man die (nach
Einschätzung des Entwicklers) gleich geliebenen Bildschirmteile nicht
aktualisieren, dafür aber die veränderten Regionen. Wenn die Elemente im
Puffer in den zu aktualisierenden Bereichen gleich bleiben, kann man die
Updates problemlos in den aktuellen Bildschirminhalt einfügen.
Beispiel: Bitmap mit Textoverlay. Der Text soll geändert werden.
Hier reicht es, nur den Teil mit dem Text erneut an das Display zu
senden.
Im Puffer ist dasselbe Bitmap weiterhin an derselben Stelle vorhanden.
Ändert man nun den Text, können exklusiv die Scanlinien, die Bitmap und
Text enthalten haben, einfach neu berechnet und an den Framebuffer im
Display gesendet werden. Da der Output deterministisch ist, funktioniert
das auch ohne Update des gesamten Bildschirms, oder Lesen des
Framebuffers.
> (könnte man sie auslesen wäre es einfach ;))
Einfach ist doch langweilig ;-)
Benedikt M. schrieb:> Beispiel: Bitmap mit Textoverlay. Der Text soll geändert werden.> Hier reicht es, nur den Teil mit dem Text erneut an das Display zu> senden.
Und hier jetzt der Gedankenanstoß: Man will nicht den Text, der da schon
im Display steht, löschen sondern einfach einen weiteren Text drüber
schreiben. Schon hast du ein Problem wenn du nicht weißt, welcher Text
da schon drin steht.
OK, bei Text ist das nicht unbedingt sinnvoll aber wenn man irgend etwas
x-beliebiges zeichnet kann ich mir schon vorstellen, dass man das schon
Gezeichnete nicht löschen will sondern einfach drüber zeichnen will,
Beispiel Koordinatensystem mit verschiedenen Kurvenverläufen und Gitter
usw. (bedenke: Diese Displays können auch nicht ein einzelnes Pixel
ändern, es sind immer mindestens 8 Pixel)
Natürlich kann man vom Puffer bei speziellen Anwendungen weg kommen, die
Textversion ist ja sowas quasi, aber allgemein kommst du nicht um den
Puffer rum wenn du keine Informationen verlieren willst.
Hallo Michael,
ich habe schon vor einiger Zeit benutzt und fand die shon richtig
klasse!
Nun habe ich ein kleines Problem mit der Initialisierung des kleineren
Displays (64x48).
Ich habe die entspr. Befehle 0x21 - Set column address und 0x22 - Set
page address gefunden. Ich weiß allerdings nicht wo ich das einbauen
muss.
Ich habe bereits an folgender Stelle ausprobiert und gesehen, dass die
anzeige sich auch verschiebt. Sobald ich auch die Displaygröße von
128x64 auf 64x48 einstelle sehe ich meine gezeichnete Linie nicht mehr.
Wie ich sehen konnte ist das nicht die richtige stelle, da du in
weiteren Funktionen den Pointer (im Display) veränderst.
1
voidlcd_data(uint8_tdata[],uint16_tsize){
2
#if defined I2C
3
//Test set memory area
4
constuint8_tdef_mem_area[]={// Adressbereich für kleiner Displays als 128x64
5
0x21,//Set column address
6
32,//Start column
7
95,//End column
8
0x22,//Set page address
9
2,//Start page
10
7//End page
11
};
12
lcd_command(def_mem_area,sizeof(def_mem_area));
13
// Test Ende
14
15
i2c_start((LCD_I2C_ADR<<1)|0);
16
i2c_byte(0x40);// 0x00 for command, 0x40 for data
17
for(uint16_ti=0;i<size;i++){
18
i2c_byte(data[i]);
19
}
20
i2c_stop();
Ich habe deine Lib (nicht die aktuellste) auf diesem (64x48) und auf
einem noch kleineren (48x32)Display ausprobiert. Buffer war dabei auf
128x64 gesetzt. Dabei habe ich gesehen, dass die sichtbaren Zellen des
Displays immer horizontal zentriert und vertikal am unteren Rand des
RAMs des Kontrollers ausgerichtet sind. Somit kann den ganzen Display
RAM ansprechen, sehe dann aber nur den 'sichtbaren' Teil der Ausgabe.
Was kann ich ich machen, an welchen Stellen müsste ich ansetzen?
Viking schrieb:> Was kann ich ich machen, an welchen Stellen müsste ich ansetzen?Viking schrieb:> Ich habe deine Lib (nicht die aktuellste)
Erstelle eine Sicherung deines Projektes und verwende dann mal die
aktuelle Version der Lib. In der alten Version gab es in der Tat
Probleme bei anderen Displaygrößen, dass aber inzwischen bearbeitet
wurde. Ggf. funktionieren deine Displays aus mit der aktuellen Lib
fehlerfrei.
HalloMichael,
danke für deine schnelle Antwort. Ich habe es vielleicht
missverständlich geschrieben. Ich habe schon die aktuelle Version von
github verwendet.
Ich werde nochmals ausprobieren und mit einem Foto dokumentieren.
Einen interessanten Ansatz habe ich hier gefunden.
http://www.technoblogy.com/show?WNM
Ein Teil deiner Init. scheint keine Auswirkung zu haben. Laut Datenblatt
sind die Befehle welche die Start page und column festlegen nur bei der
page Adressierung wirksam.
Ich schreibe gerade von meinem Handy, daher mit spärlichen Infos. Ich
werde mich die Tage melden sobald ich es getestet habe.
Danke und bis dahin...
Hallo Michael,
ich habe nochmals die aktuelle Lib (github) passend für das Display
konfiguriert. Für die Ausgabe habe habe ich dein Beispiel aus der Main.c
verwendet. (s. Bild - Aktuelle_Lib.jpg)
1
2
intmain(void)
3
{
4
lcd_init(LCD_DISP_ON);// init lcd and turn on
5
6
lcd_puts("Hello World");// put string from RAM to display (TEXTMODE) or buffer (GRAPHICMODE)
7
lcd_gotoxy(0,2);// set cursor to first column at line 3
8
lcd_puts_p(PSTR("String from flash"));// puts string form flash to display (TEXTMODE) or buffer (GRAPHICMODE)
9
#if defined GRAPHICMODE
10
lcd_drawCircle(64,32,7,WHITE);// draw circle to buffer white lines
11
lcd_display();// send buffer to display
12
#endif
13
/* Replace with your application code */
14
while(1)
15
{
16
}
17
}
Die Konfiguration für das Display sieht so aus:
#define DISPLAY_WIDTH 64
#define DISPLAY_HEIGHT 48
Im zweiten Bild (alte_Lib.jpg) habe ich die frühere version der Lib
verwendet. Die Ausgabe auf dem Display täuscht allerdings. Ich musste
Buffer mit 128x64 pix initialisieren. Mit folgendem Code habe ich auch
rausgefunden wie die kleineren Displays an den Kontroller angebunden
sind.
ACHTUNG!: Der Codeschnipsel ist jedoch auf die Ausgabe auf dem noch
kleineren Display (64x32) angepasst. Im Bild ist eine 64x48 Display zu
sehen.
1
#if defined GRAPHICMODE
2
lcd_drawPixel(32,32,WHITE);//quasi 0.0 (x.y)
3
lcd_drawPixel(95,32,WHITE);// x-ende
4
lcd_drawPixel(32,63,WHITE);// x-ende, y-start
5
lcd_drawPixel(95,63,WHITE);// x,y-ende
6
lcd_gotoxy(6,4);
7
lcd_puts_p(PSTR("1. Zeile"));//start ab dem 2. Zeichen
8
lcd_gotoxy(6,5);
9
lcd_puts_p(PSTR("2. Zeile"));
10
lcd_gotoxy(6,6);
11
lcd_puts_p(PSTR("3. Zeile"));
12
lcd_display();// send buffer to display
13
#endif
Zusammenfassung:
Atmel Studio 7.0.1645
Atmega328P (20MHz)
Hab jetzt schon ein paar Tage hier nicht reingeschaut, ich muss mal bei
Gelegenheit ein Testaufbau mit dem Display umsetzen. Was mir aber hier
jetzt auf Anhieb auffiel war, dass du z.B. schriebst:
Viking schrieb:>
1
lcd_gotoxy(6,6);
Da dein Display 48 Pixel hoch ist und jede Zeile 8 Pixel hoch ist hat
man zwar 6 Zeilen aber die 6. Zeile hat den Index 5, es müsste also
heißen
1
...
2
lcd_gotoxy(6,5);
3
...
um in die 6. Zeile zu schreiben. Ich weiß grad nicht, ob das eigentlich
von der Lib aufgefangen werden sollte.
Auch nicht so gut ist
Viking schrieb:>
1
lcd_drawPixel(95,32,WHITE); // x-ende
da du ja selbst schriebst, dass dein Display nur 64 Pixel breit ist. Da
als X 95 nun anzugeben kann auch "knallen" (das müsste abgefangen sein
und dürfte nicht zu Ausführung kommen).
Zudem muss die Initialisierung angepasst werden, ich hab ja nur eine
Initialisierung für 64 Pixel Displayhöhe und für 32 Pixel Displayhöhe.
Das könnte sich auch beißen wenn man als Displayhöhe 48 angibt.
M. K. schrieb:> Hab jetzt schon ein paar Tage hier nicht reingeschaut,
Gibt es eine fertige .ino, die unter Arduino Hello World in
unterschiedlichen Größen darstellt?
Arduino schrieb:> Gibt es eine fertige .ino, die unter Arduino Hello World in> unterschiedlichen Größen darstellt?Worauf willst du den Text darstellen?
Meine Gegenfrage soll klar machen, dass es nicht nur eine ino für
diesen Zweck geben kann.
Stefan ⛄ F. schrieb:> Worauf willst du den Text darstellen?
Auf dem OLED, wie lautet der Titel vom Thread?
(Library zum Darstellen von Text auf OLED Displays)
> Meine Gegenfrage soll klar machen, dass es nicht nur eine ino für> diesen Zweck geben kann.
Deine Gegenfrage ergibt für mich keinen Sinn.
Arduino schrieb:> Deine Gegenfrage ergibt für mich keinen Sinn.
Es gibt viele unterschiedliche Displaygrößen, die man mit der Library
ansteuern kann. Ein Testprogramm würde nur Sinn ergeben, wenn es an den
Display-Typ und die Display-Größe angepasst ist.
Stefan ⛄ F. schrieb:> Es gibt viele unterschiedliche Displaygrößen,> die man mit der Library ansteuern kann.M. K. schrieb:> Ich habe eine kleine Library für den Displaycontroller SSD1306> geschrieben, wie er häufig bei den 0.96" OLED-Displays eingesetzt wird.
Genau dieses, Standard-Chinese in Schwarz-Weiß.
Arduino schrieb:> Gibt es eine fertige .ino, die unter Arduino Hello World in> unterschiedlichen Größen darstellt?
Ne INO dafür habe ich nicht aber du kannst den Code so eins-zu-eins in
die INO schreiben, die Lib muss dann im selben Ordner liegen, und das
ganze Kompilieren. Die Arduino IDE kann nämlich auch C ;)
Alternativ kannst du auch weiterhin der typischen Syntax der Arduino-IDE
folgen, die Library ist inzwischen angepasst, dass sie ohne Änderung in
der Arduino-IDE benutzt werden kann.
Ich rate dir dich mal damit zu beschäftigen wie man das genau macht. Es
ist nicht schwer, sogar sehr einfach und du wirst es wohl noch öfter
benötigen wenn du Libs von anderen Quellen als Arduino benutzen
möchtest. Gehört IMO zu den Grundlagen die man beherrschen sollte bei
der Programmierung von Mikrocontrollern.
Hallo Michael,
ich komme in letzter Zeit auch nur sporadisch dazu und auch ich habe
lange hier nicht reingeschaut.
Ich habe einwenig experementiert und folgendes ist dabei herausgekommen.
Ich habe die Initialiesierung etwas entschlackt, soweit ich mich
errinere waren da noch Befehle enthalten welche nur für page addressing
gedacht sind. Mit "TODO" habe ich bei mir noch die stelle markiert wo
man die Grenzen des sichtbaren Bereichs im RAM setzen muss, hier 64x48.
Initialisierung:
- einiges ist noch auskommentiert, da ich mich damit noch nicht
beschäftigt habe.
0xD5, // --set display clock divide ratio/oscillator frequency
37
0xF0, // --set divide ratio
38
// Set com pins hardware configuration
39
#if DISPLAY_HEIGHT==64
40
0xDA, 0x12,
41
#elif DISPLAY_HEIGHT==32
42
0xDA, 0x02,
43
#endif
44
*/
45
};
Da ich nur die Grafikfunktionen verwende habe ich was eigenes gebaut
bzw. zusammenkopiert. Da die Grenzen des Displays bereits bei der Init
eingestellt werden und die Größe des Buffer da rein passt funktioniert
das wunderbar! Ich aktualieseiere dabei immer die gesammte Anzeige.
Ausgabe Buffer:
Hallo,
ich habe auf der oben verlinkten Github-Seite die Library
heruntergeladen. Ich steuere damit ein 0.96" Display mit 128x64 Pixel.
Ich schreibe mit
1
lcd_init(LCD_DISP_ON);
2
lcd_gotoxy(0,0);
3
lcd_puts("123");
Daten zum Testen auf das Display. Ich habe mittlerweile auch ein
umfangreiches Programm mit dem noch viel mehr Daten auf das Display
geschrieben werden. Es funktioniert alles ohne Probleme.
Jetzt habe ich mir folgendes Display mit 0.49" und 64x32 Pixel gekauft.
https://www.amazon.de/gp/product/B07QGZ4SRF/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
Ich bekomme mit dem oben stehenden Testcode keine Anzeige auf das kleine
Display. Da ich schon einen defekt oder falsche I2C-Adresse vermutet
habe habe ich extra die Arduino-IDE gestartet (zum Programmieren nehm
ich Atmel Studio). In Arduino gibt es einen I2C-Sniffer. Der gibt mir
die Adresse 0x3c zurück, die gleiche wie das große Display.
In der lcd.h habe ich folgendes angepasst:
1
#define LCD_I2C_ADR 0x3c
2
#define DISPLAY_WIDTH 64
3
#define DISPLAY_HEIGHT 32
Ich bekomme einfach keine Anzeige auf das Display.
Controller ist bei beiden Displays ssd1306.
Hat jemand noch eine Idee was man noch überprüfen könnte???
arduino nutzt nur rechtsshift Adressen 0-127
Mit AVR Studio habe ich angefangen und das write Bit selber behandelt!
http://www.peterfleury.epizy.com/avr-software.html?i=1
Du musst schon wissen wie du die I2C Adressen behandelst.
In den Datenblättern von I2C devices ist immer 8 Bit genannt, die
obersten 7 Bit sind die Adresse, Bit 0 ist das WR Bit.
Arduino 0-127 AVR 0-255 und Bit0 ausklammern
#if (ARDUINO>0)
DEBUG_PRINTLN(F(" -> Scanning..."));
char _i2c_key=0;
byte error, address;
int nDevices=0;
for(address = 1; address < 127; address++ ) { // The i2c_scanner uses
the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
DEBUG_PRINT(F("I2C device found at address 0x"));
if (address<16)
DEBUG_PRINT(F("0"));
DEBUG_PRINT_DEC_HEX(address,HEX);
DEBUG_PRINT(F("; "));
if (address<64)
DEBUG_PRINT(F("0"));
DEBUG_PRINT_DEC_HEX(address,BIN);
DEBUG_PRINT(F("x; << 0x"));
DEBUG_PRINT_DEC_HEX((address<<1),HEX);
DEBUG_PRINT(F("; "));
if ((address<<1)<128)
DEBUG_PRINT(F("0"));
DEBUG_PRINT_DEC_HEX((address<<1),BIN);
DEBUG_PRINT(F("; "));
switch(address<<1) {
case 0x40:
//i2c_test_flags|=(1<<I2C_TASTATUR);
i2c_test_flags|=(1<<I2C_TASTATUR_8574);
_i2c_key=' ';
DEBUG_PRINTLN(F("PCF8574 Tastatur"));
break;
case 0x70:
//i2c_test_flags|=(1<<I2C_TASTATUR);
i2c_test_flags|=(1<<I2C_TASTATUR_8574A);
_i2c_key='A';
DEBUG_PRINTLN(F("PCF8574A Tastatur"));
break;
case 0x78:
DEBUG_PRINTLN(F("I2C OLED"));
break;
case 0xA0:
case 0xA1:
case 0xA2:
case 0xA3:
case 0xA4:
case 0xA5:
case 0xA6:
case 0xA7:
DEBUG_PRINTLN(F("I2C_EEPROM"));
i2c_test_flags|=(1<<I2C_EEPROM);
DEBUG_PRINT(F("VOR eep_address FIND: "));
DEBUG_PRINTLN_DEC_HEX(eep_address, HEX);
eep_address=(address);
DEBUG_PRINT(F("NACH eep_address FIND: "));
DEBUG_PRINTLN_DEC_HEX(eep_address, HEX);
break;
case 0xD0:
Wire.beginTransmission(DS1307_ID);
Wire.write(0x3F);
if(Wire.endTransmission())
i2c_test_flags|=(1<<I2C_RTC_3231);
if(i2c_test_flags&(1<<I2C_RTC_3231))
DEBUG_PRINTLN(F("DS3231 RTC"));
break;
default:
DEBUG_PRINTLN();
break;
}
nDevices++;
} // if (error == 0)
else if (error==4) {
DEBUG_PRINT(F("Unknow error at address 0x"));
if (address<16)
DEBUG_PRINT(F("0"));
DEBUG_PRINTLN_DEC_HEX(address,HEX);
} // ! if(error==4)
} // for(address = 1; address < 127; address++ )
if (nDevices == 0)
DEBUG_PRINTLN(F("No I2C devices found"));
else
DEBUG_PRINTLN(F("done"));
DEBUG_PRINTLN();
#else // kein Arduino hier andere Methode einbinden
#endif // #if (ARDUINO>0)
0x3c ist ja die 0x78 um eine Stelle geschoben. Ich habe auch schon beide
Varianten ausprobiert. Arduino erkennt das kleine und das große Display
als 0x3c. Von daher müsste es ja ok sein wenn ich das kleine mit dem
Atmel Studio auch mit 0x3c anspreche, beim großen funktioniert es ja
auch mit 0x3c (wie gesagt, beide geben im Sniffer ja auch den
identischen Wert zurück).
R. F. schrieb:> 0x3c ist ja die 0x78 um eine Stelle geschoben. Ich habe auch schon beide> Varianten ausprobiert.
na denn weisst du ja bescheid
Ich habe aber auch einige I2C OLEDs gehabt die sich ums verrecken nicht
ansprechen liessen, entweder ich bin zu dusslig oder mir wurde Mist
geliefert, ist aus China auch schon öfter vorgekommen, aber wegen <=10€
macht man keinen Aufriss.
Ich bin ein klein wenig weiter gekommen.
Ich habe jetzt erst mal das AVR Studio beiseite gelegt und die
ArduinoIDE genommen.
Mein 0.96 lässt sich mit dem HelloWorld Beispiel und folgender
Displaydefinition zum Leben erwecken.
Weis jemand was der Unterschied zwischen diesem NONAME und 1F ist?
Über die Doku zur Library auf https://github.com/olikraus/u8g2 bin ich
bisher nicht weiter gekommen.
Joachim B. schrieb:> schau doch in den Code!
Da werd ich bei meinen derzeitigen Programmierkenntnissen nicht schlau
draus. Das einzige was mir bisher aufgefallen ist wäre eine
unterschliedliche multiplex ratio.
Hier steht in
1
u8x8_d_ssd1306_64x32_noname_init_seq[]=
1
U8X8_CA(0x0a8,0x02f),/* multiplex ratio: changed from 0x1f to 0x2f */
und in
1
u8x8_d_ssd1306_64x32_1f_init_seq[]=
1
U8X8_CA(0x0a8,0x01f),/* multiplex ratio: changed from 0x1f to 0x2f, 23 Sep 17: changed back to 1f */
Laut dem müsste es also 1f sein.
In der c-Library die ich verwende steht:
1
0xA8,DISPLAY_HEIGHT-1,// Set multiplex ratio(1 to 64)
Da ich bei DISPLAY_HEIGHT den Wert 32 eingebe wäre das Ergebnis 31. Und
das ergibt in HEX 1F. Demnach wäre das der richtige Wert welcher mit dem
Display funktionieren sollte.
R. F. schrieb:> Da werd ich bei meinen derzeitigen Programmierkenntnissen nicht schlau> draus.
dann musst du tiefer schauen, hier ist nicht zu sehen,
dort ist gehts weiter:
R. F. schrieb:> U8X8_CA(
In der Arduino-Library habe ich noch folgendes gefunden.
1
U8X8_CA(0x0da,0x012),/* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */[c/]
2
3
InderLibraryvonhiersteht
4
[c]#ifDISPLAY_HEIGHT==64
5
0xDA,0x12,
6
#elif DISPLAY_HEIGHT==32
7
0xDA,0x02,
Da mein DISPLAY_HEIGHT den Wert 32 hat steht bei mir dann 0x02.
Das habe ich jetzt auf 0x12 geändert. Der Unterschied ist ja genau das
5. Bit vom Kommentar (disable left/right remap). Jetzt habe ich die
Hälfte vom Display sichtbar.
Bei der derzeitigen Schriftgröße bekomme ich 10 Zeichen in eine Zeile.
Wenn ich den Sting "1234567890" ausgebe, dann steht in der linken Hälfte
vom Display "567890". Die rechte Hälfte ist leer.
Suche mal das Datenblatt von dem Display, da müsste die korrekte
Initialisierungssequenz drin stehen. Die hängt nämlich ganz stark davon
ab, wie die Pixel mit dem Chip verbunden sind. Da gibt es mehrere
Möglichkeiten, deswegen lässt das Datenblatt des Chips diesen Teil
offen.
Stefan ⛄ F. schrieb:> Suche mal das Datenblatt von dem Display
Das ist das Problem. Ich habe nur die Angaben auf Amazon. Über den
genannten Hersteller werde ich bei Google auch nicht weiter fündig.
Deswegen bestelle ich meine Displays normalerweise bei AZ Delivery. Da
gibt es eine vernünftige Doku. Und der Preisaufschlag ist bei meinen
paar Displays jetzt auch nicht entscheident. Aber bei AZ Delivery gibt
es keine so kleinen Displays. Selbst die I2C Adresse war schon
"Rätselraten".
Ic
Stefan ⛄ F. schrieb:> Habe was gefunden:> https://www.buydisplay.com/download/manual/ER-OLED0.49-1_Series_Datasheet.pdf
Nach der Doku bin ich jetzt mal vorgegangen, gleiches Ergebnis. Irgend
wie habe ich da wohl ein merkwürdiges Display mit etwas anderer
Konfiguration erwischt als die "Standard-Teile".
Aktuell schreibe ich folgendes auf das Display. Von der Breite her
müsste das exakt auf das Display passen.
1
lcd_gotoxy(0,0);
2
lcd_puts("HelloWorld");
3
4
lcd_gotoxy(0,2);
5
lcd_puts("1234567890");
Das Ergebnis sieht man auf dem Bild "64x32", WIDTH 64, HEIGHT 32
Dann habe ich einfach das Display getauscht, ohne die Definitionen
anzupassen. Das Ergebnis auf dem Bild "128x64_falsch"
Der Text landet also korrekt auf dem Controller, nur ist der Inhalt beim
kleinen Display irgend wie nach links verschoben.
Zuletzt noch das Bild mit den korrekten Einstallungen für das große
Display "128x64_ok" WIDTH 128, HEIGHT 64
128x64_ok.jpg sieht doch gut aus, wie ist deine Frage?
versuche
R. F. schrieb:> lcd_gotoxy(0,0);> lcd_puts("HelloWorld, i am OK");>> lcd_gotoxy(0,2);> lcd_puts("12345678901234567890");
Joachim B. schrieb:> 128x64_ok.jpg sieht doch gut aus, wie ist deine Frage?
128x64 ist auch nicht das Problem, wollte damit nur Zeigen das der Code
generell funktioniert. Das Problem ist das der gleiche Code auf dem
64x32 nicht läuft, bzw. die Anzeige verschoben ist. Ich muss auf dem
kleinen Display alles ein Stück nach rechts rücken, aber ich finde
einfach nicht die passende Stellschraube in der Library (auch mangels
Datenblatt vom Display). Von den WIDTH und HEIGHT Definitionen mal
abgesehen. Aber die habe ich ja angepasst.
Joachim B. schrieb:> ich versteh dich nicht und kann zu dem> Beitrag "Re: SSD1306/1309 Library zum Darstellen von Text auf OLED> Displays">> nichts mehr hinzufügen
Uppps, hatte übersehen das du in meinen zitierten Text etwas hinzugefügt
hast.
1
lcd_gotoxy(0,0);
2
lcd_puts("HelloWorld, i am OK");
3
4
lcd_gotoxy(0,2);
5
lcd_puts("12345678901234567890");
Bei der Einstellung WIDHT 64, HEIGHT 32:
Bild "64x32" kleines Display
Bild "128x64_falsch" großes Display
Bei der Einstellung WIDHT 128, HEIGHT 32:
Bild "128x64_ok" großes Display
Stefan ⛄ F. schrieb:> Ich habe dir das Datenblatt vom SSD1306 angehängt. Da sind alle> Initialisierungsparameter beschrieben.
Ich habe gedacht ich wär auf der Seite 24 bei Punkt 8.4 und 8.3 auf
Seite 23 auf der richtigen Spur. Alles ohne Erfolg. Bei dem einen Punkt
"FR synchronization" beginnt das Display nur zu flackern (bei
nochmaligem, genauerem lesen wurde auch klar warum), bei dem Punkt
"Oscillator Circuit and Display Time Generator" verschieben sich die
Zeilen in ihrer vertikalen Position. Ich müsste aber Horizontal
verschieben.
Das Datenblatt muss ich die nächsten Tage nochmals genauer anschauen.
R. F. schrieb:> Bei der Einstellung WIDHT 128, HEIGHT 32:> Bild "128x64_ok" großes Display
siehste, nun weisst du es wie es richtig geht!
und musst für das warum nicht mehr suchen!
Joachim B. schrieb:> siehste, nun weisst du es wie es richtig geht!> und musst für das warum nicht mehr suchen!
Irgend wie reden wir glaube ich aneinander vorbei, oder stehe ich
komplett auf der Leitung???
Wie schon geschrieben, mein großes Display läuft ohne Probleme, mein
Problem ist das kleine Display, das 64x32. Und da bekomme ich trotz
WIDTH 64 und HEIGHT 32 keine vernünftige Anzeige, siehe Bild "64x32"
R. F. schrieb:> Irgend wie reden wir glaube ich aneinander vorbei
möglich denn besonders klar finde ich deine seltenen Aussagen nicht, man
weiss nie worauf du dich beziehst, du hast es im Kopf, für dich ist
alles klar und hier bleiben bei mir nur ?????? über.
R. F. schrieb:> Da ich bei DISPLAY_HEIGHT den Wert 32 eingebe wäre das Ergebnis 31. Und> das ergibt in HEX 1F. Demnach wäre das der richtige Wert welcher mit dem> Display funktionieren sollte.
"welcher mit dem Display"
aha, wie war das in der Schule, einen vollständigen Satz mit
"Subjekt Prädikat Objekt"
Wie beim Notruf
www
Wer
Wo
Was
meldet!
hier brennts ist zwar richtig aber nicht zielführend.
Wo ist deine Systematik?
sich Stück für Stück einem Fehler zu nähern und dabei zu lernen.
vermutlich bekomme ich dafür wieder Dankespunkte.
R. F. schrieb:> Wie schon geschrieben, mein großes Display läuft ohne Probleme, mein> Problem ist das kleine Display, das 64x32. Und da bekomme ich trotz> WIDTH 64 und HEIGHT 32 keine vernünftige Anzeige, siehe Bild "64x32"
Ich tippe auf die Initialisierungs-Routine. Die ist u.a. abhängig von
der Dislay-Größe. Ich hab nur die 128*64er Displays hier und hab die Lib
darauf angepasst, wahrscheinlich muss da in der Initialisierung noch
etwas geändert werden damit es für ein 64*32 Display passt. Wenns klappt
bau ich die Lösung gerne in die Lib mit ein.
Ich bin an der Sache noch dran, werde da aber erst im Januar weiter
machen. Mittlerweile habe ich auch eine "provisorische Lösung" gefunden,
damit die Texte korrekt auf dem Display angezeigt werden. Allerdings als
Bastel- und nicht als saubere Dauerlösung.
Ich werde im Januar mal alles ausführlich erklärt hier posten. Kann also
noch ein paar Tage dauern, bis ich mich wieder melde.
Hallo community,
ich versuche gerade ein SSD1306 Display welches ich bei Ebay gekauft
habe in Betrieb zu nehmen, es klappt aber nicht ganz. Ich hoffe jemand
kann mir helfen. Die hardware ist atmega328p mit 8MHz RC osc.
Die Library habe ich vom
https://github.com/Sylaina/oled-display
Folgende Zeilen habe ich modifiziert :
lcd.h zeile 61
1
//#define SH1106
2
#define SSD1306
lcd.h zeile 72
1
//#define LCD_I2C_ADR (0x7a >> 1) // 7 bit slave-adress without r/w-bit
2
#define LCD_I2C_ADR (0x78 >> 1) // 7 bit slave-adress without r/w-bit
Ich hoffe die Slave-Adresse (0x78 >> 1) ist richtig.
Immerhin tut sich was mit dieser Adresse.
Wenn ich es mit (0x7a >> 1) ausprobiere tut sich nichts. Ich finde keine
Dokumentation von meinem Display.
Beim compilieren bekomme ich den folgenden Fehler :
1
..
2
avr-gcc (GCC) 4.7.2
3
Copyright (C) 2012 Free Software Foundation, Inc.
4
This is free software; see the source for copying conditions. There is NO
5
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
cc1.exe: error: no iconv implementation, cannot convert from UTF-8 to iso-8859-15
9
make.exe: *** [main.o] Error 1
Was kann ich gegen diesen Fehler machen?
Nach dem ich die folgende Zeile im Makefile auskommentiere :
# CFLAGS += -finput-charset=utf-8 -fexec-charset=iso-8859-15
lässt es sich kompilieren, es gibt aber Warnungen :
1
-------------- Build: Debug in EmcExcelRelay (compiler: GNU GCC Compiler for AVR)---------------
2
3
Checking if target is up-to-date: make.exe -q -f makefile
4
Running command: make.exe -f makefile
5
-------- begin --------
6
avr-gcc (GCC) 4.7.2
7
Copyright (C) 2012 Free Software Foundation, Inc.
8
This is free software; see the source for copying conditions. There is NO
9
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
c:\Elektrotechnik\avr-gcc-4.7.2-mingw32\bin\avr-objcopy.exe: --change-section-lma .eeprom=0x00000000 never used
47
Creating Extended Listing: main.lss
48
avr-objdump -h -S main.elf > main.lss
49
Creating Symbol Table: main.sym
50
avr-nm -n main.elf > main.sym
51
Size after:
52
main.elf :
53
section size addr
54
.data 14 8388864
55
.text 2538 0
56
.bss 3 8388878
57
.stab 1740 0
58
.stabstr 110 0
59
.comment 17 0
60
.debug_aranges 216 0
61
.debug_info 4051 0
62
.debug_abbrev 1218 0
63
.debug_line 1310 0
64
.debug_frame 732 0
65
.debug_str 566 0
66
.debug_loc 2847 0
67
.debug_ranges 96 0
68
Total 15458
69
Errors: none
Der Text auf dem Display ist aber verschoben und es gibt Artefakte.
(In dem Angehängten Bild wird nur der Textmodus getestet)
Im Graphik mode gibt es nur noch diese Artefakte zu sehen,
der Text ist nur ganz kurz im Einschaltaugenblick zu sehen, dann nur
noch die Artefakte )
Ich habe auch mit der Compilerversion avr-gcc (GCC) 9.2.0 versucht.
Das Ergebnis war aber gleich.
Vielleicht hatte jemand ein ähnliches Problem ?
Danke im Voraus.
Jan
[Mod: C- und code-Tags ergänzt.]
Hallo Jan,
du schreibst das dein Controller mit 8MHz läuft.
In deiner Ausgabe welche du gepostet hast steht
1
-DF_CPU=16000000UL
Das heißt in deiner Entwicklungsumgebung sind 16MHz eingestellt.
Das solltest du auf jeden Fall anpassen (in der Entwicklungsumgebung
korrekt eintragen).
Die Meldung
1
noiconvimplementation,cannotconvertfromUTF-8to
2
iso-8859-15
hatte ich auch schon. Ich habe dann ebenfalls
1
-finput-charset=utf-8-fexec-charset=iso-8859-15
wieder gelöscht, dann hat es funktionert. Allerdings kann ich dadurch
ä,ö,ü,ß nicht darstellen. Hier wäre ich ebenfalls an einer Lösung
interessiert.
Gruß Rüdiger
Danke für die Antworten und Erkläerungen.
das mit dem Zeichensatz werde ich später angehen. Erstmal wollte ich
soweit kommen das es das Anzeigt was es anzeigen soll.
R. F. (inet_surfer88) schrieb :
>du schreibst das dein Controller mit 8MHz läuft.>In deiner Ausgabe welche du gepostet hast steht>-DF_CPU=16000000UL>Das heißt in deiner Entwicklungsumgebung sind 16MHz eingestellt.>Das solltest du auf jeden Fall anpassen (in der Entwicklungsumgebung>korrekt eintragen).
Ich habe F_CPU = 8000000UL gesetzt.
Wie man im Anhang sieht läuft die Kommunikation mit 100KHz, das Display
antwortet auch.
(Der erste Zugriff nach dem Reset ist im Bild zu sehen)
Ich überlege ob es nicht ein Hardware Probleme ist und Frage mich auch
mit welcher Spannung das Display betrieben werden soll.
In der Beschreibung bei Ebay stand 3-5V.
Im Dattenblatt vom SSD1306 steht Power supply o VDD = 1.65V to 3.3V for
IC logic.
Ich habe es erstmal mit 5V versucht, danach habe ich es mit 3.3V
versucht.
Das Display zeigt immer diesen verschobenen Text und die Artefakte.
Schade das das hex file nicht im github dabeit ist. Das würde ich gerne
flashen um es auszuprobieren.
Vielleicht ist jemand so freundlich und kann es hochladen.
(Also das hex file vom Ausgangs Projekt
https://github.com/Sylaina/oled-display für den atmega328p )
(ob die F_CPU auf 16MHz oder 8MHz steht sollte erstmal keine Rolle
spielen, es läuft dann halt mit der halben Geschwindigkeit)
Danke im Voraus,
Jan
Jan schrieb:> Das Display zeigt immer diesen verschobenen Text
hatte ich mal bei falscher Controllerwahl
aber in welcher Lib? adafruit oder diese?
vergessen!
Jan schrieb:> Ich überlege ob es nicht ein Hardware Probleme
Die steigenden Flanken der Signale sind stark abgerundet. 400 kHz würden
sicher gar nicht mehr funktionieren, obwohl das Display eigentlich sogar
500 kHz schafft.
Vermutlich sind deine Pull-Up Widerstände and SCL und SDA zu hochohmig.
Versuche mal 2,2kΩ oder 3,3kΩ.
> Frage mich auch mit welcher Spannung das Display betrieben werden soll.
Der Display-Controller braucht ungefähr 3,3V. Die meisten Module
enthalten einen Spannungsregler, der aus einer höheren
Versorgungsspannung bis 6V diese 3,3V bereit stellt.
Trotzdem ist es wichtig, dass die Signale am I²C Bus nicht mehr als 3,3V
haben. Die Pull-Up Widerstände müssen daher auf 3,3V gehen, nicht auf
5V!
Vielen Dank für die Antworten.
Den Fehler habe ich gefunden. Ich habe es auf SH1106 umgestellt und es
funktioniert.
Danke an Joachim B für den Tip mit mit der falschen Controllerwahl.
Ich bin davon ausgegangen das ich einen SSD1306 habe.
F. (stefanus) schrieb :
>Vermutlich sind deine Pull-Up Widerstände and SCL und SDA zu hochohmig.>Versuche mal 2,2kΩ oder 3,3kΩ.
6.8KOhm habe ich drin, und sie sind auch an 5V angeschlossen.
Ich muss das noch ändern und sie an die VDD vom display anschliessen.
Vermutlich ist auf der Displayplatine ein Spannungsregler, ich muss mir
das noch genau angucken.
Siehe Anhang
Danke nochmals.
Grüße,
Jan
Jan schrieb:> Ich habe es auf SH1106 umgestellt und es> funktioniert.>> Danke an Joachim B für den Tip mit mit der falschen Controllerwahl.> Ich bin davon ausgegangen das ich einen SSD1306
ja jetzt fällt es mir wieder ein, der Unterschied war wie du schreibst!
SH1106 <-> SSD1306 :)))
Jan schrieb:> Danke an Joachim B für den Tip mit mit der falschen Controllerwahl.> Ich bin davon ausgegangen das ich einen SSD1306 habe.
Meiner Beobachtung bisher ist es übrigens so, dass die 0.96" Displays
den SSD1306 drin haben während die 1.3" Displays den SH1106 Controller
drin haben.
Jan schrieb:> 6.8KOhm habe ich drin
Die sind für 400kHz und mehr definitiv zu hoch. Meiner einer hat
üblicherweise 4k7 drin, für 1 MHz geh ich typischer Weise auf 2k2.
Jan schrieb:> Schade das das hex file nicht im github dabeit ist. Das würde ich gerne> flashen um es auszuprobieren.
Das Hex-File kann man sich ja selbst erstellen und "make all" ausführen,
das Makefile liegt ja mit bei ;)
M. K. schrieb:> Meiner Beobachtung bisher ist es übrigens so, dass die 0.96" Displays> den SSD1306 drin haben während die 1.3" Displays den SH1106 Controller> drin haben.
Hmm, ich habe neulich ein paar 1.3" Displays bestellt und die laufen
prima mit den Settings für den SSD1306. Allerdings habe ich das nur mit
meiner eigenen OLED Klasse
(http://stefanfrings.de/arduino_oled/index.html) ausprobiert.
Bei mir gibt es nur einen kleinen Unterschied bei der Datenübertragung
vom RAM zum Display:
1
// Set memory address to fill
2
i2c.beginTransmission(i2c_address);
3
i2c.write(0x00);// command
4
if(isSH1106)
5
{
6
i2c.write(0xB0+page);// set page
7
i2c.write(0x00);// lower columns address =0
8
i2c.write(0x10);// upper columns address =0
9
}
10
else
11
{
12
i2c.write(0xB0+page);// set page
13
i2c.write(0x21);// column address
14
i2c.write(0x00);// first column =0
15
i2c.write(width-1);// last column
16
}
17
i2c.endTransmission();
18
19
// send one page of buffer to the display
20
...
Ich habe irgendwo gelesen, dass beim SH1106 jede Page in einer eigenen
I2C Transaktion übertragen werden muss, während man beim SSD1306 alles
in einem Rutsch übertragen kann.
Stefan ⛄ F. schrieb:> Und AZ-Delivery hat einen neuen Chip erfunden
ruf doch mal an und frage....
kleiner Scherz am Rande, ne das habe ich alles durch, die wissen nicht
mal was sie verkaufen, ist aber bei vielen deutschen Onlinehändlern auch
nicht anders, die Leute am Telefon wissen nicht mal was in den Kisten im
Lager ist.
Stefan ⛄ F. schrieb:> Ich habe irgendwo gelesen, dass beim SH1106 jede Page in einer eigenen> I2C Transaktion übertragen werden muss, während man beim SSD1306 alles> in einem Rutsch übertragen kann.
Das ist u.a. einer der Unterschiede. Auch der ein und andere Spass mit
dem Cursor muss man etwas anders behandeln wenn ich mich recht entsinne.
Hat am Ende alles Auswirkung auf Bildwiederholrate und Co, da ist der
SSD1306 gegenüber dem SH1106 im Vorteil.
Mal eine kleine Frage an die Spezialisten, wenn ich per TWI/I2C ein FFh
sende, dann werden 8 vertikale Pixel dargestellt.
Kann man mit FFh auch 8 horizontale Pixel darstellen?
Wenn ja, wie?
Danke
Bernhard
Kleine Anmerkung:
TWI_BIT_RATE=0, TWI_PRESCALER=0
Display Clear, Takt 16MHz, SCL 444,444kHz, 1024Byte (128x64:8) in 11,6ms
mit Assembler
Bin nach euren Hinweisen und diesem Beispiel sehr viel weiter gekommen.
Konnte meine Fehler von ca. 100 auf 7 reduzieren. Was ich nicht verstehe
ist das:
> Fehlermeldung:> Severity Code Description Project File Line> Warning comparison of constant '127' with boolean expression is> always false [-Wbool-compare] ATB_I2C_OLED_L128 D:\AAA> Technik\Programme AVR> Studio\ATB_I2C_OLED_L128\ATB_I2C_OLED_L128\oledl128.c 465> Warning comparison of constant '63' with boolean expression is always> false [-Wbool-compare] ATB_I2C_OLED_L128 D:\AAA Technik\Programme AVR> Studio\ATB_I2C_OLED_L128\ATB_I2C_OLED_L128\oledl128.c 465> [/c]> nicht klar warum das kommt.
Steht doch da (Tip: Besorg Dir ein C-Buch...):
Der Ausdruck (x1 || x2) liefert true oder false. Also 1 oder 0 und das
ist immer < Deiner Display_Width oder Heigth.
Schreib das in vernünftigem C, dann geht das...
Paul schrieb:> Dieser Teil bringt eine Fehlermeldung:
Dieser Teil sieht auch komplett sinnlos aus.
Es wird eine logische ODER-Verknüpfung gemacht (die kann nur 0 oder 1
liefern, Wahrheitswerte halt), und deren Ergebnis wird dann mit Höhe
oder Breite des Displays verglichen.
Was zum Geier™ wolltest du damit eigentlich ausdrücken?
Jörg W. schrieb:> Paul schrieb:>> Dieser Teil bringt eine Fehlermeldung:>> Dieser Teil sieht auch komplett sinnlos aus.>> Es wird eine logische ODER-Verknüpfung gemacht (die kann nur 0 oder 1> liefern, Wahrheitswerte halt), und deren Ergebnis wird dann mit Höhe> oder Breite des Displays verglichen.>> Was zum Geier™ wolltest du damit eigentlich ausdrücken?
Ziemlich offensichtlich wollte er:
Nicht ganz so schnell. Versuche die Sache zu begreiffen.
Paul schrieb:> void lcd_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2,> uint8_t color)> {> if( ((x1 || x2) > DISPLAY_WIDTH-1) || ((y1 || y2) >> DISPLAY_HEIGHT-1) ) return;
Wenn ich das richtig verstehe erfolgt die Eimgabe für eine Linie als
Anfangspunkt und Endpunkt in der Richtung x und y. Dabei wird
kontrolliert das die eingebenen Punkte nicht ausserhalb der zulässigen
angebenen Grösse liegen, ansonsten Begrenzung?
Paul schrieb:> Wenn ich das richtig verstehe erfolgt die Eimgabe für eine Linie als> Anfangspunkt und Endpunkt in der Richtung x und y. Dabei wird> kontrolliert das die eingebenen Punkte nicht ausserhalb der zulässigen> angebenen Grösse liegen, ansonsten Begrenzung?
Nö, nix Begrenzung.
Paul schrieb:> Es ist doch eine Begrenzung mit x und y drin. Wie wird das sonst> gemacht?
Mal abgesehen von Deinen falschen Statements springst Du mit return
einfach zurück, wenn x- oder der y-Wert ausserhalb der
Displaykoordinaten liegen.
Zudem hast Du eine void-Funktion und somit erkennt der Aufrufer auch
nicht, ob da nun was gezeichnet wurde.
Besser wäre (je nach gewünschtem Effekt):
- Entweder bei Überschreiten der Max-Werte einfach den Max-Wert als
Koordinate setzen
- Oder einen Boolean-Wert zurückgeben, der anzeigt, ob ein Fehler
vorliegt oder nicht
Paul schrieb:> void lcd_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2,> uint8_t color)> 2 {> 3 if( ((x1 || x2) > DISPLAY_WIDTH-1) || ((y1 || y2) >> DISPLAY_HEIGHT-1) ) return;
Das ist doch nicht meine aktuelle drawLine-Funktion. Schau doch noch mal
ins github und lade dir die aktuelle Library. ;)
Dr. MCU schrieb:> Mal abgesehen von Deinen falschen Statements springst Du mit return> einfach zurück, wenn x- oder der y-Wert ausserhalb der> Displaykoordinaten liegen.
Genau das war die Idee meines Gedankens: Ich wollte nur nicht außerhalb
des Displays zeichnen. Auf Return-Werte hatte ich hier übrigens bewusst
verzichtet getreu dem Motto keep it simple, natürlich wäre es sauberer
wenn man zumindest einen Bool-Wert zurückgeben würde um zu sehen ob die
Funktion zumindest fehlerfrei abgearbeitet wurde.
An die Bereichsüberprüfung wollte ich mich eh noch mal ran setzen da ich
meine, dass sie in der drawPixel-Methode völlig ausreichen würde, die
Überprüfungen in den anderen Zeichenfunktionen sind eigentlich
überflüssig wenn ich das recht in Erinnerung habe.
M. K. schrieb:> https://github.com/Sylaina/oled-display
Dann ist das neuste von dir. Da hab ich wohl was altes geholt.
Du verwendest auch die Datein zum I2C Bus. Das klappt bei mir nicht. Da
ich noch andere Module im Bus anschliesse verwende ich eine andere
Ansteuerung.
Wie kann man das am besten lösen?
LG Paul
Welche I2C-Library du verwendest bleibt dir überlassen. Du kannst meine
Library benutzen um auch deine anderen Devices zu verwenden, du kannst
auch deine Library benutzen, dann musst du nur in der lcd.c die
Funktionen lcd_init (hier wird lediglich i2c initialisiert,
initialisierst du den i2c woanders kannst du diesen Teil
löschen/auskommentieren), lcd_command und lcd_data entsprechend
anpassen.
Danke für deine Info, werde es testen. Betreibe mit dem I2C Bus noch
eine ganze Reihe anderer Module, z.B. ein TFT Farbdisplay 3,2" mit 64000
Farben. Teilweise sind recht anspruchsvolle Libs dabei.
Paul
M. K. schrieb:> I2C ist recht überschaubar bzgl Anspruch.
Ja. Wahrscheinlich meint er, dass die Bibliothek die er benutzen muss
eine Menge Voraussetzungen hat, die erfüllt sein müssen.
Habe es ausprobiert. Ganz so einfach scheint es doch nicht zu sein.
Kommen noch eine Reihe von Fehlermeldungen. z.B. Graphicmode, i2ccommand
usw.
Versuche es durch auskommentieren erst mal zu einer Anzeige zu kommen.
Es klingt so, als ob die Datein von Peter Fleury nichts taugen, da ich
diese verwende.
Paul
Paul schrieb:> Es klingt so, als ob die Datein von Peter Fleury nichts taugen
Das klingt aber wirklich nur so. Was Peter gemacht hat ist richtig
richtig gut finde ich.
Beginne bei der Fehlersuche immer beim ersten Fehler, der dir angezeigt
wird. Viele der Fehler werden nämlich nur Folgefehler sein.
M. K. schrieb:> Was Peter gemacht hat ist richtig> richtig gut finde ich.
ganz genau, habe selber mit I2C von Fleury angefangen und viel gelernt
dadurch.
Fehlerhaft, kann nicht sein, die LIB funktioniert perfekt seit
mindestens 1 Jahrzehnt!
Hallo! Tolle Library, habe ich eingebunden funktioniert super. Ich nutze
auch das 128x32 dank den HInweisen die Anpassung vorgenommen lief
sofort. Auch die Bitmap-Funktion und die Exe klappt super.
ABER: 1 Problem habe ich. Ich habe nur die Schrift 6x8 von M. Köhler.
Wie kann ich andere Schriftgrößen erhalten (oder erstellen)? Ich brauche
am besten 2 weitere, eine die doppelt so groß ist und eine 4x so große.