Forum: Mikrocontroller und Digitale Elektronik Display gibt als String eine Art Pixelfehler aus


von Julian M. (julianm94)


Angehängte Dateien:

Lesenswert?

Hallo Community,
ich habe folgendes Problem.
An der Stelle an der die Strings ausgegeben werden sollen, gibt er eine 
Art Pixelfehler aus.
Wenn ich jedoch andere Werte in einem Integer speicher gibt er die 
Variablen richtig aus.
Jedoch brauche ich den typ uint8_t wegen den CAN daten.
Weiß einer vielleicht woran das liegen kann?
Code ist im Anhang.
Schonmal danke im Vorraus.

Mit freundlichen Grüßen

Julian

von Karl H. (kbuchegg)


Lesenswert?

Wer ist 'er'?

Kann es sein, dass dir schön langsam der SRAM Speicher ausgeht?

von Julian M. (julianm94)


Lesenswert?

oh meinte damit natürlich das Display3000 angesteuert über den 
At90Can128.
Zu dem Thema SRAM ich denke ja mal nicht, im moment werden ja gerade 
einmal 3 Ziffern ausgegeben auf dem Display. Welche bei einem Interrupt 
aktualisiert werden. Jedoch werden diese Komische Pixelfehler schon bei 
dem Programm start angezeigt, auch wenn kein CAN bus angeschlossen ist.
Diese Pixelfehler sind so groß ca. wie eine Ziffer.

von Karl H. (kbuchegg)


Lesenswert?

Julian M. schrieb:
> oh meinte damit natürlich das Display3000 angesteuert über den
> At90Can128.

Wenn ich die Produktinformation zum Display3000 richtig interpretiere, 
dann ist der AT90CAN128 auch für das TFT Display zuständig. Was soviel 
bedeutet wie: er muss auch die Farbinformation für die Pixel irgendwo 
speichern, die angezeigt werden. D.h. dazu braucht er SRAM SPeicher, von 
dem auf dem µC nur 4KB vorhanden sind.

> Zu dem Thema SRAM ich denke ja mal nicht, im moment werden ja gerade
> einmal 3 Ziffern ausgegeben auf dem Display.


Das ist ziemlich wurscht.
Du hast dazu
1
char drehstring[30];
2
char wassertempstring[30];
3
char oiltempstring[30];
4
char gangstring[30];
120 Bytes verbrutzelt.
Das klingt erst mal nicht viel.
Wenn man allerdings berücksichtigt, dass ein erklecklicher Anteil schon 
für das TFT drauf geht, dann sind 120 Bytes schon sehr viel. Vor allen 
Dingen, weil du sie ziemlich unnötig und leichtsinnig verbrutzelt hast.

von Karl H. (kbuchegg)


Lesenswert?

Denn das
1
char drehstring[30];
2
char wassertempstring[30];
3
char oiltempstring[30];
4
char gangstring[30];
5
6
....
7
8
      sprintf(drehstring, "%i", rev);
9
      sprintf(gangstring, "%i", gang[0]);
10
      sprintf(wassertempstring, "%i", temperatur[6][2]);
11
      sprintf(oiltempstring, "%i", temperatur[7][2]);
12
      
13
      Orientation = Landscape;
14
      LCD_Print (drehstring,0,0, 2, 1, 1, white, black);
15
      Orientation = Landscape;
16
      LCD_Print (gangstring,60,30, 2, 5, 5, white, black);
17
      Orientation = Landscape;
18
      LCD_Print (wassertempstring,120,120, 2, 1, 1, white, black);
19
....

ist schon ein wenig verschwenderisch im Speicherverbrauch.

Es besteht kein Grund, für jede Ausgabe ein eigenes char-Array 
anzulegen.

sprintf - LCD_print  sprintf - LCD_print ...
immer im schönen Wechsel und schon kann man immer ein und dasselbe 
char-Array benutzen.
Und weil das so ist, kann man sich dann auch eine Funktion LCD_Print_int 
machen, so dass letzten Endes dann nur noch dort steht
1
....
2
      rev=(messwerte[4] + ( messwerte[3] << 8)) / 2;
3
      
4
      LCD_Print_int( rev,                0,   0, 2, 1, 1, white, black);
5
      LCD_Print_int( gang[0],           60,  30, 2, 5, 5, white, black);
6
      LCD_Print_int( temperatur[6][2], 120, 120, 2, 1, 1, white, black);
7
8
      if(rev < 500)     //Drehzahl unter 500 u/min -> Fehlerhaftes Datenpaket
9
....

und die Details, wie du 'ASCII'-fizierung sowie das Umschalten auf 
Landscape wird von dieser einen Funktion gehandhabt. Und als Nebeneffekt 
benötigt das dann auch viel weniger SRAM Speicher. Für einen 16 Bit 
reicht ein char Array mit einer Länge von 7. Denn die 'längste' 
auszugebende Zahl ist -32767. Zähl nach, das sind 6 sichtbare Zeichen. 
30 ist da verschwendirisch überdimensioniert.

von Julian M. (julianm94)


Lesenswert?

Vielen Dank für die schnelle Antwort :)
An die Speicher begrenzung habe ich gar nicht gedacht.
Ist mein erstes Projekt in C.
Dann werde ich des mal so versuchen umzusetzten :)

von Karl H. (kbuchegg)


Lesenswert?

Julian M. schrieb:
> Vielen Dank für die schnelle Antwort :)

Ich denke, das ist das Problem. Zumindest könnte es etwas damit zu tun 
haben.
Dann abgesehen davon ist speichertechnisch da jetzt nichts auffälliges 
im Code zu sehen, was die Symptome erklären könnte.

von Julian M. (julianm94)


Lesenswert?

Danke, ich melde mich morgen.
Ob alles Funktioniert hat.

von Julian M. (julianm94)


Angehängte Dateien:

Lesenswert?

Kann es leider erst heute Nachmittag testen.
Aber ich habe nun eine externe Funktion geschrieben und Flags gesetzt, 
sodass
Nur noch die Bildschirmausgabe geändert wird wenn auch der 
dementsprechende Interrupt ausgeführt wird.

von Julian M. (julianm94)


Angehängte Dateien:

Lesenswert?

Das Programm gibt immernoch die Pixelfehler an den Stellen der Strings 
aus.
Habe den Code im Anhang dabei, vielleicht sieht ja jemand woran es 
liegen könnte.
Schonmal danke im Vorraus.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wie sehen denn Deine "Pixelfehler" aus? Gelingt es überhaupt, 
irgendwelchen Text auszugeben, oder geht das prinzipiell immer schief?

von Lars E. (potoat)


Lesenswert?

Julian M. schrieb:
> Wenn ich jedoch andere Werte in einem Integer speicher gibt er die
> Variablen richtig aus.
> Jedoch brauche ich den typ uint8_t wegen den CAN daten.

kann man das so verstehen, dass es mit uint16_t bspw. funktioniert?
Wenn ja: kann es sein, dass der "%i" im Format-String mit dem uint8_t in 
Konflikt steht? Oder kann es sein, dass der übergebene uint8_t als 
Character interpretiert wird?
Wenn etwas derartiges ist, müsste ja der Umweg über eine temporäre 
Integer-Variable funktionieren.

von Karl H. (kbuchegg)


Lesenswert?

Rufus Τ. F. schrieb:
> Wie sehen denn Deine "Pixelfehler" aus? Gelingt es überhaupt,
> irgendwelchen Text auszugeben, oder geht das prinzipiell immer schief?

Er sagt
> Wenn ich jedoch andere Werte in einem Integer speicher gibt er
> die Variablen richtig aus.
> Jedoch brauche ich den typ uint8_t wegen den CAN daten.

Die uint8_t sollten jetzt keine Rolle spielen, denn bei einem sprintf 
findet sowieso eine Promotion auf int statt. Die kann man ja auch nicht 
abschalten, oder doch?

Auch wenn es eigentlich keinen Unterschied macht:
1
  sprintf(ausgabestring, "%i", (int)uebergabe);

von Dieter F. (Gast)


Lesenswert?

Handbuch S. 16 mal gelesen - Limitation 1, letzter Satz (kann ich leider 
nicht hierhin kopieren) "... unexpected bitmap pieces are showed ..." ?

von Julian M. (julianm94)


Angehängte Dateien:

Lesenswert?

So sehen diese Fehler aus. Ja wenn ich ein anderes Programm mit integer 
werten aufspiele wird auf dem Display alles angezeigt.
Liegt es möglicherweise an der uint8_t convertation?

von Karl H. (kbuchegg)


Lesenswert?

Julian M. schrieb:
> So sehen diese Fehler aus. Ja wenn ich ein anderes Programm mit integer
> werten aufspiele wird auf dem Display alles angezeigt.


Mooooment.

Was heisst hier anderes Programm?

Hast du nicht testweise in dein Programm am Anfang mal irgend eine 
Ausgabe reingemacht? Und sei es nur, dass du irgendeinen (konstanten) 
Text ausgibst?

> Liegt es möglicherweise an der uint8_t convertation?

Nein.
Nicht wenn dein Compiler nicht massiv gepatcht wurde. In C ist genau 
geregelt, wie die Argumentübergabe im Falle variadischer Funktionen zu 
erfolgen hat. Das ist soweit alles in Ordnung.

von Julian M. (julianm94)


Lesenswert?

Ja genau, in diesem Programm funktioniert auch keine feste Ausgabe.
Aber ich verstehe nicht wieso, da in dem anderen Programm keine anderen 
Befehle für das Display zu finden sind.

von Karl H. (kbuchegg)


Lesenswert?

Julian M. schrieb:
> Ja genau, in diesem Programm funktioniert auch keine feste Ausgabe.

Dann fangen wir halt mal damit an.

Alles raus aus dem Programm!
Nur Textausgabe!

Die muss erst mal klappen.

Und dann kommen nach und nach die anderen Teile wieder dazu.
1
...
2
int main(void)
3
{
4
  cli();
5
  
6
  LCD_Init();
7
  _delay_ms(1000);
8
  LCD_Cls(black);
9
10
  sei();
11
12
  LCD_Cls(black);
13
14
  while(1)
15
  {
16
    LCD_Print_int ( 5, 60, 30, 2, 5, 5 );
17
  }
18
}

[] funktioniert
[] funktioniert nicht

Wenn das schon nicht funktioniert, dann sieht das Ganze danach aus, als 
ob in der Initialisierung irgendwas fehlt.
Wenn das funktioniert, dann verdichten sich die Hinweise, dass es 
irgendein Speicherproblem ist. Mglw. immer noch zu hoher 
Speicherverbrauch.

von Karl H. (kbuchegg)


Lesenswert?

Und beim nächsten Programm fängst du gleich damit an, dich vor allem 
anderen um die Ausgabe zu kümmern.
Es macht wenig Sinn, mit den CAN Funktionen anzufangen, wenn man die 
nicht testen kann, weil man nirgends eine Ausgabemöglichkeit hat. 
Ausgabe ist immer das Allerwichtigste.

von Julian M. (julianm94)


Lesenswert?

Habe es hin bekommen, vielen dank! :)

von Michael (Gast)


Lesenswert?

Na dann herzlichen Dank auch für die Info. Hilfreich für Andere 
(auch/insbesondere die Helfer) ist aber sicherlich, wenn du auch 
verrätst, was im Detail das Problem war

von Julian M. (julianm94)


Lesenswert?

Eine Zeitverzögerung in der while Schleife war die Lösung.
Also dass erst einen Moment gewartet wird bevor die Ausgaben 
stattfinden.

von Karl H. (kbuchegg)


Lesenswert?

Julian M. schrieb:
> Eine Zeitverzögerung in der while Schleife war die Lösung.
> Also dass erst einen Moment gewartet wird bevor die Ausgaben
> stattfinden.

Klingt nicht logisch.

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.