- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: [Gelöst] NIBObee Linienverfolgung Testprogramm

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    15.12.2009
    Beiträge
    28

    [Gelöst] NIBObee Linienverfolgung Testprogramm

    Anzeige

    Praxistest und DIY Projekte
    Hallo,

    könnte mir vielleicht mal jemand für den NIBObee ein Linienverfolgungsprogramm geben, weil bei meinem Programm funktioniert es nicht und ich will sichergehen, dass es nicht am Programm liegt. Kann man die Liniensensoren noch irgendwie testen? Die IR-Dioden funktionieren beide.

    Viele Grüße,
    Manuel

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    22.05.2007
    Ort
    Stolberg
    Beiträge
    111
    Sind die Liniensensoren kalibriert?

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    15.12.2009
    Beiträge
    28
    Ja, Liniensensoren habe ich gestern nochmal kalibriert. Hier der Code dazu. Das ist eine Kalibrierung mit anschließender Linienverfolgung.

    Code:
    /*
    Ersteller: Frank Pelzhause
    Datum: 18.11.2009
    */
    
    /* Dieses Programm vereint eine Kombination aus Kalibrierung der Line Sensoren
    und ein Pr?fprogramm f?r die Fahrt ?ber eine Linie.
    Einige Hilfsfunktionen sind aus bestehenden Programmen ?bernommen,
    aber der Ablauf ist versuchsweise nur in dieser Datei hinterlegt.
    F?r weitere Verwendung k?nnen die Funktionen auch in einzelne Dateien
    und Headerdateien ausgelagert werden.
    Das Ganze ist nat?rlich ausbauf?hig.
    
    Eine Kurzbeschreibung der Funktionen ist immer am Anfang dokumentiert,
    weitere Informationen sind jeweils vor der Funktion beschrieben.
    
    Spezielle Anmerkungen sind inline Dokumentiert. */
    
    
    /* Ben?tigte Include Dateien */
    #include <nibobee/iodefs.h>          /* muss immer als erste Datei 
                        eingebunden werden */
    
    #include <nibobee/led.h>      /* LED Funktionen */
    #include <nibobee/delay.h>      /* Verz?gerungen, Includiert
                        die avr/delay.h
                        (achtung: Zusatzfunktionen) */
    #include <nibobee/sens.h>      /* Aktivierung der F?hler */
    #include <nibobee/analog.h>      /* ????? */
    #include <nibobee/line.h>      /* Liniensensoren (Infrarot vorne) */
    #include <nibobee/motpwm.h>     /* Motorsteuerung */
    
    /* Spezielle Includes, keine Ahnung warum (Kommentare erw?nscht) */
    
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include <util/delay.h> 
    
    /* Definieren der verschiedenen Modes,
    um die Folgereaktionen auswerten zu k?nnen */
    
    enum {
      MODE_KALIBRIEREN,
      MODE_DRIVE,
      MODE_LAUFLICHT,
    };
    
    
    /* Funktion um ein Lauflicht zu starten.
    Interuptsteuerung wird aktiviert, um auch w?hrend der Funktion
    reagieren zu k?nnen und ein Ereignis zur?ckzuliefern */
    
    uint8_t Lauflicht()
    {
      led_init();
      sens_init();
    
      while(1==1)
      {
        enable_interrupts();
        int ledNr;
        for (ledNr=0; ledNr<4; ledNr++)
        {
          led_set(ledNr, 1);
          delay(350);
          led_set(ledNr, 0);
          delay(150);
        }
        /* Test auf F?hlerbet?tigung */
        /* Wenn beide F?hler nach hinten gedr?ckt wurden
           wird ein Status MODE_KALIBRIEREN zur?ckgegeben
           Die F?hler m?ssen allerdings f?r eine ganze 
           Umdrehung der LEDs festgehalten werden, 
           da die Abfrage erst nach der For-Schleife erfolgt */
        if ((sens_getLeft()==-1) && (sens_getRight()==-1)) 
        {
          while ((sens_getLeft()==-1) && (sens_getRight()==-1)) {
            delay(1);
          }
          led_init();
          return MODE_KALIBRIEREN;
        } 
      }
      return 0;
    }
    
    
    /* Calibrierung */
    /*
      Hier werden die Linesensoren kalibriert.
      Die Werte werden in das EEPROM geschrieben, wenn der Befehl dazu gegeben wurde.
      - Ablauf der Kalibrierung:
        1. Linker F?hler nach hinten dr?cken: Wei?abgleich, Dazu Nibobee auf ein wei?es
          Blatt Papier stellen. Dioden blinken.
        2. Rechter F?hler nach hinten dr?cken: Schwarzabgleich, Dazu Nibobee auf ein schwarzes
          Blatt Papier stellen. Dioden blinken.
      3. Zum speichern der Daten beide F?hler nach Vorne dr?cken.
         Die Daten werden dann dauerhaft im EEPROM gespeichert. 
        Dioden Blinken abermals und das linienverfolgungsprogramm wird gestartet.
    */
    
    /* Deklarationen */
    void line_read_persistent();
    uint16_t line_get(uint8_t idx);
    void line_calibrate_white();
    void line_calibrate_black();
    
    /* Blinkfunktion */
    void do_blink(uint8_t mask) {
      for (int i=0; i<5; ++i) {
        led_set(LED_L_RD, mask&0x01);
        led_set(LED_R_RD, mask&0x01);
        led_set(LED_L_YE, mask&0x02);
        led_set(LED_R_YE, mask&0x02);
        delay(200);
        led_set(LED_L_RD, 0);
        led_set(LED_R_RD, 0);
        led_set(LED_L_YE, 0);
        led_set(LED_R_YE, 0);
        delay(200);
      }
    }
    
    /* Kalibrieren im eigentlichen Sinn. 
    Besonderheit: Erst nach bet?tigung Beider F?hler nach Vorne
    wird nach dem speichern in den Modus "Linienvervolgung umgeschaltet */
    
    uint8_t Kalibrieren() {
      led_init();
      motpwm_init();
      sens_init();
      analog_init();
      activate_output_bit(IO_LINE_EN);
    
      line_readPersistent();
    
      while(1==1) {                      // Endlosschleife (1==1 ist immer wahr!)
        enable_interrupts();
        delay(10);
    
    
        if (sens_getLeft()==-1) {
          while (sens_getLeft()==-1) delay(1); /* Linker F?hler nach hinten --> Wei?abgleich */
          line_calibrateWhite();
          do_blink(2);
        }
         
        if (sens_getRight()==-1) {
          while (sens_getRight()==-1) delay(1); /* Linker F?hler nach hinten --> Wei?abgleich */
          line_calibrateBlack();
          do_blink(1);
        }
    
        set_output_groupbitval(IO_LEDS, L_YE, line_get(LINE_L)>160);
        set_output_groupbitval(IO_LEDS, L_RD, line_get(LINE_L)>240);
        set_output_groupbitval(IO_LEDS, R_YE, line_get(LINE_R)>160);
        set_output_groupbitval(IO_LEDS, R_RD, line_get(LINE_R)>240);
    
        /* Beide F?hler nach vorne = Speichern der Werte und weiter
         zum Linienprogramm */
      if ((sens_getLeft()==1) && (sens_getRight()==1)) {
          while ((sens_getLeft()==1) && (sens_getRight()==1)) {
            delay(1);
          }
          line_writePersistent();
          do_blink(3);
        return MODE_DRIVE;
        }
    
      }
      return 0;
    }
    
    
    
    /* Linien fahren */
    /* Das Programm l?uft solange, bis beide F?hler nach hinten get?tigt werden, 
       dann wird die Kalibrierung wieder mit dem Lauflicht gestartet. */
    
    uint8_t run_line() 
    { 
      activate_output_group(IO_LEDS);  // LED bits als Output 
      sens_init();
      motpwm_init(); 
      motpwm_setLeft(0); 
      motpwm_setRight(0); 
      analog_init(); 
      line_readPersistent(); 
      set_output_group(IO_SENS);       // Pull-ups aktivieren 
      activate_output_bit(IO_LINE_EN); 
    
      int16_t speed_flt_l=0; 
      int16_t speed_flt_r=0; 
    
      // Countdown: LEDs blinken lassen 
      for (uint8_t i=0; i<5; ++i) { 
        led_set(LED_L_RD, 1); 
        led_set(LED_R_RD, 1); 
        _delay_ms(10); 
        led_set(LED_L_RD, 0); 
        led_set(LED_R_RD, 0); 
        _delay_ms(990); 
      } 
      led_set(LED_L_YE, 1); 
      led_set(LED_R_YE, 1); 
      _delay_ms(1000); 
      led_set(LED_L_YE, 0); 
      led_set(LED_R_YE, 0); 
    
      // Hauptschleife: 
      while(1) { 
      enable_interrupts(); /* F?hler aktivieren */
        sei(); 
        _delay_ms(1); 
        int16_t speed_l=0; 
        int16_t speed_r=0; 
    
        int16_t lval = line_get(LINE_L); 
        int16_t cval = line_get(LINE_C); 
        int16_t rval = line_get(LINE_R); 
    
        if (lval+cval+rval < 20) {
          led_set(LED_L_RD, 0);
          led_set(LED_R_RD, 0);
          speed_r=300, speed_l=300;
        } else if ((lval<cval) && (lval<rval)) {
          // lval is minimum
          led_set(LED_L_RD, 1);
          led_set(LED_R_RD, 0);
          speed_r=350, speed_l=250-1*(cval-lval);
        } else if ((rval<cval) && (rval<lval)) {
          // rval is minimum
          led_set(LED_L_RD, 0);
          led_set(LED_R_RD, 1);
          speed_r=250-1*(cval-rval), speed_l=450;
        } else {
          // cval is minimum
          led_set(LED_L_RD, 1);
          led_set(LED_R_RD, 1);
          speed_r=450 + 1*(rval-cval), speed_l=450 + 1*(lval-cval);
        } 
    
        speed_flt_l*=3; speed_flt_l+=speed_l; speed_flt_l/=4; 
        speed_flt_r*=3; speed_flt_r+=speed_r; speed_flt_r/=4; 
        
        motpwm_setLeft(speed_flt_l); 
        motpwm_setRight(speed_flt_r); 
    
        /* Wenn beide F?hler nach hinten gedr?ckt werden,
         wird wieder das Lauflicht aktiviert und eine erneute
         Kalibrierung kann erfolgen */
      if ((sens_getLeft()==-1) && (sens_getRight()==-1)) {
          while ((sens_getLeft()==-1) && (sens_getRight()==-1)) {
            delay(1);
          }
      int16_t speed_l=0; 
      int16_t speed_r=0; 
        motpwm_setLeft(speed_l); 
        motpwm_setRight(speed_r); 
      return MODE_LAUFLICHT;
        }
    
      } 
      return 0; 
    } 
    
    
    /* Hauptprogramm (main()) 
       Schlicht und einfach :-)) */
    
    uint8_t mode = MODE_LAUFLICHT;
    
    int main() {
      while(1==1) {
        enable_interrupts();
        delay(1);
        switch (mode) {
          case MODE_LAUFLICHT: mode = Lauflicht(); break;
          case MODE_KALIBRIEREN: mode = Kalibrieren(); break;
          case MODE_DRIVE: mode = run_line(); break;
        }
    
      }
    return 0;
    }
    Mit der mitgelieferten Kalibration funktioniert es auch nicht besser.

    Irgendwie hab ich das Gefühl, dass einer der Phototransistoren defekt ist. Kann man die irgendiwe einzeln testen?

    Viele Grüße,
    Manuel

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Das Beispielprogramm von workwind hast du sicher schon getestet:
    https://www.roboternetz.de/phpBB2/ze...=468642#468642

    Basis für alle Linienfunktionen ist eine richtige Kalibrierung der Sensoren:
    https://www.roboternetz.de/phpBB2/ze...ag.php?t=52430

    Mehr kann ich auf die Schnelle nicht sagen, ich bin grad etwas aus dem bee-Thema

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    22.05.2007
    Ort
    Stolberg
    Beiträge
    111
    Ich habe gerade ein Testprogramm für die Liniensensoren geschrieben. Mit dem Programm lassen sich alle drei Liniensensoren nach der Kalibrierung einzeln testen:
    Durch Berührung der Fühler kann man zwischen den Sensoren wechseln. Die Anzahl der leuchtenden Leds gibt den Reflexionswert an

    Code:
    #include <nibobee/iodefs.h>
    #include <nibobee/delay.h>
    #include <nibobee/led.h>
    #include <nibobee/sens.h>
    #include <nibobee/analog.h>
    #include <nibobee/line.h>
    
    void line_read_persistent();
    uint16_t line_get(uint8_t idx);
    void line_calibrate_white();
    void line_calibrate_black();
    
    void do_blink(uint8_t mask) {
      for (int i=0; i<5; ++i) {
        led_set(LED_L_YE, mask&0x01);
        led_set(LED_L_RD, mask&0x02);
        led_set(LED_R_RD, mask&0x04);
        led_set(LED_R_YE, mask&0x08);
        delay(200);
        led_set(LED_L_RD, 0);
        led_set(LED_R_RD, 0);
        led_set(LED_L_YE, 0);
        led_set(LED_R_YE, 0);
        delay(200);
      }
    }
    
    
    int main() {
      led_init();
      motpwm_init();
      sens_init();
      analog_init();
      activate_output_bit(IO_LINE_EN);
    
      uint8_t mode;
      
      while (1==1) {
        enable_interrupts();
        delay(10);
    
        if ((sens_getLeft()!=0) || (sens_getRight()!=0)) {
          while ((sens_getLeft()!=0) || (sens_getRight()!=0)) {
            // wait for release
            delay(1);
          }
          mode++;
          if (mode==3) {
    	mode=0;
          }
          switch (mode) {
            case 0:
    	  do_blink(0x03);
    	  break;
            case 1:
    	  do_blink(0x06);
    	  break;
            case 2:
    	  do_blink(0x0c);
    	  break;
          }
        }
    
        uint16_t val;    
    
        switch (mode) {
          case 0:
    	val = line_get(LINE_L); 
    	break;
          case 1:
    	val = line_get(LINE_C); 
    	break;
          case 2:
    	val = line_get(LINE_R); 
    	break;
        }
    
        set_output_groupbitval(IO_LEDS, L_YE, val>100);
        set_output_groupbitval(IO_LEDS, L_RD, val>200);
        set_output_groupbitval(IO_LEDS, R_RD, val>300);
        set_output_groupbitval(IO_LEDS, R_YE, val>400);    
    
      }
      return 0;
    }

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    15.12.2009
    Beiträge
    28
    Vielen Dank für das Testprogramm!

    Der rechte Phototransistor hatte anscheinend einen Wackelkontakt. Habe ihn jetzt mal nachgelötet und alles funktioniert wieder einwadfrei!

    Viele Grüße,
    Manuel

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    22.05.2007
    Ort
    Stolberg
    Beiträge
    111
    Ich habe das Testprogramm auf die Roboter.CC Seite kopiert, da kann man auch direkt das hex-File runterladen:
    http://www.roboter.cc/index.php?opti...t&projectid=95

  8. #8
    Hallo,

    seit kurzem NIBObee-Nutzer.

    versuche vieles auszuprobieren, aber dieser Programmcode läuft bei mir im AVR-Studio mit folgender Fehlermeldung:

    Build started 24.1.2012 at 19:58:28
    avr-gcc.exe -I"c:\programme\nibobeelib\include" -mmcu=atmega16 -Wall -gdwarf-2 -D_NIBOBEE_ -DF_CPU=15000000UL -Os -fsigned-char -MD -MP -MT linienfolger.o -MF dep/linienfolger.o.d -c ../linienfolger.c
    ../linienfolger.c: In function 'do_blink':
    ../linienfolger.c:110: error: 'for' loop initial declaration used outside C99 mode
    ../linienfolger.c: In function 'run_line':
    ../linienfolger.c:196: error: 'for' loop initial declaration used outside C99 mode
    make: *** [linienfolger.o] Error 1
    Build failed with 2 errors and 0 warnings...

    Wer kann mir helfen?Klicke auf die Grafik für eine größere Ansicht

Name:	Fehler.jpg
Hits:	6
Größe:	99,7 KB
ID:	21308

  9. #9
    Erfahrener Benutzer Roboter Experte Avatar von ePyx
    Registriert seit
    14.05.2008
    Ort
    Falkensee
    Beiträge
    700
    Ist ein Syntaxfehler. Bei dem definiertem C-Standard ist es nicht erlaubt die Laufvariable der for-Schleife erst im Schleifenkopf zu definieren. linienfolger.c Zeile 1xx gucken und umschreiben.

  10. #10
    jeder Versuch endet mit Fehlern

    Wie umschreiben?
    Hier das Original:

    /* Blinkfunktion */
    void do_blink(uint8_t mask) {
    for (int i=0; i<5; ++i) { ---------Line 110
    led_set(LED_L_RD, mask&0x01);
    led_set(LED_R_RD, mask&0x01);
    led_set(LED_L_YE, mask&0x02);
    led_set(LED_R_YE, mask&0x02);
    delay(200);
    led_set(LED_L_RD, 0);
    led_set(LED_R_RD, 0);
    led_set(LED_L_YE, 0);
    led_set(LED_R_YE, 0);
    delay(200);
    }

    Danke für die Hilfe

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests