Hallo.
Ich habe mehr schlecht alls recht in codevision mit dem atmel 162 ein
zeitmessungsprogramm gebastelt. allerding ergab eine test messung über 2
stunden eine abweichung von ca. 10 Minuten was einer abweichung von ca.
7% entspricht.
im anhang ist der code. kann mir jemand sagen wo ich am ehesten die
ursache für die abweichung finde?
danke im vorraus.
Schmeiss die riesige float-Berechnung und die langwierige Ausgabe aus
der Interruptroutine raus. Die halten den Interrupt zu lange auf!
Merke dir nur die Anzahl der Overflows in einer volatile
gekennzeichneten globalen Variable und mache die Berechnung und die
Ausgabe im Nicht-Interruptteil.
wieso muss die berechung+ausgabe aus der interrupt routine raus?
der interrupt wird doch bloss am ende der zeitmessung wenn quasi der
auslöser betätigt wird gestoppt.
Josua Sabo wrote:
> Ich habe mehr schlecht alls recht in codevision mit dem atmel 162 ein> zeitmessungsprogramm gebastelt. allerding ergab eine test messung über 2> stunden eine abweichung von ca. 10 Minuten was einer abweichung von ca.> 7% entspricht.
Bei 4MHz kannst Du mit 32Bit nur bis 17,8min messen. Es können also
garkeine 2h+-10min angezeigt worden sein.
Peter
Karl heinz Buchegger wrote:
> Wenn du Genauigkeit haben willst, dann ist float so ziemlich das letzte> was du benutzen willst.
Immer diese Vorurteile.
Float ist auf 5..6 Digits genau, das reicht für viele Anwendungen völlig
aus.
Peter
Peter Dannegger wrote:
> Karl heinz Buchegger wrote:>> Wenn du Genauigkeit haben willst, dann ist float so ziemlich das letzte>> was du benutzen willst.>> Immer diese Vorurteile.> Float ist auf 5..6 Digits genau, das reicht für viele Anwendungen völlig> aus.
Hast du dir seine konstanten Zahlenwerte im Programm angesehen?
1
constfloattime=0.000256F;//Konstante entspricht der Zeit eines "Umschaltens" des Z�hlers
2
constfloatover=65536.0F;//Konstante die dem Wert eines �berlaufes entspricht
Karl heinz Buchegger wrote:
> Hast du dir seine konstanten Zahlenwerte im Programm angesehen?
Stimmt, der ist falsch (um 2,3%).
Für 1ms Schritte bei 4MHz Quarz nicht 0,000256 sondern:
1e3 / 4e6 = 0,00025
Die Berechnung der oberen 16 Bit sollte man auch besser als long machen,
da ja noch eine Überlaufkorrektur notwendig ist:
Beitrag "AVR Timer mit 32 Bit"
Peter
danke für den link ins tutorial. habs beim ersten mal überlesen.
aber irgendwie kann ich die Berechungen nicht erkennen. an was kann das
liegen?
mfg Josua
danke für die antworten
Der Timer ist der Hauptzähler.
In regelmässigen Abständen ruft er eine Interrupt Routine auf.
Innerhalb der Interrupt Routine installierst du einen zusätzlichen
Software-Zähler
1
intCounter;
2
3
4
ISR(...)
5
{
6
Counter++;
7
8
if(Counter==10){
9
Counter=0;
10
11
// mach was
12
}
13
}
Wenn deine ISR, sagen wir mal 1000 mal in der Sekunde aufgerufen wird,
dann wird der Teil
// mach was
tatsächlich nur 100 mal in der Sekunde ausgeführt.
Der Subcounter Counter hat den 'ISR-Takt' weiter heruntergeteilt.
Josua Sabo wrote:
> aber wie lange (wie viele takte) dauert dann die abarbeitung des> Interrupts?
Kommt drauf an wieviel du reinschreibst :-)
Lanfgdauernde Operationen, wie LCD ausgabe oder Ausgabe über UART sollte
man daher da drinnen nicht machen, sonst kann es sein, dass man in
Zeitnot kommt und der nächste Interrupt schon signalisiert wird, noch
ehe der vorhergehende fertig abgearbeitet wurde. Aber normalerweise hat
man genügend Zeit um von irgendwo Daten zu holen, ein wenig Rechenarbeit
zu machen und die Ergebnisse wieder in globalen Variablen abzulegen.
läuft während der abarbeitung des interrupts der timer nach dem lesen
oder schreiben gleich weiter oder erst nach dem interrupt(Annahme es
wird kein anderer interrupt während der abarbeitung aufgerufen) ?
und ich habe keine ahnung wie ich das in einem anderen programmteil
ausrechnen und ausgeben soll? muss ich im interrupt einfach ein
unterprogramm ausführen oder wie soll das funktionieren.
Der Timer läuft weiter.
Ein Timer läuft immer, sobald er einen Vorteiler eingestellt bekommen
hat.
In der ISr wertest du zb den Timerstand aus ... gibst ihn aber nicht auf
einem LCD aus. DIe Ausgabe dauert verhältnismässig lange.
Stattdessen kannst du zb eine globale Variable auf 1 setzen.
Im Hauptprogramm, in der Hauptschleife überwachst du ständig diese
globale Variable. Ist sie 1, dann signalisiert damit die ISR, dass es
neue Werte gibt. Die Hauptschleife holt sich dann die Werte, bereitet
sie unter Umständen für die Ausgabe vor und gibt sie am LCD aus. Die
globale Variable wieder auf 0 setzen und das wars. Allerdings gibts da
ein paar Fallen: Die Zugriffe auf die globalen Variablen müssen atomar
sein (also mit cli und sei gekapselt werden) und die global Variable
selbst muss volatile sein.
Mit dem Suchbegriff "Jobflag" müsstest du eigentlich hier im Forum
fündig werden.
Also Codevision hat keine Interrupt bibliothek.
Deshalb kennt es die Befehle CLI(); und SEI(); nicht.
Was mache ich jetzt?
Wenn ich die Zeit nicht mit float berechne muss ich ein "künstliches"
Komma einfügen oder?
Ich habe aber keinen Plan wie das funktionieren soll.
Kann ich es nicht doch mit float berechnen in der hauptschleife.
und mit globale variable auf eins setzten meinst du ein int oder den
bool gibts ja nicht.
Josua Sabo wrote:
> Also Codevision hat keine Interrupt bibliothek.> Deshalb kennt es die Befehle CLI(); und SEI(); nicht.> Was mache ich jetzt?
In deiner Doku nachsehen, wies bei Codevision heist.
>> Wenn ich die Zeit nicht mit float berechne muss ich ein "künstliches"> Komma einfügen oder?> Ich habe aber keinen Plan wie das funktionieren soll.
Ah geh. Das hast du schon millionenfach gemacht.
Wenn du zu faul bist €2.45 + @3.68 zu rechnen, weil du nicht mit
Kommazahlen rumschmeissen willst, dann rechnest du eben in Cent:
245 + 368 = 613 Cent oder €6.13
(Hier hast du ein künstliches Komma nach der 2 Stelle eingeführt)
> Kann ich es nicht doch mit float berechnen in der hauptschleife.
Sicher kannst du.
>> und mit globale variable auf eins setzten meinst du ein int oder den> bool gibts ja nicht.
unsigned char
Vereinfacht den Zugriff.
Hallo.
Ich habe das Programm soweit abgeändert bzw. neu geschrieben wie
besprochen. Jetzt funktioniert garnichts mehr. Das if sowie das else
werden nie abgearbeitet andernfalls müsste es doch eine Ausgabe auf dem
LCD-Display geben(if ja bzw. if nein). Komisch ist auch, dass das
Programm bis zu einfügen der "Komma Routine" wenigstens beim Interrupt
etwas auf dem Display ausgab. Diese Ausgabe ist bei diesem Code
allerdings nicht mehr vorhanden, ich habe die Ausgabe gelöscht, da sie
ja keinen Sinn macht wenn sie nicht mehr funktioniert. Jetzt habe ich
nur noch zwei stehende Balken auf dem 4 zeiligen Display an was liegt
das?
Kann mir jemand sagen ob es grundlegende Fehler sind, die ich gemacht
habe?
Unterprogramme habe ich zum ersten Mal verwendet.
Danke an alle Antwortenden.
Du musst t als volatile Variable definieren.
t kann sich auf Wegen verändern, die der Compiler nicht einsehen kann.
Daher muss man ihm mit 'volatile' helfen und ihn zwingen, bei einem
Zugriff auf t nicht auf irgendwelche gecachten Werte zurückzugreifen,
sondern die Variable tatsächlich aus dem Speicher zu holen.
Weiter hab ich nicht geschaut.
Jetzt springt das Programm wenigstens in die If Funktion.
Allerdings zeigt das Display garnichts an. Es flackert nur kurz wenn der
Interrupt(INT1) ausgelöst wird.
Kann es sein, dass der µC zu schnell ist für das Display? Aber dann
müsste ich doch irgendwo ein lcd_clear(); geschrieben haben damit es den
Bildschirm löscht.
Josua Sabo wrote:
> Kann es sein, dass der µC zu schnell ist für das Display? Aber dann> müsste ich doch irgendwo ein lcd_clear(); geschrieben haben damit es den> Bildschirm löscht.
Ähm. Ich zitiere mal aus deinem Programm
1
if(t==1)//sollte sobald t=1 ist abgearbeitet werden
* Spar dir die cli / sei in den Interrupt Funktionen. Die sind
kontraproduktiv!
*
1
voiduitoa(longendergeb,char*string)//addaptiertes unterprogramm zum speichern der einzelnen zeichen in einen string
2
{
3
unsignedinti;// schleifenz�hler
4
string[10]='\0';// String Terminator
5
for(i=9;i>=0;i--)
6
{
7
string[i]=(endergeb%10)+'0';// Modulo rechnen, dann den ASCII-Code von '0' addieren
8
endergeb/=10;
9
}
10
}
Die Abbruchbedingung in der for-Schleife: Da i ein unsigned int ist, ist
i per Definition immer größer oder gleich 0.
Dir ist hoffentlich klar, dass du deinem Prozessor hier eine
Fleissaufgabe aufbürdest. Du lässt ihn bei 16-Bit Arithmetik schwitzen,
nur um von 9 auf 0 zu zählen (zumindest war das die Absicht. Tatsächlich
ist das ja eine Endlosschleife, die quer durch den ganzen Speicher
marschiert und überall eine 0 reinschreibt. Solange bis es
lebenswichtige Teile berührt und der Prozessor abschmiert.)
* Wie gross ist denn in
1
charstring[];
das char Array tatsächlich?
Du musst schon eine Größe vereinbaren, der Compiler kann sich die nicht
aus den Fingern saugen. Ein Wunder das das überhaupt compiliert/linkt.
* Wo du allerdings mittels cli/sei den Zugriff auf die Variablen
absichern solltest, ist in der Berechnung! Was denkst du wohl, was
passiert, wenn dein Code gerade mitten in der Berechnung steckt und ihm
ein Interrupt unter dem Hintern die Werte verändert.
Ich würde mal in Etappen vorgehen anstatt alles in einem zu testen und
nicht zu wissen wo ich mit der Fehlersuche anfangen soll
* erster Schritt ist die Sicherstellung, dass die Ausgabefunktionen
richtig funktionieren
Dazu wird nur die Funktion ausgabe benötigt
1
intmain()
2
{
3
chartest[11]="000000000";
4
5
....
6
7
while(1)
8
{
9
ausgabe(test,0,5,2);
10
}
11
}
liefert das eine Ausgabe und wenn ja, ist sie korrekt?
Den String in test mal etwas variieren. Mit welcher Variation erwartest
du welche Anzeige und kommt die auch?
Ist dieser Test erfolgreich, wird er erweitert. Die unsigned long zu
String Wandlung kommt ins Spiel
1
intmain()
2
{
3
chartest[11];
4
unsignedlongendergeb=1000;
5
6
...
7
8
while(1)
9
{
10
uitoa(endergeb,test);
11
ausgabe(test,0,5,2);
12
}
13
}
Wird die Zahl korrekt angezeigt?
Da die Funktion ausgabe bereits getestet ist und funktioniert kann bei
einer fehlerhaften Anzeige daher nur die Funktion uitoa Schuld sein.
Also dort nach Fehlern Ausschau halten.
Jetzt kann man auch mal einen Massentest machen (auch zur eigenen
Belustigung)
1
intmain()
2
{
3
chartest[11];
4
unsignedlongendergeb=0;
5
6
...
7
8
while(1)
9
{
10
uitoa(endergeb,test);
11
ausgabe(test,0,5,2);
12
13
endergeb++;
14
}
15
}
damit kriegt man auch erst mal einen Eindruck von der Leistungsfähigkeit
so eines µC. Wie schnell die Anzeige hochzählt (und das wird sehr
schnell sein), hängt im wesentlichen von den LCD Funktionen ab.
Wahrscheinlich werden ein paar der letzten Anzeigestellen nicht zu lesen
sein und wie wild flackern. Aber ein paar Stellen davor sollte
eigentlich vernünftig und ruhig hochgezählt werden.
Ist dieser Test erfolgreich, wird er erweitert.
Die Variablen tim und overfl kommen mit ins Spiel und damit auch
gleichzeitig die Umrechnung dieser Werte ins Endergebnis
...
usw. usw.
Du darfst nicht den Fehler machen, zuviel auf einmal zu schreiben. Sonst
stehst du mit einer Menge Code da, der fehlerhaft ist und du keine
Ahnung hast, wo du mit der Fehlersuche anfangen sollst.
Du musst dir eine Entwicklungsstrategie überlegen, die dich von kleinen
testbaren Einheiten zum Gesamtsystem führt, bei dem du jeden Schritt
nach der Entwicklung sofort testen kannst und wo jeder Schritt auf dem
Vorhergehenden aufbaut. Meistens bedeutet das, dass man mit den
grundlegenden Ausgabefunktionen anfängt, denn die benötigt man um mal
gesichert Ausgaben machen zu können, die auf jeden Fall funktionieren.
Dann wird Schritt für Schritt erweitert. Und da der jeweils
vorhergehende Schritt zumindest soweit getestet wurde, dass er
funktioniert, ist es sehr wahrscheinlich, dass ein Fehler der sich zeigt
im zuletzt hinzugefügten Schritt steckt.
Und ja: Auch Profis gehen nach so einem Schema vor.
PS: Ich würd auch mal den ganzen Quatsch den dir der Code-Wizard
generiert hat rausschmeissen. 60 bis 70% deines Codes haben nichts mit
deiner Aufgabenstellung zu tun, sondern initialisieren nur
µC-Bestandteile die du nicht benutzt. Allerdings blähen sie dein
Programm soweit auf, dass man ständig rumscrollen muss.
Ich glaube der Fehler liegt bei der uitoa(), da ausgabe() einwandfrei
funktioniert.
Ich verstehe nicht warum ich einen Bit-Terminator benötige. Wenn ich
schreibe string[10] wieviele "Ziffern" kann ich dann in diesem string
speichern? (du schreibst string[11]="000000000" also nur 9 ziffern)
josua sabo wrote:
> Ich glaube der Fehler liegt bei der uitoa(), da ausgabe() einwandfrei> funktioniert.> Ich verstehe nicht warum ich einen Bit-Terminator benötige.
Was ist ein Bit-Terminator?
> Wenn ich> schreibe string[10] wieviele "Ziffern" kann ich dann in diesem string> speichern? (du schreibst string[11]="000000000" also nur 9 ziffern)
klassische C-String Verarbeitung.
In einem Array der Länge 10 gibt es grundsätzlich 10 Arrayelemente.
Durchnummeriert von 0 bis 9 (sind genau 10 Stück).
Jeder C-String hat als letztes Zeichen, welches das tatsächliche
Stringende kennzeichnet, immer ein 0-Byte.
Das Array kann also viel größer sein, als der String der darin
gespeichert ist. Durch das 0-Byte ist immer eindeutig erkennbar wo der
String aufhört.
Ich definiere string als ein Array der Größe 11, weil in uitoa eine
Zuweisung vorkommt
string[10] = '\0';
Damit ein Element mit dem Index 10 überhaupt existiert, muss das Array
aber mindestens eine Länge von 11 haben.
http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F
> Ich glaube der Fehler liegt bei der uitoa(), da ausgabe() einwandfrei> funktioniert.
Nicht glauben. Sicher gehen.
Wie sieht dein Testprogramm aus?
Dieser Analyse kann ich so nicht folgen. Dein uitoa sieht eigentlich
ganz gut aus. Solange das char Array mindestens eine Länge von 11 hat,
kann da eigentlich nichts schief gehen.
Hab den Code nochmal hochgeladen. Es sieht so aus, dass alles Super
funktioniert wenn ich z.B endergeb=0xFFFFFFFF; setzte dann gibt das LCD
49,24 aus. -->uitoa und ausgabe funktionieren der Fehler liegt bei der
berechung();. Wenn ich nämlich mein Unterprogramm berechung(); einfüge
dann gibt mir das LCD ,00000 aus. Komisch kann mir keinen Reim darauf
machen.
Josua Sabo wrote:
> Fehler liegt bei der> berechung();. Wenn ich nämlich mein Unterprogramm berechung(); einfüge> dann gibt mir das LCD ,00000 aus. Komisch kann mir keinen Reim darauf> machen.
OK. Dann musst du die mal die Funktion berechnung() mal genauer ansehen.
Hier ist sie
1
longberechung(longendergeb)//unterprogramm zur berechung des endergebnisses des z�hlers
2
{
3
4
#asm("cli")
5
endergeb=((overfl*0xFFFF)+time)*2;
6
#asm("sei")
7
8
returnendergeb;
9
10
}
Was macht sie?
Sie übernimmt einen Zahlenwert in der lokalen Variablen endergeb. Dieser
Zahlenwert ist aber völlig uninteressant, weil er sofort mit einer
Berechnung überschrieben wird und das Ergebnis dieser Berechnung ist der
Returnwert der Funktion.
Wichtig ist auch: Diese lokale Variable endergeb hat nichts mit der
globalen Variablen gleichen Namens zu tun! Das sind 2 verschiedene
Variablen!
Die Funktion liefert also ihr Ergebnis als Returnwert, so wie zb eine
Funktion sin() ihr Ergebnis auch als Ergebnis zurück liefert. Daher kann
man beim Sinus dann auch schreiben x = sin(y); und das Rechenergebnis
vom SInus wird beim Aufrufer in der Variablen x gespeichert.
Wie ist das bei dir? Wo ist der Aufruf von berechnung()? Hier:
1
if(t==1)//sollte sobald t=1 ist abgearbeitet werden
2
{
3
4
berechung(endergeb);
Du benutzt den Returnwert gar nicht! Die Funktion berechnung() rechnet
was aus, was aber anscheinend gar keinen interessiert :-)
1
if(t==1)//sollte sobald t=1 ist abgearbeitet werden
2
{
3
4
endergeb=berechung(endergeb);
(Jetzt kannst du dich mal fragen, wozu du eigentlich die Variable
endergeb in die Funktion hinein übergibst. Die Funktion braucht den Wert
sowieso nicht. Das solltest du sowieso bereinigen, denn es ist immer
unklug, wenn du mehrere Variablen, die nichts miteinander zu tun haben,
mit dem gleichen Namen im Programm hast. Man kommt dann sehr leicht
durcheinander. Und genau das ist dir passiert: Du hast eine lokale
Variable endergeb in der Funktion und gleichzeitig eine globale Variable
mitdemselben Namen. Du hast gedacht, wenn du an endergeb etwas zuweist,
dann machst du das an die globale Variable, während du das
Rechenergebnis in Wirklichkeit nur an die lokale Variable zugewiesen
hast.
1
longberechung()//unterprogramm zur berechung des endergebnisses des z�hlers
2
{
3
longresult;
4
5
#asm("cli")
6
result=((overfl*0xFFFF)+time)*2;
7
#asm("sei")
8
9
returnresult;
10
}
11
12
....
13
14
if(t==1)//sollte sobald t=1 ist abgearbeitet werden
Da das Programm jetzt vom Anzeigen her macht was ich will dachte ich,
dass ich fertig bin. Dem ist aber nicht so.
Der 16-Bit-Zähler läuft mit einer Frequenz von 500kHz das bedeutet alle
2µSekunden wird der Zählerstand um eins erhöht.
Also rechne ich den Gesamtenzählerstand aus und Multipliziere ihn mit 2
und füge ein Komma nach sechst Stellen von rechts ein.
Das Problem: Ich habe eine Abweichung von ca. 2 Sekunden.
Woran kann das liegen?
Josua Sabo wrote:
> Das Problem: Ich habe eine Abweichung von ca. 2 Sekunden.
2 Sekunden kann viel sein ( 2 Sekunden in 10 Minuten ist viel), kann
aber auch wenig sein ( 2 Sekunden in einem Jahr ist ein guter Wert)
Welcher Fall liegt bei dir vor?
Der Fehler beträgt ca. 7,9 bis 8,2%. D.h bei großen Messwerten
entsprechend mehr bei kleinen Messwerten weniger Abweichung. Aber das
zeigt, dass das Programm am Anfang garnicht so fehlerhaft war.
Hallo.
Ich habe das Programm für 2 Läufer umgeschrieben.
Laut meiner Angabe rennt der 2 Läufer jedoch immer 10ms langsamer, als
der erste Läufer egal welcher Interrupt zuerst betätigt wird.
Gibt es dafür eine logische Erklärung?
Hab das jetzt nicht im Detail analysiert.
Aber: Du solltest die Timer im gestoppten Zustand halten.
Erst dann wenn das Startsignal tatsächlich kommt, werden beide Timer
gestartet. Und sobald ein Läufer über die Ziellinie geht, wird sein
zugehöriger Timer gestoppt! Und zwar so schnell wie möglich!
Dein Overflow Interrupt für Läufer 1 läuft nämlich sonst weiter, während
Läufer 2 noch auf dem Weg ist und zählt munter weiter Overflows, die für
Läufer 1 angerechnet werden.
Josua Sabo wrote:
> Ok. Ein Timer wird mittels Vorteiler( Vorteiler auf 0) gestoppt.> Leider verwenden alle Timer den selben Vorteiler!
Möglich, dass das in deinem jetzigen Program so ist.
In deinem zuletzt geposteten Program ist es nicht so.
Timer1 ist für Läufer1 zuständig, Timer3 für Läufer3
Josua Sabo wrote:
> Das hat auch nichts mit dem Programm zu tun, sondern mit dem> Datenblatt(ATMEGA162). Im Datenblatt steht, dass alle Timer den selben> Vorteiler haben.
Wo steht das?
Auszug aus der ersten Seite des Datenblatts
Peripheral Features
– Two 8-bit Timer/Counters with Separate Prescalers and Compare Modes
– Two 16-bit Timer/Counters with Separate Prescalers, Compare Modes, and
Capture Modes
'Seperate Prescalers' klingt für mich nicht danach, dass sich alle Timer
einen einzigen Vorteiler teilen müssen. Wär auch ein kleines bischen
sinnlos, sowas zu machen.
> Timer/Counter3, Timer/Counter1, and Timer/Counter0 share the same> prescaler module, but the Timer/Counters can have different prescaler> settings.
Wenn du die Vorteiler selbst eingestellt hättest und dich nicht auf den
Generierwizzard von IAR verlassen hättest, hättest du auch gemerkt, dass
die Konfigurationsregister jedes Timers jeweils einen eigenen Satz von
Vorteilereinstellbits haben. Das ist halt die Krux bei all diesen
Wizzards: man weiß nicht mehr was man eigentlich tut.
Ok. Mit dem Starten und Stoppen der Timer funktioniert das Programm wie
gewünscht. Jetzt würde ich aber gerne die Zeit während der Messung
anzeigen. Wie mache ich das am besten?
Wenn dein Programm noch einigermassen so aussieht wie eine Version von
da weiter oben, dann wird die Zeit nur dann angezeigt, wenn t gleich 1
geworden ist (weil ein Läufer ins Ziel gekommen ist). Mach die Abfrage
weg und die Zeit wird bei jedem Schleifendurchlauf in main angezeigt.
Hallo.
Das Programm funktioniert jetzt so wie ich es wollte. Allerdings sollen
die Interrupts des Endprogramms per Funk also mittels UART-Schnittstelle
eintreffen.
Ich hätte mir das so vorgestellt:
ATMEGA162(bei den Lichtschranken):
-->bekommt einen Interrupt an dem Pin der Lichtschranke des 1 Läufers
-->schickt eine Variable laeufer1 mit dem Wert 1 per UART an den
ATMEGA162 beim Start.
ATMEGA162(am Start):
-die ankommende Variable löst den UART-Interrupt aus und stoppt
jenachdem welche Variable auf 1 gesetzt wurde den entsprechenden Timer.
Wenn der andere Läufer seine Lichtschranke unterbricht soll natürlich
der selbe Ablauf stattfinden.
Ist das so machbar?
Und müssten diese Variablen im µC beim Start global sein?
Mit welchen Zeitverzögerungen müsste man rechnen?