hallo,

es ist schon erstaunlich mit was allem man in berührung kommt, wenn man "nur" eine ladestation finden will. IR, induktives laden, oszilloskop, jede menge anderer elektronik und software. Gut so. In diesem zusammenhang taucht jetzt die linienerkennung auf...

Der RP6 ist ja nicht "von natur aus" dafür gemacht, es gibt auch relativ wenig dazu im forum zu lesen - wenn ich da an den asuro denke Da waren viele unterwegs - stochri, waste, sterntaler, radbruch und, und und...

ich hab da ein beispiel gefunden, einfach irre:
Code:
/******************************************************************************* 
* 
* Description: Asuro Linienverfolgung mit PID-Regler 
* Version 1: Korrektur auf beide Motoren verteilt 
* Autor: Waste    26.8.05 
* 
*****************************************************************************/ 
#include "asuro.h" 
#include <stdlib.h> 
 
unsigned char speed; 
int speedLeft,speedRight; 
unsigned int lineData[2]; 
int x, xalt, don, doff, kp, kd, ki, yp, yd, yi, drest, y, y2, isum; 
 
void FollowLine (void) 
{ 
unsigned char leftDir = FWD, rightDir = FWD; 
    FrontLED(OFF); 
    LineData(lineData);                        // Messung mit LED OFF 
    doff = (lineData[0] - lineData[1]);    // zur Kompensation des Umgebungslicht 
    FrontLED(ON); 
    LineData(lineData);                        // Messung mit LED ON 
    don = (lineData[0] - lineData[1]);     
    x = don - doff;                        // Regelabweichung 
    isum += x; 
    if (isum > 16000) isum =16000;            //Begrenzung um Überlauf zu vermeiden 
    if (isum < -16000) isum =-16000; 
    yi = isum/625 * ki;                    //I-Anteil berechnen 
    yd = (x - xalt)*kd;                    // D-Anteil berechnen und mit 
    yd += drest;                            // nicht berücksichtigtem Rest addieren 
    if (yd > 255) drest = yd - 255;        // merke Rest 
    else if (yd < -255) drest = yd + 255; 
    else drest = 0; 
    if (isum > 15000) BackLED(OFF,ON);    // nur zur Diagnostik 
    else if (isum < -15000) BackLED(ON,OFF); 
    else BackLED(OFF,OFF); 
    yp = x*kp;                                // P-Anteil berechnen 
    y = yp + yi + yd;                        // Gesamtkorrektur 
    y2 = y/2;                                // Aufteilung auf beide Motoren 
    xalt = x;                                // x merken 
    speedLeft = speedRight = speed; 
    MotorDir(FWD,FWD); 
    if ( y > 0) {                            // nach rechts 
        StatusLED(GREEN); 
        speedLeft = speed + y2;            // links beschleunigen 
        if (speedLeft > 255) { 
            speedLeft = 255;                // falls Begrenzung 
            y2 = speedLeft - speed;        // dann Rest rechts berücksichtigen 
        } 
        y = y - y2; 
        speedRight = speed - y;            // rechts abbremsen 
        if (speedRight < 0) { 
            speedRight = 0; 
        } 
    } 
    if ( y < 0) {                            // nach links 
        StatusLED(RED); 
        speedRight = speed - y2;            // rechts beschleunigen 
        if (speedRight > 255) { 
            speedRight = 255;                // falls Begrenzung 
            y2 = speed - speedRight;        // dann Rest links berücksichtigen 
        } 
        y = y - y2; 
        speedLeft = speed + y;                // links abbremsen 
        if (speedLeft < 0) { 
            speedLeft = 0; 
        } 
    } 
    leftDir = rightDir = FWD; 
    if (speedLeft < 20)  leftDir = BREAK; // richtig bremsen 
    if (speedRight < 20) rightDir = BREAK;  
    MotorDir(leftDir,rightDir); 
    MotorSpeed(abs(speedLeft),abs(speedRight)); 
} 
 
int main(void) 
{ 
unsigned char sw; 
    Init(); 
    MotorDir(FWD,FWD); 
    StatusLED(GREEN); 
    speed = 150; 
    kp = 3; ki = 10; kd = 70;        // Regler Parameter kd enthält bereits Division durch dt 
    sw = PollSwitch(); 
    if (sw & 0x01) 
        {ki=20;} 
    if (sw & 0x02) 
        {speed = 200;} 
    if (sw & 0x04) 
        speed = 100; 
    if (sw & 0x08) 
        kd = 35; 
    if (sw & 0x10) 
        kd = 70; 
    if (sw & 0x20) 
        kd = 140; 
    FrontLED(ON); 
    LineData(lineData); 
    speedLeft = speedRight = speed; 
    while(1){ 
        FollowLine(); 
    } 
    return 0; 
}
ich will es um gottes willen nicht nachbauen, bzw. für den RP6 umschreiben - dazu wäre ich garnicht in der lage. Aber wenn man bedenkt wieviel hirnschmalz dahintersteckt....

aber zur realität wieder zurück. Ich habe ein viel einfacheres beispiel angefangen, das linienfolgemodul muss ja genutzt werden!

das hier gibt nur die werte der Vishay-sensoren aus. Trotz der enormen speed von 20links/20rechts geht das aber so schnell, dass ich die zeile mit dem move befehl lieber auskommentiert habe und schiebe und drehe von hand um zu erkennen, was da passiert:
Code:
                while(true)
                {
//                    moveAtSpeed(20, 20);

                        setCursorPosLCD(0, 0);
                        writeStringLCD(" li      mi      re  ");
                        setCursorPosLCD(1, 0);
                        lfs_l = getLFS(CH_LFS_L);
                        writeIntegerLCD(lfs_l, DEC);
                        setCursorPosLCD(1, 8);
                        lfs_m = getLFS(CH_LFS_M);
                        writeIntegerLCD(lfs_m, DEC);
                        setCursorPosLCD(1, 16);
                        lfs_r = getLFS(CH_LFS_R);
                        writeIntegerLCD(lfs_r, DEC);
                        mSleep(500);

                        setCursorPosLCD(2, 0);
                        lfs_l = getLFS(CH_LFS_L);
                        writeIntegerLCD(lfs_l, DEC);
                        setCursorPosLCD(2, 8);
                        lfs_m = getLFS(CH_LFS_M);
                        writeIntegerLCD(lfs_m, DEC);
                        setCursorPosLCD(2, 16);
                        lfs_r = getLFS(CH_LFS_R);
                        writeIntegerLCD(lfs_r, DEC);
                        mSleep(500);

                        setCursorPosLCD(3, 0);
                        lfs_l = getLFS(CH_LFS_L);
                        writeIntegerLCD(lfs_l, DEC);
                        setCursorPosLCD(3, 8);
                        lfs_m = getLFS(CH_LFS_M);
                        writeIntegerLCD(lfs_m, DEC);
                        setCursorPosLCD(3, 16);
                        lfs_r = getLFS(CH_LFS_R);
                        writeIntegerLCD(lfs_r, DEC);
                        mSleep(500);

                        clearLCD();

                        setStopwatch1(0);
                   }
das hier geht schon weiter. mit zwei aufeinanderfolgenden if-abfragen der lfs-werte, deren vergleich - letztendlich kommt es ja "nur" drauf an, die differenz möglichst klein zu halten (abgestuft wäre natürlich besser!)....
Code:
                while(true)
                {
                    if(getStopwatch3() > 500) // 0.5s
                    {
                        moveAtSpeed(20, 20);

                        lfs_l = getLFS(CH_LFS_L);
                        lfs_m = getLFS(CH_LFS_M);
                        lfs_r = getLFS(CH_LFS_R);

                        clearLCD();
//                        for (i = 0; i < 10; i++)
//                        {
                        if(lfs_r > lfs_l)
                        {
                            lfs_l = getLFS(CH_LFS_L);
                            lfs_m = getLFS(CH_LFS_M);
                            lfs_r = getLFS(CH_LFS_R);

                            if(lfs_r > lfs_l)
                            {
                                moveAtSpeed(00, 40);
                                setbumperLEDR(1);
//                            mSleep(100);                        // Left bumper LED on
                                setbumperLEDL(0);
                            }
                        }

                        if(lfs_l > lfs_r)
                        {
                            lfs_l = getLFS(CH_LFS_L);
                            lfs_m = getLFS(CH_LFS_M);
                            lfs_r = getLFS(CH_LFS_R);

                            if(lfs_l > lfs_r)
                            {
                                moveAtSpeed(40, 00);
                                setbumperLEDL(1);                        // right bumper LED on
//                            mSleep(100);
                                setbumperLEDR(0);
                            }
                        }
//                        }
                        setStopwatch3(0);

                    }
                }
ich bin nicht der typ, der für sich allein herumtüftelt, ich brauche eine "umgebung" und austausch, es gibt ja hier ein paar, die das liniensuchboard der multi IO haben, hätte da jemand lust (und zeit)?

in dem zweiten beispiel frage ich z.b. auch den wert des mittleren sensors ab, benutze aber für das abfahren der linie nur die beiden äußeren. Würde sicher sinn machen den mittleren auch einzubinden, hat das z.b. schon jemand gemacht? Wie wäre die überlegung für die realisierung?