Hallo ich versuche den Touchscreen zu kalibrieren Touch Controller ist
ein ADS7843.
Wenn ich die werte so lasse in Coordinate DisplaySample dann kann ich
denn Touch Calibrieren das geht aufn 320x240 Display.
Mein Display ist aber ein 800x480 Display,da Funktioniert das nicht so
gut,ändere ich die werte für mein Display(800x480)
auf 45,45
755,45
400,240
So kann ich kein abgleich mehr machen.
kann mir einer weiterhelfen.
mfg
Die linke Seite des = ist zwar long double, rechts davon ist aber
alles uint16_t. Vermutlich gibt es einen Überlauf bei dem grösseren
Display. Auch müssen die Punkte so gewählt werden, dass kein Ergebnis
dieser Gleichungen negativ ist.
Lattice User schrieb:> long double?> Wirklich?typedef struct Matrix> {> long double An,> Bn,> Cn,> Dn,> En,> Fn,> Divider ;> } Matrix ;>> Ist das wirklich aus dem Orginal?
Ja das war mit auf der CD zu diesen Board.
>> Das Problem liegt vermutlich in Zeilen wie dieser: matrixPtr->An => ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y -> screenPtr[2].y)) -> ((displayPtr[1].x - displayPtr[2].x) *> (screenPtr[0].y - screenPtr[2].y)) ;>> Die linke Seite des = ist zwar long double, rechts davon ist aber alles> uint16_t. Vermutlich gibt es einen Überlauf bei dem grösseren Display.> Auch müssen die Punkte so gewählt werden, dass kein Ergebnis dieser> Gleichungen negativ ist.
wie müsste ich dann die Gleichung anpassen damit wie sie sagten das
Ergebniss nicht Negativ wird.
Für eine Antwort währe ich sehr Dankbar
mfg
Constantin schrieb:> Lattice User schrieb:>> long double?>> Wirklich?typedef struct Matrix>> {>> long double An,>> Bn,>> Cn,>> Dn,>> En,>> Fn,>> Divider ;>> } Matrix ;>>>> Ist das wirklich aus dem Orginal?>> Ja das war mit auf der CD zu diesen Board.>>
Dann stammt es von jemanden der schnell mal etwas zusammengeschustert
hat. Man braucht dafür kein Floatingpoint, und schon gar nicht long
double.
Auf die Schnelle mal
1
typedef struct POINT
2
{
3
uint16_t x;
4
uint16_t y;
5
}Coordinate;
durch
1
typedef struct POINT
2
{
3
int32_t x;
4
int32_t y;
5
}Coordinate;
ersetzen. Sollte das Overflow und auch das Vorzeichenproblem lösen.
Bei dem ganzen Floatingpoint Mist macht das auch nichts mehr aus.
Auf Dauer sich mit der Auswertung von resistiven Touch vertraut machen
und
selbst implementieren. Google ist da sicher behilflich.
Lattice User schrieb:> Dann stammt es von jemanden der schnell mal etwas zusammengeschustert> hat. Man braucht dafür kein Floatingpoint, und schon gar nicht long> double.
long double ist vermutlich etwas übertrieben.
Floating Point wird der Autor genommen haben um Nichtlinearitäten aus
dem Display rausrechnen zu können.
Hallo,
So ich hab das für mein 7Inch Display mal angepasst ich kann den Toch
auch Kalibrieren Funktioniert.
so wenn ich etwas Zeichnen will auf das Display hab ich in Y immer eine
Differenz.
In X pass der Touch einwandfrei.
1
while(1)
2
{
3
getDisplayPoint(&display,Read_Ads7846(),&matrix);
4
TP_DrawPoint(display.x,display.y+440);
5
}
zb. drücke ich den Touch bei x350 und Y460 zeichnet er mir in Y schon
bei 470
und bei Y20 zeichnet er mir Y10.
Wie kann ich diese Differenz in Y beseitigen.
mfg
> drücke ich den Touch bei x350 und Y460
wie hast du das verifiziert?
Vorgehensweise:
mittels TP_DrawPoint erst mal ein paar Punkte aufs LCD zaubern und
visuell kontrollieren, ob die Koordinaten stimmen können bzw. plausibel
sind. Auch darauf achten, in welcher Ecke der 0-Punkt liegt und in
welche Richtung die positive Koordinatenachse verläuft.
Dann machst du mittels TP_DrawPoint einen Punkt an eine bestimmte
Koordinate (zb 100/100). WEnn du dann da drauf drückst muss dir deine
Touch-Funktion auch die 100/100 liefern (mit ein wenig Abweichung, denn
so genau wirst du nicht drücken können). WEnn nicht, dann ist in deiner
Rückrechnung noch was faul: Kontrollieren, indem man sich die Werte in
der kompletten Berechnungskette ansieht und nachrechnet
Ja, so ist das nun mal. Progrmmieren heisst nicht nur, sich fertigen
Code besorgen, drauf spielen und alles ist gut.
Mit der Rückrwchnung da hab ich ja noch probleme.
Ich sehe ja wenn ich mit dem Touchstift über den Touch gehe,wirden ja
gleich die pixel gezeichnet.
in X stimmt es ja nur in Y gibs eine Differenz.
Ich mache nachher mal ein video.
Danke.
mfg
Constantin schrieb:> Mit der Rückrwchnung da hab ich ja noch probleme.>> Ich sehe ja wenn ich mit dem Touchstift über den Touch gehe,wirden ja> gleich die pixel gezeichnet.> in X stimmt es ja nur in Y gibs eine Differenz.> Ich mache nachher mal ein video.
brauchst du nicht. sieh dir die werte an. und zwar von vorn, beginnend
mit den adc werten bzw. den Faktoren in der Umrechnungsmatrix.
Insbesondere musst du bei einem Druck auf deine Kalibrierpunkte genau
die von dir vorgegebenen Pixelwerte zurückgerechnet bekommen.
Alles andere bringt nichts, da kannst du Videos machen soviel du willst
und rumdrücken so viel du willst. Das ist nur verschwendete Zeit.
ergeben. Ansonsten sind die Werte in deiner Matrix falsch bzw. bei
irgendeiner der Berechnungen zur Erlangung der Matrix läuft was über. In
dem Fall zb. mal die Berechnung von den Ausgangswerten her mit einem
Tschenrechner nachvollziehen und die Zwischenwerte notieren (und auch
mit dem Taschenrechner kontrollieren, ob die Rückrechnung mit der auf
dem Taschenrechner gewonnenen Matrix zu den DisplaySamples Punkten
passt). Danach mit den Werten vergleichen, die in deinem Programm
tatsächlich während des Rechengangs zur Gewinnung der Matrix auftauchen.
constantin schrieb:> Meine Werte sind:> 45, 45 = 320, 3545> 745, 45 = 3694, 3469> 400, 434 = 2025, 606
Ja. ok.
Und? Weiter?
Was ergibt sich daraus für eine Matrix? Welche Koordinaten kommen raus,
wenn du genau diese ScreenSample Werte durch die Matrix jagst und zurück
rechnen lässt?
Du musst schon ein bisschen mitarbeiten. Ansonsten kannst du es auch
lassen. Ich seh meinen Job hier nicht darin, mit dir Ferndebugging bis
runter auf die Statement-Ebene zu machen und dir beibringen zu müssen,
wie man eigentlich an Debugging rangeht. Wenn du von dir aus nicht
gewillt bist, zu ergründen wie und warum das funktioniert, wie die Mathe
dahinter arbeitet, dann lassen wir es.
Die ganze Rückrechnung ist nichts anders als eine lineare Gleichung
1
display.x = a * screen.x + b * screen.y + c;
2
display.y = d * screen.x + e * screen.y + f;
(und einen zusätzlichen Divisor hat er noch eingeführt, wohl zur
Vorbereitung für die Umstellung von Floating Point auf
Fixkommaarithmetik).
Aber mehr steckt da nicht dahinter. Die entscheidende Komponente ist die
Bestimmung der Koeffizienten a, b, c, d, e und f (und natürlich des
Divisors, weil er benutzt wird). Wenn die nicht korrekt sind, dann geht
das eben schief. Also muss man sich die Bestimmung dieser Koeffizienten
ansehen, wo da das Problem entsteht. Das schafft man aber nicht, in dem
man sich stundenlang irgendwelche Bildchen hinmalen lässt, sondern indem
man sich die Zahlen, Zwischenergebnisse ansieht und vor allen Dingen im
Vorfeld bestimmt, welches eigentlich dir richtigen Zwischenergebnisse
sein müssten. Dazu muss man aber wiederrum verstehen, wie man das obige
Gleichungssystem lösen kann, wenn man 3 Wertepaare hat. Mit 3
Wertepaaren lassen sich somit 6 Gleichungen aufstellen - 6 Gleichungen
mit 6 Unbekannten (a,b,c,d,e,f) und das wiederrum ist lösbar.
>>
1
> An = 0
2
> Bn = 151122
3
> Cn = 21732
4
> Dn = 0
5
> En = 184894
6
> Fn = 504048
das kann nicht stimmen. A kann schon mal nicht 0 sein. Und E müsste
negativ sein.
Wie gross ist der Divider?
Karl Heinz schrieb:> das kann nicht stimmen. A kann schon mal nicht 0 sein. Und E müsste> negativ sein.
Bist du sicher, dass deine Ausgaberoutinen korrekt sind und du die zum
Datentyp in Matrix passenden benutzt hast?
ein negatives Ergebnis. Das Ergebnis kann aber nicht negativ sein, wegen
dem uint16_t Datentyp von screenPtr.
Da haben wir schon mal die Erklärung, warum von den Y-Werten keiner
negativ ist, was er aber sein müsste, damit sich die reverese
Abhängigkeit der Y-Werte
1
45 -> 3469
2
434 -> 606
3
4
ja größer der Wert links, desto kleiner der Wert rechts
ergeben kann.
Da muss also zumindest mal irgendwo ein Umstieg auf einen signed
Datentyp rein. (und um ehrlich zu sein, würde ich die uint16_t in
Coordinate auf int16_t wechseln. Auch wenn es scheinbar unsinnig ist,
negative Display Koordinaten zu haben, so vereinfacht sich vieles, wenn
sie es sein können und man eine Linie von den Koordinaten -10/-50 zu den
Koordinaten 400/300 ziehen kann und das Display zeigt nur den davon
sichtbaren Ausschnitt an. Dazu bräuchte es allerdings wieder ein
Clipping und damit beginnt dann für dich der Rattenschwanz an
Grafik-Funktionen und der Grund, warum man Computer Grafik nicht einfach
aus der hohlen Hand schütteln kann, auch wenn es simpel ist einen
einzelnen Punkt zu setzen und alles andere darauf aufbaut.
aber eine andere Punktanordnung
Du kannst nicht einfach Punkte so anordnen, wie es dir Spass macht! Da
steckt eine Abhängigkeit in den Oririginaldaten!
1
Coordinate DisplaySample[3] = {
2
{ 45, 45 }, <- Punkt rechts oben
3
{ 45, 270}, <- x bleibt gleich, aber in y gehts nach unten (bzw. oben)
4
{ 190,190} <- diagonal gegenüber von rechts/oben
5
} ;
Der Code zur Ermittlung der Matrix geht von dieser Anordnung aus! Wenn
du die anders machst, dann stimmt nichts mehr. Beachte auch die
impliziten Größer/Gleich Beziehungen, die da in den Originaldaten
drinnen steckt. Die sind wichtig, damit sich in den Zwischenergebnissen
bei der Bestimmung der Matrix kein negatives Ergebnis ergibt.
45 ist kleiner als 190, wohingegen 190 wiederrum kleiner als 270 ist.
Diese Abhängigkeit ist mit ziemlicher Sicherheit nicht ohne Grund so
gewählt (ohne das ich jetzt die Berechnungen in der getMatrix Funktion
näher aufgedröselt hätte. Ändert aber nichts daran, dass die E
Komponente im Eregebnis negativ sein müsste. Sonst kommt die
Reverse-Beziehung in der Y Komponente nicht raus)