- 12V Akku mit 280 Ah bauen         
Seite 9 von 12 ErsteErste ... 7891011 ... LetzteLetzte
Ergebnis 81 bis 90 von 115

Thema: RP6-Projekt induktive Ladestation

  1. #81
    Erfahrener Benutzer Robotik Einstein Avatar von inka
    Registriert seit
    29.10.2006
    Ort
    nahe Dresden
    Alter
    76
    Beiträge
    2.180
    Anzeige

    LiFePo4 Akku selber bauen - Video
    @Dirk;
    Zitat Zitat von Dirk Beitrag anzeigen
    @inka: Wie wäre es auf der Empfängerseite noch mit einer Spannungsmessung am Ausgang des Empfängers? Damit könnte der RP6 seine Position auf der Senderspule evtl. korrigieren (optimale Ladeposition) bzw. überhaupt prüfen, ob er auf der Ladespule steht.
    ... nur so 'ne Idee ...
    ich wollte eigentlich eine "mechanische" lösung (quasi "nach gehör" fahren), aber die messung wäre sicher eleganter. Wäre die reaktion darauf auch schnell genug möglich? Realisierung mit "LTC2990_measure()", oder hast Du da an was anderes gedacht?

    @fabqu,
    Jetzt nen 3D-Drucker kaufen, und das Ding serienmäßig produzieren...
    tja, die sind noch ein bischen teuer...
    gruß inka

  2. #82
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hi inka,

    ja, ich hatte da an eine Spannungsmessung am Ausgang der Spule bzw. zwischen Spule und Spannungswandler gedacht.
    Man könnte einen nicht genutzten ADC-Kanal der M32 (z.B. ADC_2) dafür nehmen. Der Eingang ist auf der MultiIO am J_ADC Jumperblock Pin "2".
    Man braucht dann noch einen Spannungsteiler aus 2 Widerständen, weil der ADC ja nur bis 5V messen kann (oder ist die Spannung da nicht höher?).
    Gruß
    Dirk

  3. #83
    Erfahrener Benutzer Robotik Einstein Avatar von inka
    Registriert seit
    29.10.2006
    Ort
    nahe Dresden
    Alter
    76
    Beiträge
    2.180
    Hi Dirk,
    Zitat Zitat von Dirk Beitrag anzeigen
    ja, ich hatte da an eine Spannungsmessung am Ausgang der Spule bzw. zwischen Spule und Spannungswandler gedacht.
    Man könnte einen nicht genutzten ADC-Kanal der M32 (z.B. ADC_2) dafür nehmen. Der Eingang ist auf der MultiIO am J_ADC Jumperblock Pin "2".
    Man braucht dann noch einen Spannungsteiler aus 2 Widerständen, weil der ADC ja nur bis 5V messen kann (oder ist die Spannung da nicht höher?).
    der tip war wieder einmal goldwert: es funktioniert, mit diesem
    Code:
    void acculadung(void)
    {
    clearLCD();
    setCursorPosLCD(0, 0);
    writeStringLCD(" ADC2: ");
    uint16_t adc2 = readADC(ADC_2); // Read ADC Channel 2
    setCursorPosLCD(0, 9);
    writeIntegerLCD(adc2, DEC);
    if (adc2 > 650)
    {
    setCursorPosLCD(2, 0);
    writeStringLCD(" ladespannung ok ");
    setMultiIOLED1(1);
    }
    }
    kann ich dann später (von der ladestation ist unter dem RP6 ja nichts zu sehen, er ist aber an) eine LED oder was auch immer als zeichen dafür, dass geladen wirkt blinken lassen...

    btw. da kommen nur 3.5V an, an der empfängerspule. Eigenttlich sollten es 5V sein, aber durch eine etwas größere entfernung zu der sendespule reduziert sich das. Da gabs auch probleme am anfang mit dem einschwingen des spannungwandlers, inzwischen läuft der problemlos an...

    ich habe mich in letzter zeit mit der linienverfolgung beschäftigt und wollte jetzt wieder schauen, wie es mit dem finden der bake zusammenzubringen wäre. Und prompt geht wieder nix.

    daß das auffinden der bake schon funktioniert hat, dafür gibts ja beweise bei youtube - immerhin, nur hilft mir das jetzt nicht weiter...

    dieser
    Code:
    #include "RP6ControlLib.h"
    #include "RP6I2CmasterTWI.h"
    #include "RP6Control_MultiIOLib.h"
    #include "RP6Control_I2CMasterLib.h"
    #include "RP6Control_LFSBumperLib.h"
    #include "RP6ControlServoLib.h"
    #include "standard.h"
    
    #define I2C_RP6_BASE_ADR 10
    
    /******************variablen***************************/
    
    //uint8_t transmit_buffer[10];
    uint8_t RP6data[32];
    
    uint8_t i, j, t;
    int16_t x, y, z;
    uint8_t temp;
    
    
    //uint8_t ir_value[0];
    uint8_t temp_IR[0];
    //uint8_t feld_IR[200];
    
    
    /*******************************************************************************/
    void readAllRegisters(void)
    {
        I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 0); // Start with register 0...
        I2CTWI_readBytes(I2C_RP6_BASE_ADR,RP6data, 31); // and read all 30 registers up to
        // register Number 29 !
    
        // Now we output the Data we have just read on the serial interface:
        writeString_P("\nREADING ALL RP6 REGISTERS:");
        uint8_t i = 0;
        for(i = 0; i < 31; i++)
        {
            if(i % 8 == 0)           // add some newline chars otherwise everything
                writeChar('\n');  // is printed on ONE single line...
            else
                writeString_P(" | ");
            writeChar('#');
            writeIntegerLength(i,DEC,2);
            writeChar(':');
            writeIntegerLength(RP6data[i],DEC,3);
        }
        writeChar('\n');
    }
    
    /***************************************************************************/
    
    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;
    }
    
    /******************************************************************/
    
    void I2C_requestedDataReady(uint8_t dataRequestID)
    {
        checkRP6Status(dataRequestID);
    }
    
    
    /********************hauptprogramm*****************************/
    
    int main(void)
    {
        initRP6Control();
        multiio_init();
        initLCD();
    //orientation_init();
    
        setLEDs(0b1111);
        mSleep(500);
        setLEDs(0b0000);
    
        I2CTWI_initMaster(100);
        I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
        I2CTWI_setRequestedDataReadyHandler(I2C_requestedDataReady);
        showScreenLCD(" RP6Control M32", " bake_suche_1", "", "");
        mSleep(1500);
        clearLCD();
        accuspannung();
        mSleep(1500);
        clearLCD();
    
        while(true)
        {
    
    
            setLEDs(0b0100);
    
            readAllRegisters();
    
            startStopwatch3();
            t=0;
    
            do
            {
                if(getStopwatch3() > 50)
                {
                    temp = read_IR_value();
    
                    if (temp !=0)
                    {
                        setMultiIOLED1(1);
                        setMultiIOLED1(0);
                        rotate(80, RIGHT, 5, false);
                        temp = read_IR_value();
                        if (temp == 0) stop(); //break;
                        if(bumper_left && bumper_right) //stop();//break;
                        {
                            stop();
    
    
                        }
    
                    }
                    temp = read_IR_value();
    
                    if (temp == 0)
                    {
                        x = getStopwatch3();
                        setMultiIOLED3(1);
                        setMultiIOLED3(0);
                        if (t<10)
                        {
                            t++;
    
                            if (t == 10)
                            {
                                y = getStopwatch3();
                                z = y-x;
    /*
                                writeInteger(x, DEC);
                                writeChar('\n');
                                writeInteger(y, DEC);
                                writeChar('\n');
                                writeInteger(z, DEC);
                                writeChar('\n');
    */
                                t=0;
                                setStopwatch3(0);
                                if (z< 600)
                                {
                                    move(100, FWD, DIST_MM(100), false);
                                    setStopwatch3(0);
                                    t=0;
                                    mSleep(400);
                                    task_checkINT0();
                                    task_I2CTWI();
                                    if(bumper_left && bumper_right)
                                    {
                                        stop();
    
                                    }
    
                                }
    
                            }
    
                        }
    
    
                    }
                }
    
                task_checkINT0();
                task_I2CTWI();
            }
            while(!bumper_left && !bumper_right);
            stop();
    
        }
    
    
        return 0;
    }
    hat damals funktioniert. Es ist nicht nur dieser code, der nicht geht, ich habe mehrere varianten ausprobiert, das verhalten des RP6 ist gleich:

    er ignoriert die abfrage des vorher eingelesenen (nicht vorhandenen) IR signals ( if (temp !=0)) , die rote multiIO LED blinkt, der RP6 dreht sich nicht und sucht, sondern fährt in den 10cm steps vor (die abfrage if (temp == 0 wird als wahr erkannt) , als hätte er IR empfangen. Die bake ist dabei außer betrieb. Die bake selber habe ich überprüft (oszi), sie sendet an der richtigen frequenz, wird auch - sporadisch - empfangen...

    woran kann das denn wieder liegen? Ich musste jetzt nachdenken, was ich an hardwareänderungen eingeführt hätte - außer der verbindung von dem pin2 des J_ADC zu der spule des ladegeräts - sonst nix...
    gruß inka

  4. #84
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hi inka,
    woran kann das denn wieder liegen?
    Ich denke nicht an ein Hardware-Problem.
    Leider habe ich das Problem, dass ich deinen Such-Code nicht ganz verstehe, und so auch nicht "mitdenken" kann.

    Ich habe mal die Haupt-Suchschleife auf das hier:
    Code:
        while(true)
        {
            startStopwatch3();
            t=0;
    
            do
            {
                if(getStopwatch3() > 50)
                {
                    temp = read_IR_value();
    
                    if (temp !=0)
                    {
                        // Rotiere RECHTS 5°
                        temp = read_IR_value();
                        if (temp == 0) stop(); //break;
                        if(bumper_left && bumper_right) //stop();//break;
                        {
                            stop();
                        }
    
                    }
                    temp = read_IR_value();
                    if (temp == 0)
                    {
                        x = getStopwatch3();
    
                        if (t<10)
                        {
                            t++;
    
                            if (t == 10)
                            {
                                y = getStopwatch3();
                                z = y-x;
                                t=0;
                                setStopwatch3(0);
                                if (z< 600)
                                {
                                    Fahre VORWÄRTS 10cm
                                    setStopwatch3(0);
                                    t=0;
                                    mSleep(400);
                                    task_checkINT0();
                                    task_I2CTWI();
                                    if(bumper_left && bumper_right)
                                    {
                                        stop();
    
                                    }
    
                                }
    
                            }
    
                        }
    
    
                    }
                }
    
                task_checkINT0();
                task_I2CTWI();
            }
            while(!bumper_left && !bumper_right);
    ... reduziert.
    Wenn ich das so sehe, stellen sich ein paar Fragen (quasi als Bemühen, das zu verstehen):

    1. 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!).

    2. 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.
    Da ich diesen Teil nicht verstehe, lasse ich das mal außen vor. Aber trotzdem stellen sich Fragen:
    a) 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.
    b) 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. 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.
    c) 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.
    d) 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: ???
    e) 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.

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

  5. #85
    Erfahrener Benutzer Robotik Einstein Avatar von inka
    Registriert seit
    29.10.2006
    Ort
    nahe Dresden
    Alter
    76
    Beiträge
    2.180
    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 ...
    gruß inka

  6. #86
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hi inka,
    habs versucht ...
    Ich auch ...

    1. Die Funktion:
    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;
    }
    ... tut nicht das, was sie soll.
    Wenn du sie im Programm mit temp = read_IR_value(); aufrufst, wird von der Funktion nicht der IR-Sensor-Wert zurückgegeben, sondern der Wert der (globalen) Variablen temp.
    Allerdings wird der IR-Sensor-Wert in der (ebenfalls globalen) Variablen temp_IR gespeichert, die im Programm als Array definiert ist.
    temp_IR[0] wird von dir aber nicht weiter benutzt.
    Die Funktion müßte so aussehen:
    Code:
    uint8_t read_IR_value(void)
    {
        uint8_t tmp = 0;
        I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 30); // Start with register 30
        I2CTWI_readBytes(I2C_RP6_BASE_ADR, tmp, 1);
        return tmp;
    }
    Dann kriegst du mit temp = read_IR_value(); den IR-Sensor-Wert in temp.

    2. Nochmal zur Hauptschleife:
    Code:
        while(true)
        {
    
            do
            {
    
                // Alles weitere ...
    
    
                task_checkINT0();
                task_I2CTWI();
            }
            while(!bumper_left && !bumper_right);
            stop();
    
        }
    ... und dem Problem, dass sie m.E. nicht funktioniert. Warum soll diese Schleife auf die Bumper reagieren? Teste das mal! Wird der Stop-Befehl erreicht, wenn du einen Bumper drückst?

    3.
    reflektionen, ansonsten siehe kommentare
    Ich kann nicht verstehen, warum durch eine Abfrage des IR-Empfängers rasch hintereinander im 50ms-Teil Reflektionen "erkannt" bzw. ausgeblendet werden können. In einem Raum können Lichtreflektionen durch ein einfaches GCC-Programm nicht berechnet/erkannt werden. Sie unterscheiden sich in der Laufzeit in einem Zimmer nur im Nanosekundenbereich.

    4. ... (so viel erstmal ...)
    Gruß
    Dirk

  7. #87
    Erfahrener Benutzer Robotik Einstein Avatar von inka
    Registriert seit
    29.10.2006
    Ort
    nahe Dresden
    Alter
    76
    Beiträge
    2.180
    Hi Dirk,
    Zitat Zitat von Dirk Beitrag anzeigen
    1. Die Funktion:
    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;
    }
    ... tut nicht das, was sie soll.
    Wenn du sie im Programm mit temp = read_IR_value(); aufrufst, wird von der Funktion nicht der IR-Sensor-Wert zurückgegeben, sondern der Wert der (globalen) Variablen temp.
    Allerdings wird der IR-Sensor-Wert in der (ebenfalls globalen) Variablen temp_IR gespeichert, die im Programm als Array definiert ist.
    temp_IR[0] wird von dir aber nicht weiter benutzt.
    Die Funktion müßte so aussehen:
    Code:
    uint8_t read_IR_value(void)
    {
        uint8_t tmp = 0;
        I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 30); // Start with register 30
        I2CTWI_readBytes(I2C_RP6_BASE_ADR, tmp, 1);
        return tmp;
    }
    Dann kriegst du mit temp = read_IR_value(); den IR-Sensor-Wert in temp.
    meinst Du hier evtl "tmp"? Verstehe ich das richtig: in der ursprünglichen version wurde nicht der aktuelle sensor-wert in "temp" geschrieben, sondern ein wert aus dem IR-array? Ich werde die geändert version testen...

    Zitat Zitat von Dirk Beitrag anzeigen
    2. Nochmal zur Hauptschleife:
    Code:
        while(true)
        {
    
            do
            {
    
                // Alles weitere ...
    
    
                task_checkINT0();
                task_I2CTWI();
            }
            while(!bumper_left && !bumper_right);
            stop();
    
        }
    ... und dem Problem, dass sie m.E. nicht funktioniert. Warum soll diese Schleife auf die Bumper reagieren? Teste das mal! Wird der Stop-Befehl erreicht, wenn du einen Bumper drückst?
    der stop-befehl wird erreicht, mit diesem, unverändertem

    Code:
    #include "RP6ControlLib.h"
    #include "RP6I2CmasterTWI.h"
    #include "RP6Control_MultiIOLib.h"
    #include "RP6Control_I2CMasterLib.h"
    #include "RP6Control_LFSBumperLib.h"
    #include "RP6ControlServoLib.h"
    #include "standard.h"
    
    #define I2C_RP6_BASE_ADR 10
    
    /******************variablen***************************/
    
    //uint8_t transmit_buffer[10];
    uint8_t RP6data[32];
    
    uint8_t i, j, t;
    int16_t x, y, z;
    uint8_t temp;
    
    
    //uint8_t ir_value[0];
    uint8_t temp_IR[0];
    //uint8_t feld_IR[200];
    
    
    /*******************************************************************************/
    void readAllRegisters(void)
    {
        I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 0); // Start with register 0...
        I2CTWI_readBytes(I2C_RP6_BASE_ADR,RP6data, 31); // and read all 30 registers up to
        // register Number 29 !
    
        // Now we output the Data we have just read on the serial interface:
        writeString_P("\nREADING ALL RP6 REGISTERS:");
        uint8_t i = 0;
        for(i = 0; i < 31; i++)
        {
            if(i % 8 == 0)           // add some newline chars otherwise everything
                writeChar('\n');  // is printed on ONE single line...
            else
                writeString_P(" | ");
            writeChar('#');
            writeIntegerLength(i,DEC,2);
            writeChar(':');
            writeIntegerLength(RP6data[i],DEC,3);
        }
        writeChar('\n');
    }
    
    /***************************************************************************/
    
    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;
    }
    
    /******************************************************************/
    
    void I2C_requestedDataReady(uint8_t dataRequestID)
    {
        checkRP6Status(dataRequestID);
    }
    
    
    /********************hauptprogramm*****************************/
    
    int main(void)
    {
        initRP6Control();
        multiio_init();
        initLCD();
    //orientation_init();
    
        setLEDs(0b1111);
        mSleep(500);
        setLEDs(0b0000);
    
        I2CTWI_initMaster(100);
        I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
        I2CTWI_setRequestedDataReadyHandler(I2C_requestedDataReady);
        showScreenLCD(" RP6Control M32", " bake_suche_1", "", "");
        mSleep(1500);
        clearLCD();
        accuspannung();
        mSleep(1500);
        clearLCD();
    
        while(true)
        {
    
    
            setLEDs(0b0100);
    
    
            startStopwatch3();
            t=0;
    
            do
            {
    //            readAllRegisters();
    
                if(getStopwatch3() > 50)
                {
                    temp = read_IR_value();
    
                    if (temp !=0)
                    {
                        setMultiIOLED1(1);
                        setMultiIOLED1(0);
                        rotate(80, RIGHT, 5, false);
                        temp = read_IR_value();
                        if (temp == 0) stop(); //break;
                        if(bumper_left && bumper_right) //stop();//break;
                        {
                            stop();
    
    
                        }
    
                    }
                    temp = read_IR_value();
    
                    if (temp == 0)
                    {
                        x = getStopwatch3();
                        setMultiIOLED3(1);
                        setMultiIOLED3(0);
                        if (t<10)
                        {
                            t++;
    
                            if (t == 10)
                            {
                                y = getStopwatch3();
                                z = y-x;
    /*
                                writeInteger(x, DEC);
                                writeChar('\n');
                                writeInteger(y, DEC);
                                writeChar('\n');
                                writeInteger(z, DEC);
                                writeChar('\n');
    */
                                t=0;
                                setStopwatch3(0);
                                if (z< 600)
                                {
                                    move(100, FWD, DIST_MM(100), false);
                                    setStopwatch3(0);
                                    t=0;
                                    mSleep(400);
                                    task_checkINT0();
                                    task_I2CTWI();
                                    if(bumper_left && bumper_right)
                                    {
                                        stop();
    
                                    }
    
                                }
    
                            }
    
                        }
    
    
                    }
                }
    
                task_checkINT0();
                task_I2CTWI();
            }
            while(!bumper_left && !bumper_right);
            stop();
    
        }
    
    
        return 0;
    }
    Zitat Zitat von Dirk Beitrag anzeigen
    3. Ich kann nicht verstehen, warum durch eine Abfrage des IR-Empfängers rasch hintereinander im 50ms-Teil Reflektionen "erkannt" bzw. ausgeblendet werden können. In einem Raum können Lichtreflektionen durch ein einfaches GCC-Programm nicht berechnet/erkannt werden. Sie unterscheiden sich in der Laufzeit in einem Zimmer nur im Nanosekundenbereich.
    das ist aber das ergebnis meiner versuche. Bei einer abfrage fur der RP ganz woanders gegen die wand, weil er dort die bake gesehen hat, bei 10x nacheinader hat er die richtige richtung gefunden. Nicht nur in einem raum, sondern an verschiedene stellen, sogar draussen...
    gruß inka

  8. #88
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hi inka,
    ich werde mich jetzt erstmal hier ein wenig ausklinken, obwohl ich dein Projekt weiterhin interessant finde.

    Davor aber noch kurz abschließend:
    Verstehe ich das richtig: in der ursprünglichen version wurde nicht der aktuelle sensor-wert in "temp" geschrieben, sondern ein wert aus dem IR-array?
    Nein, so nicht richtig (siehe mein letzter Post!).

    der stop-befehl wird erreicht, mit diesem, unverändertem (Code)
    Ich denke: Nein. Testen!!!

    das ist aber das ergebnis meiner versuche.
    Ich würde dir empfehlen, die Einzelfunktionen (IR-Abfrage, Bumper-Abfrage, Drehen bis IR erkannt, Geradeausfahrt...) getrennt voneinander zu schreiben und zu testen. Damit vermeidest du, dass du ein Gesamtsystem als erfolgreich testest, was im Detail noch ggf. Macken hat.
    Besonders die IR-Abfrage würde ich als eigenständige Task (Aufgabe) für die Hauptschleife schreiben: Diese Task gibt nur eine Variable für IR AN oder IR AUS aus und tut sonst nichts. Dabei ist es deine Festlegung, ob IR AN erst nach 10 identischen Abfragen im 50ms Abstand ausgegeben wird oder irgendwie anders.
    Gruß
    Dirk

  9. #89
    Erfahrener Benutzer Robotik Einstein Avatar von inka
    Registriert seit
    29.10.2006
    Ort
    nahe Dresden
    Alter
    76
    Beiträge
    2.180
    hallo Dirk,

    ich kann verstehen, dass Du Dich zurückziehst, die diskussion über meine software ist ein geeignetes mittel um leute zu vergraulen, ich werde es lassen...

    habe hier aber ein anderes problem:

    Zitat Zitat von Dirk Beitrag anzeigen
    ja, ich hatte da an eine Spannungsmessung am Ausgang der Spule bzw. zwischen Spule und Spannungswandler gedacht.
    Man könnte einen nicht genutzten ADC-Kanal der M32 (z.B. ADC_2) dafür nehmen. Der Eingang ist auf der MultiIO am J_ADC Jumperblock Pin "2".
    Man braucht dann noch einen Spannungsteiler aus 2 Widerständen, weil der ADC ja nur bis 5V messen kann (oder ist die Spannung da nicht höher?).
    die verbindung wurde so verlegt, es funktioniert auch, was mir beim ersten test nicht auffiel ist, dass beim erreichen der ladespannung am ausgang der empfängerspule (also ab start der ladung) die 4 roten LEDs der m32 schwach leuchten und beim LCD die hintergrundbeleuchtung auch schwach an ist (der bRP6 ist aus!). Ich weiss nicht warum das so ist. Ist das ein problem, oder nur ein unangenehmer nebeneffekt?

    Ich habe schon überlegt ob ich einen anderen freien ADC-kanal verwenden könnte, trotz wirklich sehr intensiver Suche gelang mir das nicht, es in der doku zu finden, welche ADCs noch frei sind und wo sie evtl. auf der multiIO herausgeführt sind...

    Im schaltplan der m32 ist nur der kanal 0 für micro und 1 für die taster als belegt angegeben, im RN wissen für IO-board fand ich außer zahlreichen hinweisen auf ADC nur noch das hier:
    ------------------
    Ähnlich wie im gerade genannten Fall ist es auch beim 10-poligen Wannenstecker SV_ADC_MXXX. Jedoch sind hier manche Pins (1, 3, 5 und 6) direkt auf einen Wähl-Jumper JP1,2,4 gelegt, wo sie mit Jumpern weiter auf Signale gelegt werden können. Nur Pin 6 ist nicht weitergeführt und steht zur eigenen Verfügung, ist jedoch nur bei dem M128-Modul als ADC verwendbar, auf allen anderen Modulen liegt hier GND an.
    ----------------
    und stehe nach wie vor aufm schlauch...

    wer hilft weiter?

    thanks
    gruß inka

  10. #90
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.05.2009
    Ort
    Berlin
    Beiträge
    450
    Hi inka,
    ich glaube nicht das Du auf der MIO einen freien ADC Port findest ohne auf irgend etwas verzichten zu müssen.
    Am Pin 6 der SV_ADC_MXXX liegt doch bei Verbindung mit der M32 GND an. Was wolltest Du denn da machen ?
    Was ist denn mit den ADC vom Basis Board hast Du die alle in Verwendung ?
    Gruß TrainMen

Seite 9 von 12 ErsteErste ... 7891011 ... LetzteLetzte

Ähnliche Themen

  1. RP6 - Projekt Notstromversorgung
    Von Dirk im Forum Robby RP6
    Antworten: 33
    Letzter Beitrag: 19.02.2015, 19:51
  2. Ladestation für RP6?
    Von TobeFFM im Forum Robby RP6
    Antworten: 26
    Letzter Beitrag: 26.11.2013, 16:38
  3. [Projekt]RP6 per Bluetooth flashen
    Von Fabian E. im Forum Robby RP6
    Antworten: 0
    Letzter Beitrag: 15.07.2011, 18:31
  4. RP6 remote controled Projekt
    Von mr.stroh im Forum Robby RP6
    Antworten: 4
    Letzter Beitrag: 17.11.2010, 08:06
  5. Antworten: 65
    Letzter Beitrag: 01.12.2007, 12:45

Berechtigungen

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

12V Akku bauen