LCD Display - Ausgabe mittels Char Array

Gast #4086208
Lesenswert?

Ein Array von Charactern soll am LCD Display ausgegeben werden.
Aktuell wird nur der Erste Buchstaben angezeigt.
lcd_string(const char* data) ist der Befehl dazu.
Nach Tastendrücken, wird das Array Lauftext aktualisiert. Dabei wird 
jeder Buchstaben bei hinzufügen eines neuen Buchstabens bei der Ausgabe 
um eins nach Rechts verschoben und die 2. Stelle bleibt immer leer!

Ausgabebeispiel: A
                 B A
                 B BA
                 C BBA
1
char lauftext[16];
2
char* plauftext = lauftext;
3
 
4
void text(char* test)
5
{
6
  for(uint8_t j=6;j<8;j++)
7
  {
8
    for(uint8_t i=2;i<16;i++)
9
    {
10
      test[i+1]=test[i]; // Zeile um eins verschieben
11
    }
12
    test[2]=test[0];     // 2. Feld immer leer !!
13
    if((adc[j]<256) && flag_high[j])
14
    {
15
      if(j==6) test[0]='A';
16
      else if(j==7) test[0]='B';
17
      flag_high[j]=0;
18
    }
19
    else if(adc[j]>255)flag_high[j]=1;
20
  }
21
}
22

23
int main()
24
{ [...]
25
          case 1:  // Standardbetrieb
26
  {
27
            for(uint8_t m=0; m<ADCINPUTS; m++)
28
      {
29
        adc[m] = ADC_Read_Avg(m,5);
30
      }
31
      text(plauftext);  // lauftext array wird aktualisiert
32
      lcd_setcursor(0,1);
33
      lcd_string(plauftext); // Displayaktualisierung
34
        }
35
}
#4086215
Lesenswert?

1
    for(uint8_t i=2;i<16;i++)
2
    {
3
      test[i+1]=test[i]; // Zeile um eins verschieben
4
    }

Vorsicht!
Array Überlauf!

Dein Array wurde mit einer Länge von 16 definiert.
Hier wird i als Maximalwert den Wert 15 annehmen. D.h. i+1 ergibt 16. 
Ein Array Element mit dem Index 16 existiert aber nicht.
1
    test[2]=test[0];     // 2. Feld immer leer !!

das ist nicht leer.
Nur weil du am LCD nichts sehen willst, heist das noch lange nicht, dass 
das Array Element leer ist. Ein Leerzeichen ist ein Buchstabe wie jeder 
andere auch. Und wenn du ein Leerzeichen haben willst, dann musst du 
auch eines an die entsprechende Stelle im Array einfügen.
Ansonsten steht bei einem global allokierten char-Array lauter 0-Bytes 
in den entsprechenden Array Elementen. Und ein 0-Byte in einem String 
bedeutet nun mal, dass der String an dieser Stelle zu Ende ist. Hast du 
also von Anfang an in lauftext[1] ein 0-Byte stehen, dann verändert sich 
das durch deine Manipulationen nicht. Das 0-Byte bleibt genau dort 
stehen und somit ist für alle String-Funktionen dort der String zu Ende.
Gast #4086221
Lesenswert?

Das ist mir alles klar. Und nein, dass Array hat 16 Elemente, wird 
allerdings von 0 angefangen zu zählen. Also ist es richtig bis i<16 zu 
laufen.

Und mir ist auch bewusst, dass Leerzeichen auch keine Eigentliche 
Leerstelle ist. Es soll, ja auch ein Leerzeichen an dieser Stelle 
ausgegeben werden ;).
#4086222
Lesenswert?

Elektrotiger schrieb:
> Das ist mir alles klar. Und nein, dass Array hat 16 Elemente, wird
> allerdings von 0 angefangen zu zählen. Also ist es richtig bis i<16 zu
> laufen.

so, so.
i wird maximal 15. Was ergibt dann i + 1
1
    for(uint8_t i=2;i<16;i++)
2
    {
3
      test[i+1]=test[i]; // Zeile um eins verschieben
4
           ***
5
           ***
6
    }

Im letzten Schleifendruchlauf läuft es dann auf
1
     test[15+1] = test[15];
hinaus.
15+1 ergibt 16. Also
1
     test[16]=test[15];

existiert test[16]?

Nein.


> Und mir ist auch bewusst, dass Leerzeichen auch keine Eigentliche
> Leerstelle ist. Es soll, ja auch ein Leerzeichen an dieser Stelle
> ausgegeben werden ;).

Und wo machst du das.
In dem Codeschnipsel ist das nicht erkennbar.
Gast #4086230
Lesenswert?

Karl Heinz schrieb:
> Und wo machst du das.
> In dem Codeschnipsel ist das nicht erkennbar.

Kann schlecht 1000 Zeilen Code zeigen :(.
Aber danke, habe in der Schleife nicht mehr daran gedacht. Den Überlauf 
muss ich abfangen.
Leerzeile wird vorher im Programm schon definiert.

Das löst, aber alles mein Problem bisher nicht. Es wird immer noch nur, 
das Erste Symbol angezeigt.
#4086234
Lesenswert?

Elektrotiger schrieb:

> Kann schlecht 1000 Zeilen Code zeigen :(.

Dann speck auf das wesentliche ab, aber so dass der Code vollständig 
ist.

> Leerzeile wird vorher im Programm schon definiert.
Das kann ich dir glauben oder auch nicht.
Wie hast du die Leerzeile definiert?

> Das löst, aber alles mein Problem bisher nicht. Es wird immer noch nur,
> das Erste Symbol angezeigt.

Weil dein Programm fehlerhaft ist.
Ganz einfach.
#4086239
Lesenswert?

OK.
Machen wirs kurz
1
void text(char* test)
2
{
3
  for(uint8_t j=6;j<8;j++)
4
  {
5
    for(uint8_t i=2;i<14;i++)
6
//                    **                <------
7
    {
8
      test[i+1]=test[i]; // Zeile um eins verschieben
9
    }
10
    test[15] = '\0';                    // <-------
11
    test[1] = ' ';                      // <-------
12
    test[2] = test[0];
13
...

ist zwar ein wenig Overkill, die Sicherheitsterminierung bzw. das 
Leerzeichen jedesmal wieder neu einzufügen, aber im Vergleich zum 
lcd_string kostet das praktisch nichts. Durch die 2 Schleifendurchläufe 
weniger wird es auf jeden Fall wieder aufgefangen.
#4086257
Lesenswert?

mir ist der gesamte sinn und zweck des Programmes nicht klar.

In einem Zyklus, werden zuerst alle ADC-Inputs eingelesen (scheinen ja 
mindestens 8 zu sein)

dann wird für den input 6 und 7 jeweils einmal alle character nach 
rechts geschoben und nur ein buchstabe ausgegeben, wenn eine Flanke 
hoch->niedrig auftaucht.

Das heißt, das alte Zeichen wird jeweils kopiert und eventuell 
geupdated.
Ich glaube nicht, dass man dem Display dann irgendwelche sinnvollen 
Informationen entnehmen kann, weil man nicht weiß, ob das das Zeichen 
jetzt da noch vom letzten mal steht, oder in diesem Frame neu gesetzt 
wurde, außerdem wird es in jedem Frame 2 mal bewegt, aber nur der adc[7] 
input wird vom anderen abgetrennt dargestellt ....

komisches Interface.



Ansonsten würde ich dem TO empfehlen ein wenig mehr Demut an den Tag zu 
legen.
Als Anfänger kann man nicht alles wissen, das wirft dir auch niemand 
vor, aber dann die Helfenden belehren zu wollen, und dann noch in so 
einem Ton...
Gast #4086258
Lesenswert?

Funktioniert leider nicht. Sobald ich eine Zuweisung für das Array 
festlege. Wie z.B. lauftext[1]=' ';
Schwimmt das Display, sprich es gibt Zufällige Sonderzeichen und dass so 
schnell hintereinander neue, dass man da nichts mehr erkennt.
1
char lauftext[16];
2
char* plauftext = lauftext;
3

4

5
void text(char* test)
6
{
7

8
  for(uint8_t i=2;i<15;i++)
9
  {
10
    test[i+1]=test[i];  // Zeile um eine Darstellung verschieben
11
  }
12
  test[2]=test[0]; // 2. Feld immer leer !!
13
  for(uint8_t j=6;j<8;j++)
14
  {
15
    if((adc[j]<256) && flag_high[j])
16
    {
17
      if(j==6) test[0]='A';
18
      else if(j==7) test[0]='B';
19
      flag_high[j]=0;
20
    }
21
    else if(adc[j]>255)flag_high[j]=1;
22
  }
23
}
24

25
int main( void )
26
{
27
  lauftext [1]=' ';
28
  lauftext [15]='\0';
29
[...]
30
case 1:  // Standardbetrieb
31
          {
32
            for(uint8_t m=0; m<ADCINPUTS; m++)
33
            {
34
              adc[m] = ADC_Read_Avg(m,5);
35
            }
36
            text(plauftext);  // lauftext array wird aktualisiert
37
            lcd_setcursor(0,1);
38
            lcd_string(plauftext);
39
}
Gast #4086268
Lesenswert?

Vlad Tepesch schrieb:
> Das heißt, das alte Zeichen wird jeweils kopiert und eventuell
> geupdated.
> Ich glaube nicht, dass man dem Display dann irgendwelche sinnvollen
> Informationen entnehmen kann, weil man nicht weiß, ob das das Zeichen
> jetzt da noch vom letzten mal steht, oder in diesem Frame neu gesetzt
> wurde, außerdem wird es in jedem Frame 2 mal bewegt, aber nur der adc[7]
> input wird vom anderen abgetrennt dargestellt ....
>
> komisches Interface.

Liegt daran, dass der Prototyp nur 2 angesteuerte ADC Eingänge besitzt 
und die anderen Pins zum testen anderweitig genutzt werden.

Das ergibt so wie es geplant ist für unsere Zwecke Sinn.

Nochmal es geht mir nicht darum den Code schöner zu gestalten, sondern 
Allgemein zu Wissen warum nur das Erste Symbol angezeigt wird.
#4086289
Lesenswert?

Elektrotiger schrieb:
> Das ergibt so wie es geplant ist für unsere Zwecke Sinn.

das bezweifele ich, weil sich komplett unterschiedliche Situationen mit 
diesem Output nicht unterscheiden lassen.


zB bei gleichbleibendem Signal 7 kannst du nicht sagen, ob sich 6 
ändert, weil da nur As stehen werden, egal wie sich 6 verändert. high 
geht, low geht, so bleibt oder wild toggelt - sieht alles gleich aus.
vice versa
Gast #4086299
Lesenswert?

Vlad Tepesch schrieb:
> zB bei gleichbleibendem Signal 7 kannst du nicht sagen, ob sich 6
> ändert, weil da nur As stehen werden, egal wie sich 6 verändert. high
> geht, low geht, so bleibt oder wild toggelt - sieht alles gleich aus.
> vice versa

Das ist richtig, aber für uns irrelevant bzw sogar gewünscht.
Beim Drücken eines Knopfes liegt High an. Sollte ein Dauersignal 
anliegen, wissen wir, dass ein Fehler vorliegt. Sprich ein Bruch im LWL 
Kabel oder Taste hängt fest ;).
#4086366
Lesenswert?

Elektrotiger schrieb:
> Habs... ist kein Syntaxfehler, sondern Logischer Fehler.
syntaxfehler hätte der Compiler ja mit größter Wahrscheinlichkeit 
bemängelt, oder eventuell wenigstens gewarnt.

> Habe die Leerstelle rekursiv nach rechts weiter kopiert.
> Also Element 2 zu 3 und dann 3 zu 4 welches ja schon 2 ist.

Nicht die Leerstelle, das entsprechende Zeichen.
nach der ersten Flanke, sollte ja da aber ein Buchstabe stehen, der 
kopiert wird.
Wenn da also vorher ein Fehler war, der dir nur das erste Zeichen 
ausgegeben hat, sollte der jetzt ja immer noch da sein.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren