Brauche Echtzeit für RS232-Interface
Brauche Echtzeit für RS232-Interface
An alle C-Programmer!
Ich programmiere ja eigentlich schon etwas länger,
zur Zeit aber nicht mehr viel in C
und auf Linux erst seit kurzem.
Habe folgende zwei Probleme:
Ich möchte einen Thermometer an meinem COM-Port realisieren.
die Pin's ansteueren und abfragen funktioniert ja schon
aber um den Wiederstand zu messen brauche ich Echtzeitprioritaeten!
zur zeit frage ich innerhalb einer while Schleife ob das Signal angekommen ist
das schaut in etwa so aus:
while( (!(inb(0x3F8+6) & 0x020) && usleepTime < 1500000)
{
usleep(1);
++usleepTime;
}
damit komme ich auf so ca. 74 - 83 millisecunden.
wenn ich den Process mit nice -n -20 starte
auf 81 - 83 millisekunden
keine Ahnung ob diese Werte stimmen, (obwohl mir diese Werte etwas nieder vorkommen)
jedoch möchte ich den Process nicht fortwährend in einer Echtzeitschleife laufen lassen
sondern eben nur diese eine Schleife
dann warte ich vielleicht wieder eine sekunde
und messe dann wieder.
In einem Thread hat Janka geschrieben
dass das mit sched_setscheduler geht
hab aber keine Ahnung wie ich die man-Pages für diesen Befehl aufrufe
vermute mal ich brauche dafür ein extra Paket.
Nun zu meiner zweiten Frage:
Ich hab da von der Firma Conrad das Buch "Elektronik am PC"
Da wird in Visual Basic programmiert über eine port.dll
mich interresiert weniger die Elektronik als das Programmieren
(die Elektronik macht dann mein Bruder)
Aus diesem Buch habe ich die folgende Formel
wie ich von den millesecunden,
wenn ich einen NTC-Wiederstand dazwischen hänge,
auf die Temperatur komme.
T= <millisekunden>
T= T * 1.0000000001;
R= 2200 + 7800 * (T - 76300) / (294600 - 76300);
R= (int)R
Temp= 1 / (log(R / 10000) / 4300 + 1 / 298) -273
Temp= (int)(Temp * 10) / 10
mein Problem liegt beim Befehl log()
das ist der natürliche Logarithmus.
ich habe danach gegoogelt und herausgefunden
dass ich die Bibliothek math.h dafür includieren muss.
leider erkennt der gcc compiler diesen Befehl trotzdem nicht.
Ich hoffe ich war mit meiner Erklärung Verständlich
und irgendjemand kann mir weiterhelfen.
pcAlko
Ich programmiere ja eigentlich schon etwas länger,
zur Zeit aber nicht mehr viel in C
und auf Linux erst seit kurzem.
Habe folgende zwei Probleme:
Ich möchte einen Thermometer an meinem COM-Port realisieren.
die Pin's ansteueren und abfragen funktioniert ja schon
aber um den Wiederstand zu messen brauche ich Echtzeitprioritaeten!
zur zeit frage ich innerhalb einer while Schleife ob das Signal angekommen ist
das schaut in etwa so aus:
while( (!(inb(0x3F8+6) & 0x020) && usleepTime < 1500000)
{
usleep(1);
++usleepTime;
}
damit komme ich auf so ca. 74 - 83 millisecunden.
wenn ich den Process mit nice -n -20 starte
auf 81 - 83 millisekunden
keine Ahnung ob diese Werte stimmen, (obwohl mir diese Werte etwas nieder vorkommen)
jedoch möchte ich den Process nicht fortwährend in einer Echtzeitschleife laufen lassen
sondern eben nur diese eine Schleife
dann warte ich vielleicht wieder eine sekunde
und messe dann wieder.
In einem Thread hat Janka geschrieben
dass das mit sched_setscheduler geht
hab aber keine Ahnung wie ich die man-Pages für diesen Befehl aufrufe
vermute mal ich brauche dafür ein extra Paket.
Nun zu meiner zweiten Frage:
Ich hab da von der Firma Conrad das Buch "Elektronik am PC"
Da wird in Visual Basic programmiert über eine port.dll
mich interresiert weniger die Elektronik als das Programmieren
(die Elektronik macht dann mein Bruder)
Aus diesem Buch habe ich die folgende Formel
wie ich von den millesecunden,
wenn ich einen NTC-Wiederstand dazwischen hänge,
auf die Temperatur komme.
T= <millisekunden>
T= T * 1.0000000001;
R= 2200 + 7800 * (T - 76300) / (294600 - 76300);
R= (int)R
Temp= 1 / (log(R / 10000) / 4300 + 1 / 298) -273
Temp= (int)(Temp * 10) / 10
mein Problem liegt beim Befehl log()
das ist der natürliche Logarithmus.
ich habe danach gegoogelt und herausgefunden
dass ich die Bibliothek math.h dafür includieren muss.
leider erkennt der gcc compiler diesen Befehl trotzdem nicht.
Ich hoffe ich war mit meiner Erklärung Verständlich
und irgendjemand kann mir weiterhelfen.
pcAlko
Re: Brauche Echtzeit für RS232-Interface
Die gibt es als *root* (oder SUID-root), wenn man mittels sched_setscheduler den SCHED_FIFO auswählt. Aber Achtung! Nicht mit X rumprobieren, sondern nur mit einer ebenfalls auf SCHED_FIFO gesetzten Shell, denn man klemmt sich bei falscher Programmierung (Busy-Loops) schnell den Draht zum Rechner ab und muss sonst den Stecker ziehen.pcAlko wrote: die Pin's ansteueren und abfragen funktioniert ja schon
aber um den Wiederstand zu messen brauche ich Echtzeitprioritaeten!
$ man sched_setscheduler
Das Eintippen des Befehls oben in einer Konsole reicht. Manchmal gibt es ein extra (Pseudo-)Paket "allman", dass *alle* Manpages installiert. Welche Distribution benutzt du?In einem Thread hat Janka geschrieben
dass das mit sched_setscheduler geht
hab aber keine Ahnung wie ich die man-Pages für diesen Befehl aufrufe
vermute mal ich brauche dafür ein extra Paket.
Man muss außerdem noch die libm.so hinzulinken. Also im Linkerschritt gcc -o myprog -lm main.o serial.o temp.o oder ähnlich.mein Problem liegt beim Befehl log()
das ist der natürliche Logarithmus.
ich habe danach gegoogelt und herausgefunden
dass ich die Bibliothek math.h dafür includieren muss.
leider erkennt der gcc compiler diesen Befehl trotzdem nicht.
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
Ich mag die Schreie.
Mal ganz unabhängig davon rate ich dir eher zu diesen Chips:http://www.maxim-ic.com/pl_list.cfm/filter/21/ln/en
DS2480 als RS232-Interface, und DS1820 als Thermometer. Die sind laserabgeglichen, da braucht man nicht selbst Einmesskurven zu fahren. Außerdem kann man beliebig viele je DS2480/RS232-Port anschließen. Maxim rückt auch kostenlose Samples raus, wenn man es geschickt anstellt. Einen Treiber gibt es ebenfalls: http://www.owfs.org.
Janka
DS2480 als RS232-Interface, und DS1820 als Thermometer. Die sind laserabgeglichen, da braucht man nicht selbst Einmesskurven zu fahren. Außerdem kann man beliebig viele je DS2480/RS232-Port anschließen. Maxim rückt auch kostenlose Samples raus, wenn man es geschickt anstellt. Einen Treiber gibt es ebenfalls: http://www.owfs.org.
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
Ich mag die Schreie.
Hi Janka!
und habe das Paket manpages-dev schon gefunden danke!
Ich arbeite mit Eclipse dass mir ein makefile generiert
dort habe ich es eingefügt.
probleme habe ich jetzt mit der sched.h
die find ich nirgends auf meinem system! auch nicht der compiler
ist da wieder etwas zum hinzufügen?
Du meinst sicher mit nice --20
aber wie mach ich dass wenn ich den X-manager ausgeschaltet habe?
in Windows würde ich es mit CMD machen
reicht dann nice --20 bash?
Bin noch nicht dazugekommen dass alles zu lesen.
Warscheinlich komme ich da auf genauere messungen.
Da muss ich noch mit meinem Bruder darüber reden
kostet ja sicher was.
pcAlko
Ich benutze kubuntuJanka wrote:Das Eintippen des Befehls oben in einer Konsole reicht. Manchmal gibt es ein extra (Pseudo-)Paket "allman", dass *alle* Manpages installiert. Welche Distribution benutzt du?
und habe das Paket manpages-dev schon gefunden danke!
super, danke mit dem hat es auch geklappt.Janka wrote:Man muss außerdem noch die libm.so hinzulinken. Also im Linkerschritt gcc -o myprog -lm main.o serial.o temp.o oder ähnlich.
Ich arbeite mit Eclipse dass mir ein makefile generiert
dort habe ich es eingefügt.
probleme habe ich jetzt mit der sched.h
die find ich nirgends auf meinem system! auch nicht der compiler
ist da wieder etwas zum hinzufügen?
und wie setz ich eine Shell auf SCHED_FIFO?Janka wrote:Aber Achtung! Nicht mit X rumprobieren, sondern nur mit einer ebenfalls auf SCHED_FIFO gesetzten Shell,
Du meinst sicher mit nice --20
aber wie mach ich dass wenn ich den X-manager ausgeschaltet habe?
in Windows würde ich es mit CMD machen
reicht dann nice --20 bash?
was bringt mir dieser Chip?Janka wrote:Mal ganz unabhängig davon rate ich dir eher zu diesen Chips:http://www.maxim-ic.com/pl_list.cfm/filter/21/ln/en
Bin noch nicht dazugekommen dass alles zu lesen.
Warscheinlich komme ich da auf genauere messungen.
Da muss ich noch mit meinem Bruder darüber reden
kostet ja sicher was.
pcAlko
Eigentlich gehört das zu glibc-devel. Muss da sein.pcAlko wrote: probleme habe ich jetzt mit der sched.h
die find ich nirgends auf meinem system! auch nicht der compiler
ist da wieder etwas zum hinzufügen?
Nein. nice --20 setzt nur den nice-Wert auf die höchste Priorität. Das ist aber immer noch SCHED_OTHER, also niedriger, als irgendein Programm auf SCHED_FIFO. Und SCHED_FIFO-Prozesse laufen *immer*, wenn es keinen anderen SCHED_FIFO-Prozess mit höherer Priorität gibt, der ebenfalls lauffähig ist.und wie setz ich eine Shell auf SCHED_FIFO?Janka wrote:Aber Achtung! Nicht mit X rumprobieren, sondern nur mit einer ebenfalls auf SCHED_FIFO gesetzten Shell,
Du meinst sicher mit nice --20
Mir ist kein Utility bekannt, dass Echtzeitpriorität setzen kann. Ein echter Mangel. Du kannst dir allerdings ein kleines Hilfsprogramm basteln, dass halt nur einen Aufruf von sched_setscheduler enthält und die pid auf der Kommandozeile entgegennimmt.
Wir sind hier nicht bei MS-Windows. Es gibt eine Textkonsole [Strg]+[Alt]+[F1] z.B..aber wie mach ich dass wenn ich den X-manager ausgeschaltet habe?
in Windows würde ich es mit CMD machen
reicht dann nice --20 bash?
Bei MS-Windows kann man sich übrigens genauso aussperren, und da es keine vernünftige Textkonsole gibt, muss man dort zuvor *alle* Prozesse, die was mit der GUI zu tun haben, ebenfalls auf Echtzeitpriorität anheben. Oder halt den Stecker ziehen, falls man was falsch gemacht hat.
Einen NTC musst du einmessen, weil jedes Exemplar ein wenig streut. Eine größere Genauigkeit als 2..5°C solltest du mit der Kennlinie, wie sie der Hersteller im Datenblatt angibt, nicht erwarten. Da nackte NTCs üblicherweise nur in Regelkreisen als Temperatursicherung eingesetzt werden, macht das dort ja nichts. Für ein Thermometer musst du die Kennlinie jedes einzelnen NTC selbst aufnehmen. Also ein geeichtes Thermometer nehmen, Wasser erhitzen, NTC und Thermometer ins Wasser, und dann bei abkühlen zumindest 1 Messpunkt je 10°C aufnehmen. Danach die logarithmische Kurve hineininterpolieren.was bringt mir dieser Chip?Janka wrote:Mal ganz unabhängig davon rate ich dir eher zu diesen Chips:http://www.maxim-ic.com/pl_list.cfm/filter/21/ln/en
Bin noch nicht dazugekommen dass alles zu lesen.
Warscheinlich komme ich da auf genauere messungen.
Da muss ich noch mit meinem Bruder darüber reden
kostet ja sicher was.
Den Spaß kannst du dir mit den Chips oben sparen, weil diese bereits in der Fabrik einzeln ausgemessen wurden. Außerdem kannst du mehrere Messpunkte an ein dreiadriges Buskabel legen und dir die Treiberbastelei, wie du sie jetzt machst, sparen.
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
Ich mag die Schreie.
Man kann Postings auch editieren.pcAlko wrote:ach ja,
bevor ich es vergesse ...
hast Du mit dem Befehl log() schonmal gearbeitet?
Er gibt bei mir immer NaN zurück.
obwohl ich mit -lm compile
vielleicht komm ich morgen nochmals dazu Ihn besser zu testen.
pcAlko
In dem Fall solltest du mal die Variable "errno" prüfen.
$ man errno
$ man perror
Vermutlich versuchst du, den Logarithmus von 0 oder einer negativen Zahl zu ziehen. Der ist nicht definiert.
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
Ich mag die Schreie.
hallo Janka,
das mit dem log() muss ich noch besser testen,
habe im moment leider keine Zeit dafür.
die sched.h habe ich schon gefunden
hab bei der Angabe das "c" vergessen
wie funktioniert dass mit dem 3 Parameter von sched_setscheduler() ?
einen sched_param struct kann ich nicht erzeugen
bin bzw. war halt nur ein C++ programmierer!!!
was ich mich erinnern kann
musste in C für jeden struct ein typedef deffiniert werden
aber das haut bei mir auch nicht so hin.
kannst Du mir dabei bitte nochmal helfen!?
pcAlko
das mit dem log() muss ich noch besser testen,
habe im moment leider keine Zeit dafür.
die sched.h habe ich schon gefunden
hab bei der Angabe das "c" vergessen
wie funktioniert dass mit dem 3 Parameter von sched_setscheduler() ?
einen sched_param struct kann ich nicht erzeugen
bin bzw. war halt nur ein C++ programmierer!!!
was ich mich erinnern kann
musste in C für jeden struct ein typedef deffiniert werden
aber das haut bei mir auch nicht so hin.
kannst Du mir dabei bitte nochmal helfen!?
pcAlko
Und wieder ein Grund mehr, warum C++ für Einsteiger eine absolut ungeeignete Sprache darstellt.
Alternativ kannst du natürlich auch eine Variable sp definieren und dann mittels sp.sched_priority=... den Wert setzen. Guck dir mal lieber ein Lehrbuch zu C (nicht C++!) an.
Janka
Code: Select all
#include <sched.h>
#include <stdlib.h>
void setprio(pid_t pid)
{
const struct sched_param sp=
{
sched_priority: 1,
};
if (sched_setscheduler(pid, SCHED_FIFO, &sp)<0) \
{
perror("sched_setscheduler");
exit(EXIT_FAILURE);
}
}
int main(int argc, char* argv[])
{
if (argc>1)
setprio((pid_t)atoi(argv[1]));
}
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
Ich mag die Schreie.
Ich habe die Alternative vorgezogen!
Dein Beispiel mit sched_priority: 1, ist sehr interresant
das ist wohl höchst tiefes C
eigentlich habe ich ja nur struct vor der definition vergessen.
Aber ich muss zugeben gerade bei den feinen Unterschieden
da haperts halt schon ein bisschen.
Und natürlich kommt dazu dass ich schon wieder viel vergessen habe.
also jetzt funktioniert wenigstens alles.
beim log war es doch eine Negative Zahl.
Ich hab das mal untersucht,
es müssen mindestens 14757 millisekunden sein
um einen positiven Wert für log zu erhalten.
ich komm aber nur auf 91 millisekunden
heute um 19:00 hatte es 21.2 °C bei mir im Zimmer
ich glaub ich hab da einen falschen NTC-Wiederstand
muss ich mal checken.
Mir kommt das nur komisch vor,
da ich mit dieser Rechnung
um auf 77°C zu kommen
60500000000 millisecunden brauche
irgendwas läuft da noch schief.
ist nicht eine Millisekunde 1/1000 einer sekunde?
ich hab das mal mit einem händischen abbruch der Schleife,
indem ich nach einer Minute DTR und DSR verbunden habe,
ausprobiert.
Ich komme da nur auf 14940 Millisekunden.
obwohl ich im Echtzeitmodus laufe
kann ich wärend dessen ohne weiteres
jedes beliebige Programm starten.
>> wo ist der bussy-Log? <<
sched_setscheduler gibt mir 0 zurück
also kein Fehler
sched_getscheduler(0) inerhalb der Schleife gibt mir 1 zurück.
ist das alles ok so?
pcAlko
Dein Beispiel mit sched_priority: 1, ist sehr interresant
das ist wohl höchst tiefes C
diesen Joke verstehe ich aber nicht ganz!Janka wrote:Und wieder ein Grund mehr, warum C++ für Einsteiger eine absolut ungeeignete Sprache darstellt.
eigentlich habe ich ja nur struct vor der definition vergessen.
Aber ich muss zugeben gerade bei den feinen Unterschieden
da haperts halt schon ein bisschen.
Und natürlich kommt dazu dass ich schon wieder viel vergessen habe.
also jetzt funktioniert wenigstens alles.
beim log war es doch eine Negative Zahl.
Ich hab das mal untersucht,
es müssen mindestens 14757 millisekunden sein
um einen positiven Wert für log zu erhalten.
ich komm aber nur auf 91 millisekunden
heute um 19:00 hatte es 21.2 °C bei mir im Zimmer
ich glaub ich hab da einen falschen NTC-Wiederstand
muss ich mal checken.
Mir kommt das nur komisch vor,
da ich mit dieser Rechnung
um auf 77°C zu kommen
60500000000 millisecunden brauche
irgendwas läuft da noch schief.
ist nicht eine Millisekunde 1/1000 einer sekunde?
ich hab das mal mit einem händischen abbruch der Schleife,
indem ich nach einer Minute DTR und DSR verbunden habe,
ausprobiert.
Ich komme da nur auf 14940 Millisekunden.
obwohl ich im Echtzeitmodus laufe
kann ich wärend dessen ohne weiteres
jedes beliebige Programm starten.
>> wo ist der bussy-Log? <<
sched_setscheduler gibt mir 0 zurück
also kein Fehler
sched_getscheduler(0) inerhalb der Schleife gibt mir 1 zurück.
ist das alles ok so?
pcAlko
laut man-pages steht ja
"If pid equals zero, the scheduler of the calling process will be set."
dass heisst für mich dass ich da 0 hineinschreiben kann.
aber ich habe es auch mit getpid() versucht.
kannst Du mal über meinen source-code blicken!?
vielleicht ist da ja irgend ein Fehler drin den ich übersehen habe.
hierbei hab ich nur eine Minute abgestopt
und ausgegeben wiviele Millisekunden er gerechnet hat.
normaler weise müssten doch 60.000 herauskommen.
bei mir ist es aber nur 15.099
ich hab in meinem Büchlein nochmals gelesen
und entdeckt dass ich sogar Mikrosekunden brauche
eine Mikrosekunde ist laut wikipedia 1000 Nanosekunden
das klapt natürlich nie und nimmer, solange ich keine Echtzeit schaffe.
pcAlko
"If pid equals zero, the scheduler of the calling process will be set."
dass heisst für mich dass ich da 0 hineinschreiben kann.
aber ich habe es auch mit getpid() versucht.
kannst Du mal über meinen source-code blicken!?
vielleicht ist da ja irgend ein Fehler drin den ich übersehen habe.
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sched.h>
#include <errno.h>
#include <unistd.h>
int main ( )
{
int nMin;
int nSec;
int res;
time_t tnow;
struct tm *tmnow;
unsigned long usleepTime;
const struct sched_param sp=
{
sched_priority: 1
};
printf("aktuller PID %d\n", getpid());
usleepTime= 0;
res= sched_setscheduler(getpid(), SCHED_FIFO, &sp);
if(res != 0)
{
printf("set real-time scheduling \n");
printf("ERROR %d ", errno);
perror("sched_setscheduller");
printf("\n");
return(1);
}
printf("set to police %d\n", sched_getscheduler(0));
time(&tnow);
tmnow= localtime(&tnow);
nMin= tmnow->tm_min;
nSec= tmnow->tm_sec;
printf("Start %d:%d\n", nMin, nSec);
do{
usleep(1);
++usleepTime;
time(&tnow);
tmnow= localtime(&tnow);
}while(nMin == tmnow->tm_min || tmnow->tm_sec <= nSec);
printf("End %d:%d \n", tmnow->tm_min, tmnow->tm_sec);
printf("%lu milliseconds\n", usleepTime);
return (0);
}
und ausgegeben wiviele Millisekunden er gerechnet hat.
normaler weise müssten doch 60.000 herauskommen.
bei mir ist es aber nur 15.099
ich hab in meinem Büchlein nochmals gelesen
und entdeckt dass ich sogar Mikrosekunden brauche
eine Mikrosekunde ist laut wikipedia 1000 Nanosekunden
das klapt natürlich nie und nimmer, solange ich keine Echtzeit schaffe.
pcAlko
Ähm. Du gehst davon aus, dass der einzige Aufruf, der in deiner Schleife Zeit verbraucht, usleep(1) sei. Das ist aber in diesen winzigen Dimensionen nicht mehr der Fall, time und localtime werden den Rechner auch einige Mikrosekunden beschäftigen.
So genau kann man nur einen Hardwaretimer Zeit messen lassen.
Janka
So genau kann man nur einen Hardwaretimer Zeit messen lassen.
Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.
Ich mag die Schreie.
Hallo Janka!
Ohne Dich wäre dieses Forum nur halb so gut!
Ich hoffe Du bleibst uns hier noch lange erhalten.
Ich kann aber leider nichts mit dieser Aussage anfangen.
Mir wäre eine Zeitmessung wie über localtime auch lieber.
Leider habe ich aber die funktion dafür noch nicht gefunden. (über eine genauigkeit von milli-, nanosekunden)
Mit dem Wort Hardwaretimer kann auch Google nichts anfangen.
bei man uslleep steht zwar SIHE AUCH settimer, gettimer
aber die sind in den manpages nicht enthalten.
ebenso in man nanosleep -> timer_create().
was ich gefunden habe ist der Profiler
aber der ist ja von aussen und wird über eine compileroption erreicht
welches mir dann mein ganzes Programm analysiert.
kann ich diese Hardware Zeit auch über mein C-App ereichen?
habe ich mit diesem Programm jetzt die Echtzeit aktiviert oder Nicht?
oder merke ich das die Minute lang gar nicht
weil ich ja usleep() einsetze
und die Millisekunde ist genug dass man das
vor lauter geschwidigkeit gar nicht merkt!?
pcAlko
Ohne Dich wäre dieses Forum nur halb so gut!
Ich hoffe Du bleibst uns hier noch lange erhalten.
Ich kann aber leider nichts mit dieser Aussage anfangen.
Mir wäre eine Zeitmessung wie über localtime auch lieber.
Leider habe ich aber die funktion dafür noch nicht gefunden. (über eine genauigkeit von milli-, nanosekunden)
Mit dem Wort Hardwaretimer kann auch Google nichts anfangen.
bei man uslleep steht zwar SIHE AUCH settimer, gettimer
aber die sind in den manpages nicht enthalten.
ebenso in man nanosleep -> timer_create().
was ich gefunden habe ist der Profiler
aber der ist ja von aussen und wird über eine compileroption erreicht
welches mir dann mein ganzes Programm analysiert.
kann ich diese Hardware Zeit auch über mein C-App ereichen?
habe ich mit diesem Programm jetzt die Echtzeit aktiviert oder Nicht?
oder merke ich das die Minute lang gar nicht
weil ich ja usleep() einsetze
und die Millisekunde ist genug dass man das
vor lauter geschwidigkeit gar nicht merkt!?
pcAlko