Forum: Mikrocontroller und Digitale Elektronik Array Programmierung; Anzeige Display


von iGast (Gast)


Lesenswert?

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

von public (Gast)


Lesenswert?

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

von P. F. (pfuhsy)


Lesenswert?

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.

von Programmierer (Gast)


Lesenswert?

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]);
}

von Ulrich P. (uprinz)


Lesenswert?

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, &amps },
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

von iGast (Gast)


Lesenswert?

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.

von iGast (Gast)


Lesenswert?

Display hat einen Hd44780 controller

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
Noch kein Account? Hier anmelden.