Hallo!
Ich beiße mir an einem (vmtl. zwei) Problemen die Zähne aus:
Gegeben ist eine maschinelle Kabeltrommel mit Getriebemotor, der die
Trommel antreibt und einem Schrittmotor, der mittels Trapezspindel eine
Kabelführung so vor der Trommel positioniert, dass die Führung stets auf
Höhe der aktuellen Kabelbahn steht.
Die Steuerung baut auf einen Atmega1284 bei 20MHz.
Also, pro 30 Getriebemotorumdrehungen (1 Trommelumdrehung)
- gibt ein Drehgeber am Motor (1024 Imp * 30) = 30720 Impulse aus und
- verfährt die Führung um eine Kabeldicke von 10mm indem die
- Trapezspindel (Steigung 6mm) etwa 1,67 Umdrehungen, angetrieben vom
- Schrittmotor, der (1,67U * 3200 Step pro U), also 5333 Steps macht.
Oder besser, machen sollte.
Baustelle 1: Auslesens des Drehgeber
Basierend auf den Artikel
http://www.mikrocontroller.net/articles/Drehgeber
wird die Veränderung des Drehgeber wie folgt ermittelt:
ISR(TIMER2_COMPA_vect)//langsame Abfrage zum Auslesen der Enc-Diff
45
{
46
motorumdrehung_f+=encode_read4()*(1.0/1024);/*Multiplikation des Geberwertes mit 1/Aufloesung des Encoders*/
47
}
48
49
int8_tencode_read4(void)
50
{
51
int8_tval;
52
cli();
53
val=enc_delta;
54
enc_delta=val&3;
55
sei();
56
returnval>>2;
57
}
Problem 1: bei Höchstgeschwindigkeit (1450U/min) muss die "schnelle"
Abfrage (TIMER0_COMPA_vect) so oft ausgeführt werden, dass kein Impuls
verschluckt werden kann; bei 25U/s und 1024Impulsen/U sind das gut
25kHz. Bei 20MHz Takt sollten daher OCR0A=720 (bzw OCR0A=90 mit
prescaler=8) (entspr. 36µs oder 27,7kHz) genügen- tut es aber nicht.
Oberhalb von OCR0A=130 (entspr. 6,5µs oder 153kHz) werden Impule
verschluckt.
TIMER2_COMPA_vect hingegen wird nur etwa um Faktor 100 seltener
ausgelöst, um die in TIMER0_COMPA_vect beschreibene Variable auszulesen.
Baustelle 2:
Aus der sich ergebenen Motorumdrehung wird über einige
Multiplikationen/Divisionen die Kabelführungs-Sollposition "Sollschritt"
ausgerechnet. Bei Differenz zwischen Soll- und Istschritt wird Timer1
gestartet, der direkt auf den STEP-Eingang des Schrittmotors wirkt.
1
volatilelongstep_ist;
2
volatilelongstep_soll;
3
#define F_CPU 20000000
4
5
intmain(void)
6
{
7
init_sys();
8
while(1)
9
{
10
step_soll=(2*motorumdrehung_f*STEP_PER_U_ANTR);/*STEP_PER_U_ANTR= ca. 177*/
Die Frequenz dieses Timers richtet sich nach der Differenz Soll/Ist: je
größer diese ist, desto kürzer die Pulsfolge (P-Regler). Bei Erreichen
des Solslchrittes stoppt der Timer.
1
ISR(TIMER1_COMPA_vect)
2
{
3
PORTA^=(1<<STEPPER_STEP));/*invertieren des STEP-Einganges = halber Schritt*/
Problem 2:
Wenn diese Nachführfunktion aktiv ist, fängt der Drehgeber an, Schritte
zu verschlucken, sprich, die Kabelführung fährt zwar exakt an die
errechnete Stelle, allerdings geht sie davon aus, dass die Trommel
langsamer dreht als sie es tatsächlich tut.
Wäre über Tipps und Tadel heilfroh.
Grüße
Stephan
@Stephan (Gast)
>Also, pro 30 Getriebemotorumdrehungen (1 Trommelumdrehung)>- gibt ein Drehgeber am Motor (1024 Imp * 30) = 30720 Impulse aus und
Reichlicher Luxus für so eine Kabeltrommel.
>- verfährt die Führung um eine Kabeldicke von 10mm indem die>- Trapezspindel (Steigung 6mm) etwa 1,67 Umdrehungen, angetrieben vom>- Schrittmotor, der (1,67U * 3200 Step pro U), also 5333 Steps macht.>wird die Veränderung des Drehgeber wie folgt ermittelt:
volatile int8_t enc_delta; // -128 ... 127
static int8_t last; //
>volatile int val; // globale Variable fuer Encoder>float motorumdrehung_f; // globale Variable fuer Motorumdrehung
MÖÖÖP! Macht man nicht. Besser Festkommaarithmetik.
>ISR( TIMER2_COMPA_vect ) //langsame Abfrage zum Auslesen der Enc-Diff>{> motorumdrehung_f += encode_read4() * (1.0/1024); /*Multiplikation des
Geberwertes mit 1/Aufloesung des Encoders*/
>}
MÖÖP. Auch hier besser Festkommaarithmetik, ist auch schneller.
Ausserdem verballerst du hier zusätzlich Zeit, weil du eine Funktion
aufrufst. Besser ist es, hier den Code der Funktion direkt
reinzuschreiben.
>Oberhalb von OCR0A=130 (entspr. 6,5µs oder 153kHz) werden Impule>verschluckt.
Optimierung des Compilers nicht eingeschaltet? Oder deine andere ISR ist
zu langsam und bremst deine schnelle ISR periodisch aus.
Lösung: Keine langsame ISR sondern periodisch per Flag in der
Hauptschleife abfragen.
>TIMER2_COMPA_vect hingegen wird nur etwa um Faktor 100 seltener>ausgelöst, um die in TIMER0_COMPA_vect beschreibene Variable auszulesen.
val ist bei dir int, also 16 Bit, da kann man DEUTLICH langsamer
abfragen, nämlich Faktor 32768.
>Aus der sich ergebenen Motorumdrehung wird über einige>Multiplikationen/Divisionen die Kabelführungs-Sollposition "Sollschritt">ausgerechnet. Bei Differenz zwischen Soll- und Istschritt wird Timer1>gestartet, der direkt auf den STEP-Eingang des Schrittmotors wirkt.
Da muss man nix multiplizieren und dividieren. Mit Festkommaarithmetik
und ggf. Bresemhamalgorithmus kriegt man das spielend und schnell hin.
>Wenn diese Nachführfunktion aktiv ist, fängt der Drehgeber an, Schritte>zu verschlucken, sprich, die Kabelführung fährt zwar exakt an die>errechnete Stelle, allerdings geht sie davon aus, dass die Trommel>langsamer dreht als sie es tatsächlich tut.
Deine 3. ISR ist zu lang und bremst deine wichtige Encoder ISR
zusätzlich aus.
Das kann man vermeiden indem man
a) die Schrittmotoransteurun mit in TIMER0_COMPA_vect packt (ohne
Divisionen etc., siehe oben)
b) oder die Schrittmotoransteurung über ein Timer Flag in der
Hauptschleife macht, siehe Interrupt.
c) oder verschachtelte ISRs der Timer per Software macht, siehe
Interrupt
Denn dein 25 kHz Timer darf NIE durch eine andere ISR länger als 720
Takte an der Ausführung gehindert werden.
if(motorumdrehung)motorumdrehung--;/*zaehlt nicht ins Negative*/
17
}
18
}
Ergebnis war, dass bei jeder vollen Motorumdrehung der
Schrittmotor-Timer hörbar erhöht wurde, was besonders bei sehr langsamem
Lauf extrem störend ist.
Falk Brunner schrieb:> val ist bei dir int, also 16 Bit, da kann man DEUTLICH langsamer> abfragen, nämlich Faktor 32768.
Die Variable, die abgefragt werden muss und überzulaufen droht, ist
enc_delta, also nur 8bit. Überlege gerade, was gegen eine 16bit spricht.
Danke für deinen Hinweise, werde sie mal durchpflügen.
@ Stephan (Gast)
>> Reichlicher Luxus für so eine Kabeltrommel.
Ich meinte die Auflösung des Drehgebers.
>Einst arbeitete ich mit "motorumdrehung" als ganzzahlige Variable:>Ergebnis war, dass bei jeder vollen Motorumdrehung der>Schrittmotor-Timer hörbar erhöht wurde, was besonders bei sehr langsamem>Lauf extrem störend ist.
Klar, ich sagte ja auch nicht, dass man nur mit ganzen Motorumdrehungen
rechnen soll sondern mit Festkommaarithmetik! Da gibt es auch
Bruchteile einer Umdrehung. Und wenn man das geschickt macht, erhält man
daraus DIREKT die Sollposition des Schrittmotors! Ohne Multiplikation
und Division!
>Die Variable, die abgefragt werden muss und überzulaufen droht, ist>enc_delta, also nur 8bit. Überlege gerade, was gegen eine 16bit spricht.
Das meinte ich. War aber falsch geschrieben 8-0
Ich würde auch erstmal schauen, ob sich die Trommelumdrehung nicht
anders lösen lässt.
30720 Impulse pro Umdrehung? Das ist eine Auflösung von 0,012 Grad.
Wenn Du einen einen 8-Bit Binär Zähler dazwischen klemmst bekommst Du
nur noch 120 Impulse pro Umdrehung.
Hallo Stephan,
Ergänzend zu den sehr richtigen Ausführungen von Falk...
> Die Frequenz dieses Timers richtet sich nach der Differenz Soll/Ist: je> größer diese ist, desto kürzer die Pulsfolge (P-Regler). Bei Erreichen> des Solslchrittes stoppt der Timer.
Also gibst du im Prinzip eine Solldrehzahl für den Schrittmotor vor. Das
ist so zwar sehr kompakt, führt aber dazu, dass ein Sprung im Sollwert
direkt auch einen Geschwindigkeitssprung zur Folge hat. Das hast du ja
beim Rechnen mit ganzzahligen Umdrehungen (Sollwertsprünge) bereits
selbst gemerkt.
Außerdem führen große Positonsabweichungen zu entsprechend hohen
Geschwindigkeiten. Das kann alles funktionieren, kann aber auch zu
extremfällen kommen, in denen der Motor nicht mehr hinterher kommt.
Irgendwo sollte man Begrenzungen und/oder Überprüfungen einbauen, um
feststellen zu können, ob man irgendwo an ein Limit gekommen ist.
Mit freundlichen Grüßen
Thorsten Ostermann
Thorsten Ostermann schrieb:> ein Sprung im Sollwert
Dürfte ja eigentlich nicht vorkommen. Die Trommel läuft sehr träge an.
Der DIY P-Regler arbeitet bisher ganz gut, ich werde ihn noch durch
einen Minimalwert begrenzen.
Bin dabei, Festkommaarithmetik einzubauen...
Rudolph schrieb:> Ich würde auch erstmal schauen, ob sich die Trommelumdrehung nicht> anders lösen lässt.
Ich sehe die Konflikte zwischen der sehr schnellen (notwendigen) Abfrage
am Drehgeber und der sehr schnellen (notwendigen) Ansteuerung des
Schrittmotors.
Siehst Du einen Vorteil darin, die "Impulse pro Umdrehung"
herunterzuteilen?
@ Stephan (Gast)
>Der Vollständigkeit halber und um zu fragen, os sich dies auch in>Festkommaarithmetik realisieren lässt:
Ja, kann man, auch wenn man einige Werte runden muss.
#define B_TROMMEL 600 /*lichte Breite der Trommel*/
#define D_TROMMEL 400 /*Aussendurchmesser der Trommel*/
#define I_GETRIEBE 31.39 /*Getriebeuebersetzung*/
#define D_KABEL 10.4 /*Kabeldurchmesser*/
#define M_SPINDEL 6 /*Gewindesteigung der Trapezspindel*/
#define STEPS_PER_U 200 /*1.8° pro Schritt bei Vollschrittbetrieb*/
#define MICROSTEPS 16 /*Einstellung getaetigt mit TCML-IDE, */
#define RES_ENCODER 1024 /*Schritte pro Umdrehung des Winkelencoders*/
>#define U_MOTOR motorumdrehung
So ein Macro ist nicht sehr sinnvoll. Warum willst du eine echte
Variable hinter einem Macro verstecken?
>#define U_TROMMEL U_MOTOR / I_GETRIEBE /*Trommelumdrehung*/
Hier fehlen Klammern! Denn sonst kann es böse Überraschungen geben, wenn
dein Macro in einem komplexen Ausdruck genutzt wird!
>#define POS_KABEL (U_TROMMEL) * D_KABEL /*Kabelposition*/>#define STEP_PER_U_ANTR D_KABEL STEPS_PER_U MICROSTEPS / (M_SPINDEL>* I_GETRIEBE)
Hier hat die Autoformatierung des Forums die Sternchen gefressen ;-) Es
fehlt aber auch hier eine äußere Klammer.
Stephan schrieb:> Siehst Du einen Vorteil darin, die "Impulse pro Umdrehung"> herunterzuteilen?
Natürlich.
Auf wieviele Nanometer genau muss denn der Schlitten vor der
Kabeltrommel positioniert werden? Siehst du, wenn der Schlitten auf
Zentel-Millimeter genau steht, dann wird das ja wohl reichen.
Vorteil: kleinere Zahlen
Vorteil von kleineren Zahlen: kleinere Datentypen
Vorteil von kleineren Datentypen: es kann schneller gerechnet werden.
die 32tausend-irgendwas Encoder-AUflösung pro Umdrehung macht dir das
Leben unnötig schwer ohne das dir das irgendwas bringt. Denn ob deine
Mechanik den Schlitten überhaupt so genau positionieren kann, steht in
den Sternen. Was bringt es dir, wenn du auf 3 Atomradien genau
ausrechnen kannst, wo die Führung stehen müsste, wenn dein Gewindespiel
millionenfach größer ist?
Das würde ich als erstes rauswerfen.
ANstatt des Encoders wird eine einzelne Umdrehung vom Motor abgegriffen.
Einfach Lochscheibe, 2 Lichtschranken - damit man rechts und linkslauf
auseinanderhalten kann, und dann damit weiter arbeiten.
(Anstatt Lichtschranken irgendeine andere Technologie deiner Wahl.
Wesentlich ist: 1 Impuls pro 1 Motorumdrehung. Und schon lacht die Sonne
wieder, weil dein µC alle Zeit der Welt hat und nicht durch sinnlose
Encoderabfragen ausgebremst wird. Man muss auch mal die Kirche im Dorf
lassen. Nicht alles was technologisch möglich ist, ist auch sinnvoll)
Stephan schrieb:> Die Frequenz dieses Timers richtet sich nach der Differenz Soll/Ist: je> größer diese ist, desto kürzer die Pulsfolge (P-Regler).
Brauchts das wirklich?
Mit wievielfacher Schallgeschwindigkeit wird denn das Kabel abgerollt?
Der Ansatz mit Soll/Ist Vergleich ist ja ok. Aber braucht es da wirklich
diese Geschwindigkeitssteuerung? Im regulären Betrieb ist die
Ist-position ein paar Zehntel Millimeter oder Millimeter daneben. Welche
Rolle spielt es, ob du den Schrittmotor (vergeblich) nötigst, diese
Differenz in ein paar µs auszugleichen? Stell eine zeitliche
Schrittfrequenz ein, die der Motor noch gut mitmacht und gut ists.
Mal anders überlegt.
30720 Impulse -> 5333 Schritte.
Also alle 5,76 Impulse ein Schritt.
Hmm, doofe Zahl.
5,76036 * 4 = 23,041
5,76036 * 21 = 120,967
Das ist doch nett, nimm den asynchronen Zähler 2,
stell den so ein das er bei 121 nen Überlauf macht (Mode 7 - falls ich
mich jetzt nicht vertue und das garnicht so funktioniert wie ich
meine...)
In der ISR schiebst Du dann an, dass Dein Schrittmotor 21 Steps macht,
so schnell wie es eben noch geht und immer gleich schnell.
Wenn das zeitlich klappt macht der Stepper 254 Mal 21 Schritte pro
Umdrehung der Trommel.
Und bei 10 mm Weg sind das immer noch 0,039 mm pro Schritt-Paket.
Passt das zeitlich?
Wieviele Umdrehungen pro Sekunde soll die Trommel machen?
Bei 4 Umdrehungen pro Sekunden (ja, eher nicht so :-) ), sind das alle
985µs ein Interrupt.
Bei eher 1 Umdrehung pro 4s sind das alle 15,75ms ein Interrupt.
Wie schnell bewegt sich eigentlich so ein Stepper?
5333 Schritte pro Sekunde wären etwas viele, oder?
Bei alten Drehmaschinen und Drahtwickelmaschinen macht man das einfach
per Getriebe. Mehr wird hier auch nicht nachgebildet, nur mit
elektrischer Kopplung statt Mechanik. Und die ganzen vielen Rechnungen
laufen am Ende nur darauf hinaus, das eine konstante Übersetzung vom der
Drehung des Trommelmotors auf den Kabelführungsmotor erfolgt
U_Kabelfüh = k * U_Trommel
In k stecken die ganzen Übersetzungen.
Stephan schrieb:> float motorumdrehung_f; // globale Variable fuer Motorumdrehung> ...> ISR( TIMER2_COMPA_vect ) //langsame Abfrage ...> {> motorumdrehung_f += encode_read4() * (1.0/1024);> }
Ist dir eigentlich klar, was du da für einen Zauber in der ISR
anschmeißt?
Simulier den Code mal in deiner IDE und guck dir die Zahl der dafür
erforderlichen CPU-Takte an.
Falk Brunner schrieb:> So ein Macro ist nicht sehr sinnvoll. Warum willst du eine echte> Variable hinter einem Macro verstecken?
Kommt weg.
Falk Brunner schrieb:> Hier fehlen Klammern!
Danke!
Karl Heinz schrieb:> Stephan schrieb:>>> Die Frequenz dieses Timers richtet sich nach der Differenz Soll/Ist: je>> größer diese ist, desto kürzer die Pulsfolge (P-Regler).>> Brauchts das wirklich?Karl Heinz schrieb:> Auf wieviele Nanometer genau muss denn der Schlitten vor der> Kabeltrommel positioniert werden?Karl Heinz schrieb:> Aber braucht es da wirklich> diese Geschwindigkeitssteuerung?
Die "Geschwindigkeitssteuerung" soll zugleich meine Gewähr dafür sein,
dass die Schrittmotorfrequenz sich stets rampenförmig verändert.
Mike schrieb:> Simulier den Code mal in deiner IDE und guck dir die Zahl der dafür> erforderlichen CPU-Takte an.
Hab Angst.
Karl Heinz schrieb:> Anstatt des Encoders
Der Encoder ist fest mit dem Antriebsmotor verbaut. Dieser hat zwar
einen dritten Kanal, der nur einen Impuls pro Umdrehung liefert, dafür
fehlte dann die Richtungsinformation.
Rudolph schrieb:> Mal anders überlegt.
Danke, hört sich gut an.
Rudolph schrieb:> Wieviele Umdrehungen pro Sekunde soll die Trommel machen?
Etwa 1.6, da min. 1 m/s gefordert.
Rudolph schrieb:> Wie schnell bewegt sich eigentlich so ein Stepper?
Verflucht schnell. Habe keine Zahl zur Hand aber einige kHz sind´s
schon.
Karl Heinz schrieb:> Stell eine zeitliche> Schrittfrequenz ein, die der Motor noch gut mitmacht und gut ists.
Dann taucht wieder das Problem auf, dass der Schrittmotor bei jeder
Antriebsmotorumdrehung kurz hörbar seine Schritte läuft.
Bei sehr niedriger Drehgeschwindigkeit (<1/s) wirkst das unharmonisch.
@ Stephan (Gast)
>Die "Geschwindigkeitssteuerung" soll zugleich meine Gewähr dafür sein,>dass die Schrittmotorfrequenz sich stets rampenförmig verändert.
Kann man machen, aber dazu braucht man mehr als einen P-Regler.
>> Simulier den Code mal in deiner IDE und guck dir die Zahl der dafür>> erforderlichen CPU-Takte an.>Hab Angst.
Zu recht ;-)
>Der Encoder ist fest mit dem Antriebsmotor verbaut. Dieser hat zwar>einen dritten Kanal, der nur einen Impuls pro Umdrehung liefert, dafür>fehlte dann die Richtungsinformation.
OK, ist halt so. Kriegt man aber dennoch hin. Man muss halt garantieren,
dass der schnelle 25 kHz Interrupt IMMER bedient werden kann und nie
nennenswert (> 1 Dutzend Takte) warten muss. D.h. alle deutlich
langsameren Funktionen laufen per Flag in der Hauptschleife. Das passt
schon.
Man würde es vielleicht sogar hinkriegen, die Übersetzung von N
Encoderschitten auf M Schrittmotorschritte im 25 kHz Interrupt zu
erledigen (Bresenham!), das könnte die Sache deutlich vereinfachen. Dann
hat man auch eine direkte Kopplung wie in einem mechanischen Getriebe.
Die mechanische Trägheit des Trommelantriebs ist wahrscheinlich deutlich
größer als die des Schrittmotors + Mechanik.
Stephan schrieb:>> Wieviele Umdrehungen pro Sekunde soll die Trommel machen?>> Etwa 1.6, da min. 1 m/s gefordert.
Sind alle 2,46ms ein Interrupt wenn man jeden 121. Impuls einen
Interrupt macht -> ein kleine Ewigkeit. :-)
Und die 50kHz macht der Timer locker auch.
> Rudolph schrieb:>> Wie schnell bewegt sich eigentlich so ein Stepper?>> Verflucht schnell. Habe keine Zahl zur Hand aber einige kHz sind´s> schon.
Also das wären dann 8533 Schritte pro Sekunde, dabei hätten ich dann am
ehesten Bedenken.
Oder wenn man die 21 Schritte in 2ms machen will sind das nur noch 95µs
pro Schritt.
Da fehlt mir die Erfahrung zu, dafür habe ich Schrittmotoren bisher zu
selten benutzt und auch deutlich langsamer.
Aber zunächst finde ich das reichlich schnell.
Vor allem was man da ein Spannung braucht und was an Strom fliessen muss
kann nicht ganz wenig sein wenn die Geschichte ja nicht ganz ohne Kraft
auskommen kann.
Ich finde 5333 Schritte für 10mm Weg sowieso heftig übertrieben, geht
nicht auch eine andere Spindel die weniger Schritte notwendig macht?
So 200 Schritte vielleicht?
Falk Brunner schrieb:> Man würde es vielleicht sogar hinkriegen, die Übersetzung von N> Encoderschitten auf M Schrittmotorschritte im 25 kHz Interrupt zu> erledigen
Wenn innerhalb des 25kHz Interrupts die Sollschritte errechnet und mit
dem Istschritt verglichen würden- wie bzw. wo sollte dann der Step des
Schrittmotors betätigt werden?
@ Stephan (Gast)
>Wenn innerhalb des 25kHz Interrupts die Sollschritte errechnet und mit>dem Istschritt verglichen würden-
So in etwa.
>wie bzw. wo sollte dann der Step des Schrittmotors betätigt werden?
Auch im gleichen Interrupt! Mit einer einfachen Statemachine. Dein
Schrittmotor wird mit max. 8,3kHz Schrittfrequenz gesteuert, da reichen
25 kHz locker. Sprich, wenn eni Schritt ansteht, wird im Interrupt das
IO-Pin eingeschaltet und beim nächsten Interrupt wieder ausgeschaltet.
Schon ist ein Schritt gemacht.
Hallo Rudolph,
>>> Wie schnell bewegt sich eigentlich so ein Stepper?>>>> Verflucht schnell. Habe keine Zahl zur Hand aber einige kHz sind´s>> schon.>> Also das wären dann 8533 Schritte pro Sekunde, dabei hätten ich dann am> ehesten Bedenken.
...
> Da fehlt mir die Erfahrung zu, dafür habe ich Schrittmotoren bisher zu> selten benutzt und auch deutlich langsamer.> Aber zunächst finde ich das reichlich schnell.
Naja, der OP hat 3200 Schritte pro Motorumdrehung angegeben. Solche
Motoren gibt es nicht. Es wird sich wohl um einen normalen 2-phasigen
Motor mit 1,8° Schrittwinkel handeln. Der hat dann 200 Vollschritte/U,
also wird hier mit 1/16 Mikroschritt gearbeitet. Das ist nicht für die
Positioniergenauigkeit erforderlich *), aber für einen ruhigeren
Motorlauf. Aus den 8533 Mikroschritten/s kommt man dann auf 2,67 U/s.
Das ist ein durchaus realistischer Wert.
Mit freundlichen Grüßen
Thorsten Ostermann
*) Mikroschritt erhöht nur die Auflösung, nicht die Genauigkeit.
@ Thorsten Ostermann (Firma: mechapro GmbH) (ostermann) Benutzerseite
>Naja, der OP hat 3200 Schritte pro Motorumdrehung angegeben. Solche>Motoren gibt es nicht. Es wird sich wohl um einen normalen 2-phasigen>Motor mit 1,8° Schrittwinkel handeln. Der hat dann 200 Vollschritte/U,>also wird hier mit 1/16 Mikroschritt gearbeitet.
Das ist auch so, wie man seinem Quelltext entnehmen kann ;-)
Beitrag "Re: Drehgeber und Schrittmotor- 2 Riesenbaustellen im Programm"
Falk Brunner schrieb:> Mit einer einfachen Statemachine
Hm. Was ist daran Statemachine?
Und was mich noch mehr wurmt: das fixe Verhältnis ist genau 2,8975. Also
Alle 2,8975 Encoderschritte ein Schrittmotortakt (Takt-Toggeln).
Der Einfachheit halber da drei draus zu machen würde am Ende des 750m
Kabels einen Positionsfehler von 160mm ausmachen, also ist nicht drin.
Also, Festkommaarithmetik. Nur wie? Ich kann ja schlecht auf den
28974ten Encoderschritt warten und dann 10000 Schrittmotorschritte
machen?! Ich sehe es nicht, leider.
Am Rande schonmal danke für die großartigen Hilfen hier...
Ihr seid alle nächste Woche zum Babybier eingeladen :)
@Stephan R. (Firma: FHK) (nautosteer)
>> Mit einer einfachen Statemachine>Hm. Was ist daran Statemachine?
Man kann es so machen. ICH würde es wahrscheinlich so machen.
>Und was mich noch mehr wurmt: das fixe Verhältnis ist genau 2,8975.
Ja und?
>Also>Alle 2,8975 Encoderschritte ein Schrittmotortakt (Takt-Toggeln).
Ja.
>Der Einfachheit halber da drei draus zu machen würde am Ende des 750m>Kabels einen Positionsfehler von 160mm ausmachen, also ist nicht drin.
Hat auch keiner gesagt.
>Also, Festkommaarithmetik. Nur wie?
Lies den Artikel und denk drüber nach! Du hast mehr als genug Hinweise
bekommen! Stichwort Bresenham! (Nun sieht es ein Blinder!)
> Ich kann ja schlecht auf den>28974ten Encoderschritt warten und dann 10000 Schrittmotorschritte>machen?! Ich sehe es nicht, leider.
Siehe oben!
@ Stephan R. (Firma: FHK) (nautosteer)
> if (Sollschritt * 400 == 1159) PORTA ^= (1 << STEPPER_STEP);
Vergiss solche Multiplikationen, die braucht man nicht und sie sind eher
Rechenintensiv.
>Nein, ich merk schon, das macht keinen Sinn..
In der Tat.
Stephan R. schrieb:> Also, Festkommaarithmetik. Nur wie? Ich kann ja schlecht auf den> 28974ten Encoderschritt warten und dann 10000 Schrittmotorschritte> machen?! Ich sehe es nicht, leider.
Erstmal: Kürzen.
Statt alle 28975 Encoderschritte 10000 Motorschritte alle 1159
Encoderschritte 400 Schrittmotorschritte.
Dann: Bresenham. Variable anlegen als Fehlerakkumulator.
Jeder Encoderschritt zählt 400 Punkte dazu, jeder Schrittmotorschritt
zieht 1159 Punkte ab. Da es sich um einen Fehler handelt, will man ihn
möglichst klein haben. Gegen die Encoderschritte kannst du nichts
machen; die kommen einfach irgendwann und bringen 400 Fehlerpunkte. Aber
jedesmal wenn der "Kontostand" über 1159 ist, kannst du einen
Schrittmotorschritt machen und damit 1159 Punkte abbauen.
Nosnibor schrieb:> Dann: Bresenham. Variable anlegen als Fehlerakkumulator.> Jeder Encoderschritt zählt 400 Punkte dazu, jeder Schrittmotorschritt> zieht 1159 Punkte ab. Da es sich um einen Fehler handelt, will man ihn> möglichst klein haben. Gegen die Encoderschritte kannst du nichts> machen; die kommen einfach irgendwann und bringen 400 Fehlerpunkte. Aber> jedesmal wenn der "Kontostand" über 1159 ist, kannst du einen> Schrittmotorschritt machen und damit 1159 Punkte abbauen.
Wow.
Ah, das sind keine ganzen Schritte okay.
Wobei 1,67*3200 = 5344 ist. :-)
Hab mich gewundert, warum 5344/16 so krumm ist...
Warum also nicht 334 ganze Schritte statt 5344 Mikro-Schritten?
10mm/334 = 0,03 mm / Schritt
30720 / 334 = 91,976
Ist doch schick, alle 92 Impulse einen Schritt auslösen.
Hmm, 1,6 Umdrehungen für 1m Kabel, 750m Kabel.
36,864 Mio Impulse
-> 400800 Schritte notwendig
36,864 Mio / 92 -> 400695 Schritte, 105 Schritte daneben, das sind
3,14mm.
Da kann man bestimmt noch was korrigieren.
Falls das überhaupt stimmt mit 5344 Mikro-Schritten pro 10mm.
Falk Brunner schrieb:> VORSAGEN IST BÄHHH!!!!!!
Ja.
Andererseits hilft das Stichwort "Bresenham" einem Neuling nicht viel.
Die meisten Erklärungen, die man im Netz dazu findet, vernebeln den
recht einfachen, einleuchtenden Kern mit mathematischen Formalismen und
verstecken die Universalität hinter dem Fokus auf genau eine Anwendung.
Kann man ihnen auch nicht vorwerfen, schließlich hat Jack Elton
Bresenham den Algorithmus damals nur zum Zeichnen pixeliger Linien
gebraucht, und wenn man ihn dafür verwendet, muß man wirklich auf den
richtigen Startwert und die Vorzeichen und Quadranten achten, sonst
kommt Schrott raus. Aber das ist eben nicht gemeint, wenn hier jemand
"Bresenham" sagt.
Nosnibor schrieb:> Dann: Bresenham. Variable anlegen als Fehlerakkumulator.> Jeder Encoderschritt zählt 400 Punkte dazu, jeder Schrittmotorschritt> zieht 1159 Punkte ab. Da es sich um einen Fehler handelt, will man ihn> möglichst klein haben. Gegen die Encoderschritte kannst du nichts> machen; die kommen einfach irgendwann und bringen 400 Fehlerpunkte. Aber> jedesmal wenn der "Kontostand" über 1159 ist, kannst du einen> Schrittmotorschritt machen und damit 1159 Punkte abbauen.
Wow, sehr verständlich erklärt. Danke :)
Hallo Rudolph,
> Warum also nicht 334 ganze Schritte statt 5344 Mikro-Schritten?> 10mm/334 = 0,03 mm / Schritt>> 30720 / 334 = 91,976>> Ist doch schick, alle 92 Impulse einen Schritt auslösen.
Aus den gleichen Gründen, warum man auch sonst Mikroschritt statt
Vollschritt verwendet:
- Ruhigerer Motorlauf
- Deutlich geringere Gefahr von Resonanzen im Motor (führt zu einem
Einbrechen des Drehmoments und damit zu Schrittverlust)
- Geringere Schwingungsanregung der umliegenden Mechanik
Mit freundlichen Grüßen
Thorsten Ostermann