Aktuelle Version hier: Beitrag "Re: SSD1306 Library zum Darstellen von Text auf OLED Displays" Ich habe eine kleine Library für den Displaycontroller SSD1306 geschrieben, wie er häufig bei den 0.96" OLED-Displays eingesetzt wird. Als Schnittstelle wird IIC benutzt. *) Die Library zeichnet lediglich Text auf das Display. Der Vorteil bzgl. Adafruit und u8glib ist u.a., dass bei weitem nicht so viel Flash benötigt wird (etwa 1400 kByte wenn man nur "Hallo Welt!" aufs Display schreibt, Adafruit braucht da rund 10 kByte, u8glib etwa 8 kByte) und auch beim RAM sieht es erheblich besser aus als bei den üblichen Libs die jeweils mit einem Puffer in Displaygröße arbeiten, d.h. man braucht über ein 1kByte RAM alleine für die Lib. Meine Lib arbeitet ohne Puffer, daher wird hierfür auch kein statischer RAM für einen Puffer benötigt. Ich hab es nicht getestet, aber auch 128 Byte RAM müssten locker ausreichend sein. Um das gesamte Display zu beschreiben (168 Zeichen) benötigt die Lib hier bei 400 kHz IIC-Clock nur ca. 35 ms, für eine Zeile (21 Zeichen) sind es ca. 4,5 ms. Adafruit und u8glib benötigen beide alleine für eine Zeile schon mehr als 20 ms. Bei den Befehlen für das Display habe ich mich an den Befehlen von Peter Fleury's Lib für die HD44780-Displays gehalten. Getestet hab ich die Lib mit einem ATMega168PA und einem ATMega328P, beide mit 16 MHz Quarz, den II2C hab ich auf 400 kHz eingestellt gehabt, sie sollte auch auf einem ATMega88PA laufen. Interessant dürfte die Lib für all jene sein, die kleinere AVRs benutzten wollen, als die, die von ADAFRUIT und u8glib erwartet werden. Als nächstes werde ich mich an die Portierung für die ATTinys dran setzen. Eine Grafik-Variante (mit der man auch Zeichnen kann) hab ich auch fertig, allerdings braucht die noch Feintuning und sie benötigt einen AVR mit mehr als 1 kByte RAM (sie arbeitet mit einem Puffer). EDIT: Noch ein Foto angehangen. Edit: Github link https://github.com/Sylaina/oled-display.git *) SPI wird mittlerweile ebenfalls unterstützt, siehe Beitrag "Re: SSD1306 Library zum Darstellen von Text auf OLED Displays"
Gast
#4848159
Hallo, nur zur Ergänzung. Nicht alle Arduino-Libs für SSD1306 sind so gross. Bill Greiman hat auch eine eingedampfte Ascii-Lib: "Sketch uses 2,622 bytes (8%) of program storage space. Global variables use 53 bytes (2%) of dynamic memory" https://github.com/greiman/SSD1306Ascii
edsyn schrieb: > Hallo, > nur zur Ergänzung. > Nicht alle Arduino-Libs für SSD1306 sind so gross. > Bill Greiman hat auch eine eingedampfte Ascii-Lib: > "Sketch uses 2,622 bytes (8%) of program storage space. > Global variables use 53 bytes (2%) of dynamic memory" > https://github.com/greiman/SSD1306Ascii Die schaut auch interessant aus, keine Frage. Hab ich jetzt nur mal überflogen aber scheint auch für Arduino zu sein. Das benutze ich gar nicht wennauch ich Arduino Boards habe. Die habe ich aber nur weil die Boards ansich recht praktisch sind. 53 Byte für Globale Variablen ist schon einiges, beim Überfliegen hab ich so jetzt gar nicht direkt gesehen wofür die nötig sind. However, gefällt mir auch. Vielleicht mach ich die Tage mit der Lib auch noch einen Geschwindigkeitstest um sie in den Vergleich zu meiner Lib mit aufzunehmen.
Ich war dann gestern noch etwas ambitioniert und habe meiner Library noch Grafikfunktionen hinzugefügt. Jetzt benötigt die Lib leider schon etwas mehr als 4kByte Flash sowie 1029 Byte SRAM. Da ich die Grafikfunktionen nicht immer benötige hab ich für die Grafik-Variante eine eigene Lib gemacht. In meinem hier gezeigten Beispiel enthält die Refresh-Rate das Zeichnen des Rechtecks, des Kreises und des Kreuzes, das Löschen und neu Schreiben der letzten Zeile sowie den "Balken" (den lasse ich erst nach rechts hin wachsen und wenn er den rechten Rand erreicht hat lösche ich da Linie für Linie Richtung links bis er verschwunden ist). Es wird zunächst in den Puffer geschrieben und dann mittels lcd_display() dieser dem Display zur Anzeige geschickt. Die erste Zeile wird nur beim Start in den Puffer geschrieben. Das Ganze dauert, wie man sehen kann, nicht mal 35 ms. IMO gar nicht mal so schlecht für den ersten Ansatz.
Hallo, ich finde die Library interessant. Jedoch vermisse ich einen Lizenzhinweis. Darf man die Library nun frei verwenden ? Gruß Dirk
Dirk B. schrieb: > Darf man die Library nun frei verwenden ? Upsala, natürlich darf man die Library frei verwenden. Muss mir mal über Lizensen und solcher Sachen Gedanken machen, da hast du recht.
Ich wollte mich bei dir auch noch für die Lib bedanken, tolle Arbeit!
Ich hätte einen kleinen Wunsch: Könntest du noch das Zeichen "°" zum Font hinzufügen?
Max M. schrieb: > Ich hätte einen kleinen Wunsch: Könntest du noch das Zeichen "°" zum > Font hinzufügen? Ich habe sogar mehr getan. Neben "°" sind nun auch noch die Umlaute "üÜöÖäÄ" und das "ß" verfügbar. ;) Im Anhang die Text-Variante und die Grafik-Variante.
könnte mir ja gefallen nur.... es fehlt die Version für SH1106 mit SSD1306 Ansprache bekomme ich rechts Grafikfehler ein ATmega 1284p (mighty mini z.B. oder nativ) ist auch noch nicht dabei schade....
Richtig, es ist ja auch in der Entwicklungsphase und ich hab halt nur einen Atmega328p (bzw. seine kleineren Brüder) und Attiny45/85. SH1106 muss ich mal spicken, sollte recht simpel umsetzbar sein da dies nur um 2 byte verschoben ist gegenüber dem ssd1306 soweit ich das jetzt gelesen hatte im Netz. Ich werd mal schaun was sich da machen lässt. Erstmal muss ich schaun, dass ich die Attinys an den Start bekomme. Hatte die letzte Woche nicht wirklich Zeit hier mal weiter zu arbeiten, ich hoffe auf nächste Woche ;) EDIT: Hab mal geschaut. Der Atmega1284p (hab ich persönlich nicht im Einsatz, daher kenne ich ihn auch nicht) ist bzgl. i2c identisch mit dem Atmega328, d.h. die Zeile 174 in der C-Datei:
1 | |
muss nur gegen die folgende Zeile
1 | |
ersetzt werden und schon dürfte auch der Atemga1284p unterstützt werden.
M. K. schrieb: > etwa 1400 kByte wenn man nur "Hallo Welt!" aufs Display schreibt 1,4 MB, nun, auf einen modernen ARM passt das schon. ;-) <scnr> Danke schon mal, habe zwar bislang die Variante mit dem 1-KB-Puffer genutzt, aber richtig toll fand ich das nie.
danke ich mache es mir einfacher in einer pin.h
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | |
Jörg W. schrieb: > Danke schon mal, habe zwar bislang die Variante mit dem 1-KB-Puffer > genutzt, aber richtig toll fand ich das nie. Das Problem ist dabei halt, dass man beim I2C das Display nicht lesen kann. Bzgl. Zeichnen kommt man da halt um den Puffer nicht drum rum. Bei reiner Textanwendung aber kann man sich den Puffer tatsächlich sparen. Das war eine meiner Motivationen zu der Lib ;) Joachim B. schrieb: > ich mache es mir einfacher in einer pin.h Das ist natürlich auch eine Möglichkeit ;)
M. K. schrieb: > Ich habe sogar mehr getan. Neben "°" sind nun auch noch die Umlaute > "üÜöÖäÄ" und das "ß" verfügbar. ;) > Im Anhang die Text-Variante und die Grafik-Variante. Super, danke! Mir ist gerade beim portieren auf meinen Controller aufgefallen, dass bei mir das '°' nicht den Code 144 hat, deswegen hab ich das so verglichen:
1 | |
2 | |
ist vllt. einfacher zu lesen. Könntest du die lcd_putc-Funktion nicht auch deutlich kürzen, wenn du zuerst die Variable c entsprechend bestimmst und dann nur einmal die Schleife hinschreibst, in etwa so:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
Kam mir nur gerade beim Durchschauen. Tolle Arbeit! Läuft auch auf nem STM8S103 mit 1kByte RAM (ich hab den Puffer auf ~630Byte verkleinert) super! Ich hoffe es ist in Ordnung, wenn ich deinen Code leicht verändert benutze?
Hallo Max, sicher kann ich das noch entsprechend umstricken. Ich muss gestehen, ich hab das heute Mittag quasi nur so hingerotzt, Verfeinerungen werden später noch kommen ;)
M. K. schrieb: > Bei reiner Textanwendung aber kann man sich den Puffer tatsächlich > sparen. Beim Zeichnen geht es auch, wenn man halt immer komplette 8 Pixel zeichnet. Klar, mit Puffer hat auch was. Habe gerade etwas ähnliches durch bei einem Farb-LCD, aber dort braucht man pro Pixel ein ganzes Byte, damit keinen Puffer.
Jörg W. schrieb: > Beim Zeichnen geht es auch, wenn man halt immer komplette 8 Pixel > zeichnet. Hm, mach ich doch, bzw. geht bei dem Display doch gar nicht anders, das ist ja quasi das Problem warum man erst einen Puffer braucht: Man kann Pixel eigentlich immer nur im 8er-Pack modifizieren, d.h. selbst wenn man nur einen Pixel ändern will muss man dem Display Infos für 8 Pixel schicken. Wie soll das funktionieren also ohne Puffer funktionieren? Nehmen wir an, es wurde schon etwas auf das Display gezeichnet. Jetzt soll noch zusätzlich was dazu gezeichnet werden. Wie kann man das denn ohne Puffer etwas dazu zeichnen ohne den bisherigen Displayinhalt zu löschen? Ohne Puffer sehe ich da keinen Weg, vielleicht hast du ja einen Tipp für mich. Bei Text hat man ja nur deshalb den Vorteil den Puffer zu sparen weil man idR nicht 2, 3, 4, 5 usw. Buchstaben übereinander zeichnen will, man will immer nur einen einzigen Buchstaben in einem Feld stehen haben. Deshalb ist es da völlig in Ordnung wenn der vorherige Inhalt des Felds gelöscht wird. Will man z.B. den Schnittpunkt von zwei Kurven bestimmen/visualisieren ist das recht doof wenn beim Zeichnen der zweiten Kurve die erste Kurve gelöscht wird. Ohne irgendwo einen Puffer zu haben wüsste ich nicht, wie man das Lösen könnte. Und wie schon gesagt, toll wäre es, man könnte das Display-RAM als Puffer nutzen nur lässt sich das bei I2C leider nicht auslesen, sprich nicht als Puffer nutzen.
Gast
#4861771
I am very beghosted! Ich bin sehr begeistert. Super Arbeit, klasse Beitrag. Jetzt muss ich nur noch mein 0.96"OLED wiederfinden. Nochmal: herzlichen Dank :) StromTuner
M. K. schrieb: > Wie kann man das denn ohne Puffer etwas dazu zeichnen ohne den > bisherigen Displayinhalt zu löschen? Man muss sich halt das Display dann gedanklich in 8er-Schritten aufteilen – so, wie du es letztlich ja auch beim Text machst. Braucht mehr Planung (dessen, der damit was machen will), aber weniger RAM. OK, so gesehen: der nächstgrößere Controller mit ausreichend RAM ist wahrscheinlich dann doch die einfachere Wahl.
Gast
#4861932
Jörg W. schrieb: > dann doch die einfachere Wahl ...und sinnvolle Wahl, die Preis-Differenz ist minimal. M. K. schrieb: > Wie kann man das denn ohne Puffer > etwas dazu zeichnen ohne den bisherigen Displayinhalt zu löschen? ganz einfach: man löscht nicht den kompletten Displayinhalt, sondern nur den Bereich, wo "zusätzlich" geschrieben wird. Es reicht auch zu überschreiben. Dafür braucht man keinen Puffer.
Tany schrieb: > ganz einfach: man löscht nicht den kompletten Displayinhalt, sondern nur > den Bereich, wo "zusätzlich" geschrieben wird. beim Arduino TFT Shield habe ich den alten Text mit black vor dem neuen Text geschrieben, löscht schneller als rect
Tany schrieb: > ganz einfach: man löscht nicht den kompletten Displayinhalt, sondern nur > den Bereich, wo "zusätzlich" geschrieben wird. Es reicht auch zu > überschreiben. > Dafür braucht man keinen Puffer. Einfach mal mit dem Display auseinander setzen, dann wüsstest du, dass das nicht geht. Die kleinste Einheit, die man bei diesem Display ändern kann, sind "Blöcke" mit 8 Pixel Größe. Wie willst du innerhalb eines Blockes einen Pixel ändern, ohne die anderen zu beeinflussen und ohne Puffer zu haben? Auch hier wieder bedenken: Via I2C lässt sich das Display nicht auslesen, nur beschreiben. Ich sehe hier keinen Weg ohne Puffer, bin aber für konkrete Gegenbeispiele sehr offen.
Gast
#4862385
M. K. schrieb: > Einfach mal mit dem Display auseinander setzen, dann wüsstest du, dass > das nicht geht So ein klein habe ich nicht, sondern ein 240x128 Display. Und der Controller braucht nicht ein Bit, sondern 5 Bits für ein Pixel. Es geht trotzdem ohne Puffer.
M. K. schrieb: > und ich hab halt nur > einen Atmega328p (bzw. seine kleineren Brüder) und Attiny45/85. SH1106 > muss ich mal spicken, sollte recht simpel umsetzbar sein da dies nur um > 2 byte verschoben ist gegenüber dem ssd1306 soweit ich das jetzt gelesen > hatte im Netz. > Ich werd mal schaun was sich da machen lässt. wäre schön hier fand ich auch was https://forum.arduino.cc/index.php?topic=256374.0 aber ich mag nicht in deinem Code patchen, du kennst ihn ja besser! wie groß ist dein Font eigentlich, ich habe ja auch Nokia 5110 am Start mit 84x48 Pixel und 6x8 Font (oder 5x7?) mit 128 PIX kommt man weiter, komischerweise kann ich auf dem Nokia 14 Zeichen auf 6 Zeilen, mit Adafruit zwar 16 Zeichen pro Zeile bei 128 pix in x müssten über 20 Zeichen pro Zeile möglich sein x 8 Zeilen
Das schau ich mir heute abend mal an. Im Moment fehlt mir mal wieder die Zeit mich genauer mit dem Display zu beschäftigen und da ich es aktuell nur am Atmega168 benutze habe ich zur Zeit auch keine Notwendigkeit dafür. Hoffe in den nächsten Wochen haben ich wieder etwas mehr Luft dafür. Wills ja auch noch für den Attiny45 an den Start bekommen.
Die Grafikroutinen werden spürbar kleiner, wenn Du anstatt der vielen Mathe-Funktionen sowohl Linien als auch Kreise mit dem Bresenham Algorithmus implementierst. Da kommst Du komplett mit Interger zurecht und schnell ist es auch.
Da hast du recht Uwe, daher habe ich grade noch mal in den Code geschaut. Den Kreis hatte ich nämlich schon mit Bresenham implementiert, die Linien hab ich vergessen umzubauen. Kommt direkt auf die TODO-Liste ;)
Bei den kleinen Displays, bei denen man direkt mit einem Byte zur Adressierung auskommt (also max 255 Pixel für eine Achse), braucht man nicht mal Funkionen für Absolutwerte/Vorzeichen.
Joachim B. schrieb: > wie groß ist dein Font eigentlich, ich habe ja auch Nokia 5110 am Start > mit 84x48 Pixel und 6x8 Font (oder 5x7?) Mein Font ist auch 6x8 Pixel (wobei die erste Spalte und letzte Zeile ungenutzt ist) groß. Joachim B. schrieb: > bei 128 pix in x müssten über 20 Zeichen pro Zeile möglich sein x 8 > Zeilen 21 Zeichen sind es bei mir in der aktuellen Version. Und da sind wir auch schon in der Überleitung: 1. Neuerung: Ich lasse nun nur noch 21 Zeichen pro Zeile zu und es gibt auch keinen automatischen Zeilenumbruch mehr da ich den etwas unschön fand. Oder sollte ich einen Schalter einführen damit sich der User diese Funktionalität aussuchen kann? 2. Neuerung: Ich habe die Linien-Routinen noch auf Bresenham umgestellt, wie von Uwe vorgeschlagen. Bei meinem obigen Beispielcode sinkt dabei die Bildwiederholrate von rund 34 ms auf rund 28 ms (400 kHz Busgeschwindigkeit). Der benötigte Flashspeicher ist von rund 4 kByte auf unter 3 kByte gesunken. Am RAM hat sich nichts geändert, es werden immer noch 1027 Byte benötigt. OK, oben schrieb ich 1029 Byte, 2 Byte jedoch waren von einer Hilfsvariablen (uint16_t) meiner Mainloop, die ich übersah. Die gehört natürlich nicht zur Library, daher 1027 kByte ;) Die aktuelle Version der Grafikvariante meiner Library habe ich angehangen. Ein SH1106-Display hab ich mir zum Testen schon mal bestellt, sollten meine Ideen funktionieren werde ich demnächst hier darüber berichten und auch wieder eine aktuallisierte Version meiner Library online stellen.
kein automatischer Zeilenumbruch, sollen sich die User kümmern was sie wollen, über 21 Zeichen splitten und selber für die 2te Zeile sorgen oder Laufschrift machen M. K. schrieb: > Ein SH1106-Display hab ich mir zum Testen schon mal bestellt freut mich, ich habe auch noch 2 nachbestellt vielleicht wäre auch noch alternativ ein größerer Font wählbar möglich ich finde ja den puren 6x8 zu mickrig, auf dem Nokia passt das. also 16 Zeichen pro Zeile auf 5 Zeilen wäre eine vergleichbare Größe
Gast
#4877124
Tany schrieb: > sondern 5 Bits für ein Pixel. Es geht trotzdem ohne Puffer. Nicht trotzdem sondern deshalb. Zumindest, wenn die 3 andern Bits keinem anderen Pixel zugeordnet sind.
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.
ich warte noch auf meine!
Ich hätte noch zwei Fragen zur Library: Warum verwendest du in der "ssd1306_init_sequence" kein "LCD_DISP_ON" am Ende so wie du es in einer früheren Version von deiner Lib getan hast (soweit ich das richtig im Kopf hab)? Oder ist dafür der Parameter "dispAttr" der Funktion "lcd_init" zuständig? Du sendest in der "lcd_command" Funktion auch die I2C Slave Adresse des Displays nicht mit, hab ich da was verpasst, musste man das nicht?
Max M. schrieb: > Warum verwendest du in der "ssd1306_init_sequence" kein "LCD_DISP_ON" am > Ende so wie du es in einer früheren Version von deiner Lib getan hast > (soweit ich das richtig im Kopf hab)? Oder ist dafür der Parameter > "dispAttr" der Funktion "lcd_init" zuständig? Das hast du richtig erkannt, ob das Display an oder aus sein soll nach dem Init wird nun über den Parameter dispAttr gesteuert, äquivalent zu Peter Fleurys lcd-Library zum Ansteuern von Displays mit HD44780-Controllern. Max M. schrieb: > Du sendest in der > "lcd_command" Funktion auch die I2C Slave Adresse des Displays nicht > mit, hab ich da was verpasst, musste man das nicht? Ja, da hast du was verpasst und ja, man muss die Adresse senden. Auch in der lcd_command-Funktion wird die Adresse gesendet. Als erstes wird in lcd_command die Funktion lcd_send_12c_start aufgerufen und diese Funktion stellt die Startbedingung her und sendet die Adresse.
Gast
#4932337
Hallo Michael, erstmal vielen Dank für die Mühe, das Ganze von arduino.IDE abzulösen - sozusagen für simple C-Geister (mein C spricht sich Cäh) wie mich. So viel gute Hilfe wie für Deinen Transistortester. Natürlich wollen Faulpelze immer mehr. Wäre es Dir bitte möglich, ein kurzes Main als Beispiel zu posten. So etwas in der Art wie für Dein Bild vom 24. Jan. 2017 abends? Als Gegenleistung könnte ich (wenn das 1306er mal auf meinem NanoClone läuft) ein Bildchen bieten vom Oskar zu den I²C-Flanken bei den 400 kHz. Ich hatte bei so hohen Frequenzen schon mal Pferde "vor der Apotheke .. gesehen". Danke im Voraus und viele Grüße der Joe vom Berg
Uuups - war ohne Login.
Aber klar doch, die Main ist wirklich sehr einfach gestrickt gewesen. Allerdings hab ich noch ein wenig gespielt, ich weiß grad nicht wie die Main zum Beispielbild oben genau aussah. Daher hier die völlig unaufgeräumte Main:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
Gast
#4932729
Guten Morgen, ich bin Programmieranfänger. Ich wollte Deine Bibliothek gern für meinen STM8S105-Aufbau benutzen. Mittlerweile läuft es auch, (siehe Anhang) ich hätte aber trotzdem noch Fragen dazu. Du hast eine Abstraktion vom hardware-abhängigen Teil eingeführt, benutzt sie aber praktisch nicht. Warum?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
Das hätte die Portierung erheblich vereinfacht, da der Umgang mit i2c bei mir ganz anders gestaltet ist. Schwierigkeiten hatte ich auch mit den Multibyte-Literalen (Umlaute) im Quelltext, was sicher auch anderen so gehen dürfte. (siehe Beitrag von maxmicr weiter oben) Nutzt Du einen Mac oder so? Der Frage nach einem Benutzungsbeispiel aka main.c schließe ich mich übrigens an. PS: Ich habe in meiner Version lcd auf OLED umbenannt, weil ich parallel ein I2C-LCD benutze und beides klarer abgrenzen wollte. Es ist strenggenommen auch kein LCD.
Gast
#4932732
STM8-C-Anfänger schrieb: > Der Frage nach einem Benutzungsbeispiel aka main.c schließe ich mich > übrigens an. Oh, zeitliche Überschneidung, hat sich erledigt, danke. :)
STM8-C-Anfänger schrieb: > Du hast eine Abstraktion vom hardware-abhängigen Teil eingeführt, > benutzt sie aber praktisch nicht. Warum? Da hast du recht, das liegt daran, dass ich hier noch nicht weiter entwickelt habe. Die Funktionen lcd_command und lcd_data können in der aktuellen Version immer nur ein Byte übertragen. Es gibt aber auch Situationen, da werden/müssen mehrere Bytes übertragen (Beispiel: lcd_gotoxy). Für eine einfache Portierung musst du nicht lcd_command und lcd_data anpassen sondern die vier i2c-Funktionen(init, start, stop und byte), das erschien mir logischer weil diese Funktionen die Prozessorabhängigkeit beinhalten. ;)
Gast
#4932817
Wie wird eigentlich die Schriftfarbe geändert ?
Manni schrieb: > Wie wird eigentlich die Schriftfarbe geändert ? Normal gar nicht. Das Display oben hat ne andere Farbe in dem Bereich. Die kann man aber auch nicht ändern.
Gast
#4933126
Manni schrieb: > Wie wird eigentlich die Schriftfarbe geändert ? Diese Displays sind monochrom, auch wenn das auf meinem ersten Foto anders aussieht. Da ist ein Streifen gelb, der Rest blau. M. K. schrieb: > Es gibt aber auch > Situationen, da werden/müssen mehrere Bytes übertragen (Beispiel: > lcd_gotoxy). Das geht auch gut so:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
oder so:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
Jedenfalls funktioniert es so bei mir. > Für eine einfache Portierung musst du nicht lcd_command und lcd_data > anpassen sondern die vier i2c-Funktionen(init, start, stop und byte), > das erschien mir logischer weil diese Funktionen die > Prozessorabhängigkeit beinhalten. ;) Ich finde es nicht gut, I2C so häufig innerhalb der OLED-Bibliothek zu verwenden. Was passiert z.B., wenn auf SPI umgestellt werden soll? Es gibt diese Displays ja auch mit SPI. Dann muss man die ganze Bibliothek umschreiben oder aus den I2C-Funktionen leere bzw. SPI-Funktionen machen, die aber im Namen I2C tragen. Wäre sehr verwirrend. Ist auch so schon verwirrend, jedenfalls für mich. Weniger Zeilen und sprechende Funktionsnamen sind einfach besser zu nachzuvollziehen.
STM8-C-Anfänger schrieb: > Das geht auch gut so: Ja, das geht natürlich auch. Dafür steigt aber auch der Overhead was merklich auf die Refresh-Rate geht ;) STM8-C-Anfänger schrieb: > Ich finde es nicht gut, I2C so häufig innerhalb der OLED-Bibliothek zu > verwenden. Was passiert z.B., wenn auf SPI umgestellt werden soll? Es war auch nie Ziel der Bibliothek, SPI zu unterstützen. Sie war ursprünglich nur für I2C gedacht. Deine Anmerkungen sind sehr gut, ich werde es beherzigen und sehen wie ich die Bibliothek allgemeiner halten kann damit es klarer wird, vielen Dank dafür.
Gast
#4933385
Vielen Dank für Deine Antwort. Meine Beiträge wirken beim Nachlesen etwas undankbar, so ist es aber nicht gemeint. Ich freue mich immer, wenn jemand für mich brauchbare Software veröffentlicht. Die Fragen kamen dann beim Beschäftigen damit auf. Ich mag eben gern einfache, klare Strukturen. (hab früher viel hobbymäßig Turbo-Pascal programmiert)
M. K. schrieb: > Aber klar doch, die Main ist wirklich sehr einfach gestrickt gewesen. Danke für die Mühe. Einfach sicher - wenn man weiß, wo´s lang geht. Ich geh in den nächsten zwei, drei Tagen dran (danach bin ich etwas wech..).
STM8-C-Anfänger schrieb: > Vielen Dank für Deine Antwort. Meine Beiträge wirken beim Nachlesen > etwas undankbar, so ist es aber nicht gemeint. Ich freue mich immer, > wenn jemand für mich brauchbare Software veröffentlicht. Die Fragen > kamen dann beim Beschäftigen damit auf. Ich mag eben gern einfache, > klare Strukturen. (hab früher viel hobbymäßig Turbo-Pascal programmiert) Es hat ein wenig länger gedauert. Grund hierfür waren zwei Fehler. 1. ist mir mein AVRISP krepiert. Das dauerte allerdings einige Zeit dies festzustellen da ich zunächst meinen Aufbau in Verdacht hatte. Der 2. Fehler war, dass mein SH1106-Display ebenfalls das Zeitliche gesegnet hat. Diese zwei Fehler haben mich einige überflüssige Oszilloskop-Einsätze gekostet. However, im Anhang die modifizierte Grafik-Lib. Jetzt wird lcd_command und lcd_data auch wesentlich sinnvoller eingesetzt und die i2c-Funktionen werden nur noch da, in der lcd_command und der lcd_data, verwendet. Walter J. schrieb: > Danke für die Mühe. Einfach sicher - wenn man weiß, wo´s lang geht. Ich > geh in den nächsten zwei, drei Tagen dran (danach bin ich etwas wech..). Ich hab mal ein paar Kommentare eingepflegt, vielleicht macht das es noch einfacher.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | |
107 | |
cool ich hoffe ich kann es bald nutzen meine OLED 0.96" und 1.3" sind angekommen ich hänge nur noch an einer anderen Baustelle fest.
Gast
#4954742
M. K. schrieb: > However, im Anhang die modifizierte Grafik-Lib. Vielen Dank dafür. Leider hab ich erst nächste Woche Zeit und Ruhe, mal tiefer reinzugucken. Deine Änderungen machen mir die Portierung sicher deutlich leichter.
Der Fehlerteufel hat sich eingeschlichen und es gibt den ein und anderen Klammerfehler im SH1106-Bereich. Ein freundlicher User hat mich drauf hingewiesen. Die hier angehängte Version sollte nun aber problemlos auch mit SH1106-Displays funktionieren (wegen meines defekten SH1106-Displays kann ich derzeit leider nicht testen) ;)
Auf manche Sachen stößt man auch selbst. Der Library fehlte noch eine Funktion zum Schreiben vom Text, der im EEPROM des AVRs liegt. Diese Funktion habe ich nun auch ergänzt (void lcd_puts_e(const char* eemem_s)).
Sorry, dass ich die versprochenen Tests noch nicht habe, nicht mal angefangen hatte. Ich komm grad vom Schifahren zurück - einfach zu viel Tage mit zu viel Spass beim Cross (ohne KO!) und so. Kurz: Die ersten Arbeiten ergaben etliche Fehler (Lib´s fehlten eben) wie z.B. ".. adafruit_ssd1306.h ../Adafruit_SSD1306.h:25:23: error: WProgram.h: No such file or directory ../Adafruit_SSD1306.h:48:17: error: SPI.h: No such file or directory ../Adafruit_SSD1306.h:49:26: error: Adafruit_GFX.h: No such file or directory ../Adafruit_SSD1306.h:144: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Adafruit_SSD1306' .." Danke sylaina für die ausführlich(er) kommentierte Version vom 28.03.2017 11:09, da gabs auf die Schnelle auch noch Meckereien vom Compiler :-/: "Build started 3.4.2017 at 12:00:34 avr-gcc -mmcu=atmega328p -Wall -gdwarf-2 -std=gnu99 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT arno_OLED1306.o -MF dep/arno_OLED1306.o.d -c ../arno_OLED1306.c ../arno_OLED1306.c:7:18: error: main.h: No such file or directory ../arno_OLED1306.c: In function 'main': ../arno_OLED1306.c:16: warning: implicit declaration of function 'setUpAvr' ../arno_OLED1306.c: At top level: ../arno_OLED1306.c:94: warning: conflicting types for 'setUpAvr' ../arno_OLED1306.c:16: warning: previous implicit declaration of 'setUpAvr' was here ../arno_OLED1306.c: In function 'setUpAvr': ../arno_OLED1306.c:101: warning: implicit declaration of function 'sei' ../arno_OLED1306.c: At top level: ../arno_OLED1306.c:104: warning: return type defaults to 'int' ../arno_OLED1306.c: In function 'ISR': ../arno_OLED1306.c:104: warning: type of '__vector_13' defaults to 'int' ../arno_OLED1306.c:107: warning: control reaches end of non-void function make: *** [arno_OLED1306.o] Error 1 Build failed with 1 errors and 7 warnings..." Ich werde mir mal selbst die ganze Geschichte ausführlich zu Gemüte führen.
Mal nur zu meiner lib: Hast du den Code 1:1 kopiert? Zu meiner mein.c gibt es eine main.h die u.a. die Funktion setUpAvr() bekannt macht. Entweder kopierst du die setUpAvr in der main.c vor die main()-Funktion oder erstellst noch passend eine Header-Datei, den Code packe ich dir hier ans Ende des Post (als main.h abspeichern). Der Rest der Fehlermeldungen sind alles Folgefehler weil die main.h fehlt (u.a. wird in der main.h die avr/interrupt.h includiert ;))
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
Gast
#4962003
Habe die Bibliothek eben mit einem kleineren OLED-Display (0,69 Zoll, 96x16 Pixel) getestet, leider mit mäßigem Erfolg. Bild OLED_1.jpg zeigt das Ergebnis, wenn ich die oben gepostete main.c ohne Anpassungen verwende. Dass das nicht alles auf den kleinen Bildschirm passt ist verständlich, aber es wirkt noch dazu verzerrt. Bild OLED_2.jpg zeigt den Versuch, nur eine Zeile Text anzuzeigen:
1 | |
2 | |
3 | |
Die DISPLAY_WIDTH und DISPLAY_HEIGHT aus der lcd_gfx.h hab ich dazu nicht verändert, aber wenn ich sie auf 96 und 16 setze funktioniert überhaupt nichts mehr. Ich vermute, dass ich auch den Startup-Code in der init_sequence[] anpassen müsste. Leider bin ich diesbezüglich aus dem Datenblatt für den SSD1306 nicht recht schlau geworden. Hat jemand eine Idee, welche Parameter dabei eine Rolle spielen?
Versuche mal die Init-Sequence nach diesem Datenblatt (vgl. Seite 10 ff.) anzupassen http://www.buydisplay.com/download/manual/ER-OLED0.69-1_Series_Datasheet.pdf Ich hab das Display leider nicht, daher kann ich leider nicht testen, denke aber auch, dass hier die Init-Sequence angepasst werden muss.
Gast
#4962178
Danke für die schnelle Antwort! Das Dokument kannte ich noch nicht. Hab jetzt ein bisschen mit der Initialisierungssequenz auf Seite 12 gespielt und herausgefunden, dass nur zwei Änderungen gegenüber deinem Code nötig sind. Die "multiplex ratio" muss auf Anzahl der Zeilen minus eins (DISPLAY_HEIGHT-1) gesetzt werden, also 0x0F für 16 Zeilen statt 0x3F für 64 Zeilen.
1 | |
Das ist allgemeingültig und könntest du als "0xA8, DISPLAY_HEIGHT-1," auch in die Bibliothek übernehmen. Die zweite Änderung hängt mit der internen Verschaltung von SSD1306 und Display zusammen. Ich benötige die "Sequential COM pin configuration" an Stelle der bei dir verwendeten "Alternative COM pin configuration".
1 | |
So ganz hundertprozentig funktioniert es leider immer noch nicht. Angehängtes Bild OLED_3.jpg zeigt das Ergebnis für folgenden Code:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Irgendwie ist die zweite Zeile also um 8 Pixel nach links verschoben, und die (eigentlich unsichtbare) dritte Zeile fängt schon in der zweiten Zeile an. Ich fürchte da muss ich noch ein bisschen länger mit den Parametern spielen.
Das mit dem Display Ratio hab ich direkt mal umgesetzt ;) Die Verschiebung um 8 Pixel erscheint mir interessant zu sein. Da bin ich mal gespannt was das sein wird, weiß aber noch nicht wann ich dazu komme mir das genauer anzuschaun. Die Sache mit der dritten Zeile liegt einfach darin begründet, dass das lcd_gotoxy schaut ob die Parameter auch zulässig sind, also x und y innerhalb des Displays liegen. Ist dem nicht so wird die Funktion direkt wieder verlassen und der Cursor nicht weiter bewegt, in deinem Fall bleibt er dann am Ende des Textes der zweiten Zeile stehen und da wird dann der Text hingeschrieben, der eigentlich für die dritte Zeile bestimmt war.
Gast
#4963544
Den Grund für die Verschiebung der zweiten Zeile habe ich gefunden. Der SSD1306 adressiert intern immer 128x64 Pixel und merkt nicht, wenn ein kleineres Display angeschlossen ist. Wenn man ihm einen schmäleren Puffer übergibt landet der Anfang der zweiten Zeile am (unsichtbaren) Ende der ersten Zeile, was in meinem Fall zu einer Verschiebung um 32 Pixel führt. Beim Schreiben von displayBuffer[] muss man also die fehlenden Spalten mit Dummy-Bytes auffüllen.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
OLED_4.jpg zeigt das Ergebnis für den folgenden Code:
1 | |
2 | |
3 | |
4 | |
5 | |
Mit den Grafikfunktionen hatte ich auch noch Probleme und musste die Funktion lcd_drawPixel() anpassen. Was war der Grund, hier DISPLAY_HEIGHT zu referenzieren? Statt durch DISPLAY_HEIGHT/8 wird einfach durch 8 geteilt, weil jede Page über acht Zeilen reicht. Die Höhe des Displays spielt keine Rolle.
1 | |
Jetzt funktioniert alles. Danke für den Code!
Das Problem hatte ich auch mal. Das kann man aber mit der Initialisierungssequenz korrekt einstellen. Bin mir nicht ganz sicher mehr wo das war. Irgendwas mit addressing mode.
M. K. schrieb: > Auf manche Sachen stößt man auch selbst. leider nicht auf viele ich versuche gerade den Code in meinen Arduino zu integrieren
1 | |
2 | |
3 | |
4 | |
du hattest als Laufvariable i gewählt, OK mache ich auch öfter, aber bei der Integration was tun wenn i schon anderweitig belegt ist? Deswegen mache ich immer eindeutige Namen wie my_lcd_init_i hilft aber hier nicht, wo klemmst denn? ich mag ja fremde Codes intergrieren, aber derlei Stolpersteine vermiesen es, eigentlich wollte ich meine Probleme minimieren und keine neuen Nebenschauplätze eröffnen. lcd_gfx.c: In function 'lcd_init': lcd_gfx.c:240: error: 'for' loop initial declaration used outside C99 mode
Joachim B. schrieb: > was tun wenn i schon anderweitig belegt ist? Interessiert kein Schwein, solange es kein Makro ist (die benennt man daher ja auch üblicherweise in GROSSBUCHSTABEN), denn die Variable ist ausschließlich lokal zur Schleife und kollidiert dabei mit rein gar nichts. > lcd_gfx.c:240: error: 'for' loop initial declaration used outside C99 > mode Dann schalt' halt den C99-Modus endlich ein, wenn du's bislang noch nicht getan hast. -std=c99 oder -std=gnu99. Ist eigentlich unverständlich, warum der Default beim GCC nach wie vor -std=gnu89 ist.
Jörg W. schrieb: > Dann schalt' halt den C99-Modus endlich ein, wenn du's bislang noch > nicht getan hast. bin halt kein Informatiker und stolpere das erste Mal drüber, Jörg W. schrieb: > Ist eigentlich > unverständlich, warum der Default beim GCC nach wie vor -std=gnu89 > ist. da hast du Recht, an wen wendet sich denn der gcc an Hobbyprogger wie mich. Allerding zur LIB warum in einer Funktion in jeder for Schleife zig mal for ( uint8_i = 0... steht ist mir auch ein Rätsel wenn ich in einer Funktion i öfter benötige, dann wird es in der Funktion einmal am Anfang initialisiert. uint8_t i=0; das muss nicht in jeder for Schleife, wer tippt denn so gerne uint8_t ?
Joachim B. schrieb: > da hast du Recht, an wen wendet sich denn der gcc an Hobbyprogger wie > mich. Keineswegs, der ist genausogut profesionell im Einsatz. C99 ist ja nun mittlerweile durchaus schon recht betagt (C11 gibt's bereits als Nachfolger seit einiger Zeit). Ein großer Teil der C99-Erweiterungen war im GCC bereits vor dem 1999er Standard aktiv und ist daher in der Voreinstellung -std=gnu89 schon enthalten, die Schleifenvariablen der for-Anweisung sind da die wohl prominenteste Ausnahme. > warum in einer Funktion in jeder for Schleife zig mal for ( uint8_i = > 0... > > steht ist mir auch ein Rätsel Weil damit der Gültigkeitsbereich der Variablen (“scope”) explizit nur auf die Anweisung innerhalb der for-Schleife limitiert wird. Limitierung des Geltungsbereichs einer Variablen auf das notwendige Minimum ist durchaus guter Stil.
Jörg W. schrieb: > Weil damit der Gültigkeitsbereich der Variablen (“scope”) explizit > nur auf die Anweisung innerhalb der for-Schleife limitiert wird. > Limitierung des Geltungsbereichs einer Variablen auf das notwendige > Minimum ist durchaus guter Stil. OK aber das ist mir noch unklar, werden lokale Variablen nicht immer auf dem Stack initialisiert? In jeder for Schleife neu? Bringt das nicht unnötigen overhead? Warum sollte man das innerhalb einer Funktion machen? mal abgesehen vom Stil.
Joachim B. schrieb: > OK aber das ist mir noch unklar, werden lokale Variablen nicht immer auf > dem Stack initialisiert? Es geht hier nicht um den Speicherort der Variablen (der wird am Ende sehr wahrscheinlich ein Register sein), sondern um den Gültigkeitsbereich.
1 | |
2 | |
Nach der Zeile „tuwas(i);“ gibt es die Variable „i“ bereits nicht mehr. Das ist danach sowohl dem Menschen als auch dem Compiler klar. Das nächste „i“ in der nächsten Schleife ist dann bereits eine neue Variable, die mehr oder minder zufällig genauso heißt. Der Compiler würde sie natürlich auch in diesem Falle:
1 | |
2 | |
3 | |
hernach wegwerfen, wenn mit dem „i“ nichts mehr gemacht wird, aber es könnte dann später nochmal jemand daherkommen, und er müsste für Code, der gar nichts damit zu tun hat, u. U. noch Verrenkungen machen, um den Wert von „i“ zu erhalten (sofern er nicht folgern kann, dass dieser später sowieso auf jeden Fall überschrieben wird). Da der Gültigkeitsbereich so gut überschaubar ist, muss man eben auch nicht das_ist_i_in_der_funktion_xyz schreiben, sondern kann sich eine kurze und knappe Benennung leisten, denn der Betrachter des Codes kann sofort erkennen, auf wie wenigen Zeilen die Variable tatsächlich benutzt werden kann.
OK ich gebe auf, kann den Schalter C99 nicht finden, bekomme bei jeder Fehlermeldung die ich beseitige neue. Habe gegoogelt wo man beim Arduino den C99 Schalter setzt, nix gefunden aber zurück zum A-Studio 4.18 möchte ich an dieser Stelle nicht. Das wars dann hier für mich, ich kann das Display ja ansprechen nur eben mit einer dickeren LIB statt schlank!
Joachim B. schrieb: > Habe gegoogelt wo man beim Arduino den C99 Schalter setzt https://github.com/01org/corelibs-arduino101/issues/220 Du müsstest also wohl irgendwo eine Datei platform.txt finden, in der du diese Option ergänzen kannst. Du kannst auch probieren, ob Michaels Code sich als C++ übersetzen lässt, indem du die Datei nicht „lcd.c“, sondern „lcd.cc“ oder auch Arduino-mäßig „lcd.ino“ nennst. C++ kennt diese Variante der Laufvariablen in for-Anweisungen schon lange.
Jörg W. schrieb: > oder auch > Arduino-mäßig „lcd.ino“ nennst. OK ich versuche es nochmal, danke dir für deine Unterstützung!
Jörg W. schrieb: > Du kannst auch probieren, ob Michaels Code sich als C++ übersetzen lässt Bei mir lässt er sich klaglos auf diese Weise compilieren.
hmmm, kompiliert fehlerfrei mit *.ino
1 | |
2 | |
3 | |
4 | |
aber Display beibt duster, welche Adresse nutzt er denn? habe ich noch nicht gefunden meine erfolgreichen Versuche mit anderer LIB waren so
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
das muss noch was mit den I2C Routinen zu tun haben
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
Mist, auf dem Steckbrett versteckt, die alten Augen So nun bin ich weiter, seine OLED Adresse ist identisch mit meiner! hängt noch am I2C mit lcd_init gibt es Schrott auf Serial.print in einer Endlosschleife, dabei sollte da noch nichts passieren:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
sorry Mod!für code Tags -> hier gleich verbessert
Joachim B. schrieb: > mit lcd_init gibt es Schrott auf Serial.print in einer Endlosschleife, > dabei sollte da noch nichts passieren Läuft da irgendwo der RAM über (ggf. auch Stack)?
noch ziemlich unwahrscheinlich, ist echt schmal: doch das war es!!!! mit OLED Binäre Sketchgröße: 8.964 Bytes (von einem Maximum von 30.720 Bytes) advanced_OK.cpp.elf" text data bss dec hex 8724 240 1760 10724 29e4 hey warum verbraucht die schmale LIB soviel SRAM? ohne OLED mein pures Proggi Binäre Sketchgröße: 6.294 Bytes (von einem Maximum von 30.720 Bytes) dvanced_OK.cpp.elf" text data bss dec hex 6070 224 543 6837 1ab5
da komme ich ja im SRAM mit RTC, OLED und NOKIA schmaler hin Binäre Sketchgröße: 30.134 Bytes (von einem Maximum von 30.720 Bytes) C_OLE_EEP_OK.cpp.elf" text data bss dec hex 29560 574 1031 31165 79bd
also 1k statischer Displaybuffer ist mir zu viel #define DISPLAYSIZE DISPLAY_WIDTH*DISPLAY_HEIGHT/8 // 128*64/8 nun verstehe ich nix mehr: M. K. schrieb: > Meine Lib arbeitet ohne Puffer, daher wird hierfür auch kein statischer > RAM für einen Puffer benötigt. Ich hab es nicht getestet, aber auch 128 > Byte RAM müssten locker ausreichend sein.
Diese Aussage bezieht sich auf die eingangs gepostete Bibliothek zum Schreiben von Text auf so ein Display. Die von dir genannte Variable dagegen gehört in die Grafiklib, die Michael später gepostet hat. Bei einer solchen ist der Puffer praktisch unumgänglich, hatten wir weiter oben schon diskutiert. „Jetzt benötigt die Lib leider schon etwas mehr als 4kByte Flash sowie 1029 Byte SRAM.“ schrieb er dann auch selbst.
Jörg W. schrieb: > Ich finde ich Michaels Code keine einzige globale oder statische > RAM-Variable. im letzten zip Beitrag "Re: SSD1306 Library zum Darstellen von Text auf OLED Displays" in lcd_gfx.h #define DISPLAYSIZE DISPLAY_WIDTH*DISPLAY_HEIGHT/8 genutzt von in lcd_gfx.ino // lcd_gfx.c static uint8_t displayBuffer[DISPLAYSIZE]; wie soll ich das sonst nennen? ist das nicht statisch und na ja local/global? ich bin ja kein Progger aber diese Zeile dachte ich verstanden zu haben static uint8_t displayBuffer[DISPLAYSIZE]; ergibt 1k SRAM Verbrauch bei 128 x 64 Pixel / 8
Sorry, hatte erst danach bemerkt, dass es ja zwei Libs sind und daher meinen Beitrag nochmal geändert. Mit chronischer RAM-Knappheit hast du auf diesen Displays keine Chance, auch noch Grafik zu machen. Das liegt einfach daran, dass sich die Pixel ja nicht wieder auslesen lassen. Da acht Pixel in einem Byte liegen (Monochrom), muss man daher eine Schattenkopie des Displayinhalts im RAM halten, wenn man Grafik machen will. Seine Text-Lib war genau darauf ausgelegt, diese Schattenkopie nicht zu brauchen, aber dann kann man eben nur Text darstellen.
Jörg W. schrieb: > Seine Text-Lib war genau darauf ausgelegt, diese Schattenkopie nicht > zu brauchen, aber dann kann man eben nur Text darstellen. Genau, das Hauptaugenmerk lag bei mir auf der Variante, die nur Text darstellt. Diese Lib verbraucht keinen RAM. Die Grafik-Lib kommt um den RAM nicht rum wenn man nicht überzeichnen will. Willst du, Joachim, also nur Text darstellen dann benutze die lcd.c/lcd.h Lib, die ich weiter oben gepostet habe. Diese Lib alleine braucht keine 2k Flash-Speicher. Und bzgl. der Arduino-Umgebung: Da hab ich leider absolut keine Ahnung wie gut sich meine Lib in diese Umgebung integrieren lässt. Das sind so Dinge, die auf meine immer länger werdende ToDo-Liste kommt.
M. K. schrieb: > Die Grafik-Lib kommt um den RAM nicht rum wenn man nicht überzeichnen > will. Das führt zu dem Paradoxon: wenn man einen kleinen Controller mit wenig SRAM hat, kommt man am Ende besser, statt eines monochromen OLED-Displays ein RGB-Display zu nehmen. Dort beschreibt man mit einem Byte immer ein Pixel auf einmal, braucht daher keinen Puffer und kann trotzdem Grafik machen.
M. K. schrieb: > Willst du, Joachim, also nur Text darstellen dann benutze die > lcd.c/lcd.h Lib, die ich weiter oben gepostet habe. Diese Lib alleine > braucht keine 2k Flash-Speicher. wo weiter oben, du hattest viel gepostet, hast du bitte einen Link?
Gleich im ersten Beitrag.
Jörg W. schrieb: > Gleich im ersten Beitrag. danach kamen aber noch updates wegen verschiedener Controller 13xx zu 11xx wegen der Pixelgrenze und Bugs wurden später auch noch berichtigt, warum also zur ersten ZIP ?
Joachim B. schrieb: > danach kamen aber noch updates Stimmt, ein Update sehe ich noch: Beitrag "Re: SSD1306 Library zum Darstellen von Text auf OLED Displays" @Michael: soll ich mal deinen ersten Threadbeitrag editieren und die Links auf die jeweils aktuelle Version einfügen?
Gast
#4964587
Nico W. schrieb: > Das Problem hatte ich auch mal. Das kann man aber mit der > Initialisierungssequenz korrekt einstellen. Bin mir nicht ganz sicher > mehr wo das war. Irgendwas mit addressing mode. Ja, dachte ich auch. Die Lib nutzt den "horizontal addressing mode", also hatte ich in der Init-Sequenz den Befehl 0x21 ausprobiert um Start- sowie Endadresse der zu nutzenden Spalten im RAM zu setzen:
1 | |
Leider zunächst erfolglos. Auf deinen Beitrag hin habe ich mir das eben aber nochmal angeschaut und festgestellt, dass die Funktion lcd_gotoxy() den gleichen Befehl nutzt und die Einstellung aus der Init-Sequenz überschrieben hat. Wenn man die betreffende Zeile abändert funktioniert es. Damit ist dann auch meine Funktion lcd_writeBuffer() von oben überflüssig.
1 | |
Gast
#4966453
Cool danke, schön gemacht. Nur bei der GotoXY hat es bei meinem Display nicht funktioniert, ich stelle heute Abend mal meine Source für die Funktion ein. Das man um den 1K RAM nicht drumrum kommt liegt an der Speicheraddressierung des SSD1306. Hätte er einen Framebuffer wäre das alles halb so wild :-D
Gast
#4966529
Hier mal auf einem STM32F1... Grafikbibliothek und 1Bit Bild.
DraconiX schrieb: > Das man um den 1K RAM nicht drumrum kommt liegt an der > Speicheraddressierung des SSD1306. Nö, das liegt an der Schnittstelle. Bei i2c und spi kann man nur schreibend auf das Display zugreifen. Geht man ans parallele Interface des SSD1306 ran kann man das Display auch auslesen, dann braucht man den RAM nicht. Jörg W. schrieb: > @Michael: soll ich mal deinen ersten Threadbeitrag editieren und die > Links auf die jeweils aktuelle Version einfügen? Gute Idee, versuche ich gleich umzusetzen. Ich hab auch überlegt bei github ein Repository jeweils für die Text-Variante und für die Grafik-Variante zu erstellen. Joachim B. schrieb: > wo weiter oben, du hattest viel gepostet, hast du bitte einen Link? Ich hab beide Varianten in der aktuellen Version diesem Beitrag angehangen, aus dem ersten Beitrag werde ich gleich noch hierauf verlinken lassen. EDIT: Jörg, ich darf den ersten Post nicht mehr editieren. Das ist wohl eine Option, die nur Moderatoren/Administratoren zur Verfügung steht, nicht aber "normalen" Usern. Wärst du vielleicht so nett?
M. K. schrieb: > Wärst du vielleicht so nett? Ja, natürlich, darum hatte ich dir das ja angeboten.
Gast
#4966687
M. K. schrieb: > Geht man ans parallele Interface des SSD1306 ran kann man das Display > auch auslesen, dann braucht man den RAM nicht. Ah okay, das wusste ich nicht! :-D Danke für die Info, über die parallele Kommunikation hab ich mir beim SSD1306 noch keine Gedanken gemacht / im DB gestöbert weil es kaum Displays gibt die dies so ausgeführt haben. Theoretisch, gerade auf großen MCs, könnte man sich auch Gedanken machen darüber immer nur eine Page vorzuhalten - dies wiederum braucht aber mehr Flash und Rechenzeit, da ja alle 8 Pages nacheinander neu berechnet und geschrieben werden müssen. Irgendwie...
Jörg W. schrieb: > M. K. schrieb: >> Wärst du vielleicht so nett? > > Ja, natürlich, darum hatte ich dir das ja angeboten. irgendwas ist da schiefgelaufen, die SH1106 Wahl ist wieder nicht drin, ich bekomme verschobene Pixel und bei lcd_clrscr(); habe ich Rauschen auf dem Screen!
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
sollte ja nicht so schwer werden :)
ach ich liebe debugging lcd.ino: In function 'void lcd_clrscr()': lcd:324: error: invalid conversion from 'int' to 'uint8_t*' lcd:324: error: initializing argument 1 of 'void lcd_data(uint8_t*, uint16_t)'
hier klemmts irgendwo
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
Tja, manches, was bei C einfach noch so durchgeht, ist bei C++ nicht mehr zulässig, da ist das Typkonzept pingeliger. Aber: irgendwas passt da nicht. Wenn lcd_data() als erstes einen Zeiger haben will, dann hat das einen Grund, ihm einfach 0x0F zu übergeben, kollidiert zu Recht. Probier's mal damit:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
Mal was ganz anderes, Michael: GPL für Code, den man im Embedded-Bereich benutzen können soll, finde ich persönlich nicht sehr sinnvoll. Das dürfte für so ziemlich jeden, der das kommerziell verwenden möchte, schnell zum KO-Kriterium werden. Selbst LGPL ist bei so kleinen Prozessoren wie einem AVR nicht sinnvoll, denn dann brauchst du auch keine security fuse mehr, wenn du den Leuten sowieso disassemblierfähige Objektdateien mitliefern musst. Musst du natürlich am Ende selbst wissen, aber falls die Entscheidung eher nicht vorsätzlich so gefallen ist: es gibt einen Grund, warum bspw. die avr-libc eine BSD-Lizenz hat, obwohl sie sich ansonsten in eine GNU-dominierte Toolchain integriert.
Jörg W. schrieb: > ihm einfach 0x0F zu > übergeben, kollidiert zu Recht. verstehe ich ja, ich bin nur nicht der richtige Ansprechpartner, der TO nannte es LIB und die möchte ich nutzen ;)
Joachim B. schrieb: > verstehe ich ja, ich bin nur nicht der richtige Ansprechpartner, Du bist aber derjenige, der es jetzt gerade nutzen will, insofern kannst du den von mir vorgeschlagenen Ersatz ja zumindest mal testen. Ich denke, dass Michael da in der Hektik einen Bug eingesammelt hat, den sollte er korrigieren – wenn du den Bugfix aber als „funktioniert“ bestätigst, ist das ganz sicher hilfreich für ihn.
Jörg W. schrieb: > kollidiert zu Recht. > > Probier's mal damit: hmmm, Fehler im lcd_clrscr ist weg, Text auch nicht mehr sichtbar mit der 1306 Version ging wenigstens Text wenn auch buggy nun muss es noch was mit der Initialisierung sein, Timing oder Bit oder ?
Jörg W. schrieb: > Du bist aber derjenige, der es jetzt gerade nutzen will, insofern kannst > du den von mir vorgeschlagenen Ersatz ja zumindest mal testen. äh ja ich bin doch dabei! nochmal, vorher hatte ich mit der ersten LIB "hallo" und "huhu" zu Display 1106 gebracht noch mit 1306 Code! hallo und huhu landete aber auf falsche Zeilen weil ich ein 1106 habe, das Display war auch nicht clean nach clr(); sondern verrauscht mit Pixelmüll um den Text. Dann die andere LIB eingespielt mit Compilerfehler deine Korrektur eingebracht, Kompilerfehler weg aber auch nur ein leeres unverrauschtes Display, kein Text mehr sichtbar. nun hänge ich..... BTW wäre hier ein #define nicht besser? statt:
1 | |
2 | |
3 | |
besser?:
1 | |
ich hänge immer noch.....
Jörg W. schrieb: > Aber: irgendwas passt da nicht. Wenn lcd_data() als erstes einen > Zeiger haben will, dann hat das einen Grund, ihm einfach 0x0F zu > übergeben, kollidiert zu Recht. In der Tat, wie ist mir denn das passiert? Vor die 0x0f hätte noch ein (uint8_t*) gehört (wenn ich das recht im Kopf hab)...bei mir hat das der Compiler zunächst nicht mal angemeckert, daher ist mir das wohl durch die Lappen gegangen... Joachim B. schrieb: > deine Korrektur eingebracht, Kompilerfehler weg aber auch nur ein leeres > unverrauschtes Display, kein Text mehr sichtbar. Gibt der Compiler noch ein Warning oder ähnliches bei dir aus? Ich habe beim SH1106 auch ein 128*64 Pixel großes Display, benutzt du auch so eines? Wenn nicht liegt es vielleicht auch an der Displaygröße und da muss noch was eingestellt werden, dass ich bisher übersehen habe. Es tut mir echt leid, dass es bei dir solche Probleme macht, ich hoffen wir können das Problem schnell lösen. Joachim B. schrieb: > wäre hier ein #define nicht besser? Hm, so tief bin ich bei weitem nicht drin. Ich habe hier eine Funktion gewählt da ich mit dem OLED-Display auch ein paar meiner alten LCD-Displays ersetzt habe (mit HD48780-Controller) und hierbei die Lib von Peter Fleury verwendet habe. Damit ich meinen alten Code nicht umschreiben muss sondern wirklich nur die lcd-Lib austauschen muss habe ich mich bzgl. der Funktionsnamen ein wenig an Peters Lib orientiert ;) Jörg W. schrieb: > Mal was ganz anderes, Michael: GPL für Code, den man im > Embedded-Bereich benutzen können soll, finde ich persönlich nicht > sehr sinnvoll. > ... Ich hab da wenig Ahnung von und hab daher mal in meinem Dunstkreis rumgefragt und da wurde mit GPL empfohlen. In Stein gemeißelt ist das aber nicht.
Gast
#4967134
Hier mal meine, angepasst für einen STM32F103 - mit StdPeriphLib - gleich dazu mit der I2C Initialiesrung - Quasi LCD an I2C1 (PB6 und PB7). Dann noch die Header einbinden und los gehts:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
Ich erweitere meine auch noch so nach und nach, so das ich die Register direkt beschreibe und keine Lib brauche, und das ich noch Standard I2C2 und I2C3 mit rein nehme.
M. K. schrieb: > ich hoffen > wir können das Problem schnell lösen. hoffe ich auch M. K. schrieb: > Gibt der Compiler noch ein Warning oder ähnliches bei dir aus? Ich habe > beim SH1106 auch ein 128*64 Pixel großes Display, ja ist identisch M. K. schrieb: > und hierbei die Lib > von Peter Fleury verwendet habe. Damit ich meinen alten Code nicht > umschreiben muss sondern wirklich nur die lcd-Lib austauschen muss habe > ich mich bzgl. der Funktionsnamen ein wenig an Peters Lib orientiert ;) ist ja kein Problem, die hatte ich auch verwendet als ich noch auf pure AVR und lcd mit Studio 4.18 unterwegs war deswegen kenne ich die ja ganz gut momentan mache ich halt mit der "U8glib.h" weiter vielleicht klappts ja mit deiner irgendwann, Testaufbau ist vorhanden und wenn du was findest probiere ich weiter. wie gesagt mit 1306 init lief es auf 1106 mal nur mit Pixelmüll und falscher xy Adressierung nun ist der Pixelmüll weg, aber Text kommt nicht, nicht mal falsch adressiert. M. K. schrieb: > Gibt der Compiler noch ein Warning oder ähnliches bei dir aus? nein
Gast
#4967238
M. K. schrieb: > DraconiX schrieb: >> Das man um den 1K RAM nicht drumrum kommt liegt an der >> Speicheraddressierung des SSD1306. > > Nö, das liegt an der Schnittstelle. Bei i2c und spi kann man nur > schreibend auf das Display zugreifen. Geht man ans parallele Interface > des SSD1306 ran kann man das Display auch auslesen, dann braucht man den > RAM nicht. > > Jörg W. schrieb: >> @Michael: soll ich mal deinen ersten Threadbeitrag editieren und die >> Links auf die jeweils aktuelle Version einfügen? > > Gute Idee, versuche ich gleich umzusetzen. Ich hab auch überlegt bei > github ein Repository jeweils für die Text-Variante und für die > Grafik-Variante zu erstellen. > > Joachim B. schrieb: >> wo weiter oben, du hattest viel gepostet, hast du bitte einen Link? > > Ich hab beide Varianten in der aktuellen Version diesem Beitrag > angehangen, aus dem ersten Beitrag werde ich gleich noch hierauf > verlinken lassen. > > EDIT: Jörg, ich darf den ersten Post nicht mehr editieren. Das ist wohl > eine Option, die nur Moderatoren/Administratoren zur Verfügung steht, > nicht aber "normalen" Usern. Wärst du vielleicht so nett? Ich habe einen Fehler in deiner Lib gefunden - schau mal bitte danach - bei mir hat der Compiler immer eine Warnung rausgeworfen aber ich kam selber nicht dahiner. Bei deiner DrawRect, DrawLine etc... überall wo die Überprüfung des Displaybereiches ist. von:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
zu:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Sie dazu auch hier: Beitrag "C Fehler: Vergleich von Const mit bool immer falsch"
DraconiX schrieb: > Ich habe einen Fehler in deiner Lib gefunden - schau mal bitte danach - > bei mir hat der Compiler immer eine Warnung rausgeworfen aber ich kam > selber nicht dahiner. > > Bei deiner DrawRect, DrawLine etc... überall wo die Überprüfung des > Displaybereiches ist. betrifft das nicht nur die Grafik Version? Momentan gehts um Text 1306 zu 1106, jedenfalls für mich, nur um mal wieder Ordnung in die Postings zu bekommen.
Gast
#4967360
Joachim B. schrieb: > betrifft das nicht nur die Grafik Version? > Momentan gehts um Text 1306 zu 1106, jedenfalls für mich, nur um mal > wieder Ordnung in die Postings zu bekommen. Ja das betrifft nur die Grafik Version. Zum Thema 1106 kann ich leider nix sagen da ich hier keinen habe, sonst hätte ich mich auch darauf geworfen.
Joachim B. schrieb: > wie gesagt mit 1306 init lief es auf 1106 mal nur mit Pixelmüll und > falscher xy Adressierung > > nun ist der Pixelmüll weg, aber Text kommt nicht, nicht mal falsch > adressiert. Ja, das ist "normales" Verhalten, dass beim "falschen" Controller die Adressierung nicht passt und man Pixel-Salat bekommt. Aber dass da gar nix kommt ist auch ungewöhnlich soweit ich das jetzt übersehen konnte. Ich könnte mir vorstellen, dass da irgendwo ein OutOfBounds auftritt. Ich hab mir mal Gedanken um die lcd_clrscr()-Funktion gemacht und sie "vereinfacht". Es gibt da jetzt keinen Unterschied mehr zwischen SSD1306 und SH1106:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
Vorteil: Das Löschen geht jetzt etwas schneller. Nachteil: Man braucht jetzt min. 129 Byte SRAM (bei 128 Pixel Breite: 128 für clearLine, 1 Byte für die Laufvariable i). Ich glaubs zwar nicht, bei mir hat das am Display-Verhalten selbst nichts geändert, aber vielleicht ändert das ja was bei dir. Wie sieht denn deine Main dazu aus? Ich glaube zwar nicht, dass es daran liegt, aber man weiß ja nie. Weißt du eigentlich, dass das mich ein wenig fuchsig macht, dass es bei dir nicht laufen will? ;) DraconiX schrieb: > Bei deiner DrawRect, DrawLine etc... überall wo die Überprüfung des > Displaybereiches ist. In der Tat, da hast du recht. Es ist aber nur die DrawRect und die DrawLine, in der die Prüfung praktisch wirkungslos ist. Hab ich hier schon geändert, kommt also mit dem nächsten Upload...sobald wir den Fehler bei Johannes raus haben ;).
M. K. schrieb: > for (uint8_t i=0; i<DISPLAY_WIDTH; i++) { > clearLine[i]=0x00; > } Das würde ich als
1 | |
schreiben.
Jörg W. schrieb: > M. K. schrieb: > >> for (uint8_t i=0; i<DISPLAY_WIDTH; i++) { >> clearLine[i]=0x00; >> } > > Das würde ich als
1 | |
schreiben. ganz genau, memset nutze ich gerne ist schliesslich integriert und man bekommt es ja kaum besser hin! M. K. schrieb: > Weißt du eigentlich, dass das mich ein wenig fuchsig macht, dass es bei > dir nicht laufen will? ;) das freut mich, ich möchte ja auch das es läuft :)
Hier mal eine Erweiterung zur Anzeige von Bildern: Dazu einfach den Code aus der angehängten Txt-Datei in die lcd_gfx.h und lcd_gfx.c einfügen. Bilder mit Gimp etc. vorbereiten und skalieren. Dabei die maximale Größe beachten, es darf nicht größer als die Displaygröße sein. Die Höhe muss glatt durch 8 teilbar sein. Bei einem 128x64 Display wäre also z.B. eine Größe von 60x48 gültig. Mit OledBm.exe in Programmcode umwandeln. Es gibt hier noch die Möglichkeit, die Schwellwerte für RGB zu ändern, um z.B. schnell aus farbigen Bildern eine Monochrom-Bitmap zu generieren. Bessere Ergebnisse ergeben sich, wenn das schon mit dem Bildverarbeitungsprogramm gemacht wird. "Code erstellen" und "Copy Clipboard", dann in main.c oder wo immer es von der Funktion sichtbar ist, einfügen. Funktionsaufruf sieht dann so aus: lcd_drawBitmap(34, 5, wcfrei); Es können natürlich soviele Bitmaps eingefügt werden, wie der Code-Speicher zulässt. Damit konnte ich dann meine WC-Besetzt-Anzeige mit Bewegungsmelder realisieren. :-) (Zuhause schließen wir keine Türen ab, weil im Notfall erschwerte Rettungsmöglichkeit.)
Rüdiger S. schrieb: > Hier mal eine Erweiterung zur Anzeige von Bildern: > Damit konnte ich dann meine WC-Besetzt-Anzeige mit Bewegungsmelder > realisieren. :-) > (Zuhause schließen wir keine Türen ab, weil im Notfall erschwerte > Rettungsmöglichkeit.) cool, trotzdem meine WC Tür hat aussen einen Schlitz der sofort mit Spachtel, Schlüsselanhänger, Messer, Tortenheber geöffnet werden kann!
Gast
#4968149
Coole Sache mit dem Bild-C-Dings-Bums! Schreibt er das Array anhand der Bildgröße raus?! Ich hab nun noch ein SIN Generator hinzugefügt und nun bin ich vollends zufrieden. Kann es sein das der SSD1306 ab ca. 700khz bei I2C schlapp macht? Höher schafft er es nimmer.
Gast
#4968174
M. K. schrieb: > In der Tat, da hast du recht. Es ist aber nur die DrawRect und die > DrawLine, in der die Prüfung praktisch wirkungslos ist. Hab ich hier > schon geändert, kommt also mit dem nächsten Upload...sobald wir den > Fehler bei Johannes raus haben ;). Das ging in der Flut überflüssiger Posts von Joachim B. vielleicht unter, aber die von mir beobachteten Probleme konnte ich durch die weiter oben beschriebenen Anpassungen in lcd_drawPixel() und lcd_gotoxy() erfolgreich beheben. Meiner Einschätzung nach sind die allgemeingültig und können von dir in die Bibliothek übernommen werden.
DraconiX schrieb: > 700khz bei I2C I²C ist ja normal auch nur für 400 kHz spezifiziert.
Gast
#4968302
Jörg W. schrieb: > DraconiX schrieb: >> 700khz bei I2C > > I²C ist ja normal auch nur für 400 kHz spezifiziert. Das ist ein typisches i2c Problem. Wenn ein Device nur 399 kHz schafft, fällt es in die Klasse Standard, 100kHz, genau wie eins, das bei 101 kHz nicht mehr kann. Schafft es keine 3,4 MHz, ist es nur Fast, also 400kHz. Zwischenwerte gibt es nicht. MfG Klaus
DraconiX schrieb: > Coole Sache mit dem Bild-C-Dings-Bums! Schreibt er das Array anhand der > Bildgröße raus?! Ja, je nach Bildgröße enthält das Array auch mehr oder weniger Daten. Die ersten beiden Bytes im Array beschreiben die Bildgröße.
Rüdiger S. schrieb: > Mit OledBm.exe in Programmcode umwandeln. Quellcode dafür wäre natürlich nicht schlecht. Alternative: mit Gimp als XBM abspeichern. Das ist C-Quzelltext. :) Für den AVR sollte man dann aber das XBM damit nachbearbeiten:
1 | |
2 | |
3 | |
4 | |
(Makefile-Schnipsel, Kommandos bitte mit <TAB> einrücken) Damit wird ein progmem-Objekt draus gemacht.
Gast
#4968368
Jörg W. schrieb: > DraconiX schrieb: > 700khz bei I2C > > I²C ist ja normal auch nur für 400 kHz spezifiziert. Naaaa... Es gibt ja auch den I2C High-Speed-Mode mit Clockstretching bis 3,4MHz.
Jörg W. schrieb: >> Mit OledBm.exe in Programmcode umwandeln. > > Quellcode dafür wäre natürlich nicht schlecht. Kein Problem, werde das nach dem Aufräumen veröffentlichen. Ist C#, kann also mit der frei verfügbaren Visual Studio Community Edition kompiliert werden. > > Alternative: mit Gimp als XBM abspeichern. Das ist C-Quzelltext. :) > Klasse, man lernt immer was dazu. :)
Gast
#4968553
.SUFFIXES: .xbm
.xbm.h:
sed -e 's/^.* \([a-zA-Z0-9_]*_bits\).*$$/static const uint8_t
\1[] __attribute__((progmem)) = {/' $< > $@.tmp && mv $@.tmp $@
Schräg !!! :)
oberallgeier schrieb: > Hallo Michael, > ... > Als Gegenleistung .. Bildchen .. vom Oskar .. I²C-Flanken bei den 400 kHz. So Manfred, am 11.03.2017 hatte ich Dir versprochen die Bildchen vom I²C-Bus zu zeigen, der mit 400 kHz betrieben wird. Ich habe nun eine (selbst ge-copy´n´paste-e) Version aus den Tiefen des WWW (*.cpp-Version) adaptiert und das Display 1306 zum Laufen bekommen. Hier die Bilder, einmal mit 400 kHz, einmal mit 200 kHz. Man sieht bei den 400 kHz-Flanken deutlich, dass der Pegel bei 5V eindeutig nicht mehr erreicht wird - vergleiche dazu die 200-kHz-Flanken. Dieser Bustakt dürfte also schon grenzwertig sein. Sonstige Daten: nano-Clone mit 20 (!) Mhz, 5V-Pegel, je 1x 4k7 auf SDA und SCL, Datenleitung von den Steckleisten eines nanoclones bis zumSteckbrett ca. 20 cm, Display ohne Kondensator von der Nano-Steckerleiste (GND, 5V) versorgt. DraconiX schrieb: > Kann es sein das der SSD1306 ab ca. 700khz bei I2C schlapp macht? Es gilt ja: TWBR = ((F_CPU/SCL_CLOCK)-16)/2 bei (meinem Clone mit) 20 MHz ergibt sich also ein TWBR von 17, bei 16MHz UND 700 kHz ist TWBR gleich 3 (3,4..). Soweit ich die I²C-Spezifikation kenne, ist bei TWBR von etwa 10 Schluss, dann wird sowieso clock gestretcht (KANN gestretcht werden gg).
Nachtrag zu den Bildern: Gould DSO1602, 20 MHz.
Walter J. schrieb: > Hier die Bilder, einmal mit 400 kHz, einmal mit 200 kHz. Man sieht bei > den 400 kHz-Flanken deutlich, dass der Pegel bei 5V eindeutig nicht mehr > erreicht wird - vergleiche dazu die 200-kHz-Flanken. Dieser Bustakt > dürfte also schon grenzwertig sein. So aus der Hüfte geschossen würde ich da aber sagen, dass deine Pull-Ups für 400 kHz schlicht schon zu groß sind. Schau dir mal das hier von TI dazu an: http://www.ti.com/lit/an/slva689/slva689.pdf ;)
M. K. schrieb ..
> .. aus der Hüfte geschossen .. Pull-Ups für 400 kHz .. zu groß ..
Huiii, danke, was für eine praktische, gute Anleitung von TI; die kannte
ich nicht.
Nun hab ich mal die Leitung vom nano-Pinn SCL zum/inclusive Steckbrett
gemessen. Uuuuups, 33 µF (mit Billig-DMM), das sind >> 450 pF aus Fig.
3, und laut Fig. 2 können <1,6kΩ passen.
Also je 1x1k6 Ω gegen Vcc an jede I²C-Leitung - am Steckbrett,
Übertragungsrate auf 400 kHz (ERinnerung: nanoclone 20 MHz) gestellt und
Oskar angeworfen.
Genau, jetzt sieht es auch bei 400 kHz nicht mehr (so) grenzwertig aus.
Die Auflösung meines alten DSOs ist zwar leider nur bis 10 µs/DIV. Am
5V-Pegel ist trotzdem bei jedem Zacken/Puls vom SCL noch eine eindeutige
Linie zu erkennen ?~1µs?. Foto könnte ich nachreichen, aber vielleicht
reicht meine Beschreibung.
Danke für die Hilfe(n).
Walter J. schrieb: > Uuuuups, 33 µF Dann solltest du entweder den Messwert deines Schätzeisens grundlegend in Zweifel ziehen oder aber den 33-µF-Elko schnellstens von der SCL-Leitung wieder ablöten. :-)
33µF aus einer Leitung, RESPEKT wo gibt es das Kabel oder wie lang ist es? Direktleitung zur ISS?
oberallgeier schrieb: > .. Datenleitung .. nanoclones bis zumSteckbrett ca. 20 cm .. Jörg W. schrieb: > .. entweder den Messwert deines Schätzeisens .. in Zweifel ziehen .. Na ich dachte "Uuuuups, 33 µF .." sei Kommentar genug, aber man sollte halt nie zuviel voraussetzen. Gut, ne Nachmessung mit meinem selbstgebauten Transistortester nach Markus F. zeigt später "kein Bauteil" an; einen 100 pF misst der (Kontrollmessung) noch mit 0,14 nF.
Gast
#4981682
Walter J. schrieb: > Es gilt ja: > TWBR = ((F_CPU/SCL_CLOCK)-16)/2 > bei (meinem Clone mit) 20 MHz ergibt sich also ein TWBR von 17, bei > 16MHz UND 700 kHz ist TWBR gleich 3 (3,4..). Soweit ich die > I²C-Spezifikation kenne, ist bei TWBR von etwa 10 Schluss, dann wird > sowieso clock gestretcht (KANN gestretcht werden gg). Ja bei mir läuft es über ein STM32 welcher auf 64Mhz läuft und das I²C mit DMA gefeuert wird. Der würde seine 4Mhz locker schaffen, aber mir ist bis dato auch noch kein HighSpeed-Slave untergekommen, nichteinmal Kollegen die die Clock gestrecht haben, wenn es ihnen zu schnell war.
Hallo, ich versuche die Lib auf einem Tiny85 zum Laufen zu bekommen. Das geht auf Anhieb gar nicht. Wie ich festgestellt habe, fehlt bei den i2c bit-bang Routinen die Slave Adresse, deshalb fühlt sich das OLED Display (SSD1306) gar nicht angesprochen. Gruß Rainer
Rainer K. schrieb: > .. Lib auf einem Tiny85 .. fehlt bei den i2c .. Gibts beim Tiny überhaupt ein I²C - na ja, aber eben nur "handgestrickt" ? In "meiner" SSD1306.h steht die Adresse als #define SSD1306_DEFAULT_ADDRESS 0x78 aber der Code ist eben für Hardware-TWI beim ATMEGA328p.
Gast
#4987320
Walter J. schrieb: > #define SSD1306_DEFAULT_ADDRESS 0x78 > aber der Code ist eben für Hardware-TWI beim ATMEGA328p Ja, aber es wurde auch versucht zumindestens die Text-Lib mit bit-bang I2C für die Tinys zu implementieren. Scheinbar hat vor mir das niemand ausprobiert :-) Ohne slave-Adresse in den bit-bang I2C Funktionen geht es aber nicht...das Diplay bleibt einfach dunkel. Mir ist noch nicht ganz klar, wo man am Einfachsten das Schreiben der Slave-Adresse einfügt. Gruß Rainer
Gast
#5011160
Hallo zusammen, wie Schwierig ist es einen anderen Font zu integrieren ? lg Dietmar
Dietmar schrieb: > wie Schwierig ist es einen anderen Font zu integrieren ? Kommt auf den Font an. Aktuell ists nur für 6x8-Fonts gemacht. Wenn du also einen anderen 6x8-Font möchtest sollte das kein Problem sein.
Gast
#5017694
Vielen Dank für die Antwort und das erstellen der Library ! Ich finde die Library ausgezeichnet und sie ist auch nicht so überladen wie die U8G Lib. Ich verwende den 6x8 Font aber der ist für mich als älteres Semester nicht so gut lesbat ;-) lg Dietmar
Gast
#5017721
Dietmar schrieb: > Ich verwende den 6x8 Font aber der ist für mich als > älteres Semester nicht so gut lesbat ;-) Kenn ich. Es gibt auch Pin- und Funktionskompatible 1,3" Oleds. Da ist es ein wenig besser. MfG Klaus
Gast
#5019382
meine quick and dirty Variante :-)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
Hallo, ich bin hier auf die OLED Library gestoßen und wollte die ganz gerne verwenden. Leider Bekomme ich beim Compilieren immer den fehler: "undefined reference to `lcd_gotoxy(unsigned char, unsigned char)" Dieser Fehler tritt bei jeder Funktion auf. Hat einer eine Idee woran das liegen könnte? Ich benutze Atmel Studio 7. Würde mich über ein Tipp sehr freuen, Danke! Mfg
Gast
#5021742
Daniel R. schrieb: > Leider Bekomme ich beim Compilieren immer den fehler: > > "undefined reference to `lcd_gotoxy(unsigned char, unsigned char)" > > Dieser Fehler tritt bei jeder Funktion auf. > Hat einer eine Idee woran das liegen könnte? #include "SSD1306_i2c.h" vergessen?
Gast
#5021743
Sorry, das Ding heißt ja: #include "lcd_ssd1306_gfx.h"
Gast
#5021744
Beitrag "Re: SSD1306 Library zum Darstellen von Text auf OLED Displays" Sag mal bitte - woher kommt denn der Font von der Mini-Schrift am unterenb Rand? Findet man den irgendwo?
Wo bekomme ich die "lcd_ssd1306_gfx.h"? Dachte die lcd_gfx.h und lcd_gfx.c wäre das was ich brauche? Danke!
Dieter F. schrieb: > Beitrag "Re: SSD1306 Library zum Darstellen von Text auf OLED Displays" > > Sag mal bitte - woher kommt denn der Font von der Mini-Schrift am > unterenb Rand? Findet man den irgendwo? ach DU MEINST mich? da muss man erst mal drauf kommen ohne Zitat, was du siehst ist die eingebundene originale UG8LIB, da kann man size wählen beim Nokia bekomme ich 6 Zeilen a 14 Zeichen und in derselben lesbaren Größe nur 5 Zeilen a 16 Zeichen und deswegen habe ich die 6te Zeile verkleinert.
Gast
#5021878
Joachim B. schrieb: > ach DU MEINST mich? Ja, der Link ist eigentlich deutlich - oder? Danke für den Hinweis auf die Skalierung.
Dieter F. schrieb: > Joachim B. schrieb: >> ach DU MEINST mich? > > Ja, der Link ist eigentlich deutlich - oder? dazu müsste man jedem Link folgen was ich nur selten mache, wozu auch wenns mich nicht betrifft? Deswgen die Zitatfunktion nutzen dann wird es eher gesehen wen es betrifft!
Gast
#5021968
Joachim B. schrieb: > dazu müsste man jedem Link folgen was ich nur selten mache, wozu auch > wenns mich nicht betrifft? > Aufwändig - 1 Klick > Deswgen die Zitatfunktion nutzen dann wird es eher gesehen wen es > betrifft! O.K. - werde ich künftig berücksichtigen
Dieter F. schrieb: > Joachim B. schrieb: >> dazu müsste man jedem Link folgen was ich nur selten mache, wozu auch >> wenns mich nicht betrifft? >> > Aufwändig - 1 Klick ja bei begrenzter Restlebenszeit :) (PS. Mein Nachbar klickt auch immer ALLES und wundert sich wenn sein Computer wieder mal spinnt) >> Deswgen die Zitatfunktion nutzen dann wird es eher gesehen wen es >> betrifft! > > O.K. - werde ich künftig berücksichtigen danke dafür!
Gast
#5021976
Joachim B. schrieb: > ja bei begrenzter Restlebenszeit :) > (PS. Mein Nachbar klickt auch immer ALLES und wundert sich wenn sein > Computer wieder mal spinnt) Hier im Forum ... ja, wird wohl so sein ... (Wer hat keine begrenzte Restlebenszeit?)
Dieter F. schrieb: > Joachim B. schrieb: >> ja bei begrenzter Restlebenszeit :) >> (PS. Mein Nachbar klickt auch immer ALLES und wundert sich wenn sein >> Computer wieder mal spinnt) > > Hier im Forum ... ja, wird wohl so sein ... natürlich nicht, sollte nur mal aufzeigen das es (überall) keine gute Idee ist auf ALLES zu klicken! > (Wer hat keine begrenzte Restlebenszeit?) ja aber scheinbar stört es manche nicht oder sie haben Mutti Vati Frau Partner der das Leben organisiert und demzufolge genug Zeit übrig um alles zu klicken.
Hallo, ich habe mein fehler gefunden. Mein Projekt habe ich in C++ geschrieben. Da die lcd_gfx.c ja in C geschrieben ist, hat das der Compiler nicht auf reihe bekommen. Hab dann die lcd_gfx.c in eine .cpp abgespeichert und läuft jetzt auch soweit. Eine Frage habe ich allerdings noch. Kann man die Anzahl der Reihen oder die Schriftgröße verändern? Danke!
Gast
#5023956
Ich liebe diese Endlos Threads. Anleitung zum Verbreiten von eigener Sofware: 1. Die finale/stable Version im ersten Post verlinken, am besten dort alle Versionen auflisten. NIEMAND liesst alle Threads nur um die letzte Version zu finden. 2. Code Dokumentieren. Natürlich wissen die eingefuchsten Programmierer wie man diese Library benutzt. Aber für Anfänger gehören minimale Verwendungshinweise als Comment in den Code. In der Art: erst initialisieren, dann bla, dann zeichen senden Ein Hello World Beispiel, am besten gleich am Anfang des Codes.
Daniel R. schrieb: > Hallo, > ich habe mein fehler gefunden. Mein Projekt habe ich in C++ geschrieben. > Da die lcd_gfx.c ja in C geschrieben ist, hat das der Compiler nicht auf > reihe bekommen. Hab dann die lcd_gfx.c in eine .cpp abgespeichert und > läuft jetzt auch soweit. > Eine Frage habe ich allerdings noch. Kann man die Anzahl der Reihen oder > die Schriftgröße verändern? > Danke! Die Anzahl der Reihen (Pages) wird von der Displaygröße vorgegeben, eine Variation der Schriftgröße ist (noch) nicht implementiert, mir fehlt aktuell leider die Zeit weiter daran zu arbeiten, es darf sich aber jeder frei fühlen die Library um entsprechende Funktionen zu erweitern. Julius schrieb: > 1. Die finale/stable Version im ersten Post verlinken, am besten dort > alle Versionen auflisten. Die aktuelle Version ist im ersten Post verlinkt, ich kann ihn leider nicht editieren. Dazu muss ich dann immer einen Moderator/Admin fragen. ;) Julius schrieb: > 2. Code Dokumentieren. Natürlich wissen die eingefuchsten Programmierer > wie man diese Library benutzt. Aber für Anfänger gehören minimale > Verwendungshinweise als Comment in den Code. > > In der Art: > > erst initialisieren, > dann bla, > dann zeichen senden > > Ein Hello World Beispiel, am besten gleich am Anfang des Codes. Ja, einen Beispiel-Code hätte ich hier noch implementieren können. Fand ich jetzt hierbei überflüssig da man, wenn man sich wirklich mit Displays beschäftigt, sehr schnell dahinter kommt, dass man das Display erst initialisieren muss und erst dann drauf schreiben kann. Ich werde aber mal einen Beipsiel-Code als Comment mit reinpacken.
Daniel R. schrieb: > Da die lcd_gfx.c ja in C geschrieben ist, hat das der Compiler nicht auf > reihe bekommen. Dafür hätte man im Headerfile die Funktionsdeklarationen in
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
einschließen müssen. Das sagt dem C++-Compiler, dass die entsprechenden Funktionen in einer C-Datei stehen und daher eine andere Aufrufkonvention zu benutzen ist.
Jörg W. schrieb: > ....... > einschließen müssen. Das sagt dem C++-Compiler, dass die entsprechenden > Funktionen in einer C-Datei stehen und daher eine andere > Aufrufkonvention > zu benutzen ist. das verstehe ich zwar nicht, aber in Arduino habe ich meinen alten C-Quellcode einfach zu s_tools.ino (aus s_tools.c) umbenannt das funktionierte, genauso wie in der *.ino #include "s_tools.c" aber s_tools.ino kam mir praktischer vor als das include!
Joachim B. schrieb: > in Arduino habe ich meinen alten C-Quellcode einfach zu s_tools.ino (aus > s_tools.c) umbenannt Das mag für vielen C-Code funktionieren, aber nicht jedes gültige C-Programm ist auch ein gültiges C++-Programm. Das fängt bei offensichtlichen Problemen an wie die Benutzung von Schlüsselwörtern, die in C++ reserviert sind (class, new), aber es gibt subtilere Unterschiede, bis hin zu C99-Features, die in C++ keinen Einzug gefunden haben (named initializers). > das verstehe ich zwar nicht C++-Funktionen bekommen einen „verwürgten“ (engl.: mangled) Namen, in dem Anzahl und Typ der Argumente codiert werden. Dadurch hat man ein typesafe linking und kann Funktionen gleichen Namens aber mit unterschiedlichen Argumenten unterscheiden. C kennt sowas nicht. Durch die Deklaration als „extern "C"“ zeigt man dem C++-Compiler an, das die entsprechenden Funktionen der C-Notation folgen.
Hallo, danke für die Antworten. @sylaina Du hattest mal ein Stück Beispielcode hier relativ am Anfang gepostet, daran hatte ich mich orientiert. Gut zu wissen das es noch nicht Implementiert ist, dann brauch ich da nicht weiter zu suchen. Vielleicht bekomme ich da auch eine Lösung hin. Jörg W. schrieb: > ....... > einschließen müssen. Das sagt dem C++-Compiler, dass die entsprechenden > Funktionen in einer C-Datei stehen und daher eine andere > Aufrufkonvention > zu benutzen ist. Das werde ich bei Gelegenheit mal Testen. Kann man ja nur dazu lernen. Vielen Dank!
Gast
#5037648
Hallo ihr, finde die Library prima. Nach ein paar Handgriffen konnte ich damit mein Display an einem ATmega32 betreiben. Danke auch für den Codeauszug. Ohne diesen wäre ich wohl nicht so schnell auf die unscheinbare Funktion lcd_display() aufmerksam geworden und daraufhin verzweifelt. Was jedoch nicht funktioniert, ist die Ausgabe der Umlaute und Sonderzeichen. Diese werden von
1 | |
2 | |
3 | |
4 | |
5 | |
einfach verschluckt, da die Anweisung sie nicht erkennt und die Funktion abbricht. Kommentiere ich die Überprüfung aus, wird mir an den entsprechenden Stellen des Displays nur Pixelsalat angezeigt. Ich schätze, da wird auf irgendwelche Speicherbereiche außerhalb des Arrays verwiesen. Das AtmelStudio wirft mir weiterhin die Warnungen "Case label value is less than minimum value for type" und "Multi-character character constant [-Wmultichar]" aus. Diese beziehen sich auf den Bereich von lcd_putc(), in dem die Sonderzeichen vorkommen. Die erste Meldung habe ich mit einem Cast in der switch-Anweisung beseitigen können
1 | |
2 | |
3 | |
4 | |
Die zweite Warnung rührt wohl daher, dass die switch-Anweisung die Unterscheidungen als Zeichenkette und nicht als einzelnes Zeichen interpretiert. Trage ich hier die vermeintlichen Zahlenwerte der Sonderzeichen ein, wie bspw.
1 | |
2 | |
3 | |
verschwindet zwar die Fehlermeldung, aber es bleibt beim Pixelsalat, da ich mit 153 über dem Wertebereich vom Datentyp char liege, den die gesamte Funktion ja ursprünglich als Variable erhält. Auch ein ändern in unsigned char oder uint16_t brachte hier keine Verbesserung. Irgendwie scheinen die Zeichen einfach nicht richtig erkannt zu werden. Weiß hier jemand Rat?
Gast
#5037674
Die Sonderlaute müssen auch in deinem Font-Array vorhanden sein.
Gast
#5037766
Vorhanden sind sie. Habe an den Fonts nicht verändert. Sie werden auch korrekt dargestellt, wenn ich sie händisch aufrufe
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Obiges Beispiel liefert beispielsweise das "Ö", welches sich an Position 100 befindet.
Markus schrieb: > "Multi-character character constant [-Wmultichar]" Das deutet darauf hin, dass du mit UTF-8 als Sourcecode-Zeichensatz arbeitest. Damit funktioniert diese einfache switch/case-basierte Implementierung nicht, die kommt nur mit 8-Bit-Zeichen zurecht.
Gast
#5038900
Ja, das war ein guter Hinweis. Sobald ich im Atmel Studio die Option "Auto-detect UTF-8 encoding without signature" deaktiviere, wird jeder Umlaut durch zwei andere Zeichen ersetzt. Habe nun versucht, den Zeichensatz zu ändern, was aber nicht geglückt ist. Jedoch habe ich während meiner Odyssey im Internet herausgefunden, dass sich die Zeichen durch den Zahlenwert des HTML-Unicode (https://de.wikipedia.org/wiki/Hilfe:Sonderzeichenreferenz) ersetzen lassen.
1 | |
2 | |
3 | |
funktioniert beispielsweise einwandfrei. Ist zwar etwas komisch zu lesen und es geht sicherlich eleganter, aber ich schätze, es wird dann wohl bei allen existierenden Sonderzeichen funktionieren, die man irgendwie verarbeiten möchte. Jedenfalls ist es eine mögliche Lösung für Leute, die irgendwann mal ein ähnliches Problem haben.
Markus schrieb: > Zahlenwert des HTML-Unicode Genauer gesagt: Latin-1 encoding (ISO 8859-1). Das ist ein Ein-Byte-Encoding, bei dem die untere Hälfte ASCII ist und die obere Hälfte allerlei mittel-, nord- und westeuropäische Schriftzeichen enthält. ISO 8859-1 ist das Standard-Encoding bei HTTP, sofern nichts anderes vom Server angegeben ist.
Gast
#5082201
Hi
Spiele mich gerade mit der Textversion herum
Blöde Frage:
Wie kann man eigentlich Zahlen mit Dezimalstelle (einfach) darstellen ?
also zB zur Ausgabe einer Temperatur etc: 27.2 Grad ?
text geht ja einfach
lcd_gotoxy(0,0);
lcd_puts_p(PSTR("1234567890123456"));
Ich bräuchte sowas wie lcd.print (temp,1); zusätzlich zu text
any suggestions?
danke
jps2000 schrieb: > Hi > Spiele mich gerade mit der Textversion herum > Blöde Frage: > Wie kann man eigentlich Zahlen mit Dezimalstelle (einfach) darstellen ? > also zB zur Ausgabe einer Temperatur etc: 27.2 Grad ? > > text geht ja einfach > > lcd_gotoxy(0,0); > lcd_puts_p(PSTR("1234567890123456")); > > Ich bräuchte sowas wie lcd.print (temp,1); zusätzlich zu text > > any suggestions? > > danke Aus der Standard-Lib (stdlib.h): char * dtostrf( double __val, signed char __width, unsigned char __prec, char * __s) Damit wandelst du Floats/Doubles in einen String um. Für Integer gibts char * itoa( int val, char * s, int radix) Für dich vielleicht auch interessant: http://www.atmel.com/webdoc/avrlibcreferencemanual/ Ist ne recht gute Referenz
Gast
#5082743
Danke für die Antwort.- Ich hab nicht so rasch mit einer Antwort
gerechnet und was gebastelt
void lcd_print_var(uint8_t x, uint8_t y,float var){
// calculate digits
uint16_t var1 = abs(var) * 10; //single decimal -->
multiply by ten and convert to uint
uint8_t tenth = 48 + var1 %10; // 48 is Ascii 0
var1 /= 10;
uint8_t single = 48 + var1 %10;
var1 /= 10;
uint8_t ten = 48 + var1 %10;
var1 /= 10;
uint8_t hundred = 48 + var1 %10;
// blank leading zeroes
if (hundred == 48) hundred = 32;
if (hundred == 32 && ten == 48) ten = 32;
// arrange characters
char buf[6] = {32,hundred,ten,single,46,tenth}; // first sign is blank
(32) 46 is decimal point
if (var < 0) buf[0] = 45; // first sign is -
// write to display
lcd_gotoxy(x-4,y); //sign position x, y
is decimal position
lcd_puts(buf); //write digit
}
was du schreibst klingt interessant
kannst du bitte noch ergänzend für mein kleines Hirn
den syntax aufschreiben
Nehmen wir an ich will -24.5 darstellen (float val = -24.5f)
was schreibe ich dann?
lcd_puts(......);
mir helfen immer Beispiele
Danke
M. K. schrieb: > Ist ne recht gute Referenz „Das ist alles nur geklaut, das ist alles gar nicht meine!“ ;-) Sie verletzen die avr-libc-Lizenz, da sie nicht erwähnen, dass das die Doku der avr-libc ist, nur äußerlich ein bisschen auf Atmel getrimmt. Aber irgendeinen Webmaster oder dergleichen, dem man sowas melden könnte, sucht man bei Microchip vergeblich. Wahrscheinlich muss man wirklich der Rechtabteilung einen Drohbrief schreiben. :( p.s.: Der Klassiker für sowas wäre natürlich sprintf().
Jörg W. schrieb: > Sie verletzen die avr-libc-Lizenz, da sie nicht erwähnen, dass das die > Doku der avr-libc ist, nur äußerlich ein bisschen auf Atmel getrimmt. Stimmt, da hast du völlig recht. Vielleicht kannst du das ja noch für mich ergänzen damit hier niemand Probleme bekommt. ;) jps2000 schrieb: > was du schreibst klingt interessant > > kannst du bitte noch ergänzend für mein kleines Hirn > den syntax aufschreiben > Nehmen wir an ich will -24.5 darstellen (float val = -24.5f) > was schreibe ich dann? > > lcd_puts(......); > > mir helfen immer Beispiele Kein Problem, hier ein kleines Beispiel dazu
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
Jörg W. schrieb: > p.s.: Der Klassiker für sowas wäre natürlich sprintf(). Post Scriptum kürzt man PS ab, nicht P.S. und auch nicht PS. oder ähnliches ;) Und zu Sprint(): das hat ja u.U. den ein und anderen Haken.
Gast
#5083984
Vielen Dank
jetzt habe ich es verstanden
damit schrumpft die Funktion zu
void lcd_print_var(uint8_t x, uint8_t y,float var, uint8_t digits,
uint8_t resolution ){
char buf[digits];
dtostrf(var, digits, resolution, buf);
lcd_gotoxy(x-resolution,y); //sign position x, y is decimal
position
lcd_puts(buf); //write digit
}
Der einzige Pferdefuß ist dass dtostrf mehr Programmspeicher braucht
Gast
#5162290
Halo sylaina, ist die Library aus dem Beitrag Beitrag "Re: SSD1306 Library zum Darstellen von Text auf OLED Displays" noch aktuell? Falls nicht, wo kann ich die aktuelle Version finden?
Da muss ich dich leider eines besseren belehren ;) Der RAM Verbrauch der u8g2 lib lässt sich beeinflussen. das mit der Memory Konfiguration, man kann auch nur eine ROW bzw. Page als Buffer benutzen. Ein kleines Problem von einigen Controller ist leider das man nicht im RAM Zeichnen kann, da sie keinen Refresh Command besitzen. Heißt das dies sofort sichtbar wird und womit der Display Buffer nötig wird um Overlays etc. zu erzeugen. Das schöne an der Lib ist wenn man es erst mal geschafft hat einen Displaytreiber zu schreiben es portierbar funktioniert. Bei vielen libs muss man oft die Display Konfiguration oder die Ausgabe anpassen.
Marco H. schrieb: > Da muss ich dich leider eines besseren belehren Wenn den eigentlich? Der Thread ruht seit mehr als 2 Monaten in der Kiste, und auf die Frage, die wirklich neu gestellt worden ist, beziehst du dich ja ganz offensichtlich nicht. Wenn man sich nicht auf den Beitrag direkt darüber bezieht, sollte man besser den Beitrag zitieren, zu dem man etwas antworten möchte. So steht deine Wortmeldung ziemlich zusammenhanglos im Raum.
Daniel R. schrieb: > Leider Bekomme ich beim Compilieren immer den fehler: > > "undefined reference to `lcd_gotoxy(unsigned char, unsigned char)" > > Dieser Fehler tritt bei jeder Funktion auf. Darüber bin ich auch gestolpert. Hast Du auch einen anderen AVR verwendet? Dann bedarf es in der lcd_gfx.c einer Änderung: Alt:
1 | |
2 | |
3 | |
4 | |
Neu:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
Ich habe die beiden Libraries zu einer Library zusammengefasst und ein github dazu erstellt. Die aktuelle Version ist jetzt zu finden unter: https://github.com/Sylaina/oled-display.git Ich werde auch noch einen freundlichen Moderator fragen, ob er mir den Link in den Startpost stellen kann.
Gast
#5269717
Hallo Michael, kann es sein, dass bevor der Buffer zum Display gesendet wird zuerst die Adresse zuvor mit lcd_gotoxy(0,0) auf die Startadresse gesetzt werden muss? Bei meinem Display erschien der Text zu weit unten und die Linie wurde im oberen Bereich weiter gezeichnet. Im reinen Textmodus schie das Problem nicht zu geben.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
ich habe probeweise lcd_gotoxy(0,0); vor dem lcd_display() in main eingefügt und es hat funktioniert!
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
viking schrieb: > Hallo Michael, > kann es sein, dass bevor der Buffer zum Display gesendet wird zuerst die > Adresse zuvor mit lcd_gotoxy(0,0) auf die Startadresse gesetzt werden > muss? Hast du die aktuelle Version von github geladen (siehe Eröffnungspost)? Es wäre auf jeden Fall ein Fehler, das sollte nicht passieren. Ich werde mir das daheim anschaun, es kann durchaus sein, dass da noch Fehler drin sind. Die werde ich dann natürlich beheben. Danke für deine Rückmeldung. Edit: Ich hab grad bei github geschaut und ja, du hast recht. Irgendwie ist das von dir eingefügte gotoxy bei der github-Version verloren gegangen. Das lcd_gotoxy(0,0) gehört da auf jeden Fall hin.
Problem ist behoben, danke nochmal für den Hinweis, viking
Gast
#5271001
M. K. schrieb: > Hast du die aktuelle Version von github geladen (siehe Eröffnungspost)? > Es wäre auf jeden Fall ein Fehler, das sollte nicht passieren. Hallo Michael, ja hab ich direkt von github heruntergeladen.
Gast
#5272939
da fehlt noch ein ";" in
1 | |
2 | |
3 | |
4 | |
5 | |
Das hab ich jetzt davon, dass ichs mit nem iPad editiert hatte...gefixt ;)
Blöde Frage, würde das auch auf einem ESP8266/32 laufen?
Gast
#5298089
> Blöde Frage, würde das auch auf einem ESP8266/32 laufen? Das weiss ich nicht, aber auf dem ESP8266 kannst du auf jeden Fall die Libraries von Adafruit nutzen: https://github.com/adafruit/Adafruit_SSD1306 + https://github.com/adafruit/Adafruit-GFX-Library Die sind mir persönlich aber zu Speicher-Hungrig, deswegen habe ich meine eigene Variante mit weniger Grafik-Schnickschnack geschrieben: http://stefanfrings.de/esp8266/WIFI-Kit-8-Test2.zip Meine Variante benutzt digitalWrite() um die Pins "zu Fuß" als I²C Bus zu toggeln, deswegen müsste das theoretisch mit jedem Arduino Core klappen. Getestet habe ich es aber nur mit dem ESP8266.
W3ll S. schrieb: > Blöde Frage, würde das auch auf einem ESP8266/32 laufen? Wenn du die I2C-Routinen (siehe dazu die I2C-Lib, also i2c.c anpassen) für den ESP8266 entsprechend anpasst läuft die Library auch auf einem ESP8266. Die Grafik-Library an sich ist sehr allgemein gehalten.
Gast
#5317723
Hallo, bin gerade über diese nette Library gestolpert. Kann man mit dieser Library auch größere Buchstaben auf das Display zeichnen, oder nur in der Größe 6x8? Gruß
Aktuell ist nur 6x8 implementiert. Ich bin dabei einen größeren Font (doppelte Größe) zum Implementieren, das ist aber noch in der Entwicklung und nicht vorzeigbar.
Gast
#5318065
Ich habe in meinem eigenen Code einfach die Pixel in Höhe und Breite verdoppelt, um Speicherplatz für den größeren Font zu sparen. Das sieht trotzdem nicht schlecht aus.
Größere Bitmap-Fonts sollte man doch problemlos bei X11 finden. Die dürften von der Lizenz her auch frei verwendbar sein, also entweder public domain oder MIT-Lizenz oder dergleichen.
Alternativ direkt hier im Forum schauen ;-) Beitrag "LCD Schriftarten ( Fonts in veschiedenen Größen )"
Ich bekomme die Lib nicht zu laufen. Was ich geändert hab:
1 | |
2 | |
3 | |
4 | |
5 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
Oder muss man da noch was ändern?
Die I2C-Adresse ist sicher richtig? Und hast du ein Oszi? Dann prüfe direkt an den Pins des Displays ob der Clock und auch Data richtig ankommt. Hab mir letztens einen Wolf gesucht...Clock und Data waren vertauscht.
Oszi hab ich nicht. Adresse stimmt, habs mit Wire.h mit dieser Lib halbwegs hinbekommen. Frisst dann nur viel mehr Speicher. Ich nutze den Atmega324PA. Muss ich denn bei i2c.h und i2c.c was ändern?
Gast
#5319150
> Oszi hab ich nicht. Dann kaufe Dir mal einen Logic Analyzer, das kann sehr hilfreich sein. https://www.amazon.de/AZDelivery-Logic-Analyzer-kompatibel-Version/dp/B01MUFRHQ2/ref=sr_1_1?ie=UTF8&qid=1518864765&sr=8-1&keywords=logic+analyzer&dpID=51jjYdOKLLL&preST=_SY300_QL70_&dpSrc=srch Die Software dazu kannst du bei der Firma Saleae herunterladen.
J. W. schrieb: > Oszi hab ich nicht. > Adresse stimmt, habs mit Wire.h mit dieser Lib halbwegs hinbekommen. > Frisst dann nur viel mehr Speicher. > Ich nutze den Atmega324PA. > > Muss ich denn bei i2c.h und i2c.c was ändern? In der i2c.h werden die Einstellungen für I2C ansich gemacht, z.B. die Clock eingestellt. Kann du eine serielle Kommunikation zum Computer aufbauen? Wenn ja dann lasse dir mal den I2C_ErrorCode übermitteln, daraus lassen sich ggf. Rückschlüsse ziehen wo es nicht klappt. Falls du keine serielle Kommunikation aufbauen kannst: Hast du ein paar LEDs und Widerstände? Dann machen wir mal Debugging für Anfänger ;)
Oszi würde mir erstmal nichts bringen, damit kenn ich mich noch garnicht aus. Am Serial hab ich nen MAX485 hängen, Serial1 wäre frei. LEDs und Taster hab ich noch an dem Atmega angeschlossen. Am Serial wird nichts angezeigt: #include "lcd.h" void setup(){ Serial.begin( 19200 ); pinMode(23,OUTPUT); digitalWrite(23,1); lcd_init(LCD_DISP_ON); // init lcd and turn on lcd_puts("Hello World"); // put string from RAM to display (TEXTMODE) or buffer (GRAPHICMODE) lcd_gotoxy(0,2); // set cursor to first column at line 3 lcd_puts_p(PSTR("String from flash")); // puts string form flash to display (TEXTMODE) or buffer (GRAPHICMODE) } void loop(){ Serial.write(I2C_ErrorCode); }
Der I2C_ErrorCode ist auch ein uint8_t. Ich schätze mal, dass Serial.write() aber einen String haben will bzw. den Parameter als String interpretieren wird. Versuche es mal mit folgenden Loop
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
Jup, Error 0
Gast
#5319185
Wenn du gar nicht klar kommst hilft vielleicht meine alternative Library http://stefanfrings.de/esp8266/WIFI-Kit-8-Test2.zip. Ich habe das Programm nur auf einem ESP8266 Modul ausprobiert. Theoretisch müsste es aber auch mit deinem AVR funktionieren. Du musst nur die Pin Nummern ganz oben bei "OLED display=OLED(4,5,16);" anpassen. Eventuell musst du noch die I2C Adresse als weiteren Parameter hinzufügen. Siehe dazu meine Kommentare in der oled.h.
J. W. schrieb: > Jup, Error 0 Hm, d.h. dass die i2c-Kommunikation funktioniert hat. Und du hast nicht noch irgendwo auf GRAPHICMODE umgestellt? Versuche am Ende der setup() mal ein lcd_display();. Eigentlich sollte das ein Fehler werfen, wenn nicht hast du irgendwo auf den Grafikmode umgestellt.
oled-display:11: error: 'lcd_display' was not declared in this scope
lcd_display();
^
exit status 1
'lcd_display' was not declared in this scope
Hm, dann bist du im richtigen Mode (TEXTMODE). Eigentlich sollte das Display an gehen und den Text zeigen. Bist du sicher, dass die setup() auch ausgeführt wird? Setz am Ende mal den Errorcode manuell auf 18 (oder nen anderen Wert von 1-255). Diesen Wert müsstest du dann auch über die Serielle Schnittstelle bekommen, wenn nicht wird dein setup() erst gar nicht ausgeführt.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.


















