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

Zitat Zitat von Dirk Beitrag anzeigen
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 Zitat von Dirk Beitrag anzeigen
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 Zitat von Dirk Beitrag anzeigen
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 Zitat von Dirk Beitrag anzeigen
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 Zitat von Dirk Beitrag anzeigen
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 Zitat von Dirk Beitrag anzeigen
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 Zitat von Dirk Beitrag anzeigen
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 Zitat von Dirk Beitrag anzeigen
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 Zitat von Dirk Beitrag anzeigen
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 Zitat von Dirk Beitrag anzeigen
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 Zitat von Dirk Beitrag anzeigen
Vielleicht hilfst du mir beim Verständnis: Dann kann ich wieder mitziehen ...
habs versucht ...