- Labornetzteil AliExpress         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: Linienverfolgung... brauche hilfe

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    23.04.2009
    Beiträge
    13

    Linienverfolgung... brauche hilfe

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hey ihr ich hab mich mal rangesetzt um ein linienverfolgungsprogramm zu schreiben bei dem man auch abbiegen kann (sollte )

    Ich hab mir echt mühe gegeben bin aber noch anfänger deswegen können und sind auch noch einige fehler drin
    könnt ihr mir pls etwas helefn damit ich es zum laufen bekomme?

    Ich erkläre mal kurz wie ich mir es vorgestellt habe:
    Der asuro wird auf eine schwarze linie gesetzt, die er dann nachfährt bis er zu einer unterbrechung ,eine weiße fläche, der linie kommt.
    Hier wartet er auf einen befehl entweder "a" oder "d".
    bei a soll er sich links an der linie orientieren bei d dementsprechend rechts.
    nun soll er also halb auf der linie fahren.
    beim linksabbiegen sieht es also so aus, dass der linke sensor über weißem boden und der rechte über schwarzem ist.
    falls der linke sensor zu dunkel wird gibt er rechts mehr gas und wenn der rechts sensor zu hell wird gibt er links mehr gas
    das macht er nun bis er wieder zu einer unterbrechung kommt (noch nicht umgesetzt) und dann fährt er wieder normal auf der schwarzen linie.

    hoffe ihr könnt meine gedanken nachvollziehen und mir tipss geben denn so wie das programm im moment ist, läuft es nicht bzw. kann ich es nicht in eine hex datei verwandeln

    ich danke euch schonmal im vorraus

    Code:
    #include "asuro.h"
    
    
    #define SPEED  0x8F
    #define LEFT_KEY  'a'   // a links abbiegen
    #define RIGHT_KEY 'd'   // d rechts abbiegen
    
    int speedLeft,speedRight;
    unsigned int lineData[2];
    int ADOffset;
    
    
    
    void LineLeft (void)    // Links von der Linie
    {
      speedLeft  += 1;      //dann links mehr Gas geben
      if (speedLeft > 0xFE) speedLeft = 0xFF;
    }
    
    void LineRight (void)   //Rechts von der Linie
    {
      speedRight  += 1;     //dann rechts mehr Gas geben
      if (speedRight > 0xFE) speedRight = 0xFF;
    }
    
    
    void ASStop(void)  // ASURO hält an
    {
    	speedRight = speedLeft = 0;
    	FrontLED(OFF);
    	BackLED(OFF,OFF);
    }
    
    void TurnRight(void) // Asuro biegt rechts ab
    {
    
      
      GoTurn(4,0,100);
      LineData(lineData);
    
     
    
        if (lineData[0] > 200) // 200 ist geschätzt!!! ASURO ist zu weit rechts, also muss er rechts schneller
        {
          StatusLED(GREEN);
          LineRight();
        }
        else if ( lineData[1] < 300) // 300 ist geschätzt!!! ASURO ist zu weit links er muss links schneller
        {
          StatusLED(RED);
          LineLeft();
        }
        else
        {
          StatusLED(OFF);
          speedLeft = speedRight = SPEED;
        }
        MotorSpeed(speedLeft,speedRight);
      
    
    }
    
    
    
    void TurnLeft(void) // Asuro biegt links ab
    {
    
      
      GoTurn(4,0,100);
      LineData(lineData);
    
        if (lineData[1] > 200) // 200 ist geschätzt!!! ASURO ist zu weit links, also muss er links schneller
        {
          StatusLED(GREEN);
          LineLeft();
        }
        else if ( lineData[0] < 300) // 300 ist geschätzt!!! ASURO ist zu weit rechts er muss rechts schneller
        {
          StatusLED(RED);
          LineRight();
        }
        else
        {
          StatusLED(OFF);
          speedLeft = speedRight = SPEED;
        }
        MotorSpeed(speedLeft,speedRight);
      
    
    }
    
    
    
    
    int main(void)
    {
      Init();  
    				// Variablen deklarieren
      int i;
      unsigned char j;
      unsigned char cmd;
    
    
    
      FrontLED(ON);
      for (j = 0; j < 0xFF; j++) LineData(lineData);
      LineData(lineData);
      ADOffset = lineData[0] - lineData[1];
      speedLeft = speedRight = SPEED;
    
    
        
    
      while (1) // die ganze Zeit 
      {
    
        LineData(lineData);
    
    	if (LineData[0] > 800 && LineData[1] > 800)  // Wenn der ASURO über weißem Grund ist...
    	{ 
    	ASStop();   // ...dann anhalten und auf Knopfdruck warten...
    				// hier könnte ein Fehler sein, da der ASURO nur über weißem Boden kurz waretn würde und dann normal weiterläuft
    	cmd = 0;
    	switch (cmd)
    	{ 
    	case LEFT_KEY : TurnLeft(); break;  // Wenn 4 dann links halten
    	case RIGHT_KEY : TurnRight(); break; // Wenn 6 dann rechts halten
    	}
    	}
    
    
    
    	else 
    	{   								// Normale Linienverfolgung
        i = (lineData[0] - lineData[1]) - ADOffset;
        if ( i > 4)
        {
          StatusLED(GREEN);
          LineLeft();
        }
        else if ( i < -4)
        {
          StatusLED(RED);
          LineRight();
        }
        else
        {
          StatusLED(OFF);
          speedLeft = speedRight = SPEED;
        }
    
    
        MotorSpeed(speedLeft,speedRight);  
        
      
      }
      return 0;
    }

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    für das abbiegen hätte ich nen tipp, lass denasuro einfach ein stück weiter fahren, so dass er in etwa mit der antriebsachse auf dem feld steht, dann lässt du ihn mit gegenläufigen motoren rotiern und erwartest einfach folgende helligkeitswechsel
    (links abbiegen z.B.)
    links dunkel, rechts dunkel
    links hell, rechts dunkel
    links hell, rechts hell
    links dunkel, rechts hell (rotationsgeschwindigkeit verringern)
    links dunkel, rechts dunkel

    und fährst dann einfach weiter

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    01.03.2008
    Ort
    Niederlanden
    Beiträge
    1.170
    Bei jeder while-Schleife durchgang, gleich fur den switch(cmd), wird cmd immer auf 0 gesetzt. Weil du keine andere Funktion verwendet hast um cmd 'a' oder 'b' zu machen wird er da immer weiter fahren. Wie bekommst deine Asuro den 'a' oder 'b' zeichen/'wert'? Uber IR oder wird einer seiner taster angeprellt? Ich sehe keine Pollswitch, oder SerRead oder ähnliche funktion dafur verwendet.

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    23.04.2009
    Beiträge
    13
    hi leute
    ich bin echt am verzweifeln hab nur noch eine woche und es klappt einfach nicht wie ich es möchte...

    hab das Programm von oben um einiges erleichtert...denke ich

    aber es funktioniert immernoch nicht

    ich habe es jetzt mit dem SerRead gemacht aber ich verstehe nicht genau wie das funktioniert, kann mir da jemand pls helfen
    die funktion heißt ja:
    SerRead(&cmd,1,0xFFFE);
    was bedeutet hier das &cmd und das 0xFFFE?

    und wenn der knopf auf der tastatur gedrückt wurde, soll der asuro ja die ganze zeit dieentsprechende funktion ausführen, muss ich da dann noch eine while schleife reinbauen, denn sonst macht er die funktion ja nur einmal bis das nächste zeichen kommt

    und was für werte soll ich für hell bzw. für dunkel einstellen
    was für zahlen ungefähr? also ist 100 noch einigermaßen hell oder schon dunkel

    hier nochmal der neue code, bitte bitte helft mir

    Code:
    #include "asuro.h"
    #include "asuro.c"
    #include <stdlib.h>
    
    #define SPEED  0x8F
    #define LEFT_KEY  'a'   // a links abbiegen
    #define MIDDLE_KEY 's'  // s mittig halten
    #define RIGHT_KEY 'd'   // d rechts abbiegen
    
    
    
    unsigned int data[2];
    
    volatile unsigned char switchPressed;
    
    
    SIGNAL (SIG_INTERRUPT1)
    {
    	unsigned int i;
    
    	DDRD |= SWITCHES;				// Switches as Output
    	SWITCH_ON;						// Output HIGH for measurement
    	ADMUX = (1 << REFS0) | SWITCH;	// AVCC reference with external capacitor
    	for (i = 0; i < 0xFE; i++);
    
    	ADCSRA |= (1 << ADSC);			// Start conversion
    	while (!(ADCSRA & (1 << ADIF)));	// wait for conversion complete
    	ADCSRA |= (1 << ADIF);			// clear ADCIF
    	i = ADCL + (ADCH << 8);
    
    	// und ab gehts --- fahr zurück
    	MotorDir(RWD,RWD);
    	MotorSpeed(200,200);
    	FrontLED(ON);
    	BackLED(ON,ON);
    	for (i = 0; i < 0xFFFD; i++);   // Sleep does not work here
    
    	switchPressed = TRUE;
    	SWITCH_OFF;
    	DDRD &= ~SWITCHES;					// Switches as Input => ext. Int 1 
    }
    
    
    
    
    
    
    void TurnRight(void) // Asuro orientiert sich rechts
    {
    
    
       LineData(data);
    
        if (data[0] > 100) // 300 ist geschätzt!!! ASURO ist zu weit rechts, also muss er rechts schneller
        {
          StatusLED(GREEN);  //green
          MotorSpeed(80,130);      // rechts mehr Gas geben!
        }
    
        if ( data[1] < 200) // 500 ist geschätzt!!! ASURO ist zu weit links er muss links schneller
        {
          StatusLED(RED);   //red
          MotorSpeed(130,80); 
        }
    
        else
        {
         MotorSpeed(100,100);
    
    	}
    
    }
    
    
    
    void TurnLeft(void) // Asuro orientiert sich links
    {
    
    
         LineData(data);
    
        if (data[1] > 100) // 300 ist geschätzt!!! ASURO ist zu weit links, also muss er links schneller
        {
          StatusLED(GREEN);  // green
          MotorSpeed(130,80);      // links mehr Gas geben!
        }
    
        if ( data[0] < 200) // 500 ist geschätzt!!! ASURO ist zu weit rechts er muss rechts schneller
        {
          StatusLED(RED);  //red
          MotorSpeed(80,130); 
        }
    
        else
        {
         MotorSpeed(100,100);
    
    	}
      
    
    }
    
    
    void DarkLine(void)  //normale Linienverfolgung
    {
    
    
    
        LineData(data); 
    
    
    	if (data [0] > data [1] ) // links heller als rechts...
    	{
    	MotorSpeed(130,80);	// ... dann links mehr Gas geben...
    	} 					
    
    
    	else
    	{
    	MotorSpeed(80,130);	// ... sonst rechts mehr Gas geben!
    	} 	
      					
        
    }
    
    
    
    
    int main(void)
    {
    	
        unsigned char cmd;
    	unsigned char cmdold;
    
    	MotorDir(FWD,FWD);
    	Init();
    	FrontLED(ON);
    	StartSwitch();
    	sei();
    	while (1)
      {
     
    		 // cmd = 0;	
    		SerRead(&cmd,1,0xFFFE);
    
    		cmdold = cmd;
    		switch (cmdold) 
         {
    
    		case LEFT_KEY : TurnLeft(); break;  // Wenn a dann links halten
    		case MIDDLE_KEY : DarkLine(); break; // wenn s dann mittig halten
    		case RIGHT_KEY : TurnRight(); break; // Wenn d dann rechts halten	
    	 }
    
    	 
    	
    
    
      }
     
    return 0;
    }

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    01.03.2008
    Ort
    Niederlanden
    Beiträge
    1.170
    Ich sehe du hast Init(); hinter den anruf von Motorspeed(,). Und den interupt funktion ( SIGNAL (SIG_INTERRUPT1) ) ist sehr langweilig mit viele for-warte schleifen. Den interupt sol nur bemerken das einer taste eingedruckt is, und das in einer globalen (volatile) variabele speichern. Aber das motor-commando und led anschalten an den main oder andere funktion uberlassen. Interupts mussen schnell sein!

    [edit]Die interupt fur der 'taster'-pin hat auch einer hohere prioritat als den timer interupt. Weil deine 'taster'-interupt so lange dauert wird die timer-interupt solange nicht ausgefurt. Deswegen wirkt den sleep funktion nicht.

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    23.04.2009
    Beiträge
    13
    ja ich hab das einfach nur reinkopiert
    ich weiß nicht genau was der macht aber das ist ja auch nicht das problem

    ich möchte eher wissen wie eine funktion z.b. die TurnLeft-Funktion solange hintereinander ausgeführt wird, bis ein neues Zeichen über den Transceiver gesendet wird
    sonst läuft sie ja nur einmal oder?

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    01.03.2008
    Ort
    Niederlanden
    Beiträge
    1.170
    Mit interupts spielen ist nicht sehr ge-eignet fur anfanger. Wenn du das bestimmt braucht wurde ich dich den erweiterten lib emphelen. Da ist schon einer taster eingebaut. Aber vielleicht auch nicht empholen wenn du nur einer woche dafur hast.

    Den parameter fur SerRead stehen doch in dem anleitung? Aber den "&cmd" und "0xFFFE" sind etwas ungewöhn. Den & ist ein spezielles zeichen in dem C-sprache womit den speicher-platz von dem cmd variabele ubermittelt wird, und nicht den inhalt von cmd. Ein zeichenketten besteht manchmahl aus mehr bytes dan einer solcher 'zeiger' (pointer im englisch) und ist damit nicht so effizient. Ein zeiger ist nur ein wenig bytes gross.

    0xFFFE ist den 'time-out' wert. Also den anzahl von zeichen er wartet bis den funktion endet, ob genug zeichen emphangen sind oder nicht. Den 1 war die gewunschte lange den zeichenketten, also ist nur ein zeichen gewunscht. Den FFFE is einer hexadezimale nummer, gleich an 65534 decimahl. Das sind 655340 bits der den USART (serielen port) abwartet. Mit nur 2400 bits pro sekunde wirt das also 4,5 minuten warten. Wiso denn so lange? Mit 1 statt xFFFE mus es besser gehen.

    Mit den while-schleife wird das emphangen einer zeichen und das 'switch'-en zwischen TurnLeft, DarkLine oder TurnRight sehr schnell wiederholt. Naja, nur mit einer viel kleinere timeout-wert im SerRead. Den TurnLeft/Right und Darkline messen nur den liniehelligkeiten und andern den motorkraft. Das dauert nur ein wenig zeit. Sehr oftes wechseln der motorkraft konnte fehlerhaft sein fur den elektronic auf dauer. Deshalb konntest du später (wenn das program klappt) einer verzögerung einbauen im TurnLeft, TurnRight und DarkLine mit Sleep. Aber nur einiger milisekunden.

    Aber was er in diesen TurnLeft/Right funktionen tun soll verstehen ich nicht. Was meinst du genau mit links oder rechts orientieren?

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    23.04.2009
    Beiträge
    13
    ok schonmal danke dass du mir hilfst!!!

    Der ASURO soll auf einer schwarzen Linie entlang fahren, auf der es Verzweigungen der Strecke gibt.
    Wenn ich dann eine Taste auf der Tastatur drücke soll sich der asuro rechts bzw- links orientieren.
    Das Bedeutet, dass die rechte LED über weißem Boden und die linke über schwarzem boden sein soll. dies wäre bei rechts orientieren der Fall

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    01.03.2008
    Ort
    Niederlanden
    Beiträge
    1.170
    Die rechten und linkem 'led' ist keiner LED. Das sind verkleideten (photo)transistoren. Die arbeiten komplet anders.

    Achso, du meinst den rand einer flache, und nicht eine linie. Ob das mit deine If regeln so geht weiss ich nicht genau. Jedenfals haben die beiden fototransistoren unterschiedliche licht/spannung kurven. Den linken und rechter site muss man erst abstimmen mit einander. Damit er nicht immer zu einer seite gezogen wird. Nur schätzten von den wert konnte viel zeit kosten bis es gut ist. Besser ist es die werten zu messen und mit SerWrite zuruck zu senden. Leider muss den wert in einzelne zeichen ubersetzt werden. Sonnst ist das nicht lessbar.

    Das mit den switch und cmd wiederholung wird schon gut gehen. Nur eine kleine timeout wert im SerRead setzen. Ein 0 wird es auch blockieren. Schau das mal asuro.c an.

    Edit: Etwas mehr uber das "&" zeichen... es wird fur mehrere zwecken gebraucht in dem c-sprache. Nicht nur die zeiger. Es ist auch einer logische operator. Einer einzelne "&" ist einer UND operation auf jeder bit. Einer doppelte ("&&") is eine logische UND operation. Aber in deine beispiel war das die adresse von cmd.

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    23.04.2009
    Beiträge
    13
    hmmm ob ich das schaffe...

    was meinst du mit rand einer flache?

    der asuro soll schon auf einer ganz normalen linie fahren

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test