Hi Dirk,
danke für detailierte antwort...

Zitat von
Dirk
Ich denke nicht an ein Hardware-Problem.
nachdem das programm "RP6Control_10_Move2.c" problemlos funktioniert glaube ich das auch nicht, ich gerate bei problemen, die ich eigentlich als gelöst (und wenigstens ein bischen verstanden) abgehakt habe, leicht in panik...

Zitat von
Dirk
Leider habe ich das Problem, dass ich deinen Such-Code nicht ganz verstehe, und so auch nicht "mitdenken" kann.
prinzipiell: wenn kein signal empfangen wird, sollte der RP6 ständig im kreis drehen und die bake suchen...
hier meine kommentare zum ablauf in der do-schleife:
Code:
do
{
if(getStopwatch3() > 50) //evtl. zu früh beim ersten durchlauf, beim nächsten - die ganze haupt-if-schleife
//wird ja übersprungen - und wieder stopwatch >50 abgefragt, oder?
{
temp = read_IR_value(); //erstes einlesen des IR-signals
if (temp !=0) //wenn kein signal, drehe um 5°
{
setMultiIOLED1(1);
setMultiIOLED1(0);
rotate(80, RIGHT, 5, false);
temp = read_IR_value(); //lese IR noch einmal nach der drehung ein
if (temp == 0) stop(); //break; //wenn signal empfangen, stoppe drehung (stop(), oder break()?)
if(bumper_left && bumper_right) //stop();//break; // wenn hindernis, stoppe drehung
{
stop();
}
}
temp = read_IR_value(); //lese noch einmal IR signal, ob immer noch IR-signal empfangen wird
if (temp == 0) // wenn empfang...
// die wände erzeugen reflektionen, um zu verhindern dass diese mit der original IR verwechselt werden, soll überprüft
// werden ob das signal 10x hintereinander empfangen wird...
{
x = getStopwatch3(); //speichere stand der stopuhr des ersten empfangs
setMultiIOLED3(1);
setMultiIOLED3(0);
if (t<10) //10 empfang prüfen
{
t++;
if (t == 10) // wenn 10 x empfangen
{
y = getStopwatch3(); //speichre stand der stopuhr des 10ten empfangs
z = y-x; //berechne dauer zwischen erstem und zehntem empfang
t=0;
setStopwatch3(0); //stopwatsch auf null
if (z< 600) //prüfe ob in einem zeitraum von <0,6sec
{
move(100, FWD, DIST_MM(100), false); // dann fahre 100mm vorwärts
setStopwatch3(0); //setze stopuhr auf null, evtl. zu viel...
t=0;
mSleep(400); // weiss nicht wozu, ohne ging es vorher nicht...
task_checkINT0();
task_I2CTWI();
if(bumper_left && bumper_right) // stoppe beim hindernis beim geradeausfahren
{
stop();
}
}
}
}
}
}
task_checkINT0();
task_I2CTWI();
}
while(!bumper_left && !bumper_right);//führe do-schleife solange bis hindernis(ladestation)
stop();

Zitat von
Dirk
In der Hauptschleife wird ja alle 50ms (if(getStopwatch3() > 50) ) "etwas" gemacht. Verfolgt man erstmal das, was passiert, wenn die 50ms NICHT um sind:
Dann laufen nur task_checkINT0(); und task_I2CTWI(); durch und die Schleife soll durchlaufen werden, solange KEIN Bumper gedrückt wird.
Das dürfte aber so nicht funktionieren, weil die Variablen bumper_left u. bumper_right sich in der Schleife nicht verändern (es erfolgt ja keine Veränderung dieser Variablen abhängig von den Bumpern!).
sie kommentar im code...

Zitat von
Dirk
Wenn man dann in die alle 50ms angesprungene Verzweigung schaut, wird da IR gelesen (temp = read_IR_value ). Abhängig vom Ergebnis (Bake wahrgenommen oder nicht) soll ja eine Reaktion erfolgen. Es soll gedreht werden, wenn die Bake nicht erkannt wurde und geradeaus gefahren werden, wenn die Bake erkannt wird.
ja...(im prinzip)...aber halt nicht nach dem (erstbesten) signal...

Zitat von
Dirk
Da ich diesen Teil nicht verstehe, lasse ich das mal außen vor. Aber trotzdem stellen sich Fragen:
Wenn ich mich richtig an die IR-Empfänger-Abfrage erinnere, dann ist das Ergebnis von read_IR_value() NULL, wenn die Bake empfangen wurde und GRÖSSER NULL, wenn sie aus ist oder nicht in Sicht. Wenn das so ist, verstehe ich deinen Code -wie gesagt- nicht.
ja, mit dieser funktion wird das register 30 (Pb2, IR signal) eingelesen:
Code:
uint8_t read_IR_value(void)
{
// uint8_t temp = 0;
I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 30); // Start with register 30
I2CTWI_readBytes(I2C_RP6_BASE_ADR, temp_IR, 1);
return temp;
}
wenn empfang temp=0, wenn kein empfang temp>0...

Zitat von
Dirk
Im 50ms-Teil wird der IR-Sensor ZWEIMAL abgefragt und nach dem Rechts-Rotieren sogar noch einmal. Was bedeutet das? Eigentlich sollte das IR-Signal nur EINMAL alle 50ms abgefragt werden, weil eine erneute Abfrage direkt nach der ersten durchaus ein anderes Ergebnis bringen kann und dann deine Logik durcheinander bringt.
reflektionen, ansonsten siehe kommentare

Zitat von
Dirk
Vorschlag: IR nur EINMAL am Anfang des 50ms-Teils abfragen und in einer Variablen speichern ODER direkt in die beiden Zweige:
Code:
if (temp !=0) // Bake AUS
{
// Drehe rechts-links bis Bake wieder da
}
else // Bake AN
{
// Fahre geradeaus
}
... einmünden lassen.
muss darüber nachdenken, was ist mit den reflektionen?

Zitat von
Dirk
Die 50ms sind vermutlich viel zu kurz. Allein die I2C-Kommunikation dauert (Abfrage IR) fast schon länger,- an die Fahrbefehle gar nicht zu denken.
ich stehe mit den "s.watches" noch auf dem kriegsfus

Zitat von
Dirk
Das nicht blockierende Drehen und Fahren erzeugt kaum einschätzbare Phänomene. Wann ist das Fahren zuende? Meine Einschätzung: Der 50ms-Teil wird mind. schon 50 bis 200x wieder angesprungen, während der letzte Fahrbefehl noch aktiv ist. Folgen: ???
ich habe es so verstanden, dass es besser ist das nicht blockierende drehen und fahren zu verwenden, da gibt es wohl unterschiedliche auffasungen/anwendungsfälle - die auch mit den stopwatches zusammenhängen?

Zitat von
Dirk
Pause 400ms nach dem Vorwärts-Fahrbefehl. Das bedeutet letztlich fast schon ein blockierendes Fahren, weil ja fast 1/2 Sekunde gewartet wird. Das bringt aber die schnelle Hauptschleife durcheinander, so dass die weiteren Abläufe nicht mehr transparent sind.
siehe kommentar im code...

Zitat von
Dirk
Vielleicht hilfst du mir beim Verständnis: Dann kann ich wieder mitziehen ...

habs versucht ...
Lesezeichen