Forum: Mikrocontroller und Digitale Elektronik Konzept zum Auswerten von Lichtschranken gesucht


von Martin B. (methusalem)


Lesenswert?

Hallo zusammen,

ich möchte gerne 8 Lichtschranken in einer Slotbahn verbauen um damit 
vorbeifahrende Autos zu erfassen. Es geht nicht um Rundenzeitmessung, 
sondern um eine Plazierungsanzeige. Also wer ist im Rennen erster, 
zweiter, dritter, usw. Die Ausgabe soll dann auf kleinen 7 Segment 
Anzeigen im oder am Regler der Fahrer gemacht werden.

Die Autos werden vermutlich 10 Meter/Sekunde schnell und der Leitkiel 
der die Lichtschranke unterbricht, wird ca. 1cm lang sein. Das macht 
eine Unterbrechungsdauer von 1 Millisekunde.

Nun suche ich nach einer Möglichkeit die Lichtschranken auszuwerten. Es 
gibt ja zwei grundsätzlich unterschiedliche Ansätze. Zum einen könnten 
die Lichtschranken per externem Interrupt das Auslesen initiieren. Egal 
welche Lichtschranke unterbrochen wird, wird der ext. Interrupt 
aktiviert und alle Lichtschranken werden ausgelöst. Und zum anderen 
könnte ein interner Timer das Auswerten auslösen. Also entweder per 
Polling oder per Interrupt.

Mir fehlt noch jegliches Gefühl dafür, ob sich ein µController bei so 
was eher langweilt, oder ob er da schon kräftig arbeiten muss. Schön 
wäre ersteres, da der µController dann zukünftig auch noch andere 
Aufgaben übernehmen könnte.

Im Moment setze ich einen ATmega8515 ein. Und die Lichtschranken könnten 
zur Zeit einen Port blockieren (8 Eingänge).

Worauf muss ich bei meiner Planung achten, damit ich hierbei kein 
Timingproblem bekomme?

Gruß
Martin

von Karl H. (kbuchegg)


Lesenswert?

Martin Brehme schrieb:

> Mir fehlt noch jegliches Gefühl dafür, ob sich ein µController bei so
> was eher langweilt, oder ob er da schon kräftig arbeiten muss.

Lass ihn zwischendurch noch 'teuflisch schwierige quadratische 
Gleichungen lösen' (TM: Douglas Adams) sonst begeht dein AVR gleich 
Suizid, weil er nichts zu tun hat.

von Karl H. (kbuchegg)


Lesenswert?

Das Aufnehmen der Einlaufreihenfolge ist kein besonders grosses Problem, 
Polling sollte da Dicke reichen.

> Die Ausgabe soll dann auf kleinen 7 Segment
> Anzeigen im oder am Regler der Fahrer gemacht werden.

Darüber solltest du dir mehr Gedanken machen. Wie schliesst du 8 Stück 
7-Segment Anzeigen an einem µC an?

von guest (Gast)


Lesenswert?

8 Pins zur Auswahl der Anzeige und noch mal 8 gemeinsame Datenpins. Das 
ganze lässt sich doch dann ganz gut multiplexen

von Martin B. (methusalem)


Lesenswert?


von ... (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Wie schliesst du 8 Stück
>
> 7-Segment Anzeigen an einem µC an?

MAX7219

von ... (Gast)


Lesenswert?

Martin Brehme schrieb:
> damit ich hierbei kein
> Timingproblem bekomme?

und

Martin Brehme schrieb:
> der Leitkiel
> der die Lichtschranke unterbricht, wird ca. 1cm lang sein.

mmh, also wenn mehr als 2 im Abstand von 2-3mm hereinkommen hast du ein 
Problem, da hilft dann nur noch ein Zielfoto.

von Martin B. (methusalem)


Lesenswert?

Also verstehe ich Euch richtig: Polling wäre Eure Wahl. Mit meinem 
bisherigen Wissen ist das wohl auch einfacher umzusetzen.

> mmh, also wenn mehr als 2 im Abstand von 2-3mm hereinkommen hast du ein
> Problem, da hilft dann nur noch ein Zielfoto.

Also lassen wir die Kirche mal im Dorf! Wenn soetwas passiert, dann 
können die Autos gerne als Zeitgleich gewertet werden. Das muss dann 
halt nur bekannt sein, das es da Messgrenzen gibt.

Aber mal was anderes. Es wäre schön, wenn Ihr das mit den 2-3 mm noch 
mal ausführlicher erklären würdet. Ich möchte einfach verstehen, wie Ihr 
zu den Aussagen kommt. Wie oft z.B. sollte ich die Lichtschranken 
abfragen? Wie geht Ihr an solche Timingfragen heran?

von ... (Gast)


Lesenswert?

Wenn du einen ATmega64A nimmst hättest du 8 ext.Interrupt-Eingänge, die 
auf negative oder positive Flanke getriggert werden können.
An jedem Eingang hängt eine Lichtschranke (wichtig für die 
Unterscheidung der Bahn).
Der 1.Platz startet einen Timer und und der Startwert des Timers wird 
zwischengespeichert (0000). Die folgenden Plätze speichern nur die 
entsprechenden Zählerstände. Aus den Zählerstandswerten ermittels du die 
Rangfolge, setzt den Timer zurück und gibst die Rangfolge aus.

von Udo R. S. (Gast)


Lesenswert?

Die Probleme werden wohl woanders liegen...
Zum erkennen ob eine Lichtschranke ausgelöst hat genügt wenn man alle 
verodert im einfachsten Fall über ein Diodenarray. Den veroderten Wert 
dann an den externen Interrupt und im Interrupt alle 8 
Lichtschrankenstati solange auslesen bis alle wieder auf nicht mehr 
unterbrochen sind. So kann man auch erkennen wenn ein 2. Fahrzeug in 
eine Lichtschranke fährt wenn noch ein anderes drin ist.
Doch zur Berechung wer 1., 2., etc ist muss man auch die Rundenzahl der 
Fahrzeuge kennen. Da eine Lichtschranke im Slot rel. empfindlich für ne 
Fehlmessung ist kann das ins Auge gehen.
Ausserdem, wie steuert er die Displays in den Drückern an? Die sind 
normalerweise über eine oder mehrere Anschlussboxen mit 3 * 1 qmm CU 
Litze und 4mm Bananenstecker angeschlossen. Will er da noch ein 8pol 
Kabel mit passendem Stecker dazubinden?
Besser wäre wahrscheinlich eine Lösung, die die Impulse an den 
wahrscheinlich vorhandenen PC zur Rennsteuerung / Rundenzeiterfassung 
etc. weiterleitet und dem die Anzeige überlässt.

von ... (Gast)


Lesenswert?

Martin Brehme schrieb:
> wenn Ihr das mit den 2-3 mm noch

Habe ich jetzt mal so geschätzt....

Martin Brehme schrieb:
> Polling wäre Eure Wahl.

Also meine Wahl nicht, weil unter polling verstehe ich einen Eingang so 
lange abzufragen, bis sich was am Eingang ändert. Aber das würde den 
Proz. ja blockieren, es sei denn, ich hätte ein rtos laufen.

von doc (Gast)


Lesenswert?

>Also meine Wahl nicht, weil unter polling verstehe ich einen Eingang so
>lange abzufragen, bis sich was am Eingang ändert. Aber das würde den
>Proz. ja blockieren,

Und was hindert dich, in der Pollingschleife noch mehr zu machen, als 
nur den Eingang abzufragen ?

von ... (Gast)


Lesenswert?

doc schrieb:
> Und was hindert dich, in der Pollingschleife noch mehr zu machen, als
>
> nur den Eingang abzufragen ?

Die Möglichkeit, dass in der Zeit wo ich was anderes mache, ein Ereignis 
an dem Eingang auftreten kann das ich dann nicht mitbekomme.

von doc (Gast)


Lesenswert?

Man kann den Eingang auch mehrfach innerhalb der Schleife abfragen.
Aber irgendwann wirds unhandlich, stimmt, dann ist ein Interrupt besser.

Bis dahin gehts aber auch ohne ;-)

von ... (Gast)


Lesenswert?

doc schrieb:
> Bis dahin gehts aber auch ohne ;-)

Es geht immer ohne, man muss sich nur des Risikos bewußt sein ;)

von Karl H. (kbuchegg)


Lesenswert?

... schrieb:
> doc schrieb:
>> Und was hindert dich, in der Pollingschleife noch mehr zu machen, als
>>
>> nur den Eingang abzufragen ?
>
> Die Möglichkeit, dass in der Zeit wo ich was anderes mache, ein Ereignis
> an dem Eingang auftreten kann das ich dann nicht mitbekomme.

Kommt drauf an, was sonst noch so alles passieren soll.
So wie ich das sehe, muss er sich nicht aktiv um die Anzeige kümmern.
D.h. die Pollschleife ist im wesentlichen
1
  // alles auf Urzustand
2
  for( i = 0; i < 8; ++i )
3
    Einlauf[i] = 0;
4
  Counted = 0;
5
6
  alterWert = 0;
7
8
  // und los gehts
9
  while( alterWert != 0xFF ) {   // oder sonst irgendein Kriterium, das mir
10
                               // sagt, dass jetzt alles vorbei ist
11
12
    neuerWert = PINB;   // wenn dort alle 8 Eingänge der Lichtschranke hängen
13
    changed = ( neuerWert ^ alterWert );
14
    if( changed ) {
15
      // welches Bit ist in Changed gesetzt, das sagt mir, wer seine
16
      // Lichtschranke ausgelöst hat
17
      // Behandeln, indem zb die Bit-Nummer in Einlaufarray vermerkt wird
18
      mask = 0x01;
19
      for( i = 0; i < 8; ++i ) {
20
        if( ( changed & mask ) && ( neuerWert & mask ) ) {
21
          // TODO: die Nummer 'Counter' zum Kontroller i schicken
22
          Einlauf[Counted++] = i;
23
        }
24
        mask <<= 1;
25
      }
26
      alterWert = neuerWert;
27
    }
28
  }

Das erzeugt im Array Einlauf die (fast) richtige Einlaufreihenfolge. 
'Fast' deswegen, weil bei 'zeitgleichen' Einläufen die Lichtschranke mit 
der kleineren Nummer den Vorzug bekommt, auch wenn beide registriert 
werden.

Bei den Zeitvorgaben, die er hat, ist das denke ich mal schnell genug. 
Die Nummer mit dem Versenden der Einlaufnummer an den jeweiligen 
Kontroller könnte allerdings etwas Zeit verschlucken. Das müsste man 
jetzt durchrechnen, ob sich das ausgeht, dass in der Zeit nicht ein 
Einlauf unentdeckt bleibt.

von Martin B. (methusalem)


Lesenswert?

Noch mal ein paar Basics:

Ob die Anzeige jetzt tatsächlich in oder an den Regler kommt, steht noch 
nicht fest. Es würde aber dann wohl ein eigenes Kabel genutzt, da man ja 
nicht extra den Regler umbauen will, wenn man die Anzeige nutzen will. 
Die Anzeige würde wohl eher an die Regler "angesteckt" da die Fahrer ja 
in der Regel alle eigene Regler nutzen.

Im ersten Schritt werden die Anzeigen vermutlich "nur" in direkter Nähe 
zum Fahrerstand sein. Die Daten sollen nicht an einen PC weitergegeben 
werden. Es geht gerade darum unabhängig von einem PC zu sein.

Zu Euren Ausführungen:
> Zum erkennen ob eine Lichtschranke ausgelöst hat genügt wenn man alle
> verodert im einfachsten Fall über ein Diodenarray. Den veroderten Wert
> dann an den externen Interrupt und im Interrupt alle 8
> Lichtschrankenstati solange auslesen bis alle wieder auf nicht mehr
> unterbrochen sind.

Genau das war mein ursprünglicher Plan. Für jede Unterbrechung einer 
Lichtschranke wird dann ein Rundenzähler für diese Lichtschranke 
inkrementiert. Bei gleicher Rundenzahl muss ich aber noch wissen, wer 
zuerst durch die Lichtschranke durchgefahren ist. Wie würdet Ihr Euch 
das merken? Timer starten und den Timer speichern? Bei der Auswertung 
würde man dann erst die Rundenzähler auswerten und nur bei Gleichstand 
auch den Timer.

> Da eine Lichtschranke im Slot rel. empfindlich für ne
> Fehlmessung ist kann das ins Auge gehen.

Lichtschranken in Slots sind in dem Bereich der absolute Standard und 
ausgereift. Da würde ich einfach auf vorhandene Technik zurückgreifen.

Auf den Bahnen die ich kenne gibts da wegen der Lichtschranken die 
wenigsten Probleme.

Martin

von ... (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Die Nummer mit dem Versenden der Einlaufnummer an den jeweiligen
>
> Kontroller könnte allerdings etwas Zeit verschlucken.

Das kann er ja machen wenn alle Bits gesetzt sind, d.h. wenn alle im 
Ziel angekommen sind.
Kleine Zeitschleife davor und alle warten gespannt auf das Ergebniss ;)

von Martin B. (methusalem)


Lesenswert?

@Karl heinz Buchegger: Wenn ich deinen Code richtig lese, dann 
funktioniert das nur dann, wenn alle Wagen in der gleichen Runde sind. 
Sobald ein Wagen den letzten Wagen überrundet steht er an der falschen 
Position im Array.

von Karl H. (kbuchegg)


Lesenswert?

Martin Brehme schrieb:

> Genau das war mein ursprünglicher Plan. Für jede Unterbrechung einer
> Lichtschranke wird dann ein Rundenzähler für diese Lichtschranke
> inkrementiert. Bei gleicher Rundenzahl muss ich aber noch wissen, wer
> zuerst durch die Lichtschranke durchgefahren ist. Wie würdet Ihr Euch
> das merken? Timer starten und den Timer speichern? Bei der Auswertung
> würde man dann erst die Rundenzähler auswerten und nur bei Gleichstand
> auch den Timer.

Ich würde mir was ähnliches ausdenken wie weiter oben:
Gleich wenn die ISR aktiviert wird, wird die neue Platzierung erstellt.

Wie ist das eigentlich:
Gibt es bei solchen Rennen eine Rundenvorgabe oder wird da eine 
bestimmte Zeit gefahren und wer die meisten Runden fertig fährt gewinnt?

Je nachdem würde ich mir eine andere Strategie ausdenken.
Bei einer fixen Rundenzahl bietet sich zb an.
Alle starten mit der Rundenzahl. Bei aktivierung seiner Lichtschranke 
wird die zugehörige Rundenzahl um 1 verringert. Ist die dann 0, dann ist 
er im Ziel und die Slotnummer wird im Einlaufarray eingetragen. Ob das 
dann über Polling oder Interrupt funktioniert, ist gleichgültig.

von Karl H. (kbuchegg)


Lesenswert?

Martin Brehme schrieb:
> @Karl heinz Buchegger: Wenn ich deinen Code richtig lese, dann
> funktioniert das nur dann, wenn alle Wagen in der gleichen Runde sind.
> Sobald ein Wagen den letzten Wagen überrundet steht er an der falschen
> Position im Array.

Ja. Daran hab ich nicht gedacht. Aber siehe Folgeposting. Das kann man 
leicht lösen, indem man die Runden mitzählt.

von Karl H. (kbuchegg)


Lesenswert?

Möchtest du eigentlich auch zwischendurch die momenatenen Positionen 
wissen? Dann würde sich zb ein stabiles Sortieren anbieten. Bei 8 
Teilnehmern ist das noch trivial.
Am Anfang hast du ein Platzierungsarray in dem alle Teilnehmer mit ihren 
Slotnummern und ihrer Rundenzahl enthalten sind.
Löst eine Lichtschranke aus, so wird der Eintrag dort anhand der 
Slotnummer gesucht und die entsprechende Rundenzahl erhöht bzw. 
erniedrigt. Dann wird der Eintrag nach vorne verschoben, solange die 
Rundenzahl größer (kleiner) ist, als mit einem anderen Eintrag (oder man 
ganz vorne im Array angelangt ist :-)

Macht man das konsequent, so liegt in diesem Array ständig die aktuelle 
Reihung vor und natürlich auch das Endergebnis bei Rennende.

von yalu (Gast)


Lesenswert?

Ich würde mit einem Abfragetakt von etwa 100µs, getriggert durch einen
Timer-Interrupt, alle 8 Lichtschrankensignale (das ist gerade eine
Port-Breite) als ein Byte einlesen und mit dem zuletzt gelesenen Byte
per XOR-Verknüpfung vergleichen. Ist das Ergebnis 0, ist nichts weiter
zu tun. Ist es von 0 verschieden, wird überprüft, welche Bits sich von 0
nach 1 geändert haben. Für die zugehörigen Fahrspuren wird der Runden-
zähler weitergezählt und die Zeit abgespeichert. Am Schluss hast du für
jedes Auto die Gesamtzeit und alle Rundenzeiten.

Das Abfragen und Vergleichen im Interrupt kostet nur wenige Taktzyklen,
lassen wir es, pessimistisch geschätzt, 30 sein. Wird eine Lichtschranke
unterbrochen, wird etwas mehr gerechnet, aber das passiert ja nur selten
und fällt rechenzeitmäßig kaum ins Gewicht. Bei einem CPU-Takt von
16MHz entsprechen die o.g. 100µs 1600 Zyklen. Davon werden durch die
Lichtschrankenauswertung 30 Zyklen verbraucht, also weniger als 2%. Die
restlichen 98% stehen für das Lösen teuflisch schwieriger quadratischer
Gleichungen zur Verfügung :)

Die damit erreichbare 100µs Zeitauflösung entspricht einer Wegauflösung
von 1mm, was nach deiner Aussage weiter oben ja locker ausreichen
sollte. Wenn deine Lichtschranken präzise genug sind, kannst du den
Abfragetakt auch noch schneller machen.

Mit 8 Pin-Change-Interrupts geht es natürlich ebenso, wenn der Control-
ler über solche verfügt. Es gibt noch viele andere Möglichkeiten, die
Aufgabe zu lösen, was zeigt, dass diese zu leicht ist, um noch lange
darüber zu diskutieren. Fang mit der Arbeit einfach an und hab Spaß :)

von Martin B. (methusalem)


Lesenswert?

> Wie ist das eigentlich:
> Gibt es bei solchen Rennen eine Rundenvorgabe oder wird da eine
> bestimmte Zeit gefahren und wer die meisten Runden fertig fährt gewinnt?

Es gibt beides. Gängig ist aber eigentlich ein Rennen mit fest 
vorgegebener Zeit.

von Martin B. (methusalem)


Lesenswert?

Karl heinz Buchegger schrieb:
> Möchtest du eigentlich auch zwischendurch die momenatenen Positionen
> wissen? Dann würde sich zb ein stabiles Sortieren anbieten. Bei 8
> Teilnehmern ist das noch trivial.

Ja, hatte ich vergessen. Es geht um die aktuelle Plazierung WÄHREND des 
Rennens!

von Martin B. (methusalem)


Lesenswert?

yalu schrieb:
> Es gibt noch viele andere Möglichkeiten, die
> Aufgabe zu lösen, was zeigt, dass diese zu leicht ist, um noch lange
> darüber zu diskutieren. Fang mit der Arbeit einfach an und hab Spaß :)

LOL - schließ nicht von dir auf meine Wenigkeit. Für mich ist das schon 
eine Herausforderung. Aber du hast recht ... learning by doing.

Das Projekt ist - aufgrund seiner Einfachheit - vielleicht aber 
besonders geeignet für mich um einen Einstig in die µController zu 
finden.

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:

> Am Anfang hast du ein Platzierungsarray in dem alle Teilnehmer mit ihren
> Slotnummern und ihrer Rundenzahl enthalten sind.

In Code skizziert
1
struct Rank {
2
  uint8_t Slot;
3
  uint8_t Rounds;
4
};
5
6
struct Rank Ranking[8];
7
8
void StartRace()
9
{
10
  for( i = 0; i < 8; ++i ) {
11
    Ranking[i] = i;     // slots werden bei 0 beginnend gezählt
12
    Rounds[i] = 0;      // alle stehen am Start
13
  }
14
}
15
16
void PassedBy( uint8_t slotNr )    // am Slot slotNr wurde eine Durchfahrt
17
                                   // registriert
18
{
19
  for( i = 0; i < 8; ++i ) {
20
    if( Ranking[i].Slot == slotNr ) {    // da ist er ja
21
      Ranking[i].Rounds++;               // er hat jetzt 1 Runde mehr fertig
22
      // die Reihung entsprechend umstellen
23
      j = i - 1;
24
      while( j > 0 && Ranking[j].Rounds < Ranking[i].Rounds ) {
25
        tmp = Ranking[i];
26
        Ranking[i] = Ranking[j];
27
        Ranking[j] = tmp;
28
        i--;
29
        j--;
30
      }
31
32
      // ev. Anzeigetafel aktualisieren. Das Ranking ist wieder aktuell
33
      // Erster im Rennen ist Ranking[0].Slot
34
      // Zweiter im Rennen ist Ranking[1].Slot
35
      // Dritter ist Ranking[2].Slot
36
      // etc.
37
      return
38
    }
39
  }
40
}


Ich hab das jetzt schnell runtergeschrieben. Da werden sicher noch 
kleiner Fehler sein, aber das Prinzip sollte hinkommen (und Datentypen 
darfst du dir selbst ausdenken :-)

Das läuft dann so
Am Anfang ist die Situation die  (die erste Zahl ist die Slotnummer, die 
zweite Zahl die Rundennummer)

     0/0  1/0  2/0  3/0  4/0  5/0  6/0  7/0  8/0

jetzt wird bei Slot 3 ausgelöst. Der Eintrag mit der Slotnummer 3 wird 
gesucht und seine Rundenzahl erhöht

     0/0  1/0  2/0  3/1  4/0  5/0  6/0  7/0  8/0

und anschliessend wird der Eintrag solange nach links verschoben, wie 
seine Rundenzahl größer ist als aller seiner linken Nachbarn

     3/1  0/0  1/0  2/0  4/0  5/0  6/0  7/0  8/0

Das heisst also: momentan liegt die Slotnummer 3 vorne und ist erster

Jetzt löst Slot 6 aus. Wieder: suchen und erhöhen

     3/1  0/0  1/0  2/0  4/0  5/0  6/1  7/0  8/0

und nach links verschieben, solange der linke Nachbar eine kleinere 
Rundenzahl aufweist

     3/1  6/1  0/0  1/0  2/0  4/0  5/0  7/0  8/0

Aha. 3 ist erster, 6 ist zweiter. Alle anderen dahinter

Auf Slot 1 wird ein Durchgang registriert

     3/1  6/1  1/1  0/0  2/0  4/0  5/0  7/0  8/0

Slot 3 war weit vorne, hatte aber einen Unfall. Slot 6 kommt als 
nächster bei Start/Ziel vorbei (bei 6 eine Runde raufzählen und nach 
links verschieben, weil seine Rundenzahl höher ist als die seines linken 
Nachbars)

     6/2  3/1  1/1  0/0  2/0  4/0  5/0  7/0  8/0

1 kommt durchs Ziel

     6/2  1/2  3/1  0/0  2/0  4/0  5/0  7/0  8/0

3 hat sich erfangen und kommt auch durch

     6/2  1/2  3/2  0/0  2/0  4/0  5/0  7/0  8/0

Auch 4 hat sich nach einem Unfall nach dem Start gefangen und kommt 
jetzt erstmals durchs Ziel

     6/2  1/2  3/2  4/1  0/0  2/0  5/0  7/0  8/0

(Beim linksschieben ist er über die '3' nicht drübergeschoben worden, 
weil ja '3' mehr Runden aufweist als '4')
Jetzt haben 6, 1 und 3 einen Unfall und 4 holt eine Runde auf

     6/2  1/2  3/2  4/2  0/0  2/0  5/0  7/0  8/0

6, 1, und 3 sind immer noch auf der Bahn, aber 4 holt eine weitere Runde 
auf ...

     4/3  6/2  1/2  3/2  0/0  2/0  5/0  7/0  8/0

... und ist plötzlich erster, weil er die meisten Runden hat


etc.
Das Array enthält zu jedem Zeitpunkt die aktuellen Platzierungen :-)

von Martin B. (methusalem)


Lesenswert?

Schöne Erklärung! Zur Einweihung kommst du vorbei? Wenn du keinen Bock 
aufs fahren hast, darfst du auf jeden Fall die Rennen kommentieren. :-)

Ich schau mir das alles heute Abend in Ruhe noch mal an ...

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.