Hallo Allerseits,
Ich habe folgendes Problem und nach langer Suche im Forum bin ich immer
noch nicht hinter mein Problem gekommen.
Ich habe ein Grafik LCD von Pollin:
http://www.pollin.de/shop/suchergebnis.html?S_TEXT=+DG-16080-11&S_WGRUPPE=default
Das funktioniert auch wunderbar.
Da dieses Teil einen Touchscreen hat les ich den auch aus, was ebenfalls
funktioniert.
Ich bin leider gerade auf Arbeit und hab deswegen den Code nicht hier,
aber ich versuche es so gut es geht zu beschreiben:
Ich lasse die X und Y Werte der AD Wandlungen auf dem Display anzeigen.
Diese speichere ich heirzu in einem uint16_t und wandle sie mit hilfe
von itoa() in einen char. (char string[10])
Dieses lass ich auf dem Display ausgeben wenn der Touch gedrückt ist,
was auch geht, wenn nicht habe Ich eine funktion die eine AD Wandlung
macht und wenn der Wert > 1000 ist (bei nichtberühren ist er ca. 1020)
die uint16_t Variable mit 0 beschreibt.
Wenn ich die Variable aber in diesem Fall ausgeben lasse, dann erhalte
ich eine solche Anzeige _0_12: die unterstriche sind leerzeichen, die 12
eine zahl die ab und zu schwankt.
Ich habe schon alles mögliche probiert, komme aber nicht hinter das
Problem :/
Ich vermute das es etwas mit danit zu tun hat das die Variable eine
16bit breite ist.
hab auch schon versucht mit 0x0000 zu beschreiben, aber ohne erfolg :(
Wenn wer ne lösung hat, ich bin für jede Hilfe dankbar!!
Gruss an alle
Elias
Hallo,
erst mal Dnake für die Antworten.
Ich sitze wie gesagt auf Arbeit und habe den Quelltext nicht hier.
Werd Ihn heute Abend posten sobald ich daheim bin.
Ich habe mir auch schon den Wert der 16bit Variable mittels itoa(a,b,2)
binär wandeln lassen und den ausgegeben, und auch dort steht nicht 0
drin.
Ich denke der Fehler liegt irgendwo auf der Strecke von 0 in die
Variable schreiben bis zum ausgeben aufs Display.
Elias B. schrieb:
> Ich habe mir auch schon den Wert der 16bit Variable mittels itoa(a,b,2)> binär wandeln lassen und den ausgegeben, und auch dort steht nicht 0> drin.
Vorsicht.
Bei einer binären Ausgabe einer 16-Bit Zahl, kann der entstehende String
logischerweise auch 16 Zeichen lang werden. Du brauchst dann klarerweise
ein
char string[17];
10 ist dann zuwenig.
Und noch ein Fehler (aber der erklärt jetzt nicht dein Problem).
itoa: man beachte das i am Anfang. Das steht für I wie INT
(also signed int)
Du hast aber keinen signed int. Du hast einen unsigned int. Dafür
brauchst du die Funktion utoa. u wie 'unsigned'
Ich denke auch, dass die wahrscheinlichste Stelle für einen Fehler die
Ausgabefunktion ist.
Es könnte auch sein (auch ein beliebter Fehler), dass du übersehen hast,
dass eine neue Ausgabe die alte überschreibt. Ist die neue Ausgabe
kürzer als die alte, dann bleibt klarerweise von der alten Ausgabe etwas
übrig.
Wenn man die Zahl 1018 mit 99 überschreibt, dann steht am Display 9918
und das kann schnell mal zu Konfusion führen.
Hallo,
Habs wohl ein wenig dürftig beschrieben.
Der cah string[20] war 20 Zeichen lang für den versuch mit dem Binär :)
ok, das mit dem utoa leuchtet ein :) -> werd ich auf jeden Fall mal
ändern.
Mal sehen was der Abend bringt.
Wenn ich einen
1
uint16_ttest;
mit
1
test=0;
Mit nul beschreibe müsste er doch komplett null sein oder? Ich meine das
so nicht nur die untern 8 bit oder so beschrieben werden!?
>> Mit nul beschreibe müsste er doch komplett null sein oder? Ich meine das> so nicht nur die untern 8 bit oder so beschrieben werden!?
Das passt schon so.
Also ist es das hier:
Karl heinz Buchegger schrieb:
> Es könnte auch sein (auch ein beliebter Fehler), dass du übersehen hast,> dass eine neue Ausgabe die alte überschreibt. Ist die neue Ausgabe> kürzer als die alte, dann bleibt klarerweise von der alten Ausgabe etwas> übrig.> Wenn man die Zahl 1018 mit 99 überschreibt, dann steht am Display 9918> und das kann schnell mal zu Konfusion führen.
Ich sehe nämlich nur lauter lcd_gotoxy/lcd_writestring-Kombinationen,
ohne dass mal irgendwo irgendetwas auf dem LCD gelöscht würde.
Übrigens:
Dein lcd_writestring gibt auch immer die Null-Terminierung mit aus.
Hallo Karl Heinz,
Der Tipp mit dem LCD löschen hat mich schon entscheidend weitergebracht
:)
Die 0 funktioniert jetzt.
Aber dafür flackert das Display :/
Hab aber n Work around :) Nicht schön aber selten :D
1
for(;;)
2
{
3
x_value=readTouchX();// X Touch Wert lesen
4
if(x_value>0)
5
{
6
utoa(x_value,string_x,10);// INT in STRING wandeln
7
lcd_gotoxy(1,50);// Auf LCD Position springen
8
lcd_writestring(string_x);// X Wert schreiben
9
}
10
else
11
{
12
lcd_gotoxy(1,50);// Auf LCD Position springen
13
lcd_writestring("0 ");// X Wert schreiben
14
lcd_gotoxy(32,50);// Auf LCD Position springen
15
lcd_writestringP(PSTR(": X Wert"));// String dahinter schreiben
16
}
17
y_value=readTouchY();// X Touch Wert lesen
18
if(y_value>0)
19
{
20
utoa(y_value,string_y,10);// INT in STRING wandeln
21
lcd_gotoxy(1,60);// Auf LCD Position springen
22
lcd_writestring(string_y);// X Wert schreiben
23
}
24
else
25
{
26
lcd_gotoxy(1,60);// Auf LCD Position springen
27
lcd_writestring("0 ");// X Wert schreiben
28
lcd_gotoxy(32,60);// Auf LCD Position springen
29
lcd_writestringP(PSTR(": Y Wert"));// String dahinter schreiben
30
}
31
32
}
Du hast ausserdem geschrieben das:
"Übrigens:
Dein lcd_writestring gibt auch immer die Null-Terminierung mit aus."
Wie kann ich das umgehen ?
Gruss Elias
Elias B. schrieb:
> Hallo Karl Heinz,>> Der Tipp mit dem LCD löschen hat mich schon entscheidend weitergebracht> :)>> Die 0 funktioniert jetzt.> Aber dafür flackert das Display :/
Das wundert mich nicht gerade.
Deine Routinen werden ziemlich langsam sein, wenn du keine Optimierung
machst sondern ständig alles auf Pixelebene runterbrichst. Aber das soll
jetzt (noch) nicht das Problem sein :-)
> Hab aber n Work around :) Nicht schön aber selten :D
Und nicht wirklich zielführend :-)
Aber eins nach dem anderen
> Du hast ausserdem geschrieben das:> "Übrigens:> Dein lcd_writestring gibt auch immer die Null-Terminierung mit aus.">> Wie kann ich das umgehen ?
Indem du die writeString Funktion so veränderst, dass sie das
abschliessende '\0' Zeichen eines jeden Strings nicht mit ausgibt.
1
voidlcd_writestring(constchar*string)
2
{
3
while(*string)
4
lcd_writechar(*string++);
5
}
Zu deinem Problem.
Was ist denn eigentlich das Problem?
Auf dem LCD steht zb 1023
Jetzt gehst mit dem gotoxy wieder auf den Anfang an dieser Stelle und
schreibst 78 drüber.
Was steht dann am LCD? Nein da steht nicht 78. Da steht 7823. Dies
deshalb, weil ja niemand dafür gesorgt hat, dass auch die 23 von 1023
überschrieben werden.
-> Die einfachste Lösung ist es, für Zahlenausgaben eine Feldbreite
einzuführen. Also: Die Zahl wird immer in einem Feld der Breite 4
ausgegeben. Ist die Textdarstellung einer Zahl kleiner als dieses Feld,
dann wird mit Leerzeichen aufgefüllt. Man kann links auffüllen oder auch
rechts auffüllen. Füllt man links auf, dann hat man den Vorteil, dass
die Einerstelle der Zahl immer an der gleichen Position an der
Ausgabestelle erscheint. Das ist insofern gut, als es beim Lesen hilft,
wenn die Zahl nicht konstant ist und sich ständig ein wenig ändert. Die
Zahl springt dann nicht am Display hin und her, wenn sie zb ständig
zwischen 102 und 99 pendelt.
Wie kannst du auffüllen?
Ganz einfach: Stell die Stringlänge fest und gib die fehlende Anzahl an
Leerzeichen vorher aus.
Und damit sind wir beim nächsten Punkt:
Eine Zahlenausgabe ist in einem Progamm meistens eine zentrale
Operation. So wie es auch eine Stringausgabe ist. Es ist daher
vernünftig sich dafür eine Funktion zu schreiben und nicht den Code
dafür über das komplette Program x-mal zu verstreuen
lcd_writestringP(PSTR(": X Wert"));// String dahinter schreiben
8
9
y_value=readTouchY();// X Touch Wert lesen
10
lcd_gotoxy(1,60);// Auf LCD Position springen
11
lcd_writeuint(y_value,4);
12
lcd_gotoxy(32,60);// Auf LCD Position springen
13
lcd_writestringP(PSTR(": Y Wert"));// String dahinter schreiben
14
}
Und noch eine Anmerkung:
Schau dir deine Kommentare noch einmal an.
Und dann beantworte mal die Frage:
Was erzählt mir eigentlich der Kommentar, was ich Quelltext nicht auch
so sehe?
lcd_gotoxy(32,50); // Auf LCD Position springen
Super. Der Funktionsaufruf heisst lcd_gotoxy. Das dieser Funktionsaufruf
die Ausgabeposition irgendwo hinstellt, weis ich auch so. Was steht im
Kommentar? Da steht, dass die Ausgapeposition irgendwo hin gestellt
wird. Was hat mir also der Kommentar erzählt, was ich nicht auch im Code
sehe? Gar nichts.
lcd_writestringP(PSTR(": Y Wert")); // String dahinter schreiben
Selbiges. Der Funktionsaufruf heißt lcd_writestringP. Selbst wenn ich
nichts über die Funktion wüsste, was würde ich wohl ohne groß
nachzudenken annehmen was die Funktion macht? Der Name fängt mit lcd_
an, es wird sich also um eine Funktion handeln, die irgendwas mit dem
LCD macht. Dann kommt writestring. Gut da muss ich eine Weile optisch
suchen um zu erkennen dass es sich um 2 Wörter handelt. writeString wäre
leichter zu lesen, aber was solls. write ... also eine Ausgabe.
...String, also ein String. Die Funktion wird als einen String auf das
LCD schreiben. Das schiesst mir in 2 Zehntelsekunden durch den Kopf wenn
ich lcd_writeString lese. Und was erzählt mir der Kommentar "String
dahinter schreiben". Also genau dasselbe!
Wozu dann der Kommentar?
Das einzige was ich mir eventuell nicht beim Lesen des Funktionsaufrufs
erklären kann ist das P im Funktionsnamen. Aber das erklärt mir auch der
Kommentar nicht, was es damit auf sich hat.
Erkläre in einem Kommentar nicht das 'Wie'. Erkläre das 'Warum'! Und
wenn du der Ansicht bist, dass das 'Warum' aus dem Programmflus an
dieser Stelle selbsterklärend ist, dann lass den Kommentar weg! Denn
dann kann er auch nicht falsch sein, wie zb hier
1
PORTA|=(1<<PA2);// PA0 HIGH X1
2
PORTA&=~(1<<PA3);// PA2 LOW X2
Hier erklärst du wiederrum das 'Wie', aber nicht das 'Warum'.
Blöderweise ist das 'Wie' auch noch falsch kommentiert.
Hallo Karl Heinz,
erst einaml Danke für deine sehr aufschlussreiche Antwort!!
Zum Thema Kommentare:
Aller Anfang ist schwer, ich hab so of schon gelesen "Kommentier
gefälligst deinen Code" und dachte viel hilft viel.
Aber deine Kritik leuchtet ein und ich gelobe besserung :)
Gruss Elias
Bouni schrieb:
> Zum Thema Kommentare:> Aller Anfang ist schwer,
Ich weiß.
Sinnvoll kommentieren ist eines der schwersten Dinge.
> ich hab so of schon gelesen "Kommentier> gefälligst deinen Code"
... und niemand sagt einem was sinnvoll ist :-)