Hallo, ich möchte die Programmierung meines Displays vereinfachen und Strukturieren. In einem Display 2x16 sollen fünf Messwerte angezeigt werden. Über zwei Taster (auf/ab) kann die Zeile um 1 nach oben bzw unten geschoben werden. Nun möchte ich aber eine saubere Struktur haben. Momentan habe ich mehrere if Abfrage, und sollten noch mehr Messwerte oder berechnete Werte dazukommen, dann wird das unübersichtlich für meinen Geschmack. Meine Vorstellung: In einem Array, werden die fünf Messwerte gespeichert. Das Programm soll erkennen wie viele Messwerte im Array speichere und soll dann durch einfaches Hochzählen i++ die einzelnen Messwerte anzeigen. Das Hochzählen der Zeilen erfolgt über eine Variable. Messwert[Variable i?] Messwert[1] = 1234; Messwert[2] =34678; Vielleicht kann mir jemand einen Ansatz geben, wie ich weiterkomme oder auch einen besseren Lösungsweg aufzeigen
Hey, da gibt es mehrere Möglichkeiten, mir fallen da gerade drei ein. 1. definiere dir einen Wert der als ungültig deklariert ist. beispielsweise könnte man das array auf 0 initialisieren und dann schauen ob andere dinge als 0 drin stehen. Problem ist natürlich messwert 0 darf es nicht geben. 2. ein mehrdimensionales array bei dem in spalte 1 die Messwerte stehen und in spalte 2 ob ein gültiger Messwert vorliegt, ähnlich wie 1. du benötigst dann aber mehr speicherplatz und den messwert 0 darf es dann geben. 3. definiere dir ein enum oder eine art statemachine. der status wird geändert oder dein enum hochgezählt, sobald eine neue "art" von messwert vorliegt. folgende vorteile: (a) in deinem array liegen alle möglichen Messwerte und es bleibt 1-dimensional; (b) dein enum oder die state machine kannst du als "eingang" für deine anzeige verwenden; (c) du hast die "prozesse" sauber getrennt; (d) dauert wahrscheinlich länger es so zu programmieren, aber es ist dann sehr leicht erweiterbar... zum beispiel kann der höchste zustand der state machine auch gleichzeit zur initialisierung für dein array verwendet werden lass es dir mal durch den kopf gehen :) beste grüße public
Ich würde das Array erstmal mit nullen initialisieren. So oder so ähnlich:
1 | int werte[4] = {"0,0,0,0,0"}; |
Mit einer If-Abfrage würde ich prüfen ob ein Wert in den Array drin steht:
1 | if (wert[i] != 0) |
2 | {
|
3 | i++; |
4 | }
|
...so eine spontane Idee.
Also ich seh dass so: (pseudocode) Array ar; //constraint groesse(ar) >=2 int max = groesse(ar)-2; int index = 0; UP() //constraint i<= max { i++; } Down() //constraint i>=0 { i--; } Anzeige() { display(Zeile=0,Wert=ar[i]); display(Zeile=1,Wert=ar[i+1]); }
Hmmm... Die HD44780 kompatiblen Displays haben intern immer 2x40 Zeichen! Über ein Kommando (0b001xxxxx set DDRAM address) kann man die Position einstellen, die im LCD sichbar ist, also ab wo das Fenster ins DDRAM schaut. Ich würde jetzt einfach mal probieren, ob nicht immer alle Werte in das DDRAM gerschrieben werden können und man dann nur den sichtbaren Ausschnitt mit den Tasten so verschiebt, dass der Eindruck entsteht, es würde geblättert werden. Wenn Du allerdings keinen HD44780 kompatiblet Display hast, kannst Du trotzdem diese Art der Darstellung emuliere. Also einen kleinen Zeichen-Puffer vorbereiten in den Du Deine Messwerte immer aktualisierst unda aus dem Du dann den angewählten Ausschnitt darstellst. Quasi ein Zeichen basierter Framebuffer. Wenn das nicht gefällt, dann eben eine simple switch-case Anweisung:
1 | switch (pos) { |
2 | case 0: |
3 | print_lcd( 0, "A:%08d", wert_a); |
4 | print_lcd( 0, "B:%08d", wert_b); |
5 | break; |
6 | case 1: |
7 | print_lcd( 0, "B:%08d", wert_b); |
8 | print_lcd( 0, "C:%08d", wert_c); |
9 | break; |
10 | case 2: |
11 | print_lcd( 0, "C:%08d", wert_c); |
12 | print_lcd( 0, "D:%08d", wert_d); |
13 | break; |
14 | ...
|
Die nächste Möglichkeit wäre dann noch, eine Tabelle zu bauen, die das Display "beschreibt".
1 | typedef enum { |
2 | eVT_U8, |
3 | eVT_S8, |
4 | eVT_U16, |
5 | ...
|
6 | } vt; |
7 | |
8 | typedef struct { |
9 | const char *f; // format |
10 | char *s; // string |
11 | enum vt; // type enum |
12 | void *v; // pointer to variable |
13 | } sLCD; |
14 | |
15 | const sLCD lcd[] = { |
16 | { "VOLT: %5dV", eVT_S8, &volt }, |
17 | { "AMPS: %5dV", eVT_U8, &s }, |
18 | { "WATT: %5dW", eVT_U8, &watt }, |
19 | { "POW : %5dW", eVT_U8, &pow }, |
20 | }
|
21 | #define LCD_MAX (sizeof(lcd) / sizeof(sLCD))
|
22 | |
23 | und dann gibt es ein Ausgabemodul: |
24 | |
25 | display( uint8_t idx) { |
26 | uint8_t i; |
27 | /* Don't run over the end of lines */
|
28 | if (idx > (LCD_MAX -2)) |
29 | idx = LCD_MAX -2; |
30 | |
31 | for (i = 0; i < 2; i++) { |
32 | switch( lcd[idx+i].vt) { |
33 | case eVT_U8: |
34 | print_lcd( 0, 0, lcd[idx+i].f, *(uint8_t*)lcd[idx+i].v); |
35 | break; |
36 | case eVT_S8: |
37 | print_lcd( 0, 0, lcd[idx+i].f, *(int8_t*)lcd[idx+i].v); |
38 | break; |
39 | case eVT_U16: |
40 | print_lcd( 0, 0, lcd[idx+i].f, *(uint16_t*)lcd[idx+i].v); |
41 | break; |
42 | ....
|
43 | }
|
44 | i++; |
45 | }
|
46 | }
|
Dieser Aufwand spielt seine Stärken vor allem dann aus, wenn man einen uC mit viel FLASH und wenig RAM hat. Damit kann man dann unzählige Daten an beliebige Stellen auf einem Display darstellen, muss aber das Bild nicht vorher komplett im RAM aufbauen, sondern kann es direkt ans Display senden. Das Beispiel skizziert grob das Verfahren, und ich habe es aus dem Kopf getippt. Aber auf die Art habe ich mal ein 320x240 RGB-OLED Display für einen MP3 Player gemacht. Es war per 1/2 SPI angeschlossen, also ohne Rückkanal und der Controller hatte nicht genug RAM für einen kompletten RGB Frame gehabt. Die Tabelle hatte noch zusätliche Argumente wie Farbe, x und y Position und Zeichensatz. Die print_lcd hat (ebenfalls aus solchen Tabellen) die Zeichen zusammen gebastelt und Spalte für Spalte an das OLED geschickt. Gruß Ulrich
Vielen Dank für Eure Vorschläge und sachlich guten Antworten. Die Lösung von Ulrich hört sich gut an und werde ich auf jeden Fall ausprobieren. Und mit den Arrays kann ich dann perfekt die Auswahl treffen. Jetzt versuch ich mal den Code zu erstellen.
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.