Ankündigung

Einklappen
Keine Ankündigung bisher.

ARDUINO am KNX

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • WagoKlemme
    antwortet
    Das nenn ich mal "Timing", jetzt hätten wir fast gleichzeitig gepostet und der erste Gedanke ist auch noch gleich. Gedankenübertragung ?

    Buffer habe ich schon, den Rest schaue ich mir an. Danke !

    Einen Kommentar schreiben:


  • WagoKlemme
    antwortet
    Ich habe mal den Serial_Buffer_Size auf 256 und siehe da, Zufall ?
    2017-07-31 19_19_24-192.168.2.16_data_log_MONLOG_2017-07-31.htm_20170731191616.png

    Einen Kommentar schreiben:


  • Mag Gyver
    antwortet
    Hallo WagoKlemme,

    den seriellen Speicher kann man vergrößern. Dazu sind lediglich ein paar Zeilen in der

    Code:
    HardwareSerial.h
    innerhalb der IDE zu ändern. Mit allen Vorteilen und Nachteilen.

    Aber vielleicht bedarf es nur einer kleineren Änderungen. Wertest und bearbeitest du die empfangenen Daten direkt in

    Code:
    void serialEvent()
    aus? Würde dann vorschlagen, hier nur das Wesentliche zu tun. Die Leseanfrage pro Gruppenadresse in einer Variable speichern und dann den Rest in

    Code:
    void loop()
    zu erledigen -> z.B.: Antworten auf deine Leseanfrage. Dann könnte man noch den Schreibtimeout der KNX-Library von Standard

    Code:
    #define SERIAL_WRITE_DELAY_MS 100
    auf den für dich notwendigen Wert

    Code:
    #define SERIAL_WRITE_DELAY_MS (hier dein Wert)
    setzen.


    Nur noch ein Hinweis am Rande. Je mehr Ram, je mehr Gruppenadressen sind möglich. Vielleicht belegst du schon einiges durch andere Libraries davon und es kommt dann zu diesem Phänomen.

    Der Gedanke mit dem Queue in Array ist zwar ein guter Ansatz, jedoch sollte es auch ohne klappen. Die Leseanfrage an sich ist nicht groß, ich vermute nach wie vor ein Timing-Problem.




    Mit freundlichen Grüßen

    Mag Gyver

    Einen Kommentar schreiben:


  • WagoKlemme
    antwortet
    Hallo Mag Gyver,

    danke für deine Einschätzung, hierzu hätte ich noch ein paar Fragen:
    - wieviele Telegramme passen in den seriellen Speicher (ATMega328 64Bytes), bzw. wie groß ist ein Request* ? Und könnte man den nicht vergrössern, wie hier ?
    - könnte man wenigstens die GA abfangen und später eine Antwort senden
    - wie wäre es mit einer Queue in Array, und die Antworten dann sequenziell zu senden, nach Größe des Arrays ?

    Ich kann Edomi oder generell einen Initscan einer Visu nicht dazu bringen, die Read Requests schön nacheinander abzuschicken. Schliesslich sind da in der Größenordnung 1500 GA's zu lesen, das würde zu lang dauern. Den Standard KNX Geräten macht es ja nichts aus. Das ist halt die Konzeption und ansonsten kein Problem in KNX, und wird unvermeidbar sein.

    Edit: *Länge Request : Ein Datarequest ist 23 Byte und ein extended Datarequest hat 263 Bytes. Quelle
    Zuletzt geändert von WagoKlemme; 31.07.2017, 08:34.

    Einen Kommentar schreiben:


  • Mag Gyver
    antwortet
    Hallo WagoKlemme,

    ich entnehme dem Screenshot einfach anhand dem zeitlichen Verlauf, dass der ARDUINO noch in der Wartephase zwischen den Telegrammabarbeitung (delay) steckt und deswegen nicht auf deine sehr kurz hintereinander kommende Read Request antworten kann, weil der ARDUINO es einfach verschläft bzw. der Puffer der seriellen Schnittstelle überläuft.

    Abhilfe könnte hier vielleicht sein, dass man hier am Sendetimeout in der Library dreht oder vielleicht doch besser erstmal eine Wartezeit zwischen den Abfragen des anderen Gerätes einbaut, wenn möglich.

    Ich z.B. sende nur eine Anfrage (Write auf Anfrageadresse) zum ARDUINO und veranlasse den ARDUINO dann mir die aktuellen Daten zu senden, währe natürlich auch ein Weg um dein anderes Gerät mit den Daten zu füttern.




    Mit freundlichen Grüßen

    Mag Gyver
    Zuletzt geändert von Mag Gyver; 30.07.2017, 20:50.

    Einen Kommentar schreiben:


  • WagoKlemme
    antwortet
    Mag Gyver
    Ich hätte eine Frage bzgl. Lib und Read Request von KNX-Seite. Von 4 gleichzeitigen Requests über Serialevent wird immer nur 1 beantwortet.
    Was läuft schief ? Was kann ich tun ?
    Ein einzelner Request funktioniert einwandfrei.

    2017-07-30 19_47_36-192.168.2.16_data_log_MONLOG_2017-07-30.htm_20170730133735.png

    Einen Kommentar schreiben:


  • WagoKlemme
    antwortet
    Das mit der Lib muss ich mir nochmal anschauen. Zuerst dachte ich der Sensor ist defekt und wollte einfach nur Werte angezeigt bekommen. Das ging eben mit der Sparkfun-Lib erstmal nicht. Vielleicht lags auch am Wakeup.

    Ich halte, so nach 2 Tagen Beobachtung, auch erstmal am iAQ fest.

    Einen Kommentar schreiben:


  • dreamy1
    antwortet
    Hmmm, den Sparkfun habe ich auch gesehen. Wenn bei einem die Lib funktioniert und beim anderen nicht, ist das kein gutes Zeichen...dann scheinen die Sensoren unterschiedlich zu sein (kenne ich von den Fake-NRF24L01 nur zu gut).

    Aber mal ehrlich...bei 34€ kannst Du auch gleich den Core nehmen, der ist dann letztendlich kleiner und hat bereits eine Staubschutzkappe onboard. Ich bleibe jedenfalls erstmal beim Core P.

    Einen Kommentar schreiben:


  • WagoKlemme
    antwortet
    Hallo Stefan,

    meiner ist von hier. War in einer Woche da.
    Ich würde aber in Zukunft lieber den von EXPtech /Sparkfun nehmen. Kostet zwar 34 Euros, aber dafür funktioniert auch die LIB von Sparkfun. Mit meinem von Ebay funktioniert die LIB nicht. Deshalb auch die o.g. LIB, die auch prompt einen Bug bei der Modeumschaltung hatte.
    Ausserdem glaube ich, wie auch beim BME280, dass die Verarbeitung schon entscheidend ist. Und damit das Messergebnis. Deshalb habe ich einen BME280 von Sparkfun geordert und werde das mal überprüfen.

    Edit: Aufm Chip steht 811B und ein kreisförmiges Logo. Genau wie auf dem Bild in Ebay.
    Zuletzt geändert von WagoKlemme; 11.06.2017, 19:17.

    Einen Kommentar schreiben:


  • dreamy1
    antwortet
    Hallo Armin,

    danke fürs Teilen!

    Woher hast Du denn den CCS811? Ich traue den Dingern irgendwie (noch) nicht, die aktuell aus China kommen. Ist da irgendwas aufm Chip, was auf original AMS Chips hinweist?

    Einen Kommentar schreiben:


  • WagoKlemme
    antwortet
    Mein CCS811 ist eingetroffen !
    Bevor jemand viel Zeit wegen einer fehlerhaften LIB vergeudet, so wie ich, hier der Code :
    PIN WAK auf 4 Pro Mini. VCC, GND, SDA, SCL ist klar. Hiermit wird der MODE 3 aktiviert. D.h. alle 10s gepulst eine Messung. Für 60s bitte in der LIB das Byte ändern, ist mit Pfeilen markiert.
    Zur Genauigkeit zum iAQ kann ich im Moment sagen, das der CCS811 (nach Burn-in) bei CO2 400ppm mehr misst als der iAQ und VOC ca. 200 weniger. Beide lagen direkt nebeneinander.
    Welcher nun stimmt weiss ich noch nicht.
    Edit: CO2 stimmt inzwischen ziemlich überein. Nur VOC 2ppb (CCS811) zu 131ppm(iAQ) scheint dann doch daneben. Da scheint was faul zu sein.

    Der CCS811 braucht ein 48h Burn-in. Danach 20min. Nach Modeänderung auch 20min.

    Programm:
    Code:
    /***************************************************
      This is an example for the CCS811 digital TVOC/eCO2 Sensor by CCMOSS/AMS
      http://www.ccmoss.com/gas-sensors#CCS811
      Updated: March 28, 2017
    
      The sensor uses I2C protocol to communicate, and requires 2 pins - SDA and SCL
      Another GPIO is also required to assert the WAKE pin for communication. this
      pin is passed by an argument in the begin function.
      A breakout board is available: https://github.com/AKstudios/CCS811-Breakout
      The ADDR pin on the sensor can be connected to VCC to set the address as 0x5A.
      The ADDR pin on the sensor can be connected to GND to set the address as 0x5B.
      Written by Akram Ali from AKstudios (www.akstudios.com)
      GitHub: https://github.com/AKstudios/
     ****************************************************/
    
    #include <CCS811.h>
    
    #define ADDR      0x5A
    #define WAKE_PIN  4
    
    byte stat;
    byte measure;
    
    CCS811 sensor;
    
    void setup()
    {
      Serial.begin(9600);
      Serial.println("CCS811 test");
      if(!sensor.begin(uint8_t(ADDR), uint8_t(WAKE_PIN)))
      Serial.println("Initialization failed.");
      pinMode(WAKE_PIN, OUTPUT);
      digitalWrite(WAKE_PIN, LOW);
      stat=sensor.readStatus();
      measure=sensor.readMeasure();
      Serial.print("Status Byte : "); Serial.print(stat); Serial.println("");
    }
    
    void loop()
    {
        stat=sensor.readStatus();
        if (bitRead(stat,3)) {
    
    
        sensor.compensate(21.9, 48.2);  // replace with t and rh values from sensor
        sensor.getData();
        Serial.print("CO2 : "); Serial.print(sensor.readCO2()); Serial.println(" ppm");
        Serial.print("TVOC : "); Serial.print(sensor.readTVOC()); Serial.println(" ppb");
        Serial.print("Measure Byte : "); Serial.print(measure); Serial.println("");
        if (!bitRead(stat,0)) {
           Serial.print("Status : "); Serial.println("ok");
        }
        if (bitRead(stat,0)) {
          Serial.print("Status : "); Serial.println("Error");
        }
        if (!bitRead(stat,3)) {
          Serial.print("Data : "); Serial.println("No data");
        }
        if (bitRead(stat,3)) {
          Serial.print("Data : "); Serial.println("ready");
        }
        Serial.println();
        bitWrite(stat,3,0);
        delay(1000);
      //}
      }
      delay(100);
    }
    LIB CCS811.cpp:
    Code:
    /***************************************************
      This is a library for the CCS811 digital TVOC/eCO2 Sensor by CCMOSS/AMS
      http://www.ccmoss.com/gas-sensors#CCS811
    
      Updated: April 18, 2017
    
      The sensor uses I2C protocol to communicate, and requires 2 pins - SDA and SCL
      Another GPIO is also required to assert the WAKE pin for communication. this
      pin is passed by an argument in the begin function.
    
      A breakout board is available: https://github.com/AKstudios/CCS811-Breakout
    
      The ADDR pin on the sensor can be connected to VCC to set the address as 0x5A.
      The ADDR pin on the sensor can be connected to GND to set the address as 0x5B.
    
      Written by Akram Ali from AKstudios (www.akstudios.com)
      GitHub: https://github.com/AKstudios/
    
      BSD license, all text above must be included in any redistribution
     ****************************************************/
    
    #include "CCS811.h"
    
    CCS811::CCS811()
    {
      // empty constructor, just because.
    }
    
    
    boolean CCS811::begin(uint8_t I2C_ADDR, uint8_t WAKE_PIN)
    {
      delay(70); // from datasheet - up to 70ms on the first Reset after new application download; up to 20ms delay after power on
      _I2C_ADDR = I2C_ADDR;
      _WAKE_PIN = WAKE_PIN;
      Wire.begin();
      pinMode(_WAKE_PIN, OUTPUT);   // set WAKE pin as OUTPUT
      PORTD &= ~(1<<PORTD4);  // assert WAKE pin LOW to initiate communication with sensor
      digitalWrite(_WAKE_PIN, LOW);  // WAKE_PIN on the sensor is active low, must always be asserted before any communication and held low throughout
    
      byte hw_id = CCS811::readHW_ID();
      if(hw_id != 0x81)  // this is the expected hardware ID
      {
        Serial.println("Error: Incorrect Hardware ID detected.");
        return false;
      }
    
      byte status = CCS811::readStatus();
      uint8_t bit = (status & (1 << 5-1)) != 0; // black magic to read APP_VALID bit from STATUS register
      if(bit != 1)
      {
        Serial.println("Error: No application firmware loaded.");
        readErrorID(status);
        return false;
      }
    
      digitalWrite(_WAKE_PIN, LOW);
      Wire.beginTransmission(_I2C_ADDR); // least significant bit indicates write (0) or read (1)
      Wire.write(APP_START);
      Wire.endTransmission();
      digitalWrite(_WAKE_PIN, HIGH);
    
      status = CCS811::readStatus();
      bit = (status & (1<<8-1)) !=0; // black magic to read FW_MODE bit from STATUS register
      if(bit != 1)
      {
        Serial.println("Error: Firmware still in boot mode.");
        readErrorID(status);
        return false;
      }
    
      digitalWrite(_WAKE_PIN, LOW);
      Wire.beginTransmission(_I2C_ADDR);
      Wire.write(MEAS_MODE);
      Wire.write(B101000);  // constant power mode, IAQ measurement every 10 second  - B111000 = every 60s  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      Wire.endTransmission();
      //CCS811::sleep();
      digitalWrite(_WAKE_PIN, HIGH);
    
      return true;
    }
    
    
    byte CCS811::readStatus(void)
    {
      digitalWrite(_WAKE_PIN, LOW);
      Wire.beginTransmission(_I2C_ADDR);
      Wire.write(STATUS);
      Wire.endTransmission();
    
      Wire.requestFrom(_I2C_ADDR, (uint8_t)1);
      byte status;
      if(Wire.available() == 1)
        status = Wire.read();
    
      digitalWrite(_WAKE_PIN, HIGH);
      return status;
    }
    
    byte CCS811::readMeasure(void)
    {
      digitalWrite(_WAKE_PIN, LOW);
      Wire.beginTransmission(_I2C_ADDR);
      Wire.write(MEAS_MODE);
      Wire.endTransmission();
    
      Wire.requestFrom(_I2C_ADDR, (uint8_t)1);
      //byte MEAS_MODE = Wire.read();
      byte _meas;
      if(Wire.available() == 1)
        _meas = Wire.read();
    
      digitalWrite(_WAKE_PIN, HIGH);
      return _meas;
    }
    
    
    byte CCS811::readHW_ID(void)
    {
      digitalWrite(_WAKE_PIN, LOW);
      Wire.beginTransmission(_I2C_ADDR);
      Wire.write(HW_ID);
      Wire.endTransmission();
    
      Wire.requestFrom(_I2C_ADDR, (uint8_t)1);
      byte hw_id = Wire.read();
    
      digitalWrite(_WAKE_PIN, HIGH);
      return hw_id;
    }
    
    
    byte CCS811::readErrorID(byte _status)
    {
      digitalWrite(_WAKE_PIN, LOW);
      Wire.beginTransmission(_I2C_ADDR);
      Wire.write(ERROR_ID);
      Wire.endTransmission();
    
      Wire.requestFrom(_I2C_ADDR, (uint8_t)1);
      byte error_id = Wire.read();
    
      digitalWrite(_WAKE_PIN, HIGH);
      uint8_t bit = (_status & (1 << 1-1)) != 0; // black magic to read ERROR bit from STATUS register
      if(bit == 1)
      {
        Serial.print("Error ID: ");
        Serial.println(error_id);
      }
    
      return error_id;
    }
    
    
    void CCS811::sleep()
    {
      digitalWrite(_WAKE_PIN, LOW);
      Wire.beginTransmission(_I2C_ADDR);
      Wire.write(MEAS_MODE);
      Wire.write(0x00000000);  // sets sensor to idle; measurements are disabled; lowest power mode
      Wire.endTransmission();
      digitalWrite(_WAKE_PIN, HIGH);  // set WAKE_PIN high - this puts sensor in sleep mode (~2uA) and all I2C communications are ignored
    }
    
    
    void CCS811::getData(void)
    {
      //CCS811::compensate(t, rh);
      digitalWrite(_WAKE_PIN, LOW);
      delay(1000);
    
      Wire.beginTransmission(_I2C_ADDR);
      Wire.write(ALG_RESULT_DATA);    // reading ALG_RESULT_DATA clears DATA_READY bit in 0x00
      Wire.endTransmission();
    
      Wire.requestFrom(_I2C_ADDR, (uint8_t)4);
      delay(1);
      int buffer[4];
      if(Wire.available() == 4)
      {
        for(int i=0; i<4; i++)
        {
          buffer[i] = Wire.read();
          //Serial.print(buffer[i]);
        }
      }
      CO2 = ((uint8_t)buffer[0] << 8) + buffer[1];
      TVOC = ((uint8_t)buffer[2] << 8) + buffer[3];
    
      digitalWrite(_WAKE_PIN, HIGH);
    }
    
    
    int CCS811::readTVOC(void)
    {
      return TVOC;
    }
    
    
    int CCS811::readCO2(void)
    {
      return CO2;
    }
    
    
    void CCS811::compensate(float t, float rh)    // compensate for temperature and relative humidity
    {
      digitalWrite(_WAKE_PIN, LOW);
    
      int _temp, _rh;
      if(t>0)
        _temp = (int)t + 0.5;  // this will round off the floating point to the nearest integer value
      else if(t<0) // account for negative temperatures
        _temp = (int)t - 0.5;
      _temp = _temp + 25;  // temperature high byte is stored as T+25°C in the sensor's memory so the value of byte is positive
      _rh = (int)rh + 0.5;  // this will round off the floating point to the nearest integer value
    
      byte _ENV_DATA[4];
    
      _ENV_DATA[0] = _rh << 1;  // shift the binary number to left by 1. This is stored as a 7-bit value
      _ENV_DATA[1] = 0;  // most significant fractional bit. Using 0 here - gives us accuracy of +/-1%. Current firmware (2016) only supports fractional increments of 0.5
      _ENV_DATA[2] = _temp << 1;
      _ENV_DATA[3] = 0;
    
      Wire.beginTransmission(_I2C_ADDR);
      Wire.write(ENV_DATA);
      Wire.write(_ENV_DATA[0]); // 7 bit humidity value
      Wire.write(_ENV_DATA[1]);
      Wire.write(_ENV_DATA[2]);
      Wire.write(_ENV_DATA[3]);
      Wire.endTransmission();
    
      digitalWrite(_WAKE_PIN, HIGH);
    }
    LIB CCS811.h:
    Code:
    /***************************************************
      This is a library for the CCS811 digital TVOC/eCO2 Sensor by CCMOSS/AMS
      http://www.ccmoss.com/gas-sensors#CCS811
    
      October 28, 2016
    
      The sensor uses I2C protocol to communicate, and requires 2 pins - SDA and SCL
      Another GPIO is also required to assert the WAKE pin for communication. this
      pin is passed by an argument in the begin function.
    
      A breakout board is available: https://github.com/AKstudios/CCS811-Breakout
    
      The ADDR pin on the sensor can be connected to VCC to set the address as 0x5A.
      The ADDR pin on the sensor can be connected to GND to set the address as 0x5B.
    
      Written by Akram Ali from AKstudios (www.akstudios.com)
      GitHub: https://github.com/AKstudios/
      BSD license, all text above must be included in any redistribution
     ****************************************************/
    
    #ifndef CCS811_h
    #define CCS811_h
    
    #if (ARDUINO >= 100)
     #include "Arduino.h"
    #else
     #include "WProgram.h"  // to allow boolean and byte functions
    #endif
    
    #include "Wire.h"   // Wire library for I2C protocol
    
    #define nWAKE           4      // pin 4 is tied to CCS811 nWAKE pin in sensor node
    #define nINT            7      // pin 7 is tied to CCS811 nINT pin in sensor node
    
    #define ADDR            0x5A   // when I2C_ADDR pin is LOW
    //#define ADDR            0x5B   // when I2C_ADDR pin is HIGH
    
    // Registers for CCS811
    #define STATUS          0x00
    #define MEAS_MODE       0x01
    #define ALG_RESULT_DATA 0x02
    #define ENV_DATA        0x05
    #define APP_START       0xF4
    #define HW_ID           0x20
    #define ERROR_ID        0xE0
    #define SW_RESET        0xFF
    
    class CCS811
    {
      public:
        CCS811();     // constructor
        boolean begin(uint8_t I2C_ADDR, uint8_t WAKE_PIN);
        byte readStatus(void);
        byte readMeasure(void);
        byte readHW_ID(void);
        int readTVOC(void);
        int readCO2(void);
        void getData(void);
        void compensate(float t, float rh);
        byte readErrorID(byte _status);
        void reset(void);
        void sleep();
        int TVOC, CO2;
    
      private:
        uint8_t _WAKE_PIN;
        uint8_t _I2C_ADDR;
    };
    
    #endif
    Zuletzt geändert von WagoKlemme; 11.06.2017, 19:28.

    Einen Kommentar schreiben:


  • wintermute
    antwortet
    Zitat von WagoKlemme Beitrag anzeigen
    Was willst Du denn bitte in der Zwischendecke messen ?
    In der Zwischendecke liegen die rPi-Squeezeplayer, die dann praktischerweise gleich das komplette Messprogramm des BME280 per HTTP an Edomi schicken koennen. Drum dacht ich, ich "leg" den BME einfach daneben, aber die Testtemperaturmessung war dann doch eher ernuechternd...
    Also waer jetzt son kleines Gehaeuse nett, dass ich von unten an die Decke schrauben koennte. Berker-Sensoreinsatz ist mir dafuer etwas zu gross.

    Zitat von WagoKlemme Beitrag anzeigen
    Du weisst schon, was Du mit deinen Sensoren ausgelöst hast. Vormittag war für mich die Welt noch in Ordnung, jetzt muss ich zur Therapie.
    Ich kenn das, darum hab ich das Thema fuer mich selbst schon vor langer Zeit intern abgehakt

    Einen Kommentar schreiben:


  • WagoKlemme
    antwortet
    Zitat von wintermute Beitrag anzeigen
    Die Dinger in der Zwischendecke zu verbauen funktioniert naemlich ueberhaupt garnicht - zumindest nicht wenn man Ansprechzeiten von unter 2 Tagen bevorzugt
    Was willst Du denn bitte in der Zwischendecke messen ? Oder kommst Du an eine andere Stelle nicht mehr mitm Kabel hin ?

    Zur Feuchte:
    Du weisst schon, was Du mit deinen Sensoren ausgelöst hast. Vormittag war für mich die Welt noch in Ordnung, jetzt muss ich zur Therapie.

    Einen Kommentar schreiben:


  • WagoKlemme
    antwortet
    Nein, der Luftdruck muss korrigiert auf deine Meereshöhe zum Zeitpunkt des Programmstarts im Code (in meinem Fall 1018hPa) eingegeben werden. Auch nach Berücksichtigung der Meereshöhe hat er dann 968hPa angezeigt. Und somit lag er exakt 50 daneben.

    Ich denke Michael hat einen Sensor erwischt aus der Anfangsphase (sauber verarbeitet), bevor die Kopien kamen. Meine Chinakopie kann durchaus erhebliche Abweichungen haben, abhängig von der Kopierqualität. Denn eine Abweichung bei der Temperatur von 2,2K ist schon erheblich. Offensichtlich hat das der Sensor von Michael nicht.

    Einen Kommentar schreiben:


  • wintermute
    antwortet
    Zitat von WagoKlemme Beitrag anzeigen
    Die Werks-Kalibrierung deiner BMEs scheint wirklich gut zu sein. Besser gehts nicht. Beeindruckend.
    Ich hoffe, das wird bei den Zukuenftigen ebenfalls so sein

    Was mir noch fehlt ist irgendein kleines weisses Gehaeuse so etwa in der Art vom AM2302, vllt optisch etwas ansprechender...
    Die Dinger in der Zwischendecke zu verbauen funktioniert naemlich ueberhaupt garnicht - zumindest nicht wenn man Ansprechzeiten von unter 2 Tagen bevorzugt

    Einen Kommentar schreiben:

Lädt...
X