-         

Ergebnis 1 bis 8 von 8

Thema: Fehler im Code oder Hardware

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    23.01.2005
    Beiträge
    6

    Fehler im Code oder Hardware

    Anzeige

    Hallo,

    ich hatte die Tage schon mal wegen Interruptproblemen beim MCP23017 gefragt, aber keine antworten erhalten, daher habe ich mich nochmal hingesetzt und den code auf das m.e. wesentliche reduziert:

    Code:
    #include <Wire.h>
    
    #define Mcp_Reg_IODIRA            0x00      // IO direction  (0 = output, 1 = input (Default))
    #define Mcp_Reg_IODIRB            0x01
    #define Mcp_Reg_IOPOLA            0x02      // IO polarity   (0 = normal, 1 = inverse)
    #define Mcp_Reg_IOPOLB           0x03
    #define Mcp_Reg_GPINTENA         0x04      // Interrupt on change (0 = disable, 1 = enable)
    #define Mcp_Reg_GPINTENB         0x05
    #define Mcp_Reg_DEFVALA          0x06      // Default comparison for interrupt on change (interrupts on opposite)
    #define Mcp_Reg_DEFVALB          0x07
    #define Mcp_Reg_INTCONA          0x08      // Interrupt control (0 = interrupt on change from previous, 1 = interrupt on change from DEFVAL)
    #define Mcp_Reg_INTCONB          0x09
    #define Mcp_Reg_IOCON            0x0A      // IO Configuration: bank/mirror/seqop/disslw/haen/odr/intpol/notimp
    //#define Mcp_Reg_IOCON         0x0B         // same as 0x0A
    #define Mcp_Reg_GPPUA            0x0C      // Pull-up resistor (0 = disabled, 1 = enabled)
    #define Mcp_Reg_GPPUB            0x0D
    #define Mcp_Reg_INFTFA           0x0E      // Interrupt flag (read only) : (0 = no interrupt, 1 = pin caused interrupt)
    #define Mcp_Reg_INFTFB           0x0F
    #define Mcp_Reg_INTCAPA          0x10      // Interrupt capture (read only) : value of GPIO at time of last interrupt
    #define Mcp_Reg_INTCAPB          0x11
    #define Mcp_Reg_GPIOA            0x12      // Port value. Write to change, read to obtain value
    #define Mcp_Reg_GPIOB            0x13
    #define Mcp_Reg_OLLATA           0x14       // Output latch. Write to latch output.
    #define Mcp_Reg_OLLATB           0x15
    
    #define mcp                             0x21
    
    #define MCPResetPin            4        // hier hängt der MCP mit seinem Reset-Pin dran
    #define MCPInterruptA                    0        // hier hängt der MCP mit seinem Interrupt-Pin 19 dran
    #define MCPInterruptB                1        // hier hängt der MCP mit seinem Interrupt-Pin 19 dran
    #define LEDOnBoard            13        // pin 13, LED aufm Arduino-Board
    
    byte WireTransmitResult = 0;
    boolean SwitchPressed = false;
    boolean isInInit = false;
    byte inputStateA = 0;
    byte inputStateB = 0;
    
    
    void setup()
    {
      Serial.begin(9600);
      Serial.println("Start");
      Wire.begin();
      initiic();
      pinMode (LEDOnBoard, OUTPUT);
      digitalWrite (LEDOnBoard, LOW);
      attachInterrupt(MCPInterruptA, ISRSwitchPressed, FALLING);
      //  attachInterrupt(MCPInterruptB, ISRSwitchPressed, FALLING);
      Serial.println("Bereit");
    }
    
    
    
    void loop()
    {
      if (SwitchPressed)
      {
        inputStateA = readiicbyte(mcp, Mcp_Reg_INTCAPA);
        inputStateB = readiicbyte(mcp, Mcp_Reg_INTCAPB);
    
        Serial.print("LOOP inputStateA: ");
        Serial.println(inputStateA, BIN);
        Serial.print("LOOP inputStateB: ");
        Serial.println(inputStateB, BIN);
    
        digitalWrite (LEDOnBoard, LOW);
        SwitchPressed = false;
      }
    }
    
    
    
    void ISRSwitchPressed ()
    {
      Serial.println("ISRSwitchPressed");
      digitalWrite (LEDOnBoard, HIGH);
    
      inputStateA = readiicbyte(mcp, Mcp_Reg_INTCAPA);
      inputStateB = readiicbyte(mcp, Mcp_Reg_INTCAPB);
    
      Serial.print("ISR inputStateA: ");
      Serial.println(inputStateA, BIN);
      Serial.print("ISR inputStateB: ");
      Serial.println(inputStateB, BIN);
    
      if (SwitchPressed || isInInit)
      {
        /*
        Serial.println(inputState, BIN);
        Serial.print("ISR SP: ");
        Serial.println((String)isInInit);
        Serial.print("ISR iI: ");
        Serial.println((String)SwitchPressed);
        Serial.println("ISR returned");
        */
        digitalWrite (LEDOnBoard, LOW);
      }
      else
      {
        SwitchPressed = true;
      }
    }
    
    
    
    void writeiic(uint8_t adr, uint8_t port, byte value)
    {
      Wire.beginTransmission( adr );
      Wire.write( port );
      Wire.write( value );
      WireTransmitResult = Wire.endTransmission();
    
      //  String t = "writeiic: ";
      //  t += " Adr: " + String(adr) + " Port: " + String(port) + " Value: " + String(value);
      //  Serial.println(t);
    }
    
    
    
    byte readiicbyte(uint8_t adr, uint8_t port)
    {
      Serial.println("IIC Lesen");
      byte returnword = 0x00;
    
      Wire.beginTransmission(adr);
      Wire.write(port);
      Wire.endTransmission();
      Wire.requestFrom((int)adr, 1);
    
      int c = 0;
    
      if (Wire.available())
      {
        returnword = Wire.read();
      }
      return returnword;
    }
    
    
    
    void initiic()
    {
      Serial.println("Init Wire");
      isInInit = true;
      SwitchPressed = false;
    
      pinMode(MCPResetPin, OUTPUT);
      digitalWrite(MCPResetPin, LOW);
      delay(5);
      digitalWrite(MCPResetPin, HIGH);
    
      writeiic(mcp, Mcp_Reg_IODIRA,    0x00);                // Alles auf Output setzen
      writeiic(mcp, Mcp_Reg_GPIOA,    0x00);                // Alle Pins auf 0 setzen
      writeiic(mcp, Mcp_Reg_IODIRB,    0x00);                // Alles auf Output setzen
      writeiic(mcp, Mcp_Reg_GPIOB,    0x00);                // alle Pins auf 0 setzen
    
      byte inputMaskA = 0xFF;
      byte inputMaskB = 0xFF;
      byte polA = 0xFF;
      byte polB = 0xFF;
    
      writeiic(mcp, Mcp_Reg_IODIRA, inputMaskA);        // Richtung (Ein-/Ausgang) einstellen
      writeiic(mcp, Mcp_Reg_IODIRB, inputMaskB);        // Richtung (Ein-/Ausgang) einstellen
    
      writeiic(mcp, Mcp_Reg_GPPUA, inputMaskA);        // Pull-Up Widerstände einrichten
      writeiic(mcp, Mcp_Reg_GPPUB, inputMaskB);        // Pull-Up Widerstände einrichten
    
      writeiic(mcp, Mcp_Reg_IOPOLA, polA);            // Polarität einstellen (für Eingänge 0 oder 1)
      writeiic(mcp, Mcp_Reg_IOPOLB, polB);            // Polarität einstellen (für Eingänge 0 oder 1)
    
      writeiic(mcp, Mcp_Reg_GPINTENA, inputMaskA);            // Interrupt aktivieren
      writeiic(mcp, Mcp_Reg_GPINTENB, inputMaskB);            // Interrupt aktivieren
    
      writeiic(mcp, Mcp_Reg_DEFVALA, inputMaskA);        // Interrupt Default-Wert festlegen
      writeiic(mcp, Mcp_Reg_DEFVALB, inputMaskB);        // Interrupt Default-Wert festlegen
    
      writeiic(mcp, Mcp_Reg_INTCONA, inputMaskA);        // Interrupt Vergleich einstellen, 0 = Änderung zum Vorgänger, 1 = Änderung zum DEFVAL-Wert
      writeiic(mcp, Mcp_Reg_INTCONB, inputMaskB);        // Interrupt Vergleich einstellen, 0 = Änderung zum Vorgänger, 1 = Änderung zum DEFVAL-Wert
    
      readiicbyte(mcp, Mcp_Reg_INTCAPA);            // Interrupts lesen und dadurch löschen
      readiicbyte(mcp, Mcp_Reg_INTCAPB);            // Interrupts lesen und dadurch löschen
    
      Serial.println("Init Fertig");
      isInInit = false;
    }
    Leider tuts das nicht, alle Serial-angaben sind nur zu debugzwecken drin!

    Schon beim Start gehts los, es kommt gerade noch das "I" von "Init fertig" und dann passiert nix mehr.

    Lasse ich die Zeile: attachInterrupt(MCPInterruptA, ISRSwitchPressed, FALLING); weg startet er wie gewünscht, klar logisch, ISR ist dann nicht mehr.

    schaltung ist nicht spannend, spannungsversorgung an den mcp, adress-pins (die stimmen), reset und interrupts an die im code beschriebenen pins.

    gedanke ist (später) beliebigen port als input/output schalten, interrupts auf a und/oder b legen, dass ich nur einen abfragen muss.
    pull-ups aktiviert bei input. hier im test hängt nix weiter dran, daher alle pins auf input und pull-up.

    plattform: arduino uno r3
    das ist mittlerweile der 4 mcp den ich teste, alle anderen gehen aber noch!

    jemand ne idee?

    danke & grüße

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    23.01.2005
    Beiträge
    6
    Keiner ne Idee?

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    03.09.2009
    Ort
    Berlin (Mariendorf)
    Beiträge
    938
    Vorweg: Ich kann C kaum lesen geschwiege denn fremden Source nachvollziehen. Die Kommunikation via ISR zu realisieren beinhaltet bereits einige Fehlermöglichkeiten.

    Hast du schon getestet, ob es klappt, wenn alle Befehle mit ausreichend Pausenzeit dazwischen als sequentielle Befehlsfolge programmiert sind? Das vermeidet Fehlermöglichkeiten mit ISR und I2C-bezogenen Statusbits.

    Weitere Fehlermöglichkeit: Der I2C-Bus ist nach einem Warmstart (denkbar auch nach Kaltstart = Power Up) möglicherweise blockiert. Wenn zu Beginn der Kommunikation die Datenleitung low ist, wird kein Busbetrieb möglich sein. Man kann dann z.B. so lange den Pegel der Clock-Leitung hin und her wechseln, bis die Datenleitung auf High gegangen ist. Erst dann kann der Master einen Busreset durchsetzen.

    Ist das Protokoll peinlich genau eingehalten? (Ich hab schon mit einem voll I2C-konformen Baustein gearbeitet, der allerdings auf der Verwendung eines Repeated Start beharrte, wo formal auch ein Stop & Start funktionieren sollte.) Es sind m.W. verschiedene Wege möglich, um Daten an die Portpins zu schreiben.

    Sind ausreichend niederohmige Pullups an den I2C-Leitungen (ggf. inkl. Interruptleitung - da bin ich mir nicht sicher) ? Die internen Pullups den Controllers können die Busleitungen sehr wahrscheinlich nicht genügend schnell Richtung High ziehen.

    Ich hoffe doch, aus deinen Fehlern lernen zu können, denn ich habe in nächster Zeit genau diesen Baustein ebenfalls auf der Agenda stehen.

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    23.01.2005
    Beiträge
    6
    Robo, danke für deine hinweise. aber das meiste kann ich bejaen bzw. hier in meinem 5cm testaufbau als erstmal irrelevant einstufen.
    die kommunikation in der ISR ist nur das ergebniss von 1001 debug-versuchen, soll da eigentlich nicht drin sein.
    sobald ich dahinter gekommen bin werde ich es hier schreiben.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    526
    Hallo, das klingt für mich wie ein Dauerinterrupt.
    Der Prozessor hängt in einem Interrupt, verlässt ihn und landet gleich wieder dort.
    In der Interrupt Funktion muss eventuell ein Interrupt Bit gelöscht werden, bevor sie verlassen wird.

  6. #6
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    66
    Beiträge
    10.970
    @ FlyingEaglE

    Zitat Zitat von Siro Beitrag anzeigen
    In der Interrupt Funktion muss eventuell ein Interrupt Bit gelöscht werden, bevor sie verlassen wird.
    Genau, dafür habe ich das Bit in erstem Befehl am Anfang jedes Interrupts gelöscht (um es später nicht zu vergessen).
    MfG (Mit feinem Grübeln) Wir unterstützen dich bei deinen Projekten, aber wir entwickeln sie nicht für dich. (radbruch) "Irgendwas" geht "irgendwie" immer...(Rabenauge) Machs - und berichte.(oberallgeier) Man weißt wie, aber nie warum. Gut zu wissen, was man nicht weiß. Zuerst messen, danach fragen. Was heute geht, wurde gestern gebastelt. http://www.youtube.com/watch?v=qOAnVO3y2u8 Danke!

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    23.01.2005
    Beiträge
    6
    @PICture, Siro: Das verstehe ich nicht.

    Code:
    #include <Wire.h>
    #include <TimerOne.h>
    
    
    
    #define Mcp_Reg_IODIRA            0x00      // IO direction  (0 = output, 1 = input (Default))
    #define Mcp_Reg_IODIRB            0x01
    #define Mcp_Reg_IOPOLA            0x02      // IO polarity   (0 = normal, 1 = inverse)
    #define Mcp_Reg_IOPOLB           0x03
    #define Mcp_Reg_GPINTENA         0x04      // Interrupt on change (0 = disable, 1 = enable)
    #define Mcp_Reg_GPINTENB         0x05
    #define Mcp_Reg_DEFVALA          0x06      // Default comparison for interrupt on change (interrupts on opposite)
    #define Mcp_Reg_DEFVALB          0x07
    #define Mcp_Reg_INTCONA          0x08      // Interrupt control (0 = interrupt on change from previous, 1 = interrupt on change from DEFVAL)
    #define Mcp_Reg_INTCONB          0x09
    #define Mcp_Reg_IOCON            0x0A      // IO Configuration: bank/mirror/seqop/disslw/haen/odr/intpol/notimp
    //#define Mcp_Reg_IOCON         0x0B         // same as 0x0A
    #define Mcp_Reg_GPPUA            0x0C      // Pull-up resistor (0 = disabled, 1 = enabled)
    #define Mcp_Reg_GPPUB            0x0D
    #define Mcp_Reg_INFTFA           0x0E      // Interrupt flag (read only) : (0 = no interrupt, 1 = pin caused interrupt)
    #define Mcp_Reg_INFTFB           0x0F
    #define Mcp_Reg_INTCAPA          0x10      // Interrupt capture (read only) : value of GPIO at time of last interrupt
    #define Mcp_Reg_INTCAPB          0x11
    #define Mcp_Reg_GPIOA            0x12      // Port value. Write to change, read to obtain value
    #define Mcp_Reg_GPIOB            0x13
    #define Mcp_Reg_OLLATA           0x14       // Output latch. Write to latch output.
    #define Mcp_Reg_OLLATB           0x15
    
    #define mcp                             0x21
    
    #define MCPResetPin            4        // hier hängt der MCP mit seinem Reset-Pin dran
    #define MCPInterruptA                    0        // hier hängt der MCP mit seinem Interrupt-Pin 19 dran
    #define MCPInterruptB                1        // hier hängt der MCP mit seinem Interrupt-Pin 19 dran
    #define LEDOnBoard            13        // pin 13, LED aufm Arduino-Board
    
    byte WireTransmitResult = 0;
    volatile boolean SwitchPressed = false;
    volatile boolean PolledTimer = false;
    volatile boolean isInInit = false;
    byte inputStateA = 0;
    byte inputStateB = 0;
    byte inputLastStateA = 0;
    byte inputLastStateB = 0;
    int lastRead = 0;
    
    byte OutStateA = 0;
    byte OutStateB = 0;
    
    void setup()
    {
      Serial.begin(9600);
      Serial.println("Start");
      Wire.begin();
      initiic();
      pinMode (LEDOnBoard, OUTPUT);
      digitalWrite (LEDOnBoard, LOW);
      // attachInterrupt(MCPInterruptA, ISRSwitchPressed, FALLING);
      // attachInterrupt(MCPInterruptB, ISRSwitchPressed, FALLING);
      Serial.println("Bereit");
      Timer1.initialize(50000); // 10 Hz
      //  Timer1.initialize(50000); // 20 Hz
      //  Timer1.initialize(25000); // 40 Hz
      Timer1.attachInterrupt( ISRTimer ); // attach the service routine here
    }
    
    
    
    void loop()
    {
      // if (SwitchPressed || (millis() - lastRead >= 4000))
      if (SwitchPressed || PolledTimer)
      {
        digitalWrite (LEDOnBoard, HIGH);
    
        //    inputStateA = readiicbyte(mcp, Mcp_Reg_INTCAPA);
        //    inputStateB = readiicbyte(mcp, Mcp_Reg_INTCAPB);
        inputStateA = readiicbyte(mcp, Mcp_Reg_GPIOA);
        inputStateB = readiicbyte(mcp, Mcp_Reg_GPIOB);
        //    inputStateA = readiicbyte(mcp, Mcp_Reg_OLLATA);
        //    inputStateB = readiicbyte(mcp, Mcp_Reg_OLLATB);
    
        if (inputStateA != inputLastStateA || inputStateB != inputLastStateB)
        {
          for (byte i = 0; i <= 7; i++)
          {
            if (inputStateA & (1 << i))
            {
              OutStateA ^= (1 << i);
            }
            if (inputStateB & (1 << i))
            {
              OutStateB ^= (1 << i);
            }
          }
    
          Serial.print(OutStateA, BIN);
          Serial.print("  ");
          Serial.print(OutStateB, BIN);
          Serial.println("\n");
    
          inputLastStateA = inputStateA;
          inputLastStateB = inputStateB;
    
          digitalWrite (LEDOnBoard, LOW);
    
          lastRead = millis();
          SwitchPressed = false;
          PolledTimer = false;
        }
      }
    }
    
    
    
    void ISRSwitchPressed()
    {
      if (!SwitchPressed && !isInInit)
      {
        SwitchPressed = true;
      }
    }
    
    
    
    void ISRTimer()
    {
      if (!SwitchPressed && !isInInit && !PolledTimer)
      {
        PolledTimer = true;
      }
    }
    
    
    void writeiic(uint8_t adr, uint8_t port, byte value)
    {
      Wire.beginTransmission( adr );
      Wire.write( port );
      Wire.write( value );
      WireTransmitResult = Wire.endTransmission();
    
      //  String t = "writeiic: ";
      //  t += " Adr: " + String(adr) + " Port: " + String(port) + " Value: " + String(value);
      //  Serial.println(t);
    }
    
    
    
    byte readiicbyte(uint8_t adr, uint8_t port)
    {
      //Serial.println("IIC Lesen");
      byte returnword = 0x00;
    
      Wire.beginTransmission(adr);
      Wire.write(port);
      Wire.endTransmission();
      Wire.requestFrom((int)adr, 1);
    
      int c = 0;
    
      if (Wire.available())
      {
        returnword = Wire.read();
      }
      return returnword;
    }
    
    
    
    void initiic()
    {
      Serial.println("Init Wire");
      isInInit = true;
      SwitchPressed = false;
      PolledTimer = false;
    
      pinMode(MCPResetPin, OUTPUT);
      digitalWrite(MCPResetPin, LOW);
      delay(5);
      digitalWrite(MCPResetPin, HIGH);
    
      writeiic(mcp, Mcp_Reg_IODIRA,    0x00);                // Alles auf Output setzen
      writeiic(mcp, Mcp_Reg_GPIOA,    0x00);                // Alle Pins auf 0 setzen
      writeiic(mcp, Mcp_Reg_IODIRB,    0x00);                // Alles auf Output setzen
      writeiic(mcp, Mcp_Reg_GPIOB,    0x00);                // alle Pins auf 0 setzen
    
      byte inputMaskA = 0xFF;
      byte inputMaskB = 0xFF;
      byte polA = 0xFF;
      byte polB = 0xFF;
    
      writeiic(mcp, Mcp_Reg_IODIRA, inputMaskA);        // Richtung (Ein-/Ausgang) einstellen
      writeiic(mcp, Mcp_Reg_IODIRB, inputMaskB);        // Richtung (Ein-/Ausgang) einstellen
    
      writeiic(mcp, Mcp_Reg_GPPUA, inputMaskA);        // Pull-Up Widerstände einrichten
      writeiic(mcp, Mcp_Reg_GPPUB, inputMaskB);        // Pull-Up Widerstände einrichten
    
      writeiic(mcp, Mcp_Reg_IOPOLA, polA);            // Polarität einstellen (für Eingänge 0 oder 1)
      writeiic(mcp, Mcp_Reg_IOPOLB, polB);            // Polarität einstellen (für Eingänge 0 oder 1)
    
      writeiic(mcp, Mcp_Reg_GPINTENA, inputMaskA);            // Interrupt aktivieren
      writeiic(mcp, Mcp_Reg_GPINTENB, inputMaskB);            // Interrupt aktivieren
    
      writeiic(mcp, Mcp_Reg_DEFVALA, inputMaskA);        // Interrupt Default-Wert festlegen
      writeiic(mcp, Mcp_Reg_DEFVALB, inputMaskB);        // Interrupt Default-Wert festlegen
    
      writeiic(mcp, Mcp_Reg_INTCONA, inputMaskA);        // Interrupt Vergleich einstellen, 0 = Änderung zum Vorgänger, 1 = Änderung zum DEFVAL-Wert
      writeiic(mcp, Mcp_Reg_INTCONB, inputMaskB);        // Interrupt Vergleich einstellen, 0 = Änderung zum Vorgänger, 1 = Änderung zum DEFVAL-Wert
    
      //  readiicbyte(mcp, Mcp_Reg_INTCAPA);            // Interrupts lesen und dadurch löschen
      //  readiicbyte(mcp, Mcp_Reg_INTCAPB);            // Interrupts lesen und dadurch löschen
      inputStateA = readiicbyte(mcp, Mcp_Reg_INTCAPA);
      inputStateB = readiicbyte(mcp, Mcp_Reg_INTCAPB);
      inputStateA = readiicbyte(mcp, Mcp_Reg_GPIOA);
      inputStateB = readiicbyte(mcp, Mcp_Reg_GPIOB);
      inputStateA = readiicbyte(mcp, Mcp_Reg_OLLATA);
      inputStateB = readiicbyte(mcp, Mcp_Reg_OLLATB);
    
      Serial.println("Init Fertig");
      isInInit = false;
    }
    Das ist der aktuelle Stand, der Timer ist nur zum Pollen da, soll aber eigentlich so nicht sein.
    Das interrupt problem besteht weiterhin.

  8. #8
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    31.05.2009
    Beiträge
    251
    Zitat Zitat von FlyingEaglE Beitrag anzeigen
    @PICture, Siro: Das verstehe ich nicht.

    ...........................

    Das interrupt problem besteht weiterhin.

    isInInit = false; >
    Ich verstehe auch kein C, aber werden Flags nicht durch schreiben einer "1" gelöscht?
    mfG
    Willi

Ähnliche Themen

  1. Antworten: 5
    Letzter Beitrag: 25.02.2014, 13:37
  2. Fehler im Code?
    Von mtzE im Forum Asuro
    Antworten: 6
    Letzter Beitrag: 08.05.2010, 00:40
  3. sharp gp2d120 messungs oder hardware fehler !?!
    Von patti16 im Forum Sensoren / Sensorik
    Antworten: 6
    Letzter Beitrag: 20.10.2005, 18:01
  4. Fehler im Assembler-Code
    Von dark emporer im Forum AVR Hardwarethemen
    Antworten: 18
    Letzter Beitrag: 09.08.2005, 17:50
  5. Fehler im Code
    Von Vorobo im Forum PIC Controller
    Antworten: 8
    Letzter Beitrag: 10.10.2004, 13:43

Stichworte

Berechtigungen

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