Forum: Mikrocontroller und Digitale Elektronik DMX Baudrate - Einstellungen und Datenpakete "debuggen"?


von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Hi,

ich werde mit meinem Code einfach nicht warm.
Im Grunde habe ich mich recht genau an das Datenblatt vom PIC16F193X 
gehalten und dazu noch (zu Testzwecken) die C-Funktion von 
http://www.hoelscher-hi.de zum einlesen von DMX-Werten verwendet.

Dabei wurde folgendes initialisiert:
1
void init_Timer(void)
2
{
3
    //OSCCON MPU Frequenz
4
    SCS1 = 1; //1x internem Oszillator
5
    OSCCONbits.IRCF = 0b1111; //Bit 3-6 16Mhz
6
    //OPTION_REG Timer 0 0b0x0x0111
7
    OPTION_REGbits.PS = 0b000; //Prescaler = 0b000=1:2, 0b001 = 1:4, 0b010 = 1:8, 0b011 = 1:16,...,0b111= 1:256
8
    PSA = 0; //Timer0 Prescaler einschalten = 0; 1:1--> = 1
9
    TMR0CS = 0; //Countermodus = 1; Timermodus = 0
10
    nWPUEN = 0; //WPUEN = EIN
11
12
13
    //T1CON Timer 1
14
    .....
15
    //Timer 2/4/6
16
    .....
17
18
19
}
20
21
void init_USART(void)
22
{
23
    //Baudrate ist abhängig von FOSC+SPBRG+BRGH+BRG16
24
    SPBRG = 3; //HIER: FOSC/[16(n+1)]
25
    BRGH = 1; //data rate for sending
26
    BRG16 = 0; //16-Bit-Generator; -->Formel in Abhängigkeit von BRGH beachten!!
27
28
    SREN = 0; //TODO: no effect
29
    TXIE = 0; //disable tx interrupts
30
    RX9 = 0; //8-bit reception
31
    RCIF = 0;//TODO: reset notwendig?
32
    //    //----RS232---
33
    CREN = 0; //TODO: reset notwendig?
34
    CREN = 1; //Empfänger einschalten
35
    SYNC = 0; //Asyncronmodus
36
    SPEN = 1; //Seriellen Port einschalten
37
    //
38
//    ABDEN = 1; //Automatische Erkennung der Baoudrate
39
    //    
40
    RCIE = 1;//RCIE Interrupt einschalten
41
    PEIE = 1; //Peripheral
42
    init_DMX_RX();//Alle DMX-Kanäle mit "0" belegen
43
}
44
45
void init_system(void)
46
{
47
    GIE = 0;
48
    init_IO();
49
    init_USART();
50
    init_Timer();
51
    init_PWM();
52
    CPD_OFF;//TODO: Wirkung? (Defaultwert?)
53
    WDTE_OFF;//TODO: Wirkung? FIXME: CLRWDT(); muss dennoch aufgerufen werden!?!
54
    BOREN_OFF;//TODO: Wirkung? (Defaultwert?)
55
    CLKOUTEN_OFF;//TODO: Wirkung? (Defaultwert?)
56
    GIE = 1;
57
}

Ich habe hier nur Mal die Werte gepostet, die ich für relevant halte.
Da die PWM-Ausgabe bereits Fehlerfrei im 8-Bit Betrieb funktioniert, 
kann ich auch mit Sicherheit sagen, dass der unten aufgelistete ISR 
aufgerufen wird. (An verschiedenen Stellen im Code habe ich einfach eine 
der drei Farben aufleuchten lassen):
1
void interrupt ISR()
2
{
3
    //Prüfen, ob der Interrupt von USART aktiviert ist dieser übergelaufen ist
4
    if (RCIE && RCIF)
5
    {
6
        //FIFI ISR
7
        CLRWDT();
8
        decode_DMX();
9
        CLRWDT();
10
        //Flag löschen, um Endlosschleifen zu vermeiden
11
        RCIF = 0;//FIXME: writeable??
12
    }
13
....

Ich hoffe ich bekomme von Hendrik jetzt nicht einen auf den Deckel, da 
ich hier seinen (als  Free GNU General Public License) veröffentlichten 
Code in (von mir) AVR-->PIC abgewandelter Form poste:
1
void decode_DMX(void)
2
{
3
    new_DMXData = 1;
4
    uint8_t ERROR = FERR; //FERR bit must be read before reading the RCREG
5
    uint8_t DmxByte = RCREG; //get data
6
    uint8_t DmxState = gDmxState; //
7
8
9
    if (ERROR)
10
    {
11
        //FERR
12
        DmxSkipValue = DmxAddress; //Startadresse holen
13
        gDmxState = BREAK;
14
    }
15
    else if (DmxState == BREAK)
16
    {//Wir erwarten das Startbyte mit 0b00000000
17
        if (DmxByte == 0)
18
        {
19
            set_pwm(0, 1, 0, 255);
20
            gDmxState = STARTBYTE; //normal start code detected
21
            //Pointer wird auf die zweite Array-Zelle gesetzt
22
            gDmxPnt = ((uint8_t*) DmxRxField + 1);
23
        }
24
        else gDmxState = IDLE;
25
    }
26
    else if (DmxState == STARTBYTE)
27
    {//Erster Kanal mit Nutzdaten auslesen
28
        if (--DmxSkipValue == 0)//Startaddress erreicht?
29
        {
30
            set_pwm(1, 0, 0, 255);
31
            gDmxState = STARTADR;
32
            DmxRxField[0] = DmxByte;
33
        }//"else": der Counter wurde nur verringert und die Daten verworfen
34
    }
35
    else if (DmxState == STARTADR)
36
    {//Kanal 2,3,4,...wird ausgelesen
37
        uint8_t *DmxPnt; //lokaler Pointer...
38
        DmxPnt = gDmxPnt; //lokalen Pointer 
39
        *DmxPnt = DmxByte; //Daten an diese Speicheradresse eintragen
40
        if (++DmxPnt >= (DmxRxField + sizeof (DmxRxField))) //Alle Kanäle abgearbeitet?
41
        {
42
            gDmxState = IDLE;
43
            valid_DMXData = 1;
44
            set_pwm(0, 0, 1, 255);
45
        }
46
        else gDmxPnt = DmxPnt;
47
    }
48
}

So wie er hier gepostet ist bleibt bei 16Mhz alles dunkel :(
Ich habe ein auch shcon direkt in die if (ERROR){set_pwm(...)} die LED 
Funktion geschrieben und das Licht ging an.
Doch ich denke, dass ein FERR bei jeder erdenklichen Baudrate zu stande 
kommt.

Alternativ kam auf folgendes zum Test (habe sozusagen alle Formeldn für 
250k durch):
FOSC/[16 (n+1)]  8Mhz-->SPBRG = 1;  BRGH = 1;  BRG16 = 0;
FOSC/[16 (n+1)]  8Mhz-->SPBRG = 1;  BRGH = 0;  BRG16 = 1;
FOSC/[16 (n+1)] 16Mhz-->SPBRG = 3;  BRGH = 1;  BRG16 = 0;
FOSC/[16 (n+1)] 16Mhz-->SPBRG = 3;  BRGH = 0;  BRG16 = 1;
FOSC/[4 (n+1)]   8Mhz-->SPBRG = 7;  BRGH = 1;  BRG16 = 1;
FOSC/[4 (n+1)]  16Mhz-->SPBRG = 15; BRGH = 1;  BRG16 = 1;


Jetzt frage ich mich, ob es möglich ist an die stelle im ISR bei der 
"RCREG" ausgelesen wird ein Breakpoint zu setzen und zu debuggen, was 
dort rein kommt?

Falls ja, läuft der EUSART vom PIC dann beim debuggen in echtzeit, 
sprich sind die Kalkulationen für die Baudrate etc. richtig?

Oder gibt es irgendwie eine andere Möglichkeit das ganze zu überprüfen?

[Ich danke an dieser Stelle schon Mal für die Bemühungen das ganze zu 
lesen!
Falls noch etwas zur Diagnose fehlt, liefere ich es gerne nach)
Es dürfen sich auch gerne Leute aus der Region 27***/28*** melden, die 
Zeit und Lust haben mir den Kram live für 2 Kästen Bier oder so zu 
fixen. Denn nach 16Std. dauergrübeln sollte ich so langsam Mal auf die 
Problematik gestoßen sein grr PM ;) ]


Grüße Oekel

von Chris B. (dekatz)


Lesenswert?

D a v i d K. schrieb:
> Jetzt frage ich mich, ob es möglich ist an die stelle im ISR bei der
>
> "RCREG" ausgelesen wird ein Breakpoint zu setzen und zu debuggen, was
>
> dort rein kommt?
>
>
>
> Falls ja, läuft der EUSART vom PIC dann beim debuggen in echtzeit,
>
> sprich sind die Kalkulationen für die Baudrate etc. richtig

Was hat die Baudrate mit Debuggen und Breakpoint zu tun...habe es im 
Nachbarthread versucht zu erklären, scheint aber nicht angekommen zu 
sein...

Bevor du mit dem Debugger im Nebel herumstocherst (denn offensichtlich 
hast du davon eher wenig Ahnung) solltest du mal testen, ob deine EUSART 
überhaupt mit 250 kBaud eine Verbindung zu einem Terminalprogramm 
bekommt - wie z.B. "HyperTerm" o.ä.
Also Minianwendung mit EUSART-Initialisierung und einer Schleife welche 
1 Zeichen vom Terminal einliest und dieses wieder retour sendet. 
Pegelanpassung an Schnittstelle nicht vergessen (MAX2323 etc). 
Vielleicht!!! funkteoniert das sogar mit dem internen Oszillator.
Bevor so etwas "primitives" nicht läuft, brauchst du keine DMX-Routine 
testen.....

von D a v i d K. (oekel) Benutzerseite


Angehängte Dateien:

Lesenswert?

Chris B. schrieb:

> Bevor du mit dem Debugger im Nebel herumstocherst (denn offensichtlich
> hast du davon eher wenig Ahnung) solltest du mal testen, ob deine EUSART
> überhaupt mit 250 kBaud eine Verbindung zu einem Terminalprogramm
> bekommt - wie z.B. "HyperTerm" o.ä.

Habe nun endlich einen MAX232N gefunden und das vorgeschlagene 
ausprobiert.
Hyperterminal gibt es bei Win leider nicht mehr, daher habe ich 
puttytel, hterm und realter genommen.

In einer Richtung klappt es auch, jeder Buchstabe, den ich ins Terminal 
tippe kommt auch im Debug-Register zurück. Ein echo bekomme ich aus 
irgendeinem Grund nicht hin. (Brauche ich ja aber auch nicht)

Mein Problem ist nun aber, dass ich die 250k nicht testen kann (siehe 
Anhang), da der Port am Rechner sich nicht darauf konfigurieren lässt.

wie kann ich nun weiter testen und warum kann der Port diese Rate nicht?

Grüße Oekel

von Chris B. (dekatz)


Lesenswert?


von D a v i d K. (Gast)


Lesenswert?

Schön und gut, aber durch die Verwendung einer anderen Software wird 
sich die Hardware des Ports nicht ändern. Die frage lautet ja, warum 
sich der Port nur mit diesen geringen Raten unter Windows konfigurieren 
lässt. Ist dort wirklich eine Begrenzung oder brauche ich nur andere 
Treiber?
Kann ich evtl. Glück haben, dass der Port eines anderen Rechners mehr 
Baud kann oder sollte ich sogar das OS wechseln? Oder sollte jeder 
Rechner mit jedem Betriebsystem 250k Baud schaffen?

Grüße Oekel

von Chris B. (dekatz)


Lesenswert?

D a v i d K. schrieb:
> Die frage lautet ja, warum
>
> sich der Port nur mit diesen geringen Raten unter Windows konfigurieren
>
> lässt.

Das liegt an den verwendeten Terminalprogrammen.
Mein PC ist ein ordinärer "noname" PC in der 300€ Preisklasse, der 
schafft 1000kBaud - wenn sich das Terminalprogramm darauf einstellen 
läßt und HT tut das.
Win7, keine extra Treiber oder sonstigen PiPaPo.

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Chris B. schrieb:

> Das liegt an den verwendeten Terminalprogrammen.
> Mein PC ist ein ordinärer "noname" PC in der 300€ Preisklasse, der
> schafft 1000kBaud - wenn sich das Terminalprogramm darauf einstellen
> läßt und HT tut das.

Und ich hatte mich schon so gefreut, doch es klappt NICHT.
Habe mir HyperTerminal runtergeladen uns auf Win7 ausgeführt sowie einen 
alten Rechner mit original XP gestartet.

BEIDE Hyperterminals zeigen mir NUR die im Anhang (s.o.) ersichtlichen 
Raten.
Nirgends steht 250000

230400 und 460800 währen als nächstes verfügbar, doch auch diese 
verweigern den Dienst mit der Meldung:

"Unable to open COM1. Please check your port settings"

erst bei Raten 115200 funktioniert es und ich bekomme ein "Zeichen", 
sobald ich RX und TX "kurzschließe".

Habt ihr noch eine Idee?

Grüße Oekel

PS: Es handelt sich bei mir um das P5W DH Deluxe (ein nicht ganz so 
günstiges Board von Asus)

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

[[Beitrag "RS232 - hohe Baudrate"]]

Ich denke Mal, dass ihr mit eurer Hardware einfach nur Glück gehabt 
habt.
Werde Mal sehen, ob ich hier irgendwo einen Adapter auftreiben kann.
Ist aber schon ärgerlich, dass so etwas on-Board existiert, zumal Mal 
wieder keiner im Support-Center von Asus Bescheid wusste.
Falls doch noch Jemand weißt, wie ich den
"Intel(R) 82801GB/GR (ICH7-Produktfamilie) LPC-Schnittstellencontroller 
- 27B8" dazu überredet bekomme 250000 zu produzieren, möge er sich bitte 
melden.

Grüße Oekel

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Ich muss noch Mal um eure Hilfe bitten.
Ich habe zwar immer noch keinen comport mit 250k auftreiben können, doch 
ist das Vorgehen der Routinen ja auch bei einer Baudrate von 9600 
dasselbe.
ergo bin ich den Code bei 9600 mittels eingabe von 00000000 (bei 4200 
Baud für das Break) und 00000000 00000001 00000010 (bei 9600 Baud für 
startbyte + 2 Kanäle) durchprobiert und erhalte die erwarteten werte in 
meiner Variablen
DmxRxField[].

Soweit so gut, alles wieder auf 250k gestellt und an einem DMX-Sender 
angeschlossen und bei:
1
valid_DMXData = 1;//====BREAKPOINT====
 einen Breakpoint gesetzt.

Nun erhalte ich AN diesem BREAKPOINT manchmal die richtigen Werte, was 
mich davon überzeugt, dass die baudrate richtig eingestellt ist!??
Doch dann einige Schleifen lang DmxRxField[0] = DmxRxField[1] = 0 usw.

jetzt meine Theorie: Wenn die Baudrate hin und wieder nicht sauber wäre 
(aufgrund des internen osc) würde ich doch erst garnicht so weit im Code 
kommen! (Also bis zum Breakpoint)

Sieht von euch Jemand den Fehler? (hier noch Mal der Code:)
1
void decode_DMX(void)
2
{
3
    new_DMXData = 1;
4
    uint8_t _FERR = RCSTAbits.FERR; //FERR bit must be read before reading the RCREG
5
    uint8_t _OERR = RCSTAbits.OERR;
6
    uint8_t DmxByte = RCREG; //get data AND clear FERR
7
    uint8_t DmxState = gDmxState; //
8
9
10
    if (_OERR )
11
    {
12
        RCSTAbits.CREN=0;    //Overrun error (can be cleared by clearing bit CREN)
13
        RCSTAbits.CREN=1;
14
    }
15
    if (_FERR)
16
    {
17
        //FERR stellt hier das BREAK da, welches sich von 0b00000000b11 durch die fehlenden Stopbits am Ende unterscheidet
18
        DmxSkipValue = DmxAddress; //Startadresse holen
19
        gDmxState = BREAK;
20
    }
21
    else if (DmxState == BREAK)
22
    {//Wir erwarten das Startbyte mit 0b00000000
23
        if (DmxByte == 0)
24
        {
25
            gDmxState = STARTBYTE; //normal start code detected
26
            //Pointer wird auf die zweite Array-Zelle gesetzt
27
            gDmxPnt = ((uint8_t*) DmxRxField + 1);
28
        }
29
        else gDmxState = IDLE;
30
    }
31
    else if (DmxState == STARTBYTE)
32
    {//Erster Kanal mit Nutzdaten auslesen
33
        if (--DmxSkipValue == 0)//Startaddress erreicht?
34
        {
35
            gDmxState = STARTADR;
36
            DmxRxField[0] = DmxByte;
37
        }//"else": der Counter wurde nur verringert und die Daten verworfen
38
    }
39
    else if (DmxState == STARTADR)
40
    {//Kanal 2,3,4,...wird ausgelesen
41
        uint8_t *DmxPnt; //lokaler Pointer...
42
        DmxPnt = gDmxPnt; //lokalen Pointer mit globaler Speicheradresse versehen
43
        *DmxPnt = DmxByte; //Daten an diese Speicheradresse eintragen
44
        if (++DmxPnt >= (DmxRxField + sizeof (DmxRxField))) //Alle Kanäle abgearbeitet?
45
        {
46
            gDmxState = IDLE;
47
            valid_DMXData = 1;//====BREAKPOINT====
48
        }
49
        else gDmxPnt = DmxPnt;
50
    }
51
}


Grüße Oekel

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Nachtrag: wenn ich einfach die Werte 0 von einem Kanal abfange, 
funktioniert alles wie gewollt. (auch ohne warnehmbare Verzögerung)
Dennoch muss da ja irgendwo ein Fehler sein, denn der Transmitter sendet 
ja zwischendurch nicht zum Spaß Nullwerte auf allen Kanälen.

Oekel

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Ich denke ich habe die Ursache ausfindig machen können, jedoch noch 
KEINE Lösung für dieses. :((

Ich habe die Vermutung, dass meine Routine innerhalb der 512 Kanäle 
nicht nur einen BREAK am Anfang ausfindig macht, sondern mitten in den 
restlichen Kanälen ebenfalls fälschlicherweise ein oder mehrere 
BREAKs/Framingerrors erkennt.

Zum testen habe ich bisher immer die Startadresse 1 genommen und auf den 
5 Folgekanälen einen DMX-Wert von 128 und mehr ausgegeben. Alle 
restlichen Kanäle standen auf 0.

Aufgrund meiner Vermutung habe ich nun Mal ALLE restlichen Kanäle auf 1 
gestellt, um zu testen ob ich bereits durch die Veränderung der 
"falschen Pause" von 0b00000000 auf 0b00000001 einen Unterschied 
bemerke.
Und tatsächlich kann ich keinen "falschen Break" mehr erkennen.

Nun frage ich mich, ob dies durch die Missachtung des vom PIC 
einstellbaren 9ten Bits sein kann, welches ja theoretisch das 1. von 2 
Stopbits repräsentieren könnte.

Allerdings finde ich keinen logischen Zusammenhang, denn wenn mein 
DMX-Sender 2 Stopbits sendet und mein Empfänger (PIC-CODE) nach nur 
einem sucht, sollte er doch in Jedem Fall fündig werden. (Ergo kann ich 
es ignorieren, dachte ich)

Kann es damit zusammenhängen? Wenn ja, bitte ich um Erläuterung.

Grüße Oekel

PS: Stimmt denn meine Vermutung überhaupt, dass ich die Baudradte 
mitlerweile gut getroffen haben MUSS, da überhaupt Daten ankommen?

von Falk B. (falk)


Lesenswert?

@  D a v i d K. (oekel)

>Ich habe die Vermutung, dass meine Routine innerhalb der 512 Kanäle
>nicht nur einen BREAK am Anfang ausfindig macht, sondern mitten in den
>restlichen Kanälen ebenfalls fälschlicherweise ein oder mehrere
>BREAKs/Framingerrors erkennt.

Kann sein.

>Allerdings finde ich keinen logischen Zusammenhang, denn wenn mein
>DMX-Sender 2 Stopbits sendet und mein Empfänger (PIC-CODE) nach nur
>einem sucht, sollte er doch in Jedem Fall fündig werden.

Ja.

> (Ergo kann ich
> es ignorieren, dachte ich)

Ja.

>PS: Stimmt denn meine Vermutung überhaupt, dass ich die Baudradte
>mitlerweile gut getroffen haben MUSS, da überhaupt Daten ankommen?

Nein. Das kann auch Zufall sein. Ist es denn SOOO schwer, einfach 
250kbit/s korrekt einzustellen?

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Falk Brunner schrieb:

> Nein. Das kann auch Zufall sein. Ist es denn SOOO schwer, einfach
> 250kbit/s korrekt einzustellen?

Eigentlich nicht, denn ich habe ja das Datenblatt. (und auch die Formeln 
verstanden)
Doch es gab hier ja Einige, die meinten, dass ich ohne externen Quarz 
gar nicht erst weiter probieren brauch. Laut Formel habe ich einen 
Abweichung von 0,0%. Daher müsste der interne OCR schon ziemlich falsch 
gehen, wenn allein durch diesen eine so hohe Abweichung erzeugt wird, 
dass alles für den A**** ist.

Grüße Oekel

von Falk B. (falk)


Lesenswert?

@  D a v i d K. (oekel)

>Doch es gab hier ja Einige, die meinten, dass ich ohne externen quarz
>garnicht erst weiter probieren brauch.

Würde ich auch nicht.

>Laut Formel habe ich einen
>Abweichung von 0,0%.

Sicher, aber in der Formel ist die Taktquelle als exakt angenommen.

>Daher müsste der interne OCR schon ziemlich falsch
>gehen, wenn allein durch diesen eine so hohe Abweichung erzeugt wird,
>dass alles für den A**** ist.

Nimm einen Quarz(oszillator).

http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART

von Chris B. (dekatz)


Lesenswert?

D a v i d K. schrieb:
> die meinten, dass ich ohne externen Quarz
>
> gar nicht erst weiter probieren brauch. Laut Formel habe ich einen
>
> Abweichung von 0,0%.

Formel und Taschenrechner sind geduldig.

Wenn du eine niedrigere Baudrate ohne Probleme hinbekommst sollte es 
auch für 250kBaud reichen.

Ich hätt einfach mal 20 Minuten investiert, einen Timer mit 1ms 
aufgesetzt, damit einen Pin getoggelt und die erzeugte Frequenz 
gemessen(dazu reicht der "Frequenzzähler" eines Multimeters).
Bei größerer Abweichung kann man mit dem OSCTUNE-Register am internernen 
Oszillator "drehen".

Zumindest wäre damit die Baustelle "Baudrate" abgeschlossen!
(bei dem Projekt scheit es ja noch mehr Baustellen zu geben ;-) )

von D a v i d K. (oekel) Benutzerseite


Lesenswert?

Chris B. schrieb:

> gemessen(dazu reicht der "Frequenzzähler" eines Multimeters).

Ich habe leider nur ein Mittelklasse Multi. Diese Funktion habe ich 
daran noch nie gesehen.

> Bei größerer Abweichung kann man mit dem OSCTUNE-Register am internernen
> Oszillator "drehen".
Das Register habe ich bereits mehrmals anfassen wollen. Aber ohne 
Messwerte schwierig.

> Zumindest wäre damit die Baustelle "Baudrate" abgeschlossen!
> (bei dem Projekt scheit es ja noch mehr Baustellen zu geben ;-) )

Ja das stimmt leider, werdet bestimmt heute Abend noch etwas Gejammer 
zum Thema 10Bit-PWM (8Bit funktioniert) und ADC hören ;)

Grüße Oekel

von Chris B. (dekatz)


Lesenswert?

D a v i d K. schrieb:
> Ich habe leider nur ein Mittelklasse Multi. Diese Funktion habe ich
>
> daran noch nie gesehen.

Mittelklasse???? Also in der 50€ Klasse haben die meisten nen 
"Frequenzzähler" der 0,1% Genauigkeit schafft - das reicht für solche 
Zwecke locker - aber ich möchte hier keinen Multimeter-Nebenschauplatz 
aufmachen weil sonst gleich die Fetzen fliegen ;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.