-         

Ergebnis 1 bis 6 von 6

Thema: Encoder / Endlosdrehknopf in eine Richtung sehr ungenau

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    30.08.2006
    Ort
    Frankfurt
    Alter
    26
    Beiträge
    62

    Encoder / Endlosdrehknopf in eine Richtung sehr ungenau

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Hiho,

    ich hab seit längerem den Encoder von Pollin (Best.Nr. 240 313) hier rumliegen. Vorgestern hab ich den dann an meinen RP6 angeschlossen.

    Gestern hab ich dann das Programm zum Auswerten der Drehrichtung fertig bekommen. Aber es ist ungenau.

    Hier mal ein Ausschnitt aus dem Log:
    Rechtsdrehung mit ca. 1 Raster / 500ms
    Code:
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Linksrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Rechtsrum
    Sieht soweit ja ganz gut aus. Das eine ma falsch nehm ich in kauf.
    Jetzt Linksrum:
    Code:
    Linksrum
    Linksrum
    Rechtsrum
    Linksrum
    Linksrum
    Rechtsrum
    Linksrum
    Linksrum
    Rechtsrum
    Linksrum
    Linksrum
    Rechtsrum
    Linksrum
    Linksrum
    Linksrum
    Linksrum
    Linksrum
    Linksrum
    Rechtsrum
    Linksrum
    Linksrum
    Linksrum
    Linksrum
    Das wiederrum find ich net so gut.

    Hier mein Code
    Code:
    #include "RP6ControlLib.h"
    
    int main(void)
    {
    	initRP6Control(); 
    
    	writeString_P("\n\nEncoder Testing\n"); 
    
    	// Play two sounds:
    	sound(180,80,25);
    	sound(220,80,25);
    
    	setLEDs(0b1111);  // Turn all LEDs on!
    	initLCD();
    	showScreenLCD("################", "################");
    	mSleep(500);
    	showScreenLCD("Encoder Testing", "");
    	mSleep(1000);
       
       DDRD &= ~IO_PD6; //PD6 als Eingang
       DDRC &= ~IO_PC2; //PC2 als Eingang
       
       
    	setLEDs(0b0000); // All LEDs off!
       
       uint8_t laststate = 0b111;
       
       while(true) {
          
          // Encoder auswerten
          
          if(((PIND & IO_PD6) == 0b0) & ((PINC & IO_PC2) == 0b100) & (laststate != 0b01)) {
             laststate = 0b01;
          }
          
          if(((PIND & IO_PD6) == 0b1000000) & ((PINC & IO_PC2) == 0b100) & (laststate != 0b11)) {
             if(laststate == 0b01) {
                writeString_P("Rechtsrum\n");
                laststate = 0b111; 
             } else if(laststate == 0b10) {
                writeString_P("Linksrum\n");
                laststate = 0b111;
             } else {
             laststate = 0b11;
             }
          }
          
          
          if(((PIND & IO_PD6) == 0b1000000) & ((PINC & IO_PC2) == 0b0) & (laststate != 0b10)) {
             laststate = 0b10;
          }
          
          
          if(((PIND & IO_PD6) == 0b0) & ((PINC & IO_PC2) == 0b0) & (laststate != 0b00)) {
             if(laststate == 0b10) {
                writeString_P("Rechtsrum\n");
                laststate = 0b111;
             } else if(laststate == 0b01) {
                writeString_P("Linksrum\n");
                laststate = 0b111;
             } else {
             laststate = 0b00;
             }
          }
          
       }
    	return 0;
    }
    Der Encoder gibt bei einer Rastung zwei Zustände von sich.
    Und jeweils zwei verschiedene Zustände für jede Richtung.
    Das lässt sich mit zwei Bit am besten Darstellen. Bit1 = PD6 | Bit2 = PC2
    Zustand1 - Zustand2 bei einer Rastung.
    1-Rechts: 01 - 11
    2-Rechts: 10 - 00

    1-Links: 10 - 11
    2-Links: 01 - 00

    Soviel zur Funktion des Encoders.

    Ich bin mir nicht sicher ob das an meinem Programm oder am Encoder liegt.
    Vielleicht kann man noch etwas verbessern / verändern. Bin für alles offen.

    Gruß
    Spanky

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Pass' bei den "IF"s auf.
    Code:
    if ((trallala == 1) && (hoppsassa == 1) )   //    && statt & !!!! 
    {
    }
    etc.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    30.08.2006
    Ort
    Frankfurt
    Alter
    26
    Beiträge
    62
    Danke
    Ich hab mal Visual Basic gelernt. Da war das nur mit einem &

    Habs jetzt geändert. Problem besteht weiterhin.
    Ich vermute, das es am Encoder liegt, weils eben nur in eine Richtung so schlecht ist ...

    Wenn noch einer ne Idee hat ...
    Ansonsten muss ich mich halt damit abfinden.

    BTW: Ist es normal das ich die Pins mit GND auf Low ziehen muss und nicht mit VCC auf High?

    Gruß
    Spanky

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    --> BTW: Es geht beides. Da aber ein Mega eingebaute PullupWiderstände hat, wird gerne A, B auf zwei Pins gelegt, C auf GND.
    (auf A u.B ev. noch zwei Kondensatoren 0.01 µF gegen GND, wegen entprellen)
    Dann die Pullups für die Pins aufgedreht, Pins auf Input (logo) und sonst braucht man eigentlich nix.
    Im Datenblatt gibt einen "TestCircuit", den kannst du natürlich auch nehmen, braucht aber eben extra Pullups.
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beiträge
    497
    Wo setzt du denn die Pullups? Oder hast du die in der Hardware?

    Interessant bezüglich Encodern ist auch http://www.mikrocontroller.net/artic...von_Drehgebern

    sast

    雅思特史特芬
    开发及研究

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Ich empfehle, die A u B Signal auf einen Wert zusammenzufassen, dann ist die Auswertung weniger verwirrend
    z.B:
    Code:
    while (1)
    {
         newstate = 0;
         if   (PIND & IO_PD6)    newstate |= 2;     // A ist 0/1
         if   (PINC & IO_PC2)    newstate |= 1;     // B ist 0/1
        if    (newstate  == laststate)  
                continue;
    //   jetzt enthält newstate die werte 0 , 1, 3, 2 
         switch (newstate)
         {
          case 0:
                if (laststate == 2)      "rechts"
                else                          "links"
                break;
          case 1:
                if (laststate == 0)      "rechts"
                else                          "links"
                break;
          case 3:
                if (laststate == 1)      "rechts"
                else                          "links"
                break;
          case 2:
                if (laststate == 3)      "rechts"
                else                          "links"
                break;
         }     
         laststate = newstate;
    }
    Links u. rechst muss man ev. je nach polarität auswechseln
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

Berechtigungen

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