floating Point bremst den Controller schon mächtig runter ... evtl. wär ne Tabelle ne Lösung
Hallo,
Ich versuche mich gerade daran, über einen µC einen Schrittmotor sauber anzusteuern. Der Code steht und läuft auch bedingt.
Zum Aufbau:
Atmega 168 - 20 PU
16 Mhz
Verwendeter Timer: Timer1, 16bit, Prescale 64 ->250000Hz
getakteter Ausgang zum Ansteuern eines Schrittmotortreibers mit Halbschritt (800Im/Umdrehung)
Der Atmega 168 berechnet die Beschleunigungsrampe simultan im Interrupt und passt den Timer1 entsprechend an. Die Berechnung muss aus Genauigkeitsgründen mit zwei Variabeln des Typs Single erfolgen da sonst ein Fehler auftritt.
Bei kleineren Drehzahlen, wenn der Timerwert oberhalb von ca. 100 Counts (entspricht 3U/s) bleibt, läuft die Rampe sauber bis zum Ende.
Steigere ich die Drehzahl kommt er hier wahrscheinlich zu Verzögerungen - die Hochlaufzeit erhöht sich deutlich und der Motor dreht unsauber am Ende der Hochlauframpe.
Den hohen Prescale habe ich gewählt, um dem Controller genug Rechenzeit zu lassen, leider kann ich -meines Erachtens nach- nicht viel an der Berechnung ändern. Ohne Float-Werte hängt sich die Rampe irgendwann auf!
Hier der Code-Ausschnitt aus dem eigentlichen Interrupt:Code:$regfile = "m168def.dat" $crystal = 16000000 ' used crystal frequency $hwstack = 32 ' default use 32 for the hardware stack $swstack = 8 ' default use 10 for the SW stack $framesize = 24 $baud = 19200 Config Timer1 = Timer , Prescale = 64 '250000 Hz On Timer1 X_irq Enable Interrupts Dim C0 As Integer Dim Cn As Single Dim Cn_s As Single Dim Steps As Word Steps = 0 C0 = 8450 Cn = 8450 Load Timer1 , C0 Enable Timer1
Nun bin ich mir nicht sicher, ob ich irgendwo am Code etwas ändern kann, oder ob es vielleicht einen stärkeren Atmega für diese Aufgabe gibt?Code:X_irq: Toggle Pul Incr Steps Cn_s = Cn Cn = 2 * Steps Cn = Cn + 0.5 Cn = Cn_s / Cn Cn = Cn_s - Cn Load Timer1 , Round(cn)
Würde es eventuell helfen einen Atmega mit mehr Ram zu verwenden, oder eventuell auf 20Mhz umzusteigen?
MFG Erik
floating Point bremst den Controller schon mächtig runter ... evtl. wär ne Tabelle ne Lösung
Vor den Erfolg haben die Götter den Schweiß gesetzt
Löst der Timer eventuell schon wieder aus, wenn er mit dem vorherigen Aufruf noch garnicht fertig ist?
Also mein Problem bezüglich der Tabellen ist folgendes:
Die Rampe bei 3U/s besteht aus 4000 Schritten (ich kann nicht beurteilen, was für den Atmega viel ist) hinzu kommt, dass noch variable Rampen verfügbar sein sollten.
Ob der Timer sich selbst wieder aufruft weis ich leider nicht - aber eigentlich wird der Timer ja erst nach der Berechnung neu gesetzt. Das sich die hochlaufzeit der Rampe erhöht deutet ja auf eine langsame Abarbeitung hin...
Mir ist klar, dass floating Point den Controller ausbremst, aber ich habe schon alles Mögliche versucht um diesen zu umgehen - immer ohne Erfolg....
Macht es denn Sinn den Singel durch einen Long mit dem Faktor 100 zu erseten? Und diesen dann immer herunterzurechnen? (2 Kommastellen könnten noch reichen)
Bin in Bascom nicht ganz Fit, aber das sehe ich anders.aber eigentlich wird der Timer ja erst nach der Berechnung neu gesetzt.
Der Startwert wird nach den Berechnungen neu gesetzt, das schliesst doch aber nicht aus das er da schon neu gestartet ist.
Mir kommt da spontan etwas in den Sinn. Was glaubst du wie lange ich danach gesucht habe:
Bei mir war es so, dass sich bei Single - Variabeln im Interrupt plötzlich die Werte selbstständig geändert haben. Nach dem Push und Pop war das nicht mehr der Fall. Warum das bei Bascom so implemeniert wurde.....Code:'save registers bei single in interrupt nötig Push R12 ' save registers Push R13 Push R14 Push R15 code... 'restore registers bei singel in interrupt nötig Pop R15 ' restore registers Pop R14 Pop R13 Pop R12
@TobiKa
Also, zu den Interrupts, Der Interrupt kann ausgelöst werden auch
wenn der µC gerade in einer ISR ist, die Ausführung der zweiten
ISR wird aber normalerweise verschoben bis die erste abgearbeitet ist,
es sei denn man aktiviert die Interrupts in der ISR selbst wieder, was
geht, aber mächtig Probleme verursachen kann. Hat mit
Bascom direkt nicx zu tun, kann man auch in C oder ASM machen.
@leo.vetterli
wenn das pushen und poppen Abhilfe schafft sind zu 99% die Stack-
Frameeinstellungen zu klein, weil Bascom nämlich alle Register versucht
zu pushen und poppen in einer ISR ... leider.
@erik_wolfram
Timer 1, 16-Bit 4000 Schritte sind dann 8000 Byte ... Ist ne ganze Menge,
brauchts wirklich so viele? ... wie auch immer, der 16-Bit Timer kann keine
Kommastellen, shiften, addieren und subtrahieren kann der AVR recht schnell,
Berechnungen gehen sehr schnell wenn man bei Vielfachen von 2 bleibt,
Mittelwerte z.B. über 2,4,8,16,32 Werte z.B. dann kann man einfach durch
schieben um 1,2,3,4,5 Schritte eben dividieren durch 2,4,8,16,32 etc.
Auch immer gerne verwendet für solche Geschichten ist die Tabellen für Sinus,
die kann man vorwärts, rückwärts laufen lassen spiegeln, stecken etc.
Vor den Erfolg haben die Götter den Schweiß gesetzt
moin moin,
welche Form hat die Rampe? Linear oder Sinus^2?
>>der Motor dreht unsauber am Ende der Hochlauframpe.
Wie äussert sich das?
>>floating Point den Controller ausbremst
Bei meiner Fräsensteuerung habe ich per SPI einen 2.MC(100MIPS) als FPU dazugegeben. Für einen Simuswert braucht der ca. 150µs.
Mit Gruß
Peter
Wenn die Rampe linear sein soll / darf:
Warum muß die Berechnung in die ISR ?
Besser:
-Increment /Decrement vorher berechnen
-in der ISR nur Increment / Decrement addieren
mfG
Willi
Also die Rampe ist nicht linear - Sie beruht auf der Taylor-Reihe.
Nachdem ich den Motor jetzt mal unter Last laufen lassen habe, hat sich herausgestellt, dass die Rampe sehr sauber (wenn auch länger) läuft.
Wenn der Motor dann konstant läuft klingt er etwas unschön...
Die Genauigkeit ist aber da ... Schrittfehler (soll/ist) konnte ich nicht feststellen.
Das mit den Tabellen werde ich mir mal genauer angucken, dass ganze einfach vorher zu berechnen ist natürlich eine gute Idee, der ich erstmal nachgehen werde.
Danke für die Hilfe, werde das erstmal ausprobieren und berichten!
Lesezeichen