-
        

Ergebnis 1 bis 5 von 5

Thema: Asuro - Tasterfunktion beim Selbsttest, Problem

  1. #1

    Asuro - Tasterfunktion beim Selbsttest, Problem

    Anzeige

    Hallo Leute,
    bei meinem neuen Asuro habe ich ein Problem mit den Tastern beim Selbsttest. Laut Anleitung sollte bei Tastendruck folgendes passieren:

    K1-> Staus LED grün
    K2-> Status LED rot
    K3-> Front LED
    K4-> Back LED Links
    K5-> Back LED rechts
    K6-> Motor links

    bei mir passiert allerdings folgendes:

    K1-> Status LED grün + Motor links
    K2-> beide Back LED + Motor links
    K3-> Front LED
    K4-> Back LED links
    K5-> Back LED rechts
    K6-> Motor links + Back LED rechts (für den Bruchteil einer Sekunde)

    Für Rat und Hilfe bin ich sehr dankbar.

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    20.04.2006
    Ort
    München
    Beiträge
    6
    Hallo!

    Dass die Tasten nicht immer den gewünschten Wert liefern
    kommt wohl ziemlich häufig vor.
    Man kann dem durch eine kleine Ändeurng in der Software
    abhelfen.

    Schau Dir mal diesen Thread an und probiere das
    dort angegebene Testprogramm, um zu sehen, welche
    Werte welcher Taster liefert:
    http://www.roboternetz.de/phpBB2/viewtopic.php?t=11797

    Alternativ kann es natürlich auch noch sein, dass Du beim
    einlöten versehentlich ein paar Widerstände verwechselt
    hast.

    Grüße,
    Rainer

  3. #3
    Ich habe mir mittlerweile die Werte ausgeben lassen. Es wird eine 15 statt 16 und eine 7 statt der 8 geliefert.

    Das:
    alt: return ((10240000L/(long)i-10000L)*63L+5000L)/10000;
    neu: return ((10240000L/(long)i-10000L)*65L+5000L)/10000;

    hat etwas verändert, allerdings auch nach mehreren Änderungen der Werte nicht zum gewünschten Erfolg geführt. Jetzt hate ich es gelöst, allerdings etwas weniger elegant:
    --
    ret = ((10240000L/(long)i-10000L)*63L+5000L)/10000;
    if(ret == 7 { ret = 8; }
    return ret;
    --

    Es werden jetzt die korrekten Werte geliefert, allerdings ist der Fehler beim Selbsttest, natürlich mit geänderter asuro.c, immer noch genauso vorhanden. Alleridngs soll mein Asuro ja auch nicht nur Selbsttests durchführen. Wenn es bei weiteren Programmen keine Probleme gibt, soll es mich nicht weiter stören.

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    20.04.2006
    Ort
    Graz
    Beiträge
    8
    Hallo,
    ich habe auch das Problem mit den Tastern gehabt. Die Lösung mit der Modifikation der Return-Zeile in Funktion PollSwitch finde ich zwar brauchbar, sie bleibt aber meiner Meinung nach eine Quick&Dirty-Lösung. Man kann den Multiplikator variieren (*62, *63, *64, was auch immer, sogar mit Nachkommastellen) um die Werte 0, 1, 2, 4, 8, 16 und 32 zu bekommen wenn EINEN Taster gedrückt wird. Ich glaube aber, dass es sehr schwer ist die 64 Werte aller möglichen Kombinationen korrekt zu bekommen! In der Praxis kommt natürlich sehr selten vor, dass mehrere Taster z.B. 1,2,3,4 bei Kollision gleichzeitig gedrückt werden. Es macht aber trotzdem Sinn: z.B. Wenn ich feststellen will ob der Asuro an der linken oder rechten Seite mit einem Obj. kollidiert (Taster 1 und 2) dann brauche ich 48 (also 110000) und nicht 47 oder 46.
    Meine Lösung des Problems heißt "lineare Regression" oder "lineare Ausgleich". Im Prinzip versucht man die Messwerte durch eine Gerade zu beschreiben, wobei die Lage (Parameter) der Gerade die Lösung des Ausgleichsproblems ist. (Anm.: Die Formel in PollSwitch enthält bereits die (Daume-mal-Pi) Lösung des Ausgleichsproblems.)

    Nun habe ich folgendes gemacht:
    1) Als erstes versuche ich herauszufinden, welche Werte ich zurückbekomme (so genau wie möglich, ohne Info-verlust) wenn ich einen oder mehrere Taster drücke. Dazu habe ich folgendes Prg. verwendet:
    Code:
    #include "asuro.h"
    
    /* function to read out switches */
    unsigned int  testSwitch (void)
    {	unsigned int i;
    	DDRD |= SWITCHES;				// Switches as Output
    	SWITCH_ON;						// Output HIGH for measurement
    	ADMUX = (1 << REFS0) | SWITCH;	// AVCC reference with external capacitor
    	Sleep(10);
    	
    	ADCSRA |= (1 << ADSC);			// Start conversion
    	while (!(ADCSRA & (1 << ADIF)));// wait for conversion complete
    	ADCSRA |= (1 << ADIF);			// clear ADCIF
    	i = ADCL + (ADCH << 8);
    	
    	SWITCH_OFF;
    	Sleep(5);
    	return (int)(1023000L/(long)i);
    }
    
    int main(void)
    {
    	Init();
    	StatusLED(OFF);
    	
    	SerWrite("\n\rtest switch:\n",15);
    	StatusLED(GREEN);
    
    	while(1) {
    		int j;
    		long sum = 0, sw=0;
    		SerWrite("\n\r",2);
    		while (!PollSwitch());
    		Msleep(100);
    		for (j = 0; j < 100; j++)
    			sum += testSwitch();
    		
    		int sw1,sw2;
    		do {
    			sw1 = PollSwitch();
    			sw2 = PollSwitch();
    		} while (sw1 != sw2);
    		
    		PrintInt((int)(sum/100.0)+0.5);
    		Msleep(200);
    		SerWrite("  ",2);
    		PrintInt(sw1);
    	}
    	return 0;
    }
    Die Messwerte (1023/y) werden sozusagen direkt aufsummiert und Durchschnitt gebildet.

    2) Anhand der Werte und die Formel in PollSwitch lässt sich vermuten, dass 1/y linear ist. Die Formel ist auch nichts anders als lineare Transformation. Wegen der herstellungsbedingten Ungenauigkeit der Widerstände liegen die Messwerte 1023/y nicht auf einer Gerade.

    3) Als nächste habe ich Matlab angeworfen und die Ausgleichgerade berechnet:
    Code:
    Z = 1./y;
    X = [ones(64,1) (0:63)'];
    p = X\Z;   % Lsg des Glg-Systems -> Koeff. der Gerade p
    Z_out = (Z-p(1))/p(2);
    4) Für denjenigen, der kein Matlab hat, habe ich was vorgerechnet.
    Die Werte 1/y aus 1) im folgenden Prg dem y zuweisen.
    Code:
    #include "asuro.h"
    
    int main(void)
    {
          // y wird durch indiv. Messwerte ersetzt
    	int y[] = {1000, 1015, 1031, 1047, 1062, 1079, 1095, 1111, 1125, 1142,
    				1157, 1173, 1190, 1206, 1222, 1238, 1258, 1274, 1290, 1307,
    				1322, 1339, 1355, 1369, 1384, 1401, 1417, 1433, 1449, 1466,
    				1480, 1498, 1525, 1541, 1557, 1574, 1589, 1606, 1621, 1637,
    				1653, 1669, 1685, 1699, 1716, 1734, 1749, 1764, 1785, 1801,
    				1817, 1833, 1850, 1867, 1881, 1898, 1912, 1930, 1945, 1960,
    				1975, 1994, 2010, 2026},
    		A[2][64] = {{
    			6106,  5962,  5817,  5673,  5529,  5385,  5240,  5096,  4952,  4808,
    			4663,  4519,  4375,  4231,  4087,  3942,  3798,  3654,  3510,  3365,
    			3221,  3077,  2933,  2788,  2644,  2500,  2356,  2212,  2067,  1923, 
    			1779,  1635,  1490,  1346,  1202,  1058,   913,   769,   625,   481, 
    			 337,   192,    48,   -96,  -240,  -385,  -529,  -673,  -817,  -962, 
    		   -1106, -1250, -1394, -1538, -1683, -1827, -1971, -2115, -2260, -2404, 
    		   -2548, -2692, -2837, -2981},
    		   {
    		    -144,  -140,  -135,  -130,  -126,  -121,  -117,  -112,  -108,  -103,
    			 -98,   -94,   -89,   -85,   -80,   -76,   -71,   -66,   -62,   -57,
    			 -53,   -48,   -43,   -39,   -34,   -30,   -25,   -21,   -16,   -11,
    			  -7,    -2,     2,     7,    11,    16,    21,    25,    30,    34,
    			  39,    43,    48,    53,    57,    62,    66,    71,    76,    80,
    			  85,    89,    94,    98,   103,   108,   112,   117,   121,   126,
    			 130,   135,   140,   144}};
    
    	int i;
    	float p1,p2,fkt=1.e5;
    	p1 = p2 = 0;
    	Init();
    	SerWrite("\n\rlin.Regression:\n\r",19);
    	for (i = 0; i < 64; i++) {
    		p1 += (float)A[0][i]*(float)y[i];
    		p2 += (float)A[1][i]*(float)y[i];
    	}
    	p1 /= fkt;
    	SerWrite("bias: 0.",8);
    	Msleep(100);
    	PrintInt(p1);
    	SerWrite("\n\r",2);
    
    	p2 = 1000*fkt/p2;
    	SerWrite("slope: ",7);
    	Msleep(100);
    	PrintInt(p2);
    	SerWrite(".",2);
    	PrintInt((int)((p2-(int)p2)*10.0+0.5));
    	SerWrite("\n\r",2);
    	
    	while (1);
    	return 0;
    }
    Das Prg spuckt zwei Werte aus: bias b (bei mir 0.995) und slope s (die Steigung der Gerade, bei mir 61.0).

    5) Zum Schluß wird die Return-Zeile noch korrigiert mit:
    Code:
    return  ((unsigned char) ((( 1023.0/(float)i - 0.995)) * 61.0 + 0.5));
    Mit diesem Feintuning habe ich alle 64 Werte richtig. Probiert habe ich mit und ohne Motor eingeschalten. Hier ist noch das Testprg. Es gibt die Messwerte und die transf. Werte 1 bis 63 aus.
    Code:
    #include "asuro.h"
    
    /* function to read out switches */
    unsigned int  testSwitch (void)
    {	unsigned int i;
    	DDRD |= SWITCHES;				// Switches as Output
    	SWITCH_ON;						// Output HIGH for measurement
    	ADMUX = (1 << REFS0) | SWITCH;	// AVCC reference with external capacitor
    	Sleep(10);
    	
    	ADCSRA |= (1 << ADSC);			// Start conversion
    	while (!(ADCSRA & (1 << ADIF)));// wait for conversion complete
    	ADCSRA |= (1 << ADIF);			// clear ADCIF
    	i = ADCL + (ADCH << 8);
    	
    	SWITCH_OFF;
    	Sleep(5);
    	return (int)(1023000L/(long)i);
    }
    
    int main(void)
    {
    	Init();
    	StatusLED(OFF);
    	
    	SerWrite("\n\rtest switch:\n",15);
    	StatusLED(GREEN);
    
    	while(1) {
    		int j;
    		long sum = 0;
    		SerWrite("\n\r",2);
    		MotorDir(FWD,FWD);
    		MotorSpeed(150,150);
    		while (!PollSwitch());
    		Msleep(100);
    		for (j = 0; j < 100; j++)
    			sum += testSwitch();
    		
    		int sw1,sw2;
    		do {
    			sw1 = PollSwitch();
    			sw2 = PollSwitch();
    		} while (sw1 != sw2);
    		
    		PrintInt((int)(sum/100.0)+0.5);
    		SerWrite("  ",2);
    		Msleep(200);
    		PrintInt(sw1);
    		if (sw1 & 0x7)
    			MotorDir(RWD,RWD);
    		else
    			MotorDir(FWD,FWD);
    		MotorSpeed(150,150);
    		Msleep(500);
    	}
    	return 0;
    }
    Ich hoffe, dass diese codes hilfreich sind. Falls jemand einen Fehler entdeckt, bitte melden. Wenn jemand sich interessiert, kann ich auch kurz erläutern, wie das lin. Ausgleichsproblem analytisch gelöst wird (auf die Frage, wieso sieht die 2x64-Matrix A so aus).

    Felix

  5. #5
    Die Lösung mit der Modifikation der Return-Zeile in Funktion PollSwitch finde ich zwar brauchbar, sie bleibt aber meiner Meinung nach eine Quick&Dirty-Lösung.
    Ja, mehr sollte das im Moment auch nicht sein. Ich werde deine Lösung mal testen. Etwas unschön finde ich, das die Entwickler diese Fehler in Kauf genommen haben. Bauteiltoleranzen sind zwar da, aber nicht so groß, das man sie nicht von Anfang an Softwaremäßig ausgleichen könnte.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •