Forum: Mikrocontroller und Digitale Elektronik serielle Schnittstelle


von florian (Gast)


Lesenswert?

moin,
wollte mal nachfragen wie das bei der verbindung eines µC mit PC durch
die serielle schnittstelle funktioniert.
macht man eine software zur sicheren bzw. quittierten (handshake)
übertragung auf der µC seite (assambler) oder kann man z.b. mit visual
basic den port auslesen und die handshake methode anwenden?
man könnte dann evtuell im vb code eine active x (dll) eines auswerte
programms anbinden und diese werte quasi sofort darstellen.

mfg
florian

von crazy horse (Gast)


Lesenswert?

Handshake ist i.a. nicht erforderlich, es sei denn, der MC hat sowohl
viele Daten zu empfangen kann durch andere zeitkritische Sachen fast
völlig blockiert sein. Bei hohen Datenraten ist das auch kritischer als
bei den meist üblichen 9600/19200 Baud.
MC-Schnittstelle im Interrupt-Betrieb mit entsprechend ausgelegten
Datenpuffern, dann gibts i.a. keine Probleme.

von Gregor (Gast)


Lesenswert?

Hallo,

da ich mich auch für dieses Thema interessiere, wollt ich mal anfragen,
ob jemand ein Tutorial oder eine Dokumentation diesbezüglich empfehlen
kann. Ich programmiere in Dev-C++ und CodeVision. Die Google Suche hat
leider nur jede Menge Offtopic hervorgebracht.

Gruß und Dank
Gregor

von florian (Gast)


Lesenswert?

hallo,
bei mir ist das der fall das es viele daten sind. möchte messen und die
signalwerte sicher an pc schicken, deshalb brauche ich diesen handshake.
aber wo programmiere ich das ganze????? am besten, hat nicht jemand
schon sowas gemacht vielleicht fällt mir das leichter wenn ich ein
beispiel gesehen habe.

mfg
florian

von Markus_8051 (Gast)


Lesenswert?

Wenn Du wirklich sicherstellen willst, daß die Daten am PC ankommen,
helfen die Handshake-Leitungen auch nicht. Dazu würde ich die Daten
blockweise vom µC zum PC senden. Jeder Block bekommt eine fortlaufende
Nummer und eine Prüfsumme. So kann der PC feststellen, ob er alle
Blöcke richtig empfangen hat. Fehlerhafte oder verlorene Blöcke kann
der PC dann beim µC nochmal anfordern.

Gruß,
Markus_8051

von florian (Gast)


Lesenswert?

hallo,
ja genau so habe ich es vor. wie meine blöcke aussehen sollen weiss ich
auch schon.
nur kann ich mir das softwaretechnisch nicht so richtig vorstellen.
das senden programmiere ich im µC aber die quittung muss mir der PC
geben! und wenn ich diese geschichte im µC programmiere, wocher weiss
der PC das er antworten soll und vorallem wie???????
wie macht er das genau?
muss ich am PC auch noch eine software programmieren, das die daten die
am port liegen gelesen werden sollen usw.??????????

mfg
florian

von florian (Gast)


Lesenswert?

hat keiner mal so was gemacht oder ist das das einfachste auf dieser
welt und nur ich verstehe es nicht???

mfg
flo

von Martin S. (Gast)


Lesenswert?

Du solltest  etwas intensiver "auf dem Problem rumdenken". Wichtig ist
erst mal daß du dir da Gedanken machst wie das ablaufen kann.


Guckst du z..B. mal hier, da hatte ich schon mal sowas skizziert:
http://www.mikrocontroller.net/forum/read-1-170527.html#171387

von Markus_8051 (Gast)


Lesenswert?

Hi Flo,

ja, Du müßt auf der PC-Seite auch noch ein Programm haben, welches die
Daten vom µC entgegennimmt und entsprechend antwortet. Aber so wie ich
das verstanden habe, waren es ja eh irgendwelche Meßdaten, die noch
weiter verarbeitet werden sollen.

In welcher Sprache programmierst Du auf dem PC?

Gruß,
Markus_8051

von Martin S. (Gast)


Lesenswert?

Zur Ergänzung:

SICHERLICH mußt du auf beiden Seiten das Hände-Schütteln programmieren.


UC will (viele) Daten los werden, und PC will die Daten (vollständig)
empfangen.

Eine sicher(er)e Übertragung kann man abbilden, indem einzelne Blöcke
mit Prüfsummen versehen werden. UC ermittelt eine Prüfsumme und sendet
deise (inclusive der Nutzdaten) zu PC. PC wendet auf die uebersandten
Nutzdaten den gleichen Prüfsummen-Algorithmus an udn vergleicht die
übermittelten mit den selber errechneten Werten. Bei Abweichung wird
gemeckert.

eine vollständige Übertragung kann man abbilden, indem einzelne Blöcke
mit einer fortlaufenden Paketnummer versehen werden. UC hat eine
gewisse Puffergröße (z.B. für 10 Datenblöcke). PC quittiert dem UC den
erfolgreichen Empfang (bzw. auch den nicht erfolgreichen Empfang) jedes
einzelnen Datenblocks incl. dessen Blocknummer. Die sich ergebenden
Aktionen sind ziemlich offensichtlich: Wenn Block entsprechend
übermittelt werden konnte, dann kann der betreffende Sendepuffer
freigeräumt / wiederverwendet werden, ansonsten bleiben die Daten da
drin (für späteren neu angeforderten Versand)

Gehen Daten kaputt, dann kann der PC das dem UC melden, und UC schickt
einfach den betroffenen Block noch mal rüber.

Was d nun noch machen must is dir etwas zur eigentlichen Flusskontrolle
zu überlegen. Zuerst mußt du überlegen welches Verfahren du haben
möchtest, wer also "der Treibende" ist: Da gibts 2 Mitspieler: UC
und/oder PC. Es ergeben sich folgende Möglichkeiten:

A) UC sendet (unaufgefordert) immmer von sich aus Daten, sobald ihm
danach ist. PC schickt Rückmeldung an UC, wenn es ihm zu viel wird. UC
berücksichtigt dies und hält erst mal inne mit seiner Senderei. Nach
einer gewissen Zeit fragt UC beim PC an, ob dieser wieder Lust zum
Datenempfang hat.

B) PC ist die treibende Kraft und fordert vom UC "immer neue
Datenpakete". UC befriedigt die Datenanfragen (so er welche hat), bzw.
teilt dem PC mit "hab grad nix"

C) eine Kombination aus A) und B)


Ich hoffe nun hast du schon mal ein paar globale Ideen. In welcher
Programmiersprache du das codierst (Basic oder C oder Assembler) ist
dann für die weitere Betrachtung deinem persönlichen Geschmack /
Geschick überlassen

von Martin S. (Gast)


Lesenswert?

@Markus_8051
"Aber so wie ich das verstanden habe, waren es ja eh irgendwelche
Meßdaten, die noch weiter verarbeitet werden sollen."


Grundsätzlich richtig, aber man solte trennen:

UC: Datensammlung / Aufbereitung
UC: Datentransport / Handshake

PC: Datentransport / Handshake
PC: Aufbereitung / Präsentation

von florian (Gast)


Lesenswert?

Hallo,
danke für eure hilfe.
auf der UC seite programmiere ich mit assambler und PC seite mit VB.

meine probleme sind das ich noch nicht viel programmiert habe mit
schnittstellen und vorallem nicht in assambler (bin aber fleissig
dabei).
habe mir das auch schon so überlegt mit diesen blöcken bzw. davon
gelesen und versucht in meine applikation zu binden.
vielleicht erkläre ich mal was ich mir vorstelle, was ich weiss und wo
der knotten sitzt:
1. die daten im UC in diese Blöcke zu packen und z.b. eine crc drüber
und die checksumme dran. so dann wäre mein block quasi fertig, wie man
das genau in assambler machen soll mit crc und die
startkennung&blocknr&status&daten&crc zusammenpacken????was weiss
ich????bitte um beispiele am besten.
2.das packet in den ausgangsport und weg damit.
3.mit VB den COM port auszulesen wird schon irgendwie hinhauen. dann
daten lesen und den Block zerpflücken, da ich weiss was was ist, über
die nutzdaten mein generatorpoly drüberjagen und schauen ob fehlerhaft
oder nicht. wenn ok dann daten speichern. aber wo und wie werden die
daten zwischengespeichert? sofort in eine datei????
wenn die daten ok sind, was könnte ich am besten zurück schicken? ein
ok?
und wie würde mein UC das am besten verarbeiten??


denke das reicht erstmal. also das packen ,crc und auf der PC seite das
datenhandling sind wohl meine hauptprobleme.

danke für eure hilfe im vorraus

mfg
flo

von Martin S. (Gast)


Lesenswert?

Es sind 2 verschiendene Dinge die da "hin und her" gehen:

Zum einen Steuerinformationen, zum anderen "Nutzlast" (die
eigentlichen zu übermittelnden Meß-Daten oder andere Art von Info)

Das folgende ist einfach mal so "frei fantasiert", die Richtung (wer
wem was sendet) ist ziemlich offensichtlich.

CMDxx: ist eine frei von mir erfundene Kurzbezeichnung für die
einzelnen Kommandos. Das könnte z.B. durch eine 1-Byte-Variable
abgebildet werden.


CMD00: "Gib mir das nächte dir bekannte Datenpaket" [PC an UC]
CMD01: "Gib mir mal das Datenpaket Nr. xxx"  [PC an UC]
CMD02: "Halt erst mal, ich kann nicht mehr"  [PC an UC, sowie  UC an
PC]
CMD03: "darf ich ein neues Datenpaket schicken ?" [UC an PC]
CMD04: "ich habe kein Daten mehr zum übermitteln" [UC an PC]
CMD05: "Schmeiss alle deine Daten aus all deinen Puffern weg und fange
ganz von vorne an" [PC an UC]
CMD06: "Dieses Datenpaket steht nicht zur Verfügung" [UC an PC]
CMD07: "Dies ist das Datenpaket xxx" [UC an PC]
CMD08: "Die folgenden Datenpakete sind noch in meinem Ausgangspuffer"
[UC an PC]


(da fallen dir bestimmt noch mehr ein. Du mußt auch nicht alle und
nicht alle sofort implementieren.)



Ein Päckchen könnte dann z.B. so aussehen:

CMDxx | Info
bzw.
CMDxx | Länge von Nutzdaten | Nutzdaten | CRC


CRC ist angenommene 2 bytes, und wird auf Meßdaten angewendet


Und nun gehts los mit dem Gequassel:

Nach dem Einschalten fallen beide in Starre und UC wartet drauf, daß PC
ihn anspricht. Irgendwann passierts:

PC an UC: CMD05
UC an PC: CMD03
PC an UC: CMD00
UC an PC: CMD07   0010   01 2B FC A3 86 8A 9B C4 31 BF 99 64 A3 01 61
9D    4711
PC an UC: CMD00
UC an PC: CMD07   0003   A8 65 2A    761A




Bei Variabler Blockgröße wie hier skizziert muß du halt auf Sender- udn
Empfangsseite die Blockgröße jedes einzelnen Blocks mit protokollieren.
Oder du nimmst feste Blockgrößen, dann mußt du aber entsprechend
Speicher vorhalten.

von Martin S. (Gast)


Lesenswert?

Hupps, ich seh grade: Bei Meinem Befehl "CMD07" im Beispiel fehlt die
Blocknummer. Denk sie dir einfach dazu an passender Stelle

von florian (Gast)


Lesenswert?

moin,
danke martin.
werde versuchen es so hinzubekommen und die anweisungen in code
umzusetzen, falls ich fragen habe melde ich mich nochmal.


hast du vielleicht schon was mit crc gemacht???
geht das so einfach das man sich irgendein generatorpolynom nimmt, der
UC und PC bekannt ist und eine polynomdivision durch die nutzdaten
macht. den rest an die nutzdaten hängt und schickt. am PC dann nochmal
polynomdivision mit den selben divisor durch nutz+checksumme und wenn
das gleich 0 ist, dann ist alles ok??????????????

flo

von Rolf F. (Gast)


Lesenswert?

Für die PC-Seite gibt es das Serial Programming Howto; da kann man
nachlesen, wie man nach dem Posix-Standard serielle Schnittstellen
anspricht. Um alle Parameter richtig einzustellen (blocking/nonblocking
mode, bits/byte, Parity, rate, usw.) braucht man einige Zeilen und zum
Empfangen braucht man eine Funktion wie select, damit man auch ein
Timeout hat.
An Leitungen wird zu 99 % nicht mehr als RxD und TxD (+Masse)
verwendet, denn die Daten werden von der Hardware bidirektional autonom
eingelesen/ausgesendet und dann (wenn der Buffer leer bzw. voll ist) ein
IRQ ausgelöst; da ist kein Handshake nötig und viele serielle Kaben
haben die Adern dafür überhaupt nicht (d. h. nur RxD, TxD u. Masse sind
in dem seriellen Kabel).
Es gibt verschiedenste Prüfsummen, aber mehr als ein Byte bläht den
Traffic unnötig auf, denn schließlich kann eine Prüfsumme selber
fehlerhaft übertragen werden und mehr als einige (nich alle) Fehler
feststellen kann man damit nicht. Üblich ist beispielsweise das EXOR
von Byte0, Byte1 usw. als ein-Byte-Prüfsumme zu übertragen.
Wenn man genügend Bandbreite hat, kann man auch ECC nehmen. Im
einfachsten Fall werden die Daten dreimal übertragen und ausgegeben
wird dann die 2-von-3-Funktion, also (in ANSI-C):
(x0 bitand x1) bitor (x1 bitand x2) bitor (x2 bitand x0)
Damit werden alle 1-Bit-Fehler automatisch korrigiert. Meist werden
platzsparendere Codes verwendet, die auch 1-Bit-Fehler korrigieren,
aber zusätzlich 2-Bit-Fehler erkennen.

Beim Mikrocontroller sollte natürlich sowas wie ein Mutex oder Semaphor
verwendet werden, damit nicht aus erst halb gefüllten Buffern gelesen
wird oder in noch halb gefüllten Buffern der benötigte Inhalt
überschrieben wird. Aus der Betriebssytem-Theorie sollte das aber so
ziemlich jedem MC-Programmierer bekannt sein.

Zum Timing kann es auch nötig sein Wartezyklen zwischen den
ausgetauschen Datenpaketen einzufügen, denn für eine Antwort wird ja
einige Zeit benötigt und meist kann nur jeweils eine Antwort erzeugt
werden.

von Martin S. (Gast)


Lesenswert?

Zur Erläuterung für Florian
> und dann (wenn der Buffer leer bzw. voll ist) ein IRQ ausgelöst;

Damit ist der Baustein-Puffer gemeint, welcher serielle Daten in
parallele Daten wandelt, der ist ca. 1-16 bytes groß. Den Sende- bzw.
Empfangspuffer auf UC bzw PC Seite "schöpft" aus diesem
Daten-Eingangspuffer sein Daten. Diese Puffer (also Sende- und
Empfangspuffer) mußt du bzw. dein Programm verwalten, während die
Baustein-Puffer und einiuge Steuerleitungen (so Sachen wie RTS, CTS,
DTR, DSR, DCD etc) großteils von der Baustein-HArdware selbst verwaltet
werden.


> Beim Mikrocontroller sollte natürlich sowas wie ein Mutex oder
Semaphor verwendet werden, damit nicht aus erst halb gefüllten Buffern
gelesen wird oder in noch halb gefüllten Buffern der benötigte Inhalt
überschrieben wird.

Diese Aussage ist sachlich vollkommen korrekt, aber ....

> Aus der Betriebssytem-Theorie sollte das aber so
ziemlich jedem MC-Programmierer bekannt sein.

... ich hatte nicht den Eindruck, daß Florian (schon)
Betriebssystem-Theorie-Vorlesungen besucht hat.

Zur Erläuterung für Florian: Das sind definierte
Synchrionisationsmechanismen "Innerhalb" eines Programmablaufs.
Ergoogle dir das einfach mal.

> Zum Timing kann es auch nötig sein Wartezyklen zwischen den
ausgetauschen Datenpaketen einzufügen, denn für eine Antwort wird ja
einige Zeit benötigt und meist kann nur jeweils eine Antwort erzeugt
werden.

Das wird meines Erachtens besser mit request/response gelöst werden,
anstelle daß der eine oder andere Beteiligte zwangsweise Däumchen
dreht.

von Rolf F. (Gast)


Lesenswert?

> Das wird meines Erachtens besser mit request/response gelöst werden,
> anstelle daß der eine oder andere Beteiligte zwangsweise Däumchen
> dreht.

Das geht nur, wenn man das Protokoll ganz einfach halten kann, also z.
B. der MC nur auf Anfragen vom PC antwortet, aber aber auch dann muß
man ein Timing festlegen, damit der MC nicht überfordert wird. Über
Funktionen wie gettimeofday kann man das beim PC ja millisekundengenau
einhalten.

Außerdem sollte die Verarbeitung im MC nicht blockierend realisiert
sein, beispielsweise mit Zustands-Flags. Ich habe nämlich schon öfters
mit quick and dirty-Software arbeiten müssen, die für irgendwelche
Eingaben über Tasten in kleinen Schleifen so lange loopt, bis die
Eingabe abgeschlossen ist, so daß in dieser Zeit (typischerweise einige
Sekunden bis Minuten; beim Stehenlassen auch Monate) dann Anfragen von
Außen nicht bearbeitet werden, obwohl der MC zu 99,999 % nichts zu tun
hat. Und so ein Unsinn muß ja nicht sein.

von peter dannegger (Gast)


Lesenswert?

@Rolf,

"Aus der Betriebssytem-Theorie sollte das aber so
ziemlich jedem MC-Programmierer bekannt sein."

Das beißt sich aber.
Die meisten MCs haben kein OS und die meisten MC-Programmierer (ich
auch) kommen aus der Hardware.

Mit "Mutex oder Semaphor" kann ich daher überhaupt nichts anfangen.


Ich nehme relativ einfach gestrickte Protokolle:

Die Kommandos werden als Text übertragen, d.h. jedes Kommando endet mit
0x0A und/oder 0x0D.
Damit ist sichergestellt, daß keine Synchronisationsprobleme
auftreten.
Jedes Kommando wird vom MC mit einem Byte quittiert (ob falsch oder
richtig).
Anfragen an den MC erhalten zusätzlich noch den Antworttext (wieder mit
0x0A und/oder 0x0D abgeschlossen).

In meinem Bootloader (Codesammlung) findest Du dazu ein Beispiel, da
ist sogar eine 16-Bit CRC mit drin, die mit einem Kommando überprüft
werden kann.


Peter

von Rolf F. (Gast)


Lesenswert?

@Peter,

> "Aus der Betriebssytem-Theorie sollte das aber so
> ziemlich jedem MC-Programmierer bekannt sein."
>
> Das beißt sich aber.
> Die meisten MCs haben kein OS und die meisten MC-Programmierer (ich
> auch) kommen aus der Hardware.

Wenn da kein OS drauf ist, dann ist dein Programm quasi das OS. Deshalb
muß man sich ja darum kümmern. Mit einem richtigen OS kann man ja Posix-
und Kernel-Threads mit den üblichen Synchronisationmechanismen
verwenden; beim MC muß man sowas minimalisiert selber machen.


> Mit "Mutex oder Semaphor" kann ich daher überhaupt nichts
anfangen.

Ein Mutex ist ein Flag (Bit einer volatile Variablen) das z. B.
bedeutet "Buffer0815 wird verwendet; nix mehr hineinschreiben"; ganz
einfach.


> Ich nehme relativ einfach gestrickte Protokolle:
>
> Die Kommandos werden als Text übertragen, d.h. jedes Kommando endet
mit
> 0x0A und/oder 0x0D.
> Damit ist sichergestellt, daß keine Synchronisationsprobleme
> auftreten.

Naja, fehlertolerant ist das nicht und als Text sind die Datenpakete
größer als binär.
Deshalb verwende ich zur Synchronisation als Erstes die Timings, also
z. B. mindestens 10 ms zwischen dem Ende den letzten Datenpaketes und
dem Anfang den neuen (ansonsten wird verworfen) und zwischen
Datenpaket-Anfang (erstes Byte) und -Ende müssen zwischen 1 und 20 ms
vergehen.
Das ist auch auf PC-Seite mit select und gettimeofday ganz einfach
machbar
(auf MC-Seite noch einfacher).
Bei langsamen Übertragungen checke ich auch noch die Zeit zwischen zwei
Bytes eines Datenpaketes, denn da die Pakete über eine ISR versendet
werden, gibt es keine oder sehr kleine Pausen zwischen den Bytes eines
Paketes.


> Jedes Kommando wird vom MC mit einem Byte quittiert (ob falsch oder
> richtig).
> Anfragen an den MC erhalten zusätzlich noch den Antworttext (wieder
mit
> 0x0A und/oder 0x0D abgeschlossen).

So eine Master-Slave-Kommunikation ist nicht schlecht, aber ich checke
auch a) ob die Antwort zu der Anfrage paßt (i. d. R. nur erstes Byte
von Anfrage und Antwort checken), b) wird ein timeout gesetzt (mittels
select) und c) wird die Datenpaket-Länge überprüft; wenn es zu kurz
oder zu lang ist, wird es ebenfalls verworfen.

von florian (Gast)


Lesenswert?

hallo,
danke erstmal für eure postings, werde mich am wochenend hinsetzen und
versuchen alles zu verstehen und melde mich dann.

mfg
flo

von florian (Gast)


Lesenswert?

moin,
habe erst jetzt gerade zeit gefunden weiter zu forschen.

erstmal danke nochmal für die tipps, ist viel auf einmal wenn man neu
in diesem gebiet ist.

das mit den mutex usw. habe ich nachgelesen, verstanden habe ich es wie
ich es im code genau anwende weiss ich noch nicht, aber ich empfange ja
daten und schicke sie durch die serielle schnittstelle an den pc und so
laufen auch zwei sachen ab, die sich bei einem parallelen abarbeiten
evtl. stören würden. also erst einlesen und dann senden. nicht
parallel.

was ich noch nicht ganz verstanden habe ist mit den timern bzw. den
pausen zwischen packeten usw.
also so wie ich das verstehe wendet man das zur synchrosation und
kontrolle (ob daten korrekt transferiert sind)an.
werden in den pausen andere befehle abgearbeitet wie z.B. packete
packen oder weiss der teufel was???
das mit den timer für die übertragung ist eine gute zusatz kontrolle
bzw. sicherung finde ich, da ich immer die selbe datenmende senden
möchte.

im moment beschäftigt mich auch noch zum verständnis das mit den
datenpacketen packen, nicht der inhalt aber das zusammen führen der
ganzen bytes. wie läuft das ab?
ok habe variable für blocknr die ich inkrementiere + weitere infos.
aber das mit den daten, habe mir gedacht das ich sie entweder aus dem
sram nehme (wenn der speicher reicht und ich sie da ablege) oder
anderen speichern , auf die man schnell zugreifen kann, vielleicht habt
ihr da auch noch ein guten bzw. besseren tip zum schnellen grossen
speicher für analog digitalisierte werte.
das problem ist ich weiss nicht wie ich diese ganzen daten dan nehme,
crc check mache und sie in das packet lege und dann nochmals zur
sicherung irgendwo hinterlege oder im speicher lasse bis die daten
drüben sind und dann erst aus dem speicher entferne.
tips und hilfen würden mich sehr freuen.

@peter
habe dein Bootloader prog angeschaut aber die routine bzw. code für den
crc16 nicht gefunden, kannst du mir sagen wo ich genau suchen soll????

mfg
flo

von Rolf F. (Gast)


Lesenswert?

Ich verwende eine Mainloop (keine nested Interrupts) und warte an deren
Ende, wenn weniger als 100 ms seit dem letzten Durchlauf vergangen
sind.
Weil an nur einer Stelle der Mainloop gesendet wird, ist so zwischen
den Datenpakete jeweils mindestens 100 ms Pause.
Für dieses kooperative Multitasking dürfen die Funktionen natürlich
nicht blockiernen, aber das ist nicht schwer und spart auch den Aufwand
für einen Scheduler und zugehörigen Timer.

von florian (Gast)


Lesenswert?

hallo,
wollte nur nochmal nach fragen ob meine gedanken so richtig waren mit
den timern usw.????

das mit dem crc16 wäre für mich auch wichtig, falls jemand weiss wo ich
das bei peters bootloader code finde, bitte her damit.

mfg
flo

von Rolf F. (Gast)


Lesenswert?

Also in den Pausen ist Pause; da ist nichts. Ansonsten hat man ja einen
kontinuierlichen Datenstrom, aus dem man die Daten rausfischen muß. Da
aber fast immer einzelne Datenpakete lückenlos per Interrupts
rausgeschickt werden, hat man deshalb automatisch lückenlose Pakete und
Pausen dazwischen.
Statt CRC reicht auch das exor (aller Daten-Bytes); das braucht nur 1
Byte und funktioniert z. B. bei der Relaiskarte 8fa von Conrad ganz gut
und ist einfacher.

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.