Forum: Mikrocontroller und Digitale Elektronik AVR: ISR "ausstoppen"?


von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Guten Morgen allerseits,

ich habe eine komplexere Timer-ISR, in der ich auch float-Berechnungen 
machen muss. Daher wäre es wichtig zu wissen, wie lange die ISR (in 
CPU-Takten) braucht. Daher möchte ich die irgendwie "ausstoppen".

Als "normale" Funktion wird das eher schwierig, da Prolog und Epilog 
u.U. anders aussehen...

Meine Idee dazu wäre, die Funktion erstmal in eine andere spezielle ISR 
zu geben, welche ich per Instruktion triggern kann. Dann Timer1 
entsprechend hoch auflösend programmieren, TCNT1 merken, ISR auslösen, 
TCNT1 nochmal auslesen, die Differenz sollte dann (mit etwas Offset) 
recht genau die Laufzeit ergeben.

Welcher Interrupt wäre dafür geeignet? Ich kann mich dunkel erinnern, 
dass es da irgendwas mit EEPROM write gibt...

von Wayne (Gast)


Lesenswert?

Du kannst die ISR im AVR-Studio simulieren und dabei die Takte zählen.
Grundsätzlich sollte eine Interruptroutine aber so kompakt wie möglich 
sein und deine Fliesskommazahlberechnung in einer seperaten Funktion 
liegen die vom Hauptprogram aufgerufen wird. Die ISR setzt dann nur den 
Trigger.

von Falk B. (falk)


Lesenswert?

@ Michael Reinelt (fisa)

>machen muss. Daher wäre es wichtig zu wissen, wie lange die ISR (in
>CPU-Takten) braucht. Daher möchte ich die irgendwie "ausstoppen".

Früher hieß das schlicht "messen". Kann man im Simulator oder mit einem 
Testpin und Oszilloskop.

>Meine Idee dazu wäre, die Funktion erstmal in eine andere spezielle ISR
>zu geben, welche ich per Instruktion triggern kann. Dann Timer1
>entsprechend hoch auflösend programmieren, TCNT1 merken, ISR auslösen,
>TCNT1 nochmal auslesen, die Differenz sollte dann (mit etwas Offset)
>recht genau die Laufzeit ergeben.

Nö.

: Bearbeitet durch User
von Ast E. (vis)


Lesenswert?

Wayne schrieb:
> Du kannst die ISR im AVR-Studio simulieren und dabei die Takte
> zählen.
> Grundsätzlich sollte eine Interruptroutine aber so kompakt wie möglich
> sein und deine Fliesskommazahlberechnung in einer seperaten Funktion
> liegen die vom Hauptprogram aufgerufen wird. Die ISR setzt dann nur den
> Trigger.

verstehe auch immer nicht, was alle welt riesige berechungen und 
algorithmen in einen armen kleinen interrupt setzen will :-)

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Falk Brunner schrieb:
> Nö.

Warum nicht?

Simulator hab ich im Moment keinen (ich verwend kein AVR Studio), wenns 
sich vermeiden lässt möchte ich mir den auch nicht antun...

Wayne schrieb:
> Grundsätzlich sollte eine Interruptroutine aber so kompakt wie möglich
> sein und deine Fliesskommazahlberechnung in einer seperaten Funktion
> liegen die vom Hauptprogram aufgerufen wird. Die ISR setzt dann nur den
> Trigger.

Das stimmt grundsätzlich, es gibt aber Fälle wo es klüger ist solche 
Berechnungen in der ISR auszuführen (ist so wie mit dem "goto", das 
nicht immer böse ist)

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Michael Reinelt schrieb:
> Simulator hab ich im Moment keinen (ich verwend kein AVR Studio), wenns
> sich vermeiden lässt möchte ich mir den auch nicht antun...

Ist das irgendwie eine Glaubensfrage? Der Simulator jedenfalls ist kein 
Hexenwerk und ist für vieles unbrauchbar, aber gerade die Laufzeiten von 
Routinen sind etwas, das er recht gut kann, wenn man die Breakpoints 
richtig setzt.
'Türlich kannst du auch die Timernummer machen, aber das erfordert 
Eingriffe in den Code, den du messen willst.

von (prx) A. K. (prx)


Lesenswert?

Oszi oder Logikanalysator vorhanden, oder sonst irgendwas, das Zeiten 
eines Pins messen kann? Dann Pin am Anfang der ISR setzen, am Ende 
zurücksetzen. Da fehlt dann nur der Overhead des Handlers,

: Bearbeitet durch User
von tester (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Falk Brunner schrieb:
>> Nö.
>
> Warum nicht?
>
> Simulator hab ich im Moment keinen (ich verwend kein AVR Studio), wenns
> sich vermeiden lässt möchte ich mir den auch nicht antun...
>
> Wayne schrieb:
>> Grundsätzlich sollte eine Interruptroutine aber so kompakt wie möglich
>> sein und deine Fliesskommazahlberechnung in einer seperaten Funktion
>> liegen die vom Hauptprogram aufgerufen wird. Die ISR setzt dann nur den
>> Trigger.
>
> Das stimmt grundsätzlich, es gibt aber Fälle wo es klüger ist solche
> Berechnungen in der ISR auszuführen (ist so wie mit dem "goto", das
> nicht immer böse ist)

ich bin neugierig... nenne mir bitte ein beispiel damit ich die logik 
dahinter verstehe
meine intuition ist nach wie vor: was macht das programm bei langen IR 
routinen, wenn beispielsweise ein neuer IR und wieder ein neuer IR 
kommt... das ist dann nicht ganz sauber meiner meinung nach... ein IR 
gibt eigtl nur einen "anstoß"

von Peter II (Gast)


Lesenswert?

tester schrieb:
> meine intuition ist nach wie vor: was macht das programm bei langen IR
> routinen, wenn beispielsweise ein neuer IR und wieder ein neuer IR
> kommt...

das ist doch exakt im Datenblatt beschrieben.

von spontan (Gast)


Lesenswert?

>meine intuition ist nach wie vor

Da ist ja Glaskugelschauen noch exakter. Man-o-man.

von tester (Gast)


Lesenswert?

dann antwortet dem poster ihr klugscheißer, statt einem weiteren 
fragenden das obst hinter her zu werfen ;-)

von m.n. (Gast)


Lesenswert?

A. K. schrieb:
> Oszi oder Logikanalysator vorhanden, oder sonst irgendwas, das Zeiten
> eines Pins messen kann? Dann Pin am Anfang der ISR setzen, am Ende
> zurücksetzen. Da fehlt dann nur der Overhead des Handlers,

So würde ich es auch machen.
Falls die Frequenz des Interrupts konstant ist, kannst Du auch den 
Ausgangspin über ein RC-Glied 10k+100nF leicht filtern, die Spannung 
messen und daraus das Tastverhältnis und die eff. Ausführungszeit 
ermitteln.

Selbst, wenn die Frequenz nicht konstant ist, zeigt das Tastverhältnis 
die Auslastung des Prozessors an; bei unter 50% bist Du im grünen 
Bereich.
Und wenn Du float Berechnungen im Interrupt brauchst, dann mache es und 
laß Dich nicht von Anderen anmachen, die darin den Weltuntergang sehen.

Das Thema Angsthasen hatten wir doch schon die Tage? :-)

von Michl (Gast)


Lesenswert?

Matthias Sch. schrieb:
> Ist das irgendwie eine Glaubensfrage? Der Simulator jedenfalls ist kein
> Hexenwerk und ist für vieles unbrauchbar, aber gerade die Laufzeiten von
> Routinen sind etwas, das er recht gut kann, wenn man die Breakpoints
> richtig setzt.

Nicht jeder arbeitet unter Windows und hat damit Zugang zum AVR Studio, 
was aber leider, das muss man zugeben, den besten Simulator und Debugger 
mitbringt.
simulavr ist da eine Krücke dagegen, wird (imho) nicht mehr gepflegt und 
Takte zählen konnte es sowieso noch nie.

@ TO: du kannst natürlich die Timermethode verwenden. Dann würd ich das 
aber gleich konsequent zu Ende denken und das ganze sauber aufziehn.
Routinen um Zeiten zu messen kann man öfter brauchen.

von Peter II (Gast)


Lesenswert?

Michl schrieb:
> Nicht jeder arbeitet unter Windows und hat damit Zugang zum AVR Studio,
> was aber leider, das muss man zugeben, den besten Simulator und Debugger
> mitbringt.

also das eine Glaubensfrage. Welchen Grund gibt es kein Windows zu 
verwenden wenn es dort die passenden Tools für die Arbeit gibt? (Man 
kann Windows auch ohne Netzwerk betreiben, falls man Paranoid ist.)

geht es wirklich um die Lizenzkosten von 40€?

von m.n. (Gast)


Lesenswert?

Michl schrieb:
> Routinen um Zeiten zu messen kann man öfter brauchen.

Da war doch mal was?
Beitrag "Stoppuhr – Geschwindigkeit – Pulsweite mit Atmega88"

von Peter D. (peda)


Lesenswert?

Michael Reinelt schrieb:
> ich habe eine komplexere Timer-ISR, in der ich auch float-Berechnungen
> machen muss. Daher wäre es wichtig zu wissen, wie lange die ISR (in
> CPU-Takten) braucht. Daher möchte ich die irgendwie "ausstoppen".

Der Timer läuft doch mit. Einfach am Ende den Timer auslesen und in eine 
Variable speichern, wenn er größer als der vorherige Wert war.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Danke für die rege Beteiligung!

Glaubensfrage ist das keine, ich arbeite halt eher "old school", linux, 
emacs und ein Makefile sind meine Freunde :-) Und ich hab einen 
Microsoft-freien Haushalt.

Oszi wäre vorhanden, Logikanalysator nicht. Ist mir aber zu ungenau, zu 
umständlich, greift tatsächlich in den Code ein (ich muss ja schließlich 
einen Pin hoch-. und runterziehen). Vor allem ist es damit schwierig, 
Maximalwerte zu ermitteln (und die float-Berechnungen  zeigen durchaus 
unterschiedliche laufzeiten)

Dis Diskussion, ob float-Berechnungen in die ISR gehören, können wir 
gerne in einem anderen Thread führen, das gehört nicht unbedingt 
hierher. in meinem Fall ist es sinnvoll.

Zur Klarstellung: ich rede von Laufzeiten von 600-800 Zyklen, also nix 
mörder-kompliziertes... trotzdem kann das eng werden, wenn der Timer 
alle 1000 Takte zuschlägt.

Mittlerweile bin ich eh etwas schlauer: "Software-Interrupts" lautet das 
zauberwort, diese kennt der AVR aber direkt nciht. man kann sich aber 
helfen, indem man einen PinChange-Interrupt verwendet, und den Pin per 
Software ändert (löst dann auch den interrupt aus).

Und da gab es eben eine zweite Methode, die mir Peter Dannegger mal 
verraten hat, irgendwas mit dem EEPROM... ich find aber den Thread nicht 
mehr. Ist aber egal, PCINT reicht mir vorerst.

Pseudo-Code:
1
ISR(PCINT)
2
{
3
   /* tu was kompliziertes */ 
4
   double x = 65535*sqrt(rand()));
5
   /* verwende die Varia<ble auch */
6
   OCR1A = (uint16_t) x;
7
}
8
9
int main (void)
10
{
11
12
   setup_timer(); /* Timer 1 ohne Prescaler initialisieren */ 
13
   setup_pcint(); /* PCINT initialisieren */
14
15
   uint16_t min = 65535;
16
   uint16_t max = 0;
17
18
   for (uint16_t n = 0; n < 1000; n++) {
19
      uint16_t t1 = TCNT1;
20
      trigger_pcint(); /* PCINT auslösen */
21
      uint16_t t2 = TCNT1;
22
      uint16_t t = t2-t1;
23
      if (t < min) min = t;
24
      if (t > max) max = t;
25
      uart_printf ("%d: t=%d min=%d max=%d\n", n, t, min, max);
26
      _delay_ms (100); // for UART flush
27
   }
28
}

von m.n. (Gast)


Lesenswert?

Michael Reinelt schrieb:
> ich rede von Laufzeiten von 600-800 Zyklen, also nix
> mörder-kompliziertes... trotzdem kann das eng werden, wenn der Timer
> alle 1000 Takte zuschlägt.

Für mich wäre das schon zu eng!
Wenn ich nicht irre, geht es immer noch um Rampenberechnung für 
Schrittmotore. Da würde ich die Berechnung nicht bei jedem Schritt 
durchführen, sondern meinetwegen bei jedem 2. oder 5..
Damit wäre Alles viel entspannter.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

m.n. schrieb:
> Michael Reinelt schrieb:
>> ich rede von Laufzeiten von 600-800 Zyklen, also nix
>> mörder-kompliziertes... trotzdem kann das eng werden, wenn der Timer
>> alle 1000 Takte zuschlägt.
>
> Für mich wäre das schon zu eng!
> Wenn ich nicht irre, geht es immer noch um Rampenberechnung für
> Schrittmotore. Da würde ich die Berechnung nicht bei jedem Schritt
> durchführen, sondern meinetwegen bei jedem 2. oder 5..
> Damit wäre Alles viel entspannter.

Du hast recht. Mit an Sicherheit grenzender Wahrscheinlichkeit werd ich 
aber nie in die Region 1000 Takte Timer kommen (so schnell muss mein 
Stepper nie im Leben drehen).

Aber um das alles besser abschätzen zu können, müsste ich halt erstmal 
wissen wieviele takte die ISR tatsächlich (worst case) brauchen kann, 
dann weiss ich ob ich genug "Sicherheitsabstand" habe.

von Uwe (de0508)


Lesenswert?

Hallo Michael,

ich habe so etwas mal mit einem 16Bit Zähler und Vorteiler 1 realisiert.

Am Anfang der ISR Routine wird der Timer gestartet und am Ende 
entsprechend gestoppt und das Ergebnis - die Takte für Start/Stop an das 
Hauptprogramm übergeben.

Pseudocode
1
Start() {
2
 16Bit-Timer Prescaler = 1
3
}
4
Stop() {
5
 16Bit-Timer Prescaler = 0
6
 Zaehler auslesen
7
 Zaehler an das Hauptprogramm uebergeben
8
 Zaehler=0 setzen
9
}

Im Hauptprogramm wurden die Taktzyklen dann auf einem LCD ausgegeben.

: Bearbeitet durch User
von Bitflüsterer (Gast)


Lesenswert?

Michael Reinelt schrieb:
> m.n. schrieb:
>> Michael Reinelt schrieb:
>>> ich rede von Laufzeiten von 600-800 Zyklen, also nix
>>> mörder-kompliziertes... trotzdem kann das eng werden, wenn der Timer
>>> alle 1000 Takte zuschlägt.
>>
>> Für mich wäre das schon zu eng!
>> Wenn ich nicht irre, geht es immer noch um Rampenberechnung für
>> Schrittmotore. Da würde ich die Berechnung nicht bei jedem Schritt
>> durchführen, sondern meinetwegen bei jedem 2. oder 5..
>> Damit wäre Alles viel entspannter.

@ Michael Reinelt

Ist das richtig? Geht es um eine Rampenberechnung für einen 
Schrittmotor? Falls ja, ist das eine lineare Rampe?

von m.n. (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Aber um das alles besser abschätzen zu können, müsste ich halt erstmal
> wissen wieviele takte die ISR tatsächlich (worst case) brauchen kann,
> dann weiss ich ob ich genug "Sicherheitsabstand" habe.

Das nutzt Dir solange nichts, solange Du nicht auch alle anderen 
Interrupts im Programm berücksichtigst. Für eine Abschätzung hast Du 
genug Vorschläge bekommen: such Dir einen aus und mache es einfach!

Eine weitere Möglichkeit wäre noch, einen Pin zu setzen, wenn intern 
mehr als 800 Takte benötigt wurden (>= 80%). Im Betrieb kann man dann 
sehen, ob diese Grenze überschritten wird bzw. wurde.
Um sicher zu gehen, Dein ATmega328 wird ja hoffentlich mit 20MHz 
betrieben?

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Bitflüsterer schrieb:
> Ist das richtig? Geht es um eine Rampenberechnung für einen
> Schrittmotor? Falls ja, ist das eine lineare Rampe?

Ja. Aber mit etwas "unüblichen" Randbedingungen: ich fahre keine 
Positionen an, sondern Geschwindigkeiten (Position ist völlig 
irrelevant). Berechnung nach Aryeh Eiderman siehe hier: 
http://www.hwml.com/LeibRamp.htm

m.n. schrieb:
> Das nutzt Dir solange nichts, solange Du nicht auch alle anderen
> Interrupts im Programm berücksichtigst.

Mach ich, bzw. gibt es deren wenige, und die sind sehr kurz.

m.n. schrieb:
> Um sicher zu gehen, Dein ATmega328 wird ja hoffentlich mit 20MHz
> betrieben?
Momentan 16, könnte aber noch auf 20 gehen. Hängt aber alles davon ab 
wie eng es dann tatsächlich wird...

von (prx) A. K. (prx)


Lesenswert?

Michael Reinelt schrieb:
> greift tatsächlich in den Code ein (ich muss ja schließlich
> einen Pin hoch-. und runterziehen).

Kostet 2 Takte vorne, 2 Takte hinten. Bei 600-600 Takten. Ok. Wenn das 
wirklich auf den einzelnen Takt genau sein muss und 4 abziehen nicht in 
Frage kommt...

: Bearbeitet durch User
von Bitflüsterer (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Bitflüsterer schrieb:
>> Ist das richtig? Geht es um eine Rampenberechnung für einen
>> Schrittmotor? Falls ja, ist das eine lineare Rampe?
>
> Ja. Aber mit etwas "unüblichen" Randbedingungen: ich fahre keine
> Positionen an, sondern Geschwindigkeiten (Position ist völlig
> irrelevant). Berechnung nach Aryeh Eiderman siehe hier:
> http://www.hwml.com/LeibRamp.htm

@ Michael Reinelt
Aha. Wärst Du denn grundsätzlich daran interessiert, die 
Fließkommarechnung zu vermeiden?

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Bitflüsterer schrieb:
> Aha. Wärst Du denn grundsätzlich daran interessiert, die
> Fließkommarechnung zu vermeiden?

Ja. Siehe hier: Beitrag "AVR: Floating Point => integer arithmetik"

von Kein Troll (Gast)


Lesenswert?

Allenfalls kann man auch mit fixedpoint arbeiten, wenn man den 
dynamischen Bereich der float nicht benoetigt. Eine integer operation 
ist noch ein stueck schneller als eine float operation, da der Exponent 
nicht gerechnet(normalisiert) werden muss.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

A. K. schrieb:
> Michael Reinelt schrieb:
>> greift tatsächlich in den Code ein (ich muss ja schließlich
>> einen Pin hoch-. und runterziehen).
>
> Kostet 2 Takte vorne, 2 Takte hinten. Bei 600-600 Takten. Ok. Wenn das
> wirklich auf den einzelnen Takt genau sein muss und 4 abziehen nicht in
> Frage kommt...

Die 2+2 Takte sind mir egal, aber der gesamte Pre- und Epilog fehlt mir 
(und der ist nichtmal konstant, je nachdem wieviele Register verwendet 
werden, fürchte ich)

Obwohl das bei 600 Takten auch nicht wirklich ins Gewicht fallen wird 
<trotzig> aber trotzdem, ich wills wissen </trotzig> :-)

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Kein Troll schrieb:
> Allenfalls kann man auch mit fixedpoint arbeiten, wenn man den
> dynamischen Bereich der float nicht benoetigt. Eine integer operation
> ist noch ein stueck schneller als eine float operation, da der Exponent
> nicht gerechnet(normalisiert) werden muss.

Ich brauch vermutlich den dynamischen Bereich. Ein großer Vorteil von 
Float ist, dass man Divisionen mit konstantem Divisor durch eine 
Multiplikation mit dem Kehrwert ersetzen kann. Wenn man im 
integer-Bereich dividieren muss, schmilzt der Geschwindigkeitsvorteil 
ziemlich dahin...

von Bitflüsterer (Gast)


Lesenswert?

@ Michael Reinelt

Ich will auf folgendes hinaus:
Ganz allgemein  gehe ich so vor, diese Werte nicht während des Laufs 
auszurechnen sondern vorher. (Es sei denn, es existieren noch 
dynamische Nebenbedingungen).

Ich hatte selbst vor kurzer Zeit den Fall, das ich die Geschwindigkeit 
eines Schrittmotors, innerhalb einer vorgegebenen Schrittzahl von Null 
auf einen gewissen Wert bringen musste. Der "gewisse Wert" musste nahe 
genug an einem dynamischen Sollwert liegen; bei dem dann ein PI-Regler 
eingegriffen hat.
Der zeitliche Verlauf der Geschwindigkeit aber, war nebensächlich. 
Konnte also auch linear sein.

Daraus ergibt sich ein konstantes Dekrement für die Timerperiode. Der 
rechnerisch sich ergebende Rest der Division der Differenz der 
Impulsperioden durch die Anzahl der Schritte, kann entweder beim 
Initialwert oder beim Endwert berücksichtigt werden.
Damit ergibt sich ein konstanter integer Dekrement für die Timerperiode.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Bitflüsterer schrieb:
> @ Michael Reinelt
>
> Ich will auf folgendes hinaus:
> Ganz allgemein  gehe ich so vor, diese Werte nicht während des Laufs
> auszurechnen sondern vorher. (Es sei denn, es existieren noch
> dynamische Nebenbedingungen).
>
> Ich hatte selbst vor kurzer Zeit den Fall, das ich die Geschwindigkeit
> eines Schrittmotors, innerhalb einer vorgegebenen Schrittzahl von Null
> auf einen gewissen Wert bringen musste. Der "gewisse Wert" musste nahe
> genug an einem dynamischen Sollwert liegen; bei dem dann ein PI-Regler
> eingegriffen hat.
> Der zeitliche Verlauf der Geschwindigkeit aber, war nebensächlich.
> Konnte also auch linear sein.
>
> Daraus ergibt sich ein konstantes Dekrement für die Timerperiode. Der
> rechnerisch sich ergebende Rest der Division der Differenz der
> Impulsperioden durch die Anzahl der Schritte, kann entweder beim
> Initialwert oder beim Endwert berücksichtigt werden.
> Damit ergibt sich ein konstanter integer Dekrement für die Timerperiode.

Das ist dann aber alles andere als eine lineare Rampe!

Was ich brauche ist eine (zumindest annähernd) konstante Beschleunigung, 
die möglichst nahe an der maximal möglichen Beschleunigung liegt. Die 
dafür notwendige Mathematik beschriebt Eiderman sehr gut, inklusive 
einiger guter Optimierungen.

von Walter Tarpan (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Was ich brauche ist eine (zumindest annähernd) konstante Beschleunigung,

Die Du realistisch hervorragend in einer Lookup-Table hinterlegen 
kannst.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Walter Tarpan schrieb:
> Michael Reinelt schrieb:
>> Was ich brauche ist eine (zumindest annähernd) konstante Beschleunigung,
>
> Die Du realistisch hervorragend in einer Lookup-Table hinterlegen
> kannst.

Nein, eben nicht. Aber das hatten wir alles schon an anderer Stelle.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Dieter Frohnapfel schrieb im Beitrag #3655229:
> Kennst Du das?
>
> http://hwml.com/LeibRamp.pdf

Lieb von dir :-)

Magst mal ein paar Beiträge nach oben scrollen (oder nach "LeibRamp" 
suchen?)

von Bitflüsterer (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Bitflüsterer schrieb:
>> @ Michael Reinelt
>> ...
>> Damit ergibt sich ein konstanter integer Dekrement für die Timerperiode.
>
> Das ist dann aber alles andere als eine lineare Rampe!

Das ist durchaus eine lineare Rampe. Die Geschwindigkeit steigt linear 
an. :-)

> Was ich brauche ist eine (zumindest annähernd) konstante Beschleunigung,
> die möglichst nahe an der maximal möglichen Beschleunigung liegt.

Aha. Die Beschleunigung soll konstant sein. (Daraus ergibt sich aber 
auch nichts lineares, oder?)

Darf ich fragen, warum die Beschleunigung konstant sein soll?

Als Bemerkung möchte ich noch hinzufügen, dass ein (allgemein üblicher) 
Schrittmotor keinen linear über die Drehzahl verlaufenden maximale 
Beschleunigung hat. Das ist zwar ein wenig um die Ecke ausgedrückt, ist 
aber das Äquivalent zu der Tatsache, dass das maximale Drehmoment (bei 
konstanter Last) über die Drehzahl nicht konstant ist. Im Stillstand ist 
der Drehmoment am höchsten und er sinkt mit steigender Drehzahl.
Daraus würde folgen, dass eine konstante Beschleunigung nur mit der 
minimal auftretenden möglich ist; also bei Enddrehzahl und gegebener 
Last.

Könnte das für Deine Aufgabe relevant sein?

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Bitflüsterer schrieb:
> Das ist durchaus eine lineare Rampe. Die Geschwindigkeit steigt linear
> an. :-)

Aber die Zeit nicht (in deinem Fall)

> Aha. Die Beschleunigung soll konstant sein. (Daraus ergibt sich aber
> auch nichts lineares, oder?)

konstante beschleunigung heisst konstante geschwindigkeitsänderung pro 
zeiteinheit, oder?

> Darf ich fragen, warum die Beschleunigung konstant sein soll?

sie muss nicht konstant sein, aber maximal hoch (was idR auf konstant 
hinausläuft)

Dein Einwand mit dem nicht konstanten Drehmoment ist korrekt. Das 
Drehmoment sinkt aber erst bei recht hohen Drehzahlen stark ab, ich 
bleib aber eh im unteren bereich, meine maximale Beschleunigung 
entspricht halt dem Drehmoment bei maximaldrehzahl.

von Dieter F. (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Magst mal ein paar Beiträge nach oben scrollen (oder nach "LeibRamp"
> suchen?)

Habs leider zu spät gesehen - aber noch vor Deiner Antwort :-)

Arbeite damit (ATMEGA32 mit 16 MHz) - wenn ich die Rampe berechne und 
den Schrittmotor rennen lasse muss ich alle anderen Interrupts etc. 
ausschalten :-(

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Dieter Frohnapfel schrieb:
> Michael Reinelt schrieb:
>> Magst mal ein paar Beiträge nach oben scrollen (oder nach "LeibRamp"
>> suchen?)
>
> Habs leider zu spät gesehen - aber noch vor Deiner Antwort :-)

Und ich konnte meine Antwort nicht mehr löschen :-(

> Arbeite damit (ATMEGA32 mit 16 MHz) - wenn ich die Rampe berechne und
> den Schrittmotor rennen lasse muss ich alle anderen Interrupts etc.
> ausschalten :-(

Kannst/Darfst du mir Source zukommen lassen?

von Bitflüsterer (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Bitflüsterer schrieb:
>> Das ist durchaus eine lineare Rampe. Die Geschwindigkeit steigt linear
>> an. :-)
>
> Aber die Zeit nicht (in deinem Fall)

Huch?! Die Zeit ist per Axiom linear. Wahrscheinlich ein 
Missverständnis. Was meinst Du?

>> Aha. Die Beschleunigung soll konstant sein. (Daraus ergibt sich aber
>> auch nichts lineares, oder?)
>
> konstante beschleunigung heisst konstante geschwindigkeitsänderung pro
> zeiteinheit, oder?

Ja richtig. Ist zwar unüblich das zu betrachten, aber formal hast Du 
recht.
Ob das unüblich ist, hängt allerdings sicher davon ab, in welchen 
Kontexten man sich bewegt.

>> Darf ich fragen, warum die Beschleunigung konstant sein soll?
>
> sie muss nicht konstant sein, aber maximal hoch (was idR auf konstant
> hinausläuft)

Gut. Darf ich dann fragen warum die Beschleunigung maximal sein soll?

> Dein Einwand mit dem nicht konstanten Drehmoment ist korrekt. Das
> Drehmoment sinkt aber erst bei recht hohen Drehzahlen stark ab, ich
> bleib aber eh im unteren bereich, meine maximale Beschleunigung
> entspricht halt dem Drehmoment bei maximaldrehzahl.

Aha. Verstehe.

von (prx) A. K. (prx)


Lesenswert?

Michael Reinelt schrieb:
> Die 2+2 Takte sind mir egal, aber der gesamte Pre- und Epilog fehlt mir
> (und der ist nichtmal konstant, je nachdem wieviele Register verwendet
> werden, fürchte ich)

Ja. Aber das abzuzählen ist überschaubar.

von Kein Troll (Gast)


Lesenswert?

>Ich brauch vermutlich den dynamischen Bereich. Ein großer Vorteil von
Float ist, dass man Divisionen mit konstantem Divisor durch eine
Multiplikation mit dem Kehrwert ersetzen kann. Wenn man im
integer-Bereich dividieren muss, schmilzt der Geschwindigkeitsvorteil
ziemlich dahin...

Kann man mit fixed point alles auch.

von Dieter F. (Gast)


Angehängte Dateien:

Lesenswert?

Michael Reinelt schrieb:

> Kannst/Darfst du mir Source zukommen lassen?

Habe ich im Rahmen meines "Laser-Exposer-Projektes" aus Spass mal 
gemacht, weil mir die Rückfahrt des Schlittens zu lange gedauert hat. 
Ist also in eine etwas größere Anwendung eingebunden ... und 
wahrscheinlich auch nicht optimal.

Schau Dir erstmal mein "Basis-Excel-Sheet" dazu an - falls dann immer 
noch Interesse besteht (da musste ich schon einiges rumfrickeln ...) 
kann ich Dir die Includes (ohne die Projekt-spezifischen Teile 
herauszunehmen) gerne per PN zusenden.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Kein Troll schrieb:
>>Ich brauch vermutlich den dynamischen Bereich. Ein großer Vorteil
> von
> Float ist, dass man Divisionen mit konstantem Divisor durch eine
> Multiplikation mit dem Kehrwert ersetzen kann. Wenn man im
> integer-Bereich dividieren muss, schmilzt der Geschwindigkeitsvorteil
> ziemlich dahin...
>
> Kann man mit fixed point alles auch.

Ja, wenn man einen festen Dynamikbereich hat, den ich nicht habe.

von (prx) A. K. (prx)


Lesenswert?

Fliesskommarechnung pauschal zu verteufeln bringt nicht weiter. Sie hat 
ihre Berechtigung. Festkommarechnung kann sie nicht immer ersetzen und 
kann einen erheblichen Umstellungsaufwand bedeuten, nicht zuletzt in 
Form von Vorarbeit.

Nur muss man sich eben darüber im Klaren sein, dass AVR dafür eine etwas 
langsame Plattform ist. Da gibt es (pro Stück) günstige Alternativen mit 
viel höherer Leistung.

: Bearbeitet durch User
von Kermit (Gast)


Lesenswert?

Dein Timer und seine OCRx Register arbeiten eh nur mit Integer bzw. 
rationalen Verhältnissen. Somit kannst du gleich mit 
Integer-Approximation rechnen, statt mit Float.

von Falk B. (falk)


Lesenswert?

@ Michael Reinelt (fisa)

>Glaubensfrage ist das keine, ich arbeite halt eher "old school", linux,
>emacs und ein Makefile sind meine Freunde :-) Und ich hab einen
>Microsoft-freien Haushalt.

Naja.

>Oszi wäre vorhanden, Logikanalysator nicht.

Dann NIMM IHN! Mein Gott!

> Ist mir aber zu ungenau, zu
>umständlich, greift tatsächlich in den Code ein (ich muss ja schließlich
>einen Pin hoch-. und runterziehen).

Was für eine ZUMUTUNG!

> Vor allem ist es damit schwierig,
>Maximalwerte zu ermitteln (und die float-Berechnungen  zeigen durchaus
>unterschiedliche laufzeiten)

Die musst du so oder so geschickt ermittlen, egal ob im Simulator oder 
mit der Realmessung.

>Zur Klarstellung: ich rede von Laufzeiten von 600-800 Zyklen, also nix
>mörder-kompliziertes... trotzdem kann das eng werden, wenn der Timer
>alle 1000 Takte zuschlägt.

Dein uC läuft nur auf 1MHz? Takt hochstellen?

>Mittlerweile bin ich eh etwas schlauer: "Software-Interrupts" lautet das
>zauberwort,

Wer keine Probleme hat, macht sich welche.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Bitflüsterer schrieb:
> Michael Reinelt schrieb:
>> Bitflüsterer schrieb:
>>> Das ist durchaus eine lineare Rampe. Die Geschwindigkeit steigt linear
>>> an. :-)
>>
>> Aber die Zeit nicht (in deinem Fall)
>
> Huch?! Die Zeit ist per Axiom linear. Wahrscheinlich ein
> Missverständnis. Was meinst Du?

Vielleicht ist es ein Mißverständnis: Wenn du in der Timer-ISR die den 
Step-Impuls für den Schrittmotor-Controller erzeugt, jedesmal den 
Timer-Wert konstant erniedrigst, so hast du zwar auf den ersten Blick 
einen linearen Anstieg der Geschwindigkeit. Eigentlich steigt aber sogar 
die Geschwindigkeit über die Schirttanzahl betrachtet nciht linear. Dazu 
kommt, dass die Zeit die für jeden Schritt benötigt wird, wird ja immer 
kleiner. Daraus resultiert keine konstante Geschwindigkeitsänderung 
pro Zeit.

Beispiel: Annahme: 16 MHz CPU-Takt, Timer1 läuft mit Prescaler 16 und 
erzeugt beim Overflow den Step-Impuls (Effektive Timer-Clock 1 MHz)

Wir beginnen mit einer Geschwindigkeit von 100 Schritten/sec, und wollen 
auf 1000 Schritte/sec beschleunigen

Wir beginnen bei einem Timer-Wert von 10.000 => Geschwindigkeit 100 
Steps/sec

Nun beschleunigen wir, indem wir den Zähler konstant um 100 
dekrementieren

Nächster Timer-Wert: 9.900 => Geschwindigkeit 101 Schritte pro Sekunde 
=> delta von 1 Schritt/sec

Inzwischen sind 9.9 msec vergangen

a = delta v durch delta t = 1 / 0.099 =? 101 Schritte/sec^2

gegen Ende hin sind wir bei 1.100 => Geschwindigkeit 909 Schritte/sec
letzter Schritt: 1.000 => Geschwindigkeit 1000 Schritte/sec
Geschwindigkeitsänderung: 91 Schritte/sec
Zeit für den letzten Schritt: 1 msec
Beschleunigung: 91/0.001 = 91.000 Schritte/sec^2

Sieht für mich nicht sonderlich linear aus...

>> konstante Beschleunigung heisst konstante Geschwindigkeitsänderung pro
>> Zeiteinheit, oder?
>
> Ja richtig. Ist zwar unüblich das zu betrachten, aber formal hast Du
> recht.
Entweder ich habe meinen gesamten Physik-Unterricht vergessen (oder 
versoffen), aber ich denke ich habe nicht nur formal recht ;-)

> Gut. Darf ich dann fragen warum die Beschleunigung maximal sein soll?
Weil ich die neue Solldrehzahl so schnell wie möglich erreichen will? 
Ist das so unüblich???

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Peter Dannegger schrieb:
> Der Timer läuft doch mit. Einfach am Ende den Timer auslesen und in eine
> Variable speichern, wenn er größer als der vorherige Wert war.

Danke, Peter! Deine Antwort hatte ich in den ganzen 
Grundsatzdiskussionen hier glatt übersehen...

Du triffst wie üblich den Punkt: Damit erreiche ich mit minimalem 
Aufwand ein maximal genaues Ergebnis, und fange damit auch etwaige 
"Ausreißer" nach oben hin.

von Bitflüsterer (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Bitflüsterer schrieb:
>> Michael Reinelt schrieb:
>>> Bitflüsterer schrieb:
>>>> Das ist durchaus eine lineare Rampe. Die Geschwindigkeit steigt linear
>>>> an. :-)
>>>
>>> Aber die Zeit nicht (in deinem Fall)
>>
>> Huch?! Die Zeit ist per Axiom linear. Wahrscheinlich ein
>> Missverständnis. Was meinst Du?
>
> Vielleicht ist es ein Mißverständnis: Wenn du in der Timer-ISR die den
> Step-Impuls für den Schrittmotor-Controller erzeugt, jedesmal den
> Timer-Wert konstant erniedrigst... Daraus resultiert keine konstante
> Geschwindigkeitsänderung pro Zeit.

Ja richtig. Mein Fehler.

>> Gut. Darf ich dann fragen warum die Beschleunigung maximal sein soll?
> Weil ich die neue Solldrehzahl so schnell wie möglich erreichen will?
> Ist das so unüblich???

Durchaus nicht. Danke für die Information.

von S. R. (svenska)


Lesenswert?

Lasse einen Timer schnell frei laufen und lies in der (fast leeren) 
Hauptschleife ständig den Wert. Wenn die Differenz zweier Werte über 
einem Schwellwert ist, hat der Interrupt zugeschlagen - und du kennst 
die Zeit in der Auflösung des Timers.

von c-hater (Gast)


Lesenswert?

tester schrieb:

> ich bin neugierig... nenne mir bitte ein beispiel damit ich die logik
> dahinter verstehe

Wenn man es beherrscht, schreibt man die komplette Anwendung als 
Sammlung von ISRs.

Die Hauptschleife sieht dann (auf das Wesentliche vereinfacht) so aus:

main:
 sleep
 rjmp main

Und dieses Konstrukt ist bei weitem nicht exotisch, sondern Standard bei 
allen modernen MT-OS, bloß dieses main dort meist IdleTask oder so 
ähnlich heißt.
Alles andere wird als Reaktion auf einen Interrupt abgearbeitet, sogar 
sämtliche Anwendungstasks sind allesamt letztlich nichts anderes als 
unterbrechbare Abschnitte einer Timer-ISR.

Erkennst du jetzt den Sinn?

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.