Ich habe wieder ein Problem mit meinem I2C OLED Display, angesteuert mit einem Arduino Uno. Ich lese einen Wert ein (testweise mit einem Poti), rechne ihn um und gebe ihn auf dem dem Display wieder aus. Die gemessene Spannung ist eine in einem Netzteil und ändert sich mit dem Ausgangsstrom. Hier ist mal der Sketch plus Schaltungssimulation. https://wokwi.com/projects/325872467916620372 Das problem ist, wenn sich die Kommastelle veschiebt, weil z.b. der Wert vorher 8(A) war und jetzt 15, dann ändern sich zwar die Zahlen wie gewünscht, aber das Komma bliebt und überlagert sich mit der Zahl die dort hingehört. Beim Minus passiert das selbe, aber im fertigen Zustand wird dann eh nichts mehr nagativ, also ist das egal. Aber wie schaffe ich es jetzt dass sich Komma und Zahl nicht mehr überlagern? Ich habe schon clearBuffer(); und auch clearDisplay(); vor dem sendBuffer(); ausprobiert, aber dann wird gar nichts mehr angezeigt. Ideal wäre es, wenn das Komma einen fixen Platz hätte und sich nur die Zahlen herum ändern, aber ich weiß nicht wie das machbar ist. Der Wert 10 müsste da ein bisschen weiter vorne geschrieben werden als z.B. 1. Oder davor einfach Leerzeichen als Platzhalter? Kann mir bitte jemand weiterhelfen? Schönen Abend noch, Julian
Julian D. schrieb: > Hier ist mal der Sketch hier ist er jedenfalls nicht, Code hier hochladen damit das später auch noch andere nachsehen können, das ist ein Forum!
1 | #include <U8g2lib.h> |
2 | #include <Wire.h> |
3 | U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE); |
4 | |
5 | |
6 | void setup() { |
7 | // put your setup code here, to run once:
|
8 | Serial.begin(9600); |
9 | u8g2.begin(); |
10 | analogReference(DEFAULT); |
11 | }
|
12 | void settings() { |
13 | u8g2.setFont(u8g2_font_6x10_tr ); |
14 | u8g2.setFontRefHeightExtendedText(); |
15 | u8g2.setDrawColor(1); |
16 | u8g2.setFontPosTop(); |
17 | u8g2.setFontDirection(0); |
18 | }
|
19 | |
20 | void loop() { |
21 | // put your main code here, to run repeatedly:
|
22 | |
23 | int messung = analogRead(A0); |
24 | double spannung = messung / 204.8; |
25 | double strom = -45.411 + 44.5642 * spannung; |
26 | Serial.println(strom, 5); |
27 | String stromstr = String(strom, 5); |
28 | |
29 | settings(); |
30 | u8g2.drawStr(10, 10, stromstr.c_str()); |
31 | |
32 | u8g2.sendBuffer(); |
33 | |
34 | delay(100); |
35 | }
|
Hoffe der ist noch nicht zu lange. Funktioniert der Link gar nicht oder meinst du nur dass es besser ist wenn der Code auch hier steht?
Julian D. schrieb: > Ich habe schon clearBuffer(); und auch clearDisplay(); vor > dem sendBuffer(); ausprobiert, aber dann wird gar nichts mehr angezeigt. Vielleicht braucht der Display-Controller ein bisschen Zeit für das Löschen des Displays und du sendest ihm die neuen Daten, bevor er damit fertig ist. Genaueres sollte im Datenblatt zu deinem Display stehen. In den Code habe ich jetzt nicht geguckt - wer weiß, wo der Link hinführt.
Julian D. schrieb: > Aber wie schaffe ich es jetzt dass sich Komma und Zahl nicht mehr > überlagern? anders programmieren Erst mal baust du deinen String, ich schreibe das immer in ein Zeilenbuffer. Mehr als 4- maximal 10 Aktualisierungen braucht kein Mensch ist nicht mehr lesbar, der µC ist viel schneller. Ich schreibe in den Buffer wenn es sein soll, aber auf das Display nur wenn 25ms(100ms) um sind für 4(10) Updates/s ich mittle auch einige ADC Werte je nach Bedarf 8 16 32 auf addieren und shift right 8->3 16->4 32->5 Neue Werte werden im Zeilenbuffer geschrieben also hast du das Problem nicht mit alten Daten! Eine Ausnahme gibt es, der Zeichen Buffer im Oled wird nicht gelöscht, aber da du nichts zeigst ist das stochern im Nebel.
Julian D. schrieb: > überlagern? Ich habe schon clearBuffer(); und auch clearDisplay(); vor > dem sendBuffer(); ausprobiert, aber dann wird gar nichts mehr angezeigt. u8g2.drawStr() wandelt die Daten in Pixel um und schreibt sie in einen Buffer. Wenn du danach clearBuffer() oder clearDisplay() aufrufst, sind die aufbereiteten Daten weg. Wenn du "clear" vor "drawStr" aufrufst sollte das funktionieren.
Wolfgang schrieb: > In den Code habe ich jetzt nicht geguckt - wer weiß, wo der Link > hinführt. Er führt zu einem Arduino Schaltungssimulator, den benutze ich immer z.B. wenn ich zu faul bin meinen Arduino aufzubauen. Und der Code stand übrigens auch schon vor deiner Antwort direkt im Forum ;) Holger schrieb: > Wenn du "clear" vor "drawStr" aufrufst > sollte das funktionieren. Danke, das hat funktioniert. Es wird alles angezeigt wie erwünscht, ohne Überlagerungen.
Julian D. schrieb: > Und der Code stand übrigens auch schon vor deiner Antwort direkt im > Forum ;) Er stand im Forum, bevor ich meine Antwort veröffentlicht habe, aber nicht, bevor ich auf Basis der vorhandenen Antworten angefangen habe, meine Antwort zu verfassen. Das ist ein kleiner Unterschied.
Hallo, clear ist ungünstig, weil jedesmal das gesamte Display gelöscht wird. Das führt zu flimmern, wirste später noch bemerken. In der Regel kennt man die maximale "Zeilenbreite" für sein Datenformat und löscht dahinter die nicht mehr benötigten Stellen mittels Leerzeichen. Das geht schneller und das gesamte Display flimmert nicht. Die Refreshrate langsamer stellen wurde schon erwähnt. Alles ohne delay dafür mittels millis lässt auch den Code nicht blockieren. Kannste ungebremst einlesen und filtern und unabhängig auf das Display ausgeben.
Veit D. schrieb: > clear ist ungünstig, weil jedesmal das gesamte Display gelöscht wird. Was meinst Du, was bei Julian D. schrieb: > sendBuffer(); passiert?
Julian D. schrieb: > Ideal wäre es, wenn das Komma einen fixen Platz hätte und sich nur die > Zahlen herum ändern, aber ich weiß nicht wie das machbar ist. In der Tat. > Der Wert > 10 müsste da ein bisschen weiter vorne geschrieben werden als z.B. 1. > Oder davor einfach Leerzeichen als Platzhalter? BINGO! > Kann mir bitte jemand > weiterhelfen? Grundlagen von C. Nicht immer nur auf dem Arduino-Level rumplanschen. Formatierte Zahlenausgabe ist das Zauberwort. Man brauch auch keine Fließkommazahlen mit DOPPELTER Genauigkeit, Festkommaartithmetik reicht locker, auch wenn man da mal drei Minuten nachdenken muss.
1 | void loop() { |
2 | char tmp_string[10]; |
3 | |
4 | long strom = -45411L + (44564L * analogRead(A0)) >> 11; // mA |
5 | strom /= 100; // 0.1A Auflösung |
6 | Serial.println(strom, 5); |
7 | |
8 | sprintf(tmp_string, "%+2d.%1d" strom/10, abs(strom%10)) |
9 | settings(); |
10 | u8g2.drawStr(10, 10, tmp_string); |
11 | u8g2.sendBuffer(); |
12 | |
13 | delay(100); |
14 | }
|
Julian D. schrieb: > Holger schrieb: >> Wenn du "clear" vor "drawStr" aufrufst >> sollte das funktionieren. > > Danke, das hat funktioniert. Es wird alles angezeigt wie erwünscht, ohne > Überlagerungen. aber alles zu "clearen" für dem Neuprinten kann lahm sein und das Display zu flackern bringen wenn es zu oft gemacht wird.Ich kenne die LIB un nicht genau, aber ähnliches verwende ich auch bei TFT, wenn die Lib die Möglichkeit bietet auch schwarz (keine leuchtenden Pixel) statt farbig (leuchtende Pixel) zu printen, dann schreibt man in einen Puffer die geänterten Zeichen in schwarz, also kein Pixel leuchtet mehr und danach wieder die Änderung. Der Vorteil man spart Prozessorzeit, Das Programm kann evtl. leichter arebeiten, es findet keine überflüssige "Löschung des ganzen Screens" statt und es wird nur veränderter Inhalt neu geschrieben! Falk B. schrieb: > Festkommaartithmetik > reicht locker Falk hat soooo Recht, mit etwas Nachdenken werden aus Fliesskomma Volt Integer Volt z.B. je nach gewünschter Stellenzahl mV cV dV, alles Integer! Das Komma fügen wir im String ein, muss nicht groß float gerechnet werden bei 5002 mV 5,002V bei 502 cV 5,02V bei 52 dV 5,2V
:
Bearbeitet durch User
Joachim B. schrieb: > aber alles zu "clearen" für dem Neuprinten kann lahm sein und das AUA!!!!! http://kamelopedia.net/wiki/Denglisch
Falk B. schrieb: > AUA!!!!! nix aua, das war bewusst auf: Hugo H. schrieb: > Veit D. schrieb: >> clear ist ungünstig, weil jedesmal das gesamte Display gelöscht wird. Julian D. schrieb: > Holger schrieb: >> Wenn du "clear" vor "drawStr" aufrufst >> sollte das funktionieren.
Beitrag #7001763 wurde vom Autor gelöscht.
> Fließkommazahlen mit DOPPELTER Genauigkeit, Festkommaartithmetik > reicht locker, auch wenn man da mal drei Minuten nachdenken muss. Ich hab mir dafuer vor vielen Jahren mal ein eigenes printf geschrieben. Das kann dann sowas: printf("%2f", 123) ==> 1.23 So kann ich in meiner Software immer mit zwei (oder mehr) Festkommastellen rechnen ohne es zu merken. :-D Allerdings muss man leider sagen das Microcontroller heute so schnell geworden sind das man halt doch sehr oft double nutzen kann ohne drueber nachzudenken. Wichtig wird es erst dann wieder wenn man Sachen macht die mit sehr wenig Energie auskommen muessen. Der Unterschied zwischen klug und doof sind dann 3Monate oder 2Jahre mit derselben CR2032. Und die Ausgabe eines kompletten Buffers an ein Display ist auch Schwachsinn. Bei mir sieht der Buffer fuers Display so aus: #define SEGMENTSIZE 32 typedef struct{ unsigned char segment[SEGMENTSIZE]; unsigned char dirty; } OLEDColumnType; #define PAGES 8 #define SEGMENTS 4 OLEDColumnType OLED_Buff[SEGMENTS][PAGES]; Mein Buffer ist also in Segmente eingeteilt. Wird eines beschrieben wird das als dirty markiert. In meinem TickerIRQ wird dann geschaut ob es ein dirty Segment gibt und dann nur dieses ausgeben. Es ist erstaunlich wie wenig Datenverkehr es dann noch zum Display gibt. .-) Aber ja, da muss man wohl mal was selber programmieren und nicht nur im Internet von den Einaeugigen abschreiben damit man selber blind bleiben kann. Olaf
Olaf schrieb: > Mein Buffer ist also in Segmente eingeteilt. Wird eines beschrieben wird > das als dirty markiert. In meinem TickerIRQ wird dann geschaut ob es ein > dirty Segment gibt und dann nur dieses ausgeben. Es ist erstaunlich wie > wenig Datenverkehr es dann noch zum Display gibt. .-) liest sich wie mein Ansatz, mit anderen Worten. Schon erstaunlich das verschiedene Menschen durch nchdenken zur selben Lösung kommen, Grammophon, Fahrrad, Automobil, Telefon Ein Glück müssen wir nicht um Patente streiten.
Joachim B. schrieb: > Hugo H. schrieb: >> Veit D. schrieb: >>> clear ist ungünstig, weil jedesmal das gesamte Display gelöscht wird. Bitte korrekt zitieren: Hugo H. schrieb: > Veit D. schrieb: >> clear ist ungünstig, weil jedesmal das gesamte Display gelöscht wird. > > Was meinst Du, was bei > > Julian D. schrieb: >> sendBuffer(); > > passiert?
Julian D. schrieb: > Ich habe wieder ein Problem mit meinem I2C OLED Display, angesteuert mit > einem Arduino Uno. Ähem... nein. Mit dem OLED hast du gewiß kein Problem. Dein Problem ist die Ausgabe-Routine für deine Display-Grafik. Ich habe schon vor Jahren dieses U8G2 Zeugs nicht gemocht, zum einen, weil es keine saubere Trennung zwischen dem GDI und dem eigentlichen Treiber zum Display hin hat, sodann weil es keine wirkliche Trennung zwischen den grafischen Daten (Fonts, Grafiken usw.) und dem Programm hat und hier in deinem Falle auch deshalb, weil du sowas lediglich benutzt, ohne dabei verstanden zu haben, wie das Zeugs funktioniert. Also: stelle dir mal ne Tafel in der Schule vor. Da kann man was draufschreiben. Und man muß auch das früher geschriebene irgendwann mal wieder ablöschen, wenn man etwas neues draufschreiben will und es hinterher auch lesbar sein soll. So ungefähr geht es bei vielen GDI Versionen. Wenn man (anders als bei der Schultafel mit der Kreide) als Textzeichen immer nur gleichgroße "Kacheln" auf die Grafik-Oberfläche malt und dabei nicht nur die Stellen malt, die bei der Tafel etwas Kreide abkriegen, sondern dabei auch alle die Stellen ablöscht, die keine "Kreide" abkriegen sollen, dann spart man sich das vorherige Ablöschen und erkauft sich das mit einem höheren Schreib-Aufwand beim Malen des Textzeichens. Ich mache das bei meinen Projekten so, daß ich eine strikte Trennung habe zwischen GDI und Display-Treiber und das GDI zeichnet auf eine Grafik-Oberfläche im RAM. Das GDI setzt bei jedem Schreibvorgang eine Boolean-Variable, die anzeigt, daß die Grafik-Oberfläche verändert wurde. Ganz woanders, zumeist irgendwo in main() wird danach geschaut und wenn besagte Variable gesetzt ist, wird der Display-Treiber aufgerufen, der die Daten ins Display kopiert und die Variable wieder löscht. Nun ja, obendrein trenne ich auch sowas wie Fonts und Grafiken vom auszuführenden Code. Und bei mir muß der betreffende Bereich abgelöscht werden, bevor dort irgend etwas draufgemalt wird. Aber das ist auch alles selber geschrieben und nicht von irgendwo kopiert. Also: Verstehe du mal das, was du benutzt. Dann wird dir gewiß klar, an welcher Stelle der Programmfehler bei dir steckt. W.S.
Hallo, Libs sind zum benutzen da. Man muss die internen Abläufe nicht verstehen. Nur wenn es einen genau interessiert schaut man hinter die Kulissen. Oder lernt jeder Auto Mechaniker nur damit er Auto fahren darf? Ich glaube nicht. Jeder der selbst Libs schreibt benutzt sie danach nur noch. Die internen Abläufe interessieren später nicht mehr. Dafür hat man sie ja schließlich geschrieben um sich und vielleicht anderen den Umgang einfacher zu machen. Also lasst mal die Kirche im Dorf.
Beitrag #7002149 wurde von einem Moderator gelöscht.
> Libs sind zum benutzen da. Man muss die internen Abläufe nicht > verstehen. Das kann man sich mit Einschraenkungen noch auf PCs erlauben, aber selbst da fuehrt es dazu das Computer sich heute 10x langsamer anfuehlen als sie sein muessten. Bei den begrenzten Resourcen eines Microcontrollers sieht das anders aus. Da kuemmerst du dich um deine Libaries, versteht ihren Inhalt, bist dir darueber im klaren ob die Vorgehensweise in einer Libarie zu deinem Gesamtprojekt passt oder nicht, oder du produzierst Muell. Letzeres kannst du derzeit sehr schoen bei der Programmierung in aktuellen VWs sehen. Man hat dort Controller mit mehreren Kernen in der 1Ghz Klasse und trotzdem ist das Ergebnis ein laecherlicher Witz. Bei noch kleineren Controllern wird es dann immer schlimmer, ausser sie sind dann wieder so klein das man keine Libaries verwenden kann. :) Das muss nicht zwangslaeufig heissen das man keine Libaries verwenden darf! Ein sehr schoenes Beispiel dafuer ist die FAT-Libarie von elm-chan. Programmiert man sich sowas selber wird man, angesichts der grossen Anzahl unterschiedlichster Speicherkarten schnell feststellen das es hier die breite Nutzung dieser Libarie zu sehr viel mehr Zuverlaessigkeit fuehrt als man es selber in endlicher Zeit schaffen wird. Benutzt man sie aber nur ohne Nachzudenken und mal reinzuschauen, ist man also faul und bequem, wird man schnell auf Anwendungen stossen wo man Probleme bekommt. Die Loesung der Faulen und Dummen ist dann normalerweise nach mehr Rechenleistung zu schreien. (vgl auch VW :-) ) Olaf
Olaf schrieb: > Das kann man sich mit Einschraenkungen noch auf PCs erlauben, aber > selbst da fuehrt es dazu das Computer sich heute 10x langsamer anfuehlen > als sie sein muessten. Das ist wohl leider wahr. :-( https://de.wikipedia.org/wiki/Bloatware > Bei den begrenzten Resourcen eines Microcontrollers sieht das anders > aus. Da kuemmerst du dich um deine Libaries, versteht ihren Inhalt, Jain. Man kann und WILL nicht jedes Detail einer Lib verstehen, wohl aber wesentliche Eigenschaften und Konzepte. Das ist ein Unterschied.
> Jain. Man kann und WILL nicht jedes Detail einer Lib verstehen, wohl > aber wesentliche Eigenschaften und Konzepte. Das ist ein Unterschied. Natuerlich, so meinte ich das. Man kann nicht jede einzelne Zeile kontrollieren, obwohl das manchmal (SIL-Zertifizierung/Audit) auch notwendig ist. Aber man sollte schon wissen wie eine Libary funktioniert. Olaf
Olaf schrieb: > Das kann man sich mit Einschraenkungen noch auf PCs erlauben, aber > selbst da fuehrt es dazu das Computer sich heute 10x langsamer anfuehlen > als sie sein muessten. https://de.wikipedia.org/wiki/Wirthsches_Gesetz
Olaf schrieb: > Ein sehr schoenes Beispiel dafuer ist die FAT-Libarie von elm-chan. > Programmiert man sich sowas selber wird man, angesichts der grossen > Anzahl unterschiedlichster Speicherkarten schnell feststellen das es > hier die breite Nutzung dieser Libarie zu sehr viel mehr > Zuverlaessigkeit fuehrt als man es selber in endlicher Zeit schaffen > wird. Da schreibst du hanebüchenen Unsinn, denn gerade der Teil, der sich mit "der großen Anzahl unterschiedlichster Speicherkarten" befassen muß, ist da augeklammert und muß vom jeweiligen Anwender beigesteuert werden. W.S.
> Da schreibst du hanebüchenen Unsinn, denn gerade der Teil, der sich mit Nein, ich schreibe aufgrund intellektueller Ueberlegenheit und angeborener Schoenheit immer das richtige. .-) > "der großen Anzahl unterschiedlichster Speicherkarten" befassen muß, ist > da augeklammert und muß vom jeweiligen Anwender beigesteuert werden. Nein. Die Libarie hat ja eine sehr grosse Zahl von Anwender welche sich vermutlich schon im Forum bei elm-chan gemeldet haetten wenn sie ein Problem gefunden haetten. Ich weiss auch das man den Lowleveltreiber selber schreiben soll und hab das auch schon getan, aber viele sind ja auch schon dafuer zu faul. Und auch die hoeheren Level des FAT-System sind nicht ganz ohne. Es ist schon nett das dies von einer Menge Leute getestet wurde bevor man es selbst nutzt. Ich hab sowas vor 20Jahren mal komplett selber geschrieben. Getestet mit etwa 20 verschiedenen Speicherkarten in allen groessen. Trotzdem kam kurz nach der Auslieferung der erste Kunde mit einer noch groesseren Karte an als man erwartet haette und ich damals kaufen konnte und ein Jahr spaeter wieder groesser usw. Da nimmt einen elm-chan schon 50% der Arbeit ab die man sonst haette. Olaf
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.