-
        

Ergebnis 1 bis 9 von 9

Thema: Inkrementale Gabellichtschranke am PIC

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    02.11.2006
    Beiträge
    18

    Inkrementale Gabellichtschranke am PIC

    Anzeige

    Hallo!
    Ich überlege nun schon eine weile, wie ich am besten folgendes Problem löse.
    ich habe 2 Inkrementale Gabellichtschranken (GP1A038RBK) mit Encoderscheibe. Nun möchte ich beide Lichtschranken möglichst auf einen PIC-Controller (16F88 o.ä.) mit 20MHz betreiben, meine bedenken liegen jedoch da, ob der PIC die flanken erkennt, wenn ich z.b. nebenher noch den I²C Bus anspreche. nicht das er 1-2 Takte verpasst und somit den Weg/position verfälscht. leider haben die dinger ja nur 1 Timer der "Takte" zählen kann

    Hat vielleicht jmd hiermit schon erfahrungen gesammelt und könnte mir Tipps geben?

    Danke im vorraus, Stefan

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    30.01.2005
    Ort
    Tokyo
    Alter
    59
    Beiträge
    242
    Das kommt natürlich auf die Taktfrequenz der Scheibe an.
    Prinzipiell würde ich einen IRQ Timer vorsehen, der min 2x so schnell getrigget wird wie die höchste vorkommende Taktfrequenz. In diesem IRQ liest man dann beide Lichtschranken (genauer 2x2) und wertet die Positionen aus. Sonst darf nichts in diesen IRQ.
    Wenn Du diesen IRQ geschrieben hast, kannst Du innerhalb dieses IRQ temporär noch einen freien Port hin und herschalten und mit einem Oszi schauen, wie schnell der IRQ läuft (Anfang IRQ-> PIN ein, Ende IRQ -> Pin aus). Dann siehst Du ob es für deine geforderte Geschwindigkeit reicht.

    Gruß
    pctoaster

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    15.09.2006
    Ort
    Berlin
    Beiträge
    21
    Der PortB-Change-Interrupt bietet sich hier an. (RB4-RB7)
    Der meldet sich nur, wenn sich an den Eingängen was ändert, und man kann den Prozessor inzwischen mit anderen Sachen beschäftigen.

    Mfg
    Digger

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    02.11.2006
    Beiträge
    18

    Danke :)

    Erstmal danke für die "Denkanstöße"
    auf die Idee, die Interrupt Pins von dem PIC zu benutzen bin ich noch garnicht gekommen.

    Habe es nun wie folgt gemacht: Würde ich alle 4 Eingänge der 2 Drehgeber auf die Interrupt Pins legen, würde er zwar brav inner die ISR aufrufen, jedoch wüsste ich nur umständlich welcher Port nun wirklich was macht. Deshalb habe ich nun die beschaltung wie folgt gemacht.
    Auf RB0 (Flankenerkennung und Interrupt) -> Drehgeber 1 eingang A
    Auf RB4 (Interrupt on change) -> Drehgeber 2 eingang A
    RA1,2 (nix besonderes ) -> Drehgeber 1, 2 eingang B
    somit würde dann jeder Drehgeber seinen eigenen Interrupt aufrufen und vergleichen ist leicht gemacht. hoffe es funktioniert - werd es heute oder morgen mal ausprobieren.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    30.01.2005
    Ort
    Tokyo
    Alter
    59
    Beiträge
    242
    Find ich nicht so dolle. Vor allem, wenn es Dir auf Geschwindigkeit ankommt.
    Jeder Drehgeberausgang bekommt einen IRQ. Dann fragst Du ab, in welche Richtung sich dieser Porteingang geändert hat. Diesen Gesamtzustand (aus allen 4 Ports) speicherst Du anschließend ab und hast dann den Ausgangszustrand für den nächsten IRQ.
    Jetzt kannst Du die Drehrichtung auswerten und die aktuelle Position absspeichern.
    Alles andere außerhalb des IRQ.

    Guckst Du hier (für Atmega in C). So habe ich es mal gemacht:
    Code:
    #define TURN_ENC_1         PD7
    #define TURN_ENC_2         PD6
    
    volatile uint8_t iTurnOldEncPort;
    volatile uint8_t iTurnNewEncPort;
    volatile int16_t lTurnActPosition;
    volatile int16_t lTurnTargetPosition;
    
    
    ISR(INT0_vect) { VerticalEncoderRead(); }
    
    void TurnEncoderRead(void) {
       iTurnNewEncPort = PIND;
       if ( iTurnOldEncPort & (1<<TURN_ENC_1) ) {
          if ( iTurnNewEncPort & (1<<TURN_ENC_1) ) {
             if ( iTurnOldEncPort & (1<<TURN_ENC_2) ) {
                if (!( iTurnNewEncPort & (1<<TURN_ENC_2) )) lTurnActPosition++;
             }
             else {
                if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lTurnActPosition--;
             }
          }
          else {
             if ( iTurnOldEncPort & (1<<TURN_ENC_2) ) {
                if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lTurnActPosition--;
                else lErrorFlags |= ERR_TURN_ENC;
             }
             else {
                if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lErrorFlags |= ERR_TURN_ENC;
                else lTurnActPosition++;
             }
          }
       }
       else {
          if ( iTurnNewEncPort & (1<<TURN_ENC_1) ) {
             if ( iTurnOldEncPort & (1<<TURN_ENC_2) ) {
                if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lTurnActPosition++;
                else lErrorFlags |= ERR_TURN_ENC;
             }
             else {
                if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lErrorFlags |= ERR_TURN_ENC;
                else lTurnActPosition--;
             }
          }
          else {
             if ( iTurnOldEncPort & (1<<TURN_ENC_2) ) {
                if (!( iTurnNewEncPort & (1<<TURN_ENC_2) )) lTurnActPosition--;
             }
             else {
                if ( iTurnNewEncPort & (1<<TURN_ENC_2) ) lTurnActPosition++;
             }
          }
      }
       iTurnOldEncPort = iTurnNewEncPort;
    }
    Das "TURN" kannst Du weglassen. Das ist für eine Mehrachsensteuerung.)

    Gruß
    pctoaster

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    02.11.2006
    Beiträge
    18
    hm, ja sicher wäre das flotter.
    Dummerweise ist leider bei den 16F88 der I²C Bus auf RB1 und 4. bin mal gespannt ob er da auch nen interrupt auslöst wenn der I2C bus aktiv ist...

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    30.01.2005
    Ort
    Tokyo
    Alter
    59
    Beiträge
    242
    Also, sollstest Du vorhaben einen Pin für einen IRQ und I2C zu verwenden, kannst Du das vergessen. Entweder, oder.
    Wenn es aber darum geht, nur bestimmte Pins als IRQ zu definieren, sollte das bei einem Pic aber auch möglich sein.
    Mit den Pics kenne ich mich nicht so aus. Wenn Du keinen IRQ frei hast, mußt Du doch pollen.
    Um welche Geschwindigkeiten geht es hier denn ?

    Gruß
    pctoaster

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    02.11.2006
    Beiträge
    18
    Also bei den PICs kann man lediglich die ISR für alle Ports (RB4-7) ein bzw ausschalten. [BSF INTCON, RBIE]. das ich einen port net für I2C und als takt eingang nehmen kann ist mir auch klar


    Zur Geschwindigkeit, die Scheibe hat 120 Makierungen - die Motoren drehen mit 80 & 40 rpm.

    für 80 Rpm -> 160 "makierungen" pro sek.
    für 40 rpm -> 80 "makierungen" pro sek.

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    30.01.2005
    Ort
    Tokyo
    Alter
    59
    Beiträge
    242
    Da kannst Du locker pollen wie ich es anfangs beschrieben habe. Der IRQ Code, den ich oben für den AVR geschrieben habe, ist in längstens 20uS durchgelaufen.

    Gruß
    pctoaster

Berechtigungen

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