Also wenn dir schon der Timer Probleme macht,
und du alle Flanken mit Interrupt abfragst,
ist der Weg noch weit, verdammt weit.
Du hast einen Encoder, der uC muss den also auslesen
können und möglichst zeitnah wissen wo er steht.
Nehmen wir an, es gibt nun eine Speicherstelle im uC,
in dem die aktuell erfasste Encoderposition steht.
Dann gibt es einen Schrittmotor der auch eine intern
gezählte Position innehat.
Und du hast ein Poti, welches z.B. am einem Analogeingang
hängt, und der eingestellte Wert ist dem uC bekannt.
Wenn nun die Encoderposition kleiner oder grösser ist als
die Schrittmotorposition, muß sich der Schrittmotor bewegen.
Du hast aber richtig erkannt, daß er wohl nicht gleich mit
vollem Tempo laufen kann (das wäre dann ein eher niedriges
Tempo), sondern beschleunigen und abbremsen muß damit er mit
der bewegten Masse keine Schritte verliert weil seine Kraft
nicht zum so schnellen Beschleunigen oder Bremsen der Masse
reicht.
Mit dem Beschleunigen ist es nicht so ein Problem, man darf
halt nicht zu schnell die Taktrate ansteigen lassen, sondern
mit dem Bremsen, weil das bereits passieren muß bevor das
Ziel erreicht ist. Es gibt ungefähr so einen Zusammenhang:
Sollposition erreicht: Tempo 0
Motorposition noch 10 vor Sollposition: Tempo 100 Schritte/Sekunde
Motorposiiton noch 20 vor Sollposition: Tempo 1000 Schritte/Sekunde
Hast du diese Rampe
_ _ _
/ \
/ \
dann hast du die halbe Miete. Leider musst du jedesmal neu
messen und berechnen, weil sich wohl der Encoder verändern
kann während der Motor auf ihn zuläuft. Dabei kann der
Encoder dem Motor entgegen kommen und man kann nicht mehr
schnell genug bremsen sondern muß über's Ziel hinausschiessen
und danach umkehren. Damit muß dein Code klarkommen.
Berechne die GESCHWINDIGKEIT in Abhängigkeit von der
Sollposisiotn, nicht die ENTFERNUNG (in absoluten Schritten)
dann kann dein Code akzeptieren, daß Encoder und Schritte
nicht exakt übereinstimmen sondern mal Messfehler auftreten.
Besonders zickig wird die Sache, wenn der Encoder nicht die
aktuelle Position widergibt, sondern die Position vor 1/10
Sekunde. Es macht Sinn, diese Verzögerungszeit so klein wie
möglich zu halten.
Dein Potzi multipliziert einfach die Encoderposition damit
mehr oder weniger Schritte bei rauskommen.
Starker Tip: Vergiss Flanken, vergiss Interrupts, baue eine
einzige Schleife ins Programm mit einiges if's, die jeweils
reagieren: Ein if auf neue Encoderdaten, ein If auf Ablauf
der Zeit des letzten Schritts (also auslösen des nächsten),
jedes if macht nur minimale Sachen (z.B. es hat die
steigende Flanke erkannt, merke das Ereignis) und niemals
ganze Jobs (nach der Flanke im IF auf die nächste warten ist
bäh) manches geht ohne if, z.B. einlesen von A-B-Encodern und
neuberechnen der Position (oftmals +0, also unverändert,
aber ausführen kann man das jedesmal). Achte darauf, daß
die Impulse des Schrittmotors zum sauberen Bremsen und
Beschleunigen nicht im festen raster (z.B. 1kHz) erfolgen
sondern in reellzahligen Zeiteinheiten, also 'jetzt', 'in
737154 Maschinentakten', 'in 1097653 Maschinentakten' und
den Timer verwendest du nur 'free running' um die aktuelle
Zeit abfragen zu können.