PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ausuro Tasterproblem



Ilm_Stoffel
13.12.2011, 09:09
Hallo, ich habe ein Problem mit meinem Asuro.
Die Funktion poll-switch sollte ja eigentlich die Werte 0, 1, 2, 4, 8, 16, 32 zurückgeben. Im Teste waren bei mir alle Werte um Eins zu klein, d.h. scheinbar ging der eine Taster, der sonst 1 liefern sollte, nicht. Ich habe daraufhin den Wert von 63 im Funktionsrückgabewert der pollSwitch Funktion geändert kam jedoch nicht auf die angestrebten Werte (Ich hab alle Werte von 55 bis 65 durchprobiert).
Der normale Rückgabewert lautet

return ((10240000 / (long)i - 10000) * 63L + 5000) / 10000;
Testweise hab ich mal ein +1 dahintergeschrieben also:

return ((10240000 / (long)i - 10000) * 63L + 5000) / 10000 +1;
-> Werte von 32, 16, 8, 4, 2, 1. Natürlich war jetzt aber auch wenn kein Schalter gerdückt wurde der Rückgabewert eins.
Also habe ich mir Spaßhalber mal den Wert i zurückgeben lassen und festgestellt das alle Taster wirklich funktionieren und unterschiedliche Werte liefern. Wenn kein Schalter gedrückt war lieferte die Funktion den Rückgabewert 255.
Also hab ich folgenden Code eingefügt:

int x=1;
if((unsigned char)i==255){0}
return ((10240000 / (long)i - 10000) * 63L + 5000) / 10000 + x;
Das sollte Bewirken das immer Eins addiert wird falls ein Taster gedrück ist und sonst eben 0 addiert wird.
Ich habe auch den x-Wert ausgeben lassen und alles hat gepasst. Er war 1 für gedrückte Taster und 0 für keinen Taster.
Die Funktionsausgabe macht jetzt aber überhaupt keinen Sinn mehr, es kommt irgendwas um die 190 zurück.

return ((10240000 / (long)i - 10000) * 63L + 5000) / 10000 + ((unsigned char)i == 255)?0:1;
Auch auf diese Weise kommt der Wert mit 190 raus. Ich hab auch versucht den x Wert nicht als Integer sondern als Unsigned Char zu deklarieren auch das hat nichts geändert.
Wie kann es sein das eine simple Addition funktioniert wenn ich '+1' oder '+0' dranschreibe aber komische Werte liefert wenn ich den selben Wert als Variable addiere?

Aus Verzweiflung habe ich sogar noch versucht die Addition im Integer-Bereich durchzuführen falls die Probleme wegen dem Datentyp char auftauchen.

unsigned char val = ((10240000 / (long)i - 10000) * 63L + 5000) / 10000;
int val_int = val;

int x=1;
if((unsigned char)i == 255){x=0;}

return val_int;
... so Funktioniert die Ausgabe auch mit 31, 15, 7, 3, 1. Aber sobald ich

val_int = val_int+x; oder
return val_int+x; einfüge kommen wieder die Werte um die 190 raus.

Meine letzte Idee wäre es in der Poll_Switch Funktion den Rückgabewert "return i; " zu lassen und eine weitere Funktion schreibe die den i-Wert durch eine große Switch-Case Anweisung schickt um die Tasterwerte dann richtig zu setzten. Da ich maximal 2 Taster gleichzeitig bräuchte wären das aber immernoch 21 Case-Fälle. Das wäre eine unschöne Lösung auf dich ich ungern zurückgreifen würde.

Hat irgendjemand eine Idee für mich wie ich das Problem in den Griff bekomme?

PS: Es scheint bei weitem kein einzelfall zu sein, viele meiner Kommilitonen haben auch das Problem sind bisher allerdings immer davon ausgegangen das der eine Taster einfach kaputt ist.

Achja falls sich jemand wundert: ich habe auch die Werte von zwei gedrückten Tasten alle angeschaut und das +1 würde auch für zwei Taster noch zum richtigen Bitmuster führen.

markusj
13.12.2011, 10:46
Wenn man unvorsichtig die Formeln verändert, kann dies zu Überläufen und damit zu komischen Berechnungsergebnissen führen. Probier Mal folgende Formel:

return ((uint8_t) ((1024UL * SWITCH_FACTOR + value / 2) / value)) - (uint8_t) SWITCH_FACTOR;
wobei SWITCH_FACTOR wieder die Zahl um die 63 ist. Du wirst vermutlich eher größere Werte brauchen, probier Mal 63..67 oder so aus, die Formel verkraftet das ohne Überläufe.
Wenn du am Ende doch auf einen SWITCH_FACTOR von 63 oder weniger kommst, reicht dir auch eine leicht modifizierte Form, die weniger Rechenintensiv ist, weil sie mit einem uint16 statt uint32 arbeitet (man beachte die 1024U statt 1024UL):

return ((uint8_t) ((1024U * SWITCH_FACTOR + value / 2) / value)) - (uint8_t) SWITCH_FACTOR;
Zusammengefasst und mit etwas Präprozessor-Magie musst du dir darum noch nicht Mal Gedanken machen:


#if SWITCH_FACTOR * 1024 + 512 > UINT16_MAX
return ((uint8_t) ((1024UL * SWITCH_FACTOR + value / 2) / value)) - (uint8_t) SWITCH_FACTOR;
#else
return ((uint8_t) ((1024U * SWITCH_FACTOR + value / 2) / value)) - (uint8_t) SWITCH_FACTOR;
#endif


(Alles aus der Tiny ASURO Library)

mfG
Markus

PS: Was bei mir "value" ist, ist bei dir "i"

Ilm_Stoffel
13.12.2011, 18:48
Danke für die schnelle Antwort!

Hat leider noch nicht zum gewünschten Ergebnis geführt.


unsigned char t1, t2;
while(1){
t1 = PollSwitch();
t2 = PollSwitch();
if(t1 == t2){ /* irgendeine Taste gedrueckt */
PrintInt(t1); /* Tastenwert senden */
SerWrite("\r\n", 2); /* Zeilenvorschub */
mSleep(500); /* halbe Sekunde warten */
}
}

Das ist die Funktion mit der ich die Taster teste. Den neuen return Wert habe ich wie folgt eingesetzt:

return ((uint8_t) ((1024UL * 63 + i / 2) / i)) - (uint8_t) 63;
Den Wert von 63 habe ich dann verändert. Für alles <=63 sieht die Ausgabe so aus:

Tastsensor Test
190\0x9f\0x01 || 190\0x9f\0x01 || ...
Wo jetzt ein "||" steht geht es eigentlich im 0.5s Takt ohne Freizeichen/Zeilenumbruch weiter. Ich hab keine Ahnung woran das liegen könnte.
Sobald ich einen Taster betätige hört die Ausgabe via IR sofort auf, lasse ich ihn los geht es wieder mit 190\0x9f\0x01 weiter.
Wenn ich Werte einsetze die größer sind als 63 wird außer "Tastsensor Test" garnichts mehr ausgegeben.

markusj
14.12.2011, 00:22
Mich irritiert am meisten, dass die Zeichenkette mit dem Zeilenumbruch nicht korrekt ausgegeben wird. Da sind noch ganz andere Dinge kaputt bei dir, evtl. die Initialisierung? Der Code ist auch nicht vollständig, sonst könnte ich ihn Mal bei mir laufen lassen (mein ASURO steht schon lange einsam im Schrank ...)
Zur Fehlersuche bei der Tasterauswertung solltest du dir Mal die Rohdaten vom ADC und das Berechnungsergebnis der Formel ausgeben lassen, möglichst kontinuierlich, das 500ms-Raster ist da schon kein schlechter Ansatz.

Ich hänge Mal noch eine Testanwendung von mir an, die sollte alle 500ms die einzelnen Tasterzustände in Binärschreibweise (also 0b00100000) ausgeben. Verwendet wird dabei meine Formel mit dem Wert 63.

mfG
Markus

EDIT: Siehe Anhang zwei Posts weiter, da sind alle Werte zwischen 60 und 70 abgedeckt.

Ilm_Stoffel
14.12.2011, 06:19
So, ich hab es jetzt mal ausprobiert: die Ergebnisse stimmen mit meinen ersten Ergebnissen überein. Alle ausgabewerte sind um eins zu klein.
0: 0b00000000
1: 0b00011111
2: 0b00001111
3: 0b00000111
4: 0b00000011
5: 0b00000001
6: 0b00000000

Auch so lässt sich also nicht unterscheiden ob der 6. oder kein Taster gedrückt ist.

markusj
14.12.2011, 12:13
Wenn ich mir die Formel ansehe, ist das Ergebnis zu klein, nach der Formel (1024 * x + i / 2) / i würde das Ergebnis größer mit größerem x. Eigentlich sollte 64 oder 65 bei dir funktionieren. Ich hänge dir Mal in einem Archiv das Programm für x zwischen 60 und 70 an (hoffentlich habe ich mich bei der Nummerierung nicht vertan ...), alternativ kannst du das Kalibrierungs-Tool, das irgendwo im asurowiki bzw. hier im Forum herumgeistert, ausprobieren.

mfG
Markus

Ilm_Stoffel
14.12.2011, 13:54
Das sind jetzt meine Bitmuster:



70 69 68 67 66
k0 000000 000000 000000 000000 000000
k1 100010 100010 100001 100001 100000
k2 010001 010001 010000 010000 010000
k3 001000 001000 001000 000111 000111
k4 000100 000100 000011 000011 000011
k5 000001 000001 000001 000001 000001
k6 000000 000000 000000 000000 000000

65 64
k0 000000 000000
k1 100000 011111
k2 010000 001111
k3 000111 000111
k4 000011 000011
k5 000001 000001
k6 000000 000000

Unter 64 wird alles nur noch kleiner.... nur über den Wert lässt sich das Problem also anscheinend nicht lösen...

Ich hab das Problem jetzt übergangsweise gelößt, ist aber alles andere als ne schöne Lösung. Zumindest kann ich jetzt erstmal an anderen Stellen weiterarbeiten.

int val = (unsigned char)i;

if(254<=val && val<=255) {return 0;}

if(173<=val && val<=175) {return 32;} //K1
if(57<=val && val<=59) {return 16;} //K2
if(152<=val && val<=154) {return 8;} //K3
if(205<=val && val<=207) {return 4;} //K4
if(236<=val && val<=238) {return 2;} //K5
if(251<=val && val<=253) {return 1;} //K6

markusj
14.12.2011, 18:23
Hast du evtl. einen Fehler beim Aufbauen gemacht? Ich denke da vertauschten Widerstände. Dass vom letzten Taster nie etwas zu sehen ist, kann so eigentlich nicht sein. Wenn da untereinander etwas vertauscht wäre, könnte das evtl. auch eine Ursache für die Abweichungen bei den anderen sein, wenn der Vergleichswiderstand betroffen ist.

mfG
Markus

Edit: Deine Übergangslösung scheitert, wenn mehr als ein Taster gedrückt wird.

Ilm_Stoffel
15.12.2011, 13:19
Ich selbst hab den Asuro nicht gelötet aber mehrfach alle Widerstände nach den Farbringen überprüft. Das Problem tritt auch noch bei mehreren anderen Asuros von meinen Kommilitonen auf.
Ich werde wohl die Übergangslösung noch erweitern das es mit allen kombinationen von 2 Tastern klappt. Aber ja: mehr wird dann nicht möglich sein... sollte fürs Projekt aber eigentlich reichen.
Vielen Dank für die Hilfe!

markusj
16.12.2011, 20:41
Falls du noch nicht genug von der Diagnose hast, anbei ist ein Programm angehängt, das die ADC-Rohdaten ausgibt, anstelle der Ausgewerteten, ebenfalls wieder im 500ms Intervall. Vergleichswerte sind im AsuroWiki (http://www.asurowiki.de/pmwiki/pmwiki.php/Main/Tasten) zu finden.

mfG
Markus

radbruch
16.12.2011, 21:00
Dazu passend eine Messanleitung für die Widerstände, die errechneten Werte und in den folgenden Beiträgen Messwerte und Vorschläge zur Korrektur der Formel:

https://www.roboternetz.de/community/threads/50158-T9-glimmt-nur-und-Schalter-funktionieren-nicht-richtig?p=483740&viewfull=1#post483740

oderlachs
18.12.2011, 18:51
Ich hoffe mich erschlägt hier keiner, weil ich mich mit einer Frage hier einreihe. Habe heute den Ersttest als "stolzer Asuroerbauer" gemacht ;)
Nun habe ich folgendes Problem beim Switchtest:
"ASURO steht still, alle Anzeigenelemente sind aus. Ein gutes Zeichen! Die Schalter werden nun
überprüft (ca 15sec). Einfach mal ein bisschen rumdrücken, irgendetwas wird hoffentlich
passieren.

Die Zuordnung sollte wie folgt aussehen :
K1 --> Status-LED (D12) leuchtet grün
K2 --> Status-LED (D12) leuchtet rot
K3 --> Front-LED auf der Unterseite leuchtet auf (D11)
K4 --> Back-LED links (D15)
K5 --> Back-LED rechts (D16)
K6 --> Motor links dreht sich (Sollte sich der Motor nicht drehen kann im Selbsttest ..." aus der Anleitung.
Alles klappt nur das bei K1 Status = Rot und K2 Status = Grün ist.
Da sich die Schalter ja im Widerstandsnetzwerk zur Spannungsteilung befinden habe ich alle Widerstände auf event. Verwechslung geprüft...nix der Gleichen, nun steh ich erst mal vor einem Rätsel ..:confused:

Was kann das wohl sein ?
Morgen werde ich noch mal die Spannungen alle messen, die beim Tasten da so entstehen. Muss das bei tageslicht machen sonst habe ich Prob mit den Augen
und Kunstlicht.

Gerhard

Edit 1: ich habe glaube ich den Fehler gefunden, die Status-LED ist verdreht eingelöten, da hatte ich beim Einlöten Probleme das konkret zu erkennen welche Seite wohin...

Valen
18.12.2011, 19:54
...

Die Zuordnung sollte wie folgt aussehen :
K1 --> Status-LED (D12) leuchtet grün
K2 --> Status-LED (D12) leuchtet rot

...

Alles klappt nur das bei K1 Status = Rot und K2 Status = Grün ist.
Da sich die Schalter ja im Widerstandsnetzwerk zur Spannungsteilung befinden habe ich alle Widerstände auf event. Verwechslung geprüft...nix der Gleichen, nun steh ich erst mal vor einem Rätsel ..:confused:

Was kann das wohl sein ?
Morgen werde ich noch mal die Spannungen alle messen, die beim Tasten da so entstehen. Muss das bei tageslicht machen sonst habe ich Prob mit den Augen
und Kunstlicht.

Gerhard

Edit 1: ich habe glaube ich den Fehler gefunden, die Status-LED ist verdreht eingelöten, da hatte ich beim Einlöten Probleme das konkret zu erkennen welche Seite wohin...Immer die einfachste Lösung. ;)