Hallo zusammen, ich suche gerade nach Ideen wie ihr das angehen würdet. Ich möchte zwei Schrittmotoren antreiben, und habe hierfür als Schrittmotortreiber die TMC2660. Diese können bis zu 256-fach Mikroschritte. Das bedeutet bei einem "normalen" Schrittmotor mit 200 Schritten pro Umdrehung, dass man 51,200kHz für eine Umdrehung pro Sekunde als Schrittfrequenz braucht. Bei 10 U/s brauche ich also eine Frequenz von etwa 500kHz. Zum Problem: Meine (im Moment noch Dummy-) Servorate mit der die Rampe für die Schrittmotoren berechnet wird habe ich willkürlich auf 100Hz festgelegt. Wenn ich jetzt die Timer auf "Toggle Pin" bei "Output Compare" stelle und keinen Interrupt benutze (also die HAL Funktion "HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_4)"), funktioniert die Rampe wie sie soll. Aktiviere ich nun den Interrupt mit "HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_4)", um die PinToggle im Interrupt mitzuzählen, damit ich weiß wo der Schrittmotor gerade steht, beschleunigen die Schrittmotoren nur auf etwa 3U/s. Nach etwas debuggen ist mir aufgefallen, dass die HAL Interrupt Routine ("TIM1_CC_IRQHandler(void)" ruft "HAL_TIM_IRQHandler(&htim1)" auf), welche die ganzen Flags prüft und auch löscht, etwas länger ist. Wenn ich selbst in "TIM1_CC_IRQHandler(void)" die Flags lösche und dann die Funktion per return beende ohne den "HAL_TIM_IRQHandler(&htim1)" aufzurufen, beschleunigt der Motor wieder normal. Allerdings soll der Mikrocontroller natürlich noch viel mehr andere Dinge machen als nur die Position des Schrittmotors zu zählen. Aber überschlagsmäßig ist auch direkt klar: 2x Interrupts mit 500kHz, bei (noch niedrigen) 200Mhz bedeutet dass ich nur etwa 200 Instruktionen zwischen den Interrupts Zeit habe. Schon alein für das Einspringen und sichern der Floatingpoint Einheit gehen 20 Cycles drauf, dann noch Schritmtotorposition aktualisieren und Flags löschen. Dann noch den neuen Timer-Compare-Wert berechnen (auch noch eine float-Division) und zack ist keine Rechenzeit mehr übrig. Mir ist natürlich klar dass ich einfach weniger Mikroschritte wählen kann oder auch das Interpolationsfeature des TMC2660, bei dem zwischen 16fach Mikroschritte noch einmal interpoliert wird, nutzen kann. Am liebsten wäre mir aber eine Idee wie ich die Position des Schrittmotors kenne ohne immer einen Interrupt auszulösen. Beispielsweise dachte ich daran die Schrittmotortimer ohne Interrupt laufen zu lassen, gleichzeitig aber einen zweiten Timer mit Interrupt laufen zu lassen der den gleichen Comparewert bekommmt, allerdings einen Prescaler von 15 (also nur 1/16 so schnell zählt) hat. Im Interrupt dieses Timers wird dann die Position des Schrittmotors gezählt (nur eben als hätte der Motor 16 Mikroschritte). Allerdings vermute ich dass durch nicht synchrones Zählen die berechnete Position von der echten mit der Zeit auseinander läuft. Ähnliches gilt auch für "Position rechnen in der Servoloop". Da ich den Compare-Wert nur alle 10ms berechne, weiß ich natürlich wie lange ich mit welcher Schrittfrequenz fahre. Aber hier wird wahrscheinlich durch Jitter die berechnete Position von der echten mit der Zeit abweichen. Hat sonst jemand eine Idee?
Also ich habe jetzt mehrmals deinen Text gelesen, aber mir ist immernoch nicht klar wo deine Position genau her kommt. Encoder? Oder zählst du nur die Schritte? Wieso braucht man zum Zählen einen Interrupt? Da gibt es beim H7 doch mit Sicherheit auch Hardware dafür wie ein Counter on Edge x oder ein QEI oder so was...
Hallo, ja, ich zähle einfach die Schritte. Deswegen habe ich ja gefragt ob jemand eine andere Lösung hat.
Gerald M. schrieb: > Am liebsten wäre mir aber eine Idee wie ich die Position des > Schrittmotors kenne ohne immer einen Interrupt auszulösen. Die Position des Motors kennst du höchstwahrscheinlich sowieso nicht wirklich mit dieser 256-Step Genauigkeit, da dein Schrittmotor das Ansteuersignal gar nicht so genau in eine mechanische Position umsetzt. Die hohe Rechenbelastung hast du nur, wenn sich die Schrittfrequenz auf einer Rampe ändert. Wie lang ist deine Interruptverarbeitung und wie hoch ist daran der Anteil für den "Luxus" der Nutzung des HAL. Brauchst du dort wirklich diese Auflösung? Oder reicht es, die Rampen mit 16-µSchritt zu fahren und für ruhiger Dauerstrecken, auf denen keine Rechnerei erforderlich ist auf 256-µSchrittbetrieb umzuschalten?
Manchmal ist es sinnvoller, die Ansteuerung der Motoren, und die sonstige Programmlogik voneinander zu trennen. Es ist nicht verboten, mehrere Mikrocontroller einzusetzen. Man sollte dabei auch immer berücksichtigen, wie aufwändig die Programmierung ist. Wenn du zu viel auf einem µC machst, wird die Softwareentwicklung auffällig teuer. Je geringer die produzierte Stückzahl ist, umso schlechter ist das dann. Die Reduktion der Hardware, um jeden Cent heraus zu quetschen, lohnt sich oft nicht.
Hallo, die Position im Mikroschritt Betrieb ist mir relativ egal. Mit reicht die Position des Vollschritts. Der Schrittmotor bewegt einen Kolben, der natürlich nur begrenzt Hub hat und den ich ungern im den Hardstop fahren würde. Die momentane Mikroschritt Position kann ich sogar vom Schrittmotor Treiber abfragen. Ich selbst brauche in der Interrupt Routine nur eine Addition ("Stepper.Position += Stepper.Direction"). Dazu noch das Makro "__HAL_TIM_CLEAR_IT" was im Endeffekt auch nur ein Registerzugriff bedeutet. Den Rest habe ich ja durch das return deaktiviert. Mein "Problem" ist auch, dass es nicht nur reicht die Pulse zu zählen, sondern es muss auch die Laufrichtung beachtet werden.
Stefan ⛄ F. schrieb: > Manchmal ist es sinnvoller, die Ansteuerung der Motoren, und die > sonstige Programmlogik voneinander zu trennen. Es ist nicht verboten, > mehrere Mikrocontroller einzusetzen. Das stimmt natürlich. Zumal das hier nur ein Hobbyprojekt ist. Die Platine habe ich allerdings schon hier liegen (und per Hand mit ~200 Bauteilen bestückt). Das Problem hatte ich bei meinen Tests so allerdings nicht im Blick.
Stefan ⛄ F. schrieb: > Es ist nicht verboten, > mehrere Mikrocontroller einzusetzen. Hier aber garnicht erforderlich. Wolfgang hatte doch schon die wesentlichen Punkte genannt. Für hohe Geschwindigkeiten braucht man keine Mikroschritte. 256 Mikroschritte sind sowieso fraglich, sofern man nicht einen guten Schrittmotor und leichtgängige Mechanik verwendet. Das Ganze dann noch mit HAL zu programmieren, ist äußerst fraglich. Um die genaue Position des Motors anhand der erzeugten Schritte zu ermitteln, muß man nur mitzählen. Lediglich beim Umschalten der Mikroschritte muß man den richtigen Schritt abwarten, um den Modus zu ändern. Zwei Stepper mit 10 U/s schafft schon ein ATmega328. Gerald M. schrieb: > die Position im Mikroschritt Betrieb ist mir relativ egal. Mit reicht > die Position des Vollschritts. Dann nimm doch durchgehend 1/4 oder 1/8 Schritt. Damit bleiben die Taktfrequenz niedrig, die Resonanzen gering und die Programmierung recht einfach. > Mein "Problem" ist auch, dass es nicht nur reicht die Pulse zu zählen, > sondern es muss auch die Laufrichtung beachtet werden. Dafür kann man dann statt einer Addition eine Subtraktion nehmen ;-)
m.n. schrieb: > Dann nimm doch durchgehend 1/4 oder 1/8 Schritt. Damit bleiben die > Taktfrequenz niedrig, die Resonanzen gering Das entspricht leider gar nicht meiner Erfahrung. Bei solch kleinen Mikroschritt ist der Motor deutlich laufruhiger und man bekommt viel weniger Resonanzen. Ansonsten hätte die ganzen Mirkoschritte ja auch keinen Sinn. Denn die Position wird vermutlich ab 16-fach Mikroschritten nicht wirklich genauer. Mit höherer Geschwindigkeit die Mikroschritten zu reduzieren wäre auch möglich. Dann muss natürlich dann auch das Timing passen.
Wenn die Position gar nicht so genau gebraucht wird dann sollte die Interpolation im Treiber reichen. Die Laufruhe hat man damit bei moderater Taktfrequenz.
Gerald M. schrieb: > dass die HAL > Interrupt Routine ("TIM1_CC_IRQHandler(void)" ruft Bei so einer Problematik schreibt man sich in ein paar Minuten in Assembler eine Interrupt-Service-Routine, die nichts tut als einen Zähler aufwärts oder abwärts zu zählen, die ist sicher schnell genug. Georg
Gerald M. schrieb: > m.n. schrieb: >> Dann nimm doch durchgehend 1/4 oder 1/8 Schritt. Damit bleiben die >> Taktfrequenz niedrig, die Resonanzen gering > > Das entspricht leider gar nicht meiner Erfahrung. Bei solch kleinen > Mikroschritt ist der Motor deutlich laufruhiger und man bekommt viel > weniger Resonanzen. Ja und? Soll alles geräuschlos ablaufen oder gehen etwa Schritte verloren? Ich denke, Du suchst eine praktikable Lösung?
georg schrieb: > Bei so einer Problematik schreibt man sich in ein paar Minuten in > Assembler eine Interrupt-Service-Routine, die nichts tut als einen > Zähler aufwärts oder abwärts zu zählen, die ist sicher schnell genug. > > Georg Hallo Georg, ich bezweifle dass der Compiler aus:
1 | void TIM2_IRQHandler(void) |
2 | { |
3 | /* USER CODE BEGIN TIM2_IRQn 0 */ |
4 | MotorCold.position += MotorCold.direction; |
5 | __HAL_TIM_CLEAR_IT(&htim2, TIM_IT_CC4); |
6 | return; |
7 | /* USER CODE END TIM2_IRQn 0 */ |
8 | HAL_TIM_IRQHandler(&htim2); |
9 | /* USER CODE BEGIN TIM2_IRQn 1 */ |
10 | |
11 | /* USER CODE END TIM2_IRQn 1 */ |
12 | } |
mit
1 | #define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__)) |
etwas anderes macht als du in Assembler. m.n. schrieb: > Ja und? > Soll alles geräuschlos ablaufen oder gehen etwa Schritte verloren? > Ich denke, Du suchst eine praktikable Lösung? Geräuschlos wäre schön, ja. Außerdem zitiere ich hierzu aus meinem ersten Post: Gerald M. schrieb: > Mir ist natürlich klar dass ich einfach weniger Mikroschritte wählen > kann oder auch das Interpolationsfeature des TMC2660, bei dem zwischen > 16fach Mikroschritte noch einmal interpoliert wird, nutzen kann. > Am liebsten wäre mir aber eine Idee wie ich die Position des > Schrittmotors kenne ohne immer einen Interrupt auszulösen.
ich habe zum SM Takten einen Timer als OneShot konfiguriert und in der ISR die Zeit zum nächsten Schritt berechnet und den Timer wieder getriggert. Die ISR hat dafür mit Interpolation in float auf einem F407 @ 168 MHz ca. 0,7 µs gebraucht. Die Interruptlast ist damit variabel, bei stehendem Motor passiert gar nix. Die HAL bietet in dem OC und OneShot Mode wenig Unterstützung, ich habe nur die Initialisierung und ein paar HAL Makros genutzt. Auch die unübersichtliche HAL ISR, die dann mit weak Callbacks arbeitet, habe ich durch eine eigene ISR ersetzt. Das geht bei den Cortex-M ja sogar gut zur Laufzeit weil die ISR Vektoren ins RAM kopiert werden können.
Gerald M. schrieb: > Am liebsten wäre mir aber eine Idee wie ich die Position des >> Schrittmotors kenne ohne immer einen Interrupt auszulösen. Du kannst natürlich einen externen Vor/Rückwärtszähler an Step/Dir anschliessen und den nur bei Bedarf auslesen. Aber nur um Interrupts zu vermeiden? Die sind doch für den Controller das täglich Brot. Georg
m.n. schrieb: > Zwei Stepper mit 10 U/s schafft schon ein ATmega328. Der schafft noch WESENTLICH mehr... Tja: nix BASIC, nix PASCAL, nix C. Einzig pure Asm treibt ihn zu Höchstleistungen. Denn nur das erlaubt, die ganzen Bremsen der Hochsprachenabstraktionen (und ihrer RT-Umgebung) leicht zu entfernen. Vor allem: nur in Asm kann man auch zuverlässig BEWEISEN, dass er bestimmte Anforderungen erfüllt. Auch über die eigentliche Schrittsteuerung hinausgehend für das Gesamtsystem... Ja, das ist deutlich mehr Aufwand bei der Entwicklung. Ob sowas ökonomisch lohnt, hängt tatsächlich von der Stückzahl ab, diesbezüglich hat Stefan F. absolut Recht. Aber (gerade für ein privates Projekt): Da guckt man doch nicht unbedingt auf die Kosten der Arbeitszeit. Da will man was schönes bis perfektes mit minimierten Hardwarekosten. Aber OK: das ist natürlich nur meine Sicht der Dinge. Also mehr so eine "der Weg ist das Ziel"-Sache. Die Alternative ist allerdings (wenn die Erreichung des Ziels das einzige Ziel ist): Kaufe was kommerziell Entwickeltes. Billiger und zuverlässiger kannst du selber nichts entwickeln... Also auf keinen Fall Arduino-Gebastel. Das ist (relativ) teuer UND garantiert massiv suboptimal UND garantiert letztlich garnix (nichtmal die grundsätzliche Funktion). So sieht's aus...
Gerald M. schrieb: > Der Schrittmotor bewegt einen Kolben, der natürlich nur begrenzt Hub hat > und den ich ungern im den Hardstop fahren würde. Eine sicherheitsrelevante Positionsbestimmung allein durch Schritte zählen halte ich für einen Entwicklungsfehler. Dort sollte immer noch ein Endschalter sitzen, der den Motor hardwaremäßig ausschaltet.
Harald W. schrieb: > Eine sicherheitsrelevante Positionsbestimmung allein durch Schritte > zählen halte ich für einen Entwicklungsfehler. Woher weisst du, dass die Positionsbestimmung sicherheitsrelevante ist. Um das zu beurteilen, müsste man wissen, was das Anfahren des Hardstops außer "ungerne" für schädliche, insbesondere sicherheitsrelevante Nebenwirkungen hätte.
Einfach wäre es, pro Kanal einen weiteren Zähler zu opfern. Teilweise kann man die Zähler im STM kaskadieren -> Datenblatt und Refman studieren. Alternativ kann man natürlich auch extern den Step-Ausgang auf den Eingang eines Zählers legen. Dann muss man nur noch auf Überläufe und die Schrittrichtung achtgeben, hat die Position aber im Prinzip immer im Zählerregister vorrätig, ohne Rechenzeit zu verbraten.
c-hater schrieb: > m.n. schrieb: > >> Zwei Stepper mit 10 U/s schafft schon ein ATmega328. > > Der schafft noch WESENTLICH mehr... Du kennst doch garnicht die Rahmenbedingungen. Zudem sind Deine vollmundigen Aussagen nichts wert. Viel Gelaber, aber wenn Du auf konkretes Vorgehen angesprochen wirst, kneifst Du. Lass stecken! @TO Soweit ich Dich verstanden habe, schaffst Du von den gewünschten 10 U/s bislang mit Rampe nur 3 U/s. Da würde ich mich doch zunächst einmal darum kümmern, wie Du die geforderte Geschwindigkeit hinbekommst, bevor es besonders leise oder wie auch immer funktionieren soll. Was Du auf jeden Fall meiden solltest, sind die intransparenten HAL-Aufrufe. Auch lese ich, daß Du nur 200 MHz CPU-Takt verwendest. Ich lasse die H7 immer mit 480 MHz laufen, die werden dann etwas handwarm, was ich aber als sehr angenehm empfinde: es wird gearbeitet ;-) So, wie ich Dich verstanden habe, willst Du einen Kolben verfahren, indem eine Fahrt von der Ist- auf eine Sollposition durchgeführt wird. Startrampe, lin. Bewegung und Stopprampe: das läuft alles in der ISR ab und daher kann/soll/muß die Position auch in der ISR erfaßt werden.
Wolfgang schrieb: > Harald W. schrieb: >> Eine sicherheitsrelevante Positionsbestimmung allein durch Schritte >> zählen halte ich für einen Entwicklungsfehler. > Woher weisst du, dass die Positionsbestimmung sicherheitsrelevante ist. > Um das zu beurteilen, müsste man wissen, was das Anfahren des Hardstops > außer "ungerne" für schädliche, insbesondere sicherheitsrelevante > Nebenwirkungen hätte. Danke. Tatsächlich hat der Motortreiber sogar eine "Hardstop-Erkennung". Wenn sich die Last ruckartig über einen bestimmten Punkt hinaus ändert gibt er ein "Stall"-Signal per Pin aus (so werde ich auch die Referenzfahrt durchführen). Ansonten ist das so konstruiert dass der Kolben im Hardstop nichts kaputt macht. Mich würde die Position nicht nur wegen den Endstops interessieren, sondern auch weil ich nur eine bestimmte Menge Wasser pumpen möchte. Also entsprechend früh anfangen muss zu bremsen. Hierbei entspricht ein Fullstep ürigens etwa 15 Mikroliter. Mir reicht es wen ich am Ende auf einen Milliliter genau bin.
m.n. schrieb: > Auch lese ich, daß Du nur 200 MHz CPU-Takt verwendest. Ich lasse die H7 > immer mit 480 MHz laufen, die werden dann etwas handwarm, was ich aber > als sehr angenehm empfinde: es wird gearbeitet ;-) > > So, wie ich Dich verstanden habe, willst Du einen Kolben verfahren, > indem eine Fahrt von der Ist- auf eine Sollposition durchgeführt wird. > Startrampe, lin. Bewegung und Stopprampe: das läuft alles in der ISR ab > und daher kann/soll/muß die Position auch in der ISR erfaßt werden. Ja, den Takt erhöhen geht auf jeden fall noch. Zur Kolbenfahrt: Ich plane eine Espressomaschine, welche aber anstatt einer Vibrationspumpe eine Kolbenpumpe hat, wie die alten Handhebel-Espressomaschinen. Nur bewege ich den Kolben nicht mit Gefühl von Hand, sondern über einen Schrittmotor mit Spindel. Idealerweise fahre ich ein "Flowprofil" ab ohne zu regeln (bei anderen Espressomaschinen wird hierfür der Druck geregelt). Allerdings möchte ich auch ein "klassisches" Druckprofil fahren, bei dem der Durchfluss nach dem Druck geregelt wird. Falls ich keine Lösung mit selbstzählenden Timern o.ä. finde, werde ich eben auf eine berechnete Menge an Espresso zurückgreifen (Fluss welchen ich vorgebe integrieren) und danach einfach wieder die Referenz anfahren. m.n. schrieb: > Soweit ich Dich verstanden habe, schaffst Du von den gewünschten 10 U/s > bislang mit Rampe nur 3 U/s. Da würde ich mich doch zunächst einmal > darum kümmern, wie Du die geforderte Geschwindigkeit hinbekommst, bevor > es besonders leise oder wie auch immer funktionieren soll. Mit "Handgeschriebener" ISR funktionieren auch die 10 U/s. Aber trotzdem habe ich alle paar hundert Cycles einen Sprung in die ISR, was eben nur durch den Sprung inkl. speichern der FloatingPoint Unit, Position zählen und löschen der Flag an die 40-50 Cycles brauch. Das stört mich einfach insgesamt, da noch mehrere andere Parameter geregelt werden sollen. Wenn man die HAL-ISR anschaut, sieht man auch, dass dort gar nicht so viel mehr gemacht wird. Ich schätze also dass ich mich bei 10U/s schon ziemlich nah an der Reserve des STM32H7 befinde (zumindest bei aktueller Clock). Edit: Zur Regelung an sich. Ich habe eine Servorate von 100Hz ausgesucht um alles zu steuern. Allerdings weiß ich nicht ob das für die Motorregelung reicht. Alle anderen Regelparameter sind eher gemütlich (fast ausschließlich Temperaturen).
:
Bearbeitet durch User
Beitrag #6248538 wurde von einem Moderator gelöscht.
moin Gerald, Frage: Verstehe ich das richtig: Du treibst einen Kolben über eine Spindel mit einem Schrittmotor an? Welchen Hub bringt eine Motorumdrehung -> welche Fördermenge ergibt das?
Hallo, du verstehst richtig. Der Schrittmotor ist zum Kolben 1:2.5 untersetzt und der Kolben hat einen Durchmesser von 44mm. Die Spindel hat eine Steigung von 4mm/Umdrehung. Also 2.5ml pro Motorumdrehung.
moin, also ist die Fördermenge bei 10U/s => 25ml/s. 10U => 2000 VollSteps Somit ist 1 VollStep => 12,5µl Für die 2000 Steps/s ist aller 500µs ein TimerINT notwendig. Die Drehrichtung darf nur bei Motorstillstand geändert werden, bleibt im INT daher unberücksichtigt. Die Drehzahl ( eigendlich die Schrittzahl ) pro Sec. liegt im Bereich 0..2000. Das INT macht nur: ------------------ if ( StepPin > 0 ) { StepSum += Steps; if ( StepSum > 2000 ){ StepSum -= 2000; IstPOS += 1; StepPin = 0 } } else StepPin = 1; ---------------- Da der TimerINT das StepPin ein/ausschaltet muss er mit der halben Zeit laufen, also TimerINT auf 4000/s. Der INT selber braucht <1µs auf 250µs, das sollte keine Rolle spielen. Im Main setzt Du dann die Drehzahl und los gehts. Die Drehzahl kannst Du mit einer (sin^2-) Rampe hochfahren und die Position mit SollPos == IstPOS überwachen. =========== Kolbendurchmesser 44mm -> 138,23mm^2 Hub/Step 4mm/ 200Step -> 0,02mm ergibt bei mir 2,7646ml Um exakt zu arbeiten, bräuchtest Du einen Nullschalter der die Position besser 0,02mm erkennt. Habe ich micht verständlich ausgedrückt?
Gerald M. schrieb: > Mich würde die Position nicht nur wegen den Endstops interessieren, > sondern auch weil ich nur eine bestimmte Menge Wasser pumpen möchte. > Also entsprechend früh anfangen muss zu bremsen. Das rechtzeitige Bremsen muss doch sowieso im Algorithmus für die Berechnung der Schrittabstände drin stehen. (siehe z.B. AN_8017: Atmel AppNote AVR446 - Linear speed control of stepper motor)
c-hater schrieb im Beitrag #6248538: > Insert coin and demands->get a working solution. > > Darunter gibt's von mir nur Hilfe zur Selbsthilfe und Warnungen vor > offensichtlichen Fehlentwicklungen. Keinerlei Wichsvorlagen für lau. > Wer lernfähig und lernwillig ist, wird meine Beiträge zu schätzen > wissen, der Rest ist mir eigentlich ziemlich egal. Ich verstehe. Aber gut, daß Du mal über Deine Krankheit geredet hast. Pieter schrieb: > Für die 2000 Steps/s ist aller 500µs ein TimerINT notwendig. > ... > Da der TimerINT das StepPin ein/ausschaltet muss er mit der halben Zeit > laufen, also TimerINT auf 4000/s. Der INT selber braucht <1µs auf 250µs, > das sollte keine Rolle spielen. Diese 2000 Schritte/s macht aber der Motor nicht als Start-Stopp-Frequenz. Daher ist eine Rampe unumgänglich. Vollschritt ist ebenfalls nicht empfehlenswert; die machen nun wirklich Krach! Auch muß die Timerfrequenz nicht verdoppelt werden, bloß um den Ausgangsimpuls wieder zu löschen. Bei geschickter Planung setzt der Timer den Ausgang nach ein paar µs per Hardware (Compare-Output) selber zurück. Pieter schrieb: > Um exakt zu arbeiten, bräuchtest Du einen Nullschalter der die Position > besser 0,02mm erkennt. Nicht unbedingt. Die relative Bewegung könnte schon ausreichen. Es dürfen lediglich keine Schritte verloren gehen (hohes Risiko bei Vollschritt) und dann reicht auch ein einfacher Schalter (ggf. auch ein Anschlag).
Hallo Pieter, die Ansteuerung habe ich ja bereits. Ich kann durch den Timer auch ein Interrupt auslösen lassen, und in diesen zählen. Allerdings ist dieser Interrupt sehr Resourcenhungrig. Deshalb hätte ich gerne eine Variante bei der ich den Interrupt nicht brauche, oder zumindest seltener. Pieter schrieb: > =========== > Kolbendurchmesser 44mm -> 138,23mm^2 > Hub/Step 4mm/ 200Step -> 0,02mm > ergibt bei mir 2,7646ml Hier hast du vermutlich den Umfang des Kolbens berechnet. Die Untersetzung von 1:2.5 hast du vermutlich überlesen. Aber interessant dass trotzdem fast der gleiche wert raus kommt. Die Schrittmotortreiber kann man (und habe ich) übrigens einfach auf einen Schritt bei jedem Flankenwechsel (also auch Low zu High) einstellen. Dann fällt die doppelte Geschwindigkeit des Timers wieder heraus. @Wolfgang, das rechtzeitige Bremsen ist an sich auch nicht schwer. Zumal ich ja die Beschleunigung kenne. Allerdings muss ich um rechtzeitig bremsen zu können (also z.b. damit 30ml Wasser in der Tasse sind) eben wissen wieviel bisher schon herausgelaufen ist. Und dafür brauche ich wieder die Schritte. Ich denke ich werde den Schrittmotor ansteuernden Timer ohne Interrupt laufen lassen, und parallel dazu einen weiteren Timer mit 1/16 der Frequenz. Dieser wird dann immer auf den gleichen Capture Wert wie der Schrittmotor Treiber gelegt und zählt somit die 16tel Mikroschritte im Interrupt. Bei einem Wechsel der Schrittfrequenz erhalte ich zwar Ungenauigkeiten (da der zweite Counter erst zählt wenn der Schrittmotor 16 Mal gesteppt hat, ich also diese Schritte nicht Messe), ich vermute aber dass diese deutlich unterhalb meiner Toleranz liegen. Eventuell kann ich ja auch noch statistisch immer einen halben 16tel Schritt hinzuzählen und statistisch bin ich dann an der richtigen Position. Damit ihr euch vorstellen könnt wie das aussieht, habe ich ein Foto einer Decent Espresso Maschine angehängt.
die low-Tech Automaten messen den Wasserzufluss mit einem einfachen Flügelrad, wäre das nicht auch ausreichend genau? Was im Puck hängen bleibt kann man doch eh nur abschätzen, was rauskommt auf den ml genau zu bestimmen ist doch kaum möglich? Und wie geschrieben, der 16x oder 32x Mode plus Interpolation sorgt schon für einen seidenweichen lauf. Aber auch bei 3D-Druckern bringt das nur akustische Verbesserung und keinen Gewinn an Genauigkeit. Und bei 50 kHz Interruptfrequenz kann man immer noch bequem mit float interpolieren. Wobei das v doch auch immer gleich sein wird und die Rampen nur einmal in eine Tabelle gepackt werden müssten.
Gerald M. schrieb: > Hat sonst jemand eine Idee Du braucht die Schritte nicht zu zählen, denn dein Programm gibt ja vor, wie viele Schritte gemacht werden solle. Dein Programm weuss also schon wie viele Schritte. Und ja: 256 Mikroschritte sind technisch einfach Unsinn. Schrittmotore drehen nicht genauer, als das Verhältnis von Drehmoment zu Haltemoment, meist 1:10. Die Welt ist leider voll von Leuten, die glauben: viel bringt viel.
Ich möchte noch einmal betonen dass ich die "Genauigkeit" der Mikroschritte nicht brauche. Mir geht es wirklich nur um den ruhigen Lauf. Ich weiß auch dass der Treiber sehr gut interpolieren kann, aber prinzipbedingt sind native 256-Mikroschritte eben gleichmäßiger. Mir geht es hauptsächlich um die technische Möglichkeit. Denn der Mikrocontroller kann problemlos die Pulse für die 256 Mikroschritte erzeugen. Nur das mitzählen belastet ihn Recht stark. Deshalb suche ich nach einer Lösung die "von alleine" mitzählt. Und @MaWin, das ist auch das Problem. Ich gebe per Timer vor wie schnell ich fahren möchte, weiß also nur durch Mitzählen in einem Interrupt wo ich bin. Dieser Brauch aber sehr viel Rechenzeit da er häufig aufgerufen und angesprungen werden muss. Deshalb würde ich ihn gerne vermeiden und nur den automatischen Pintoggle benutzen, der komplett ohne Rechenzeit auskommt.
Gerald M. schrieb: >... Nur das mitzählen belastet ihn Recht stark. Deshalb suche ich > nach einer Lösung die "von alleine" mitzählt. Ja dann benutz doch deinen Pulse Toggle Ausgang (intern oder extern) als Clk Source für einen der Timer/Counter. Der H7 hat doch genug, oder?
Gerald M. schrieb: > Ich gebe per Timer vor wie schnell > ich fahren möchte, weiß also nur durch Mitzählen in einem Interrupt wo > ich bin. Dieser Brauch aber sehr viel Rechenzeit da er häufig aufgerufen > und angesprungen werden muss. Deshalb würde ich ihn gerne vermeiden und > nur den automatischen Pintoggle benutzen, der komplett ohne Rechenzeit > auskommt. Die Schritte mit einem freilaufenden Timer zu erzeugen, ist doch nur bei längeren, konstanten Geschwindigkeiten sinnvoll. Bei Deiner Anwendung mit kurzen Hüben, kommt nach erfolgter Startrampe doch schon gleich die Stopprampe. Du unterschätzt m.M.n. auch die Geschwindigkeit des H7. Das Teil ist affenschnell und verkraftet durchaus hochfrequente ISRs. Es bliebe auch noch der Weg, die Rampen per Integer-Berechnungen zu erzeugen. Das spart ein paar Zyklen für PUSH/POP der float-Register. Das Schrittmuster (Timerwerte) könnte man auch ins RAM schreiben und per DMA ausgeben. Aber ich denke, das ist einfach Quatsch.
KM schrieb: > Gerald M. schrieb: > >>... Nur das mitzählen belastet ihn Recht stark. Deshalb suche ich >> nach einer Lösung die "von alleine" mitzählt. > > Ja dann benutz doch deinen Pulse Toggle Ausgang (intern oder extern) als > Clk Source für einen der Timer/Counter. Der H7 hat doch genug, oder? Gibt es dazu auch Hilfe? Spontan finde ich nicht wie ich konkret den Ausgang des Tim1 Ch4 (dessen Pin PE14 an dem Step Eingang des ersten Schrittmotors verbunden ist) und Tim2 Ch4 (mit Pin PB11) an Motor 2, intern mit einem Counter verbinden kann. Die Richtung kann ich ja per Software addieren wenn ich die Position wissen möchte. Das wäre mein Wunschszenario. Ich nutze übrigen Timer 1 und 2 für die beiden Stepper, Timer 3 und Timer 4 im Encodermodus, und Timer13 für den Servozyklus. Alle anderen Timer sind noch frei. Bild der Ursprungskonfiguration in CubeMX habe ich angehängt. m.n. schrieb: > Die Schritte mit einem freilaufenden Timer zu erzeugen, ist doch nur bei > längeren, konstanten Geschwindigkeiten sinnvoll. Bei Deiner Anwendung > mit kurzen Hüben, kommt nach erfolgter Startrampe doch schon gleich die > Stopprampe. > Du unterschätzt m.M.n. auch die Geschwindigkeit des H7. Das Teil ist > affenschnell und verkraftet durchaus hochfrequente ISRs. Es bliebe auch > noch der Weg, die Rampen per Integer-Berechnungen zu erzeugen. Das spart > ein paar Zyklen für PUSH/POP der float-Register. > Das Schrittmuster (Timerwerte) könnte man auch ins RAM schreiben und per > DMA ausgeben. Aber ich denke, das ist einfach Quatsch. Ich empfand es als elegant, die Geschwindigkeit in jedem Servozyklus einmal zu berechnen und dann autark weiterlaufen zu lassen. Dafür muss sogar nur ein Register beschrieben werden. Für die Regelung später kann dann auch einfach der Wert vergrößert oder verkleinert werden. Ich weiß dass der H7 schnell ist. Doch fals es wie gerade erwähnt eine Möglichkeit gibt den h7 nicht zu belasten, würde ich diese natürlich bevorzugen. So kann ich später bei den Regelungen etwas "mehr auf den Putz" hauen und einen predictive Control Algorithmus einprogrammieren.
:
Bearbeitet durch User
c-hater schrieb: > Vor allem: nur in Asm kann man auch zuverlässig BEWEISEN, dass er > bestimmte Anforderungen erfüllt. Welche?
Also, ich bin den Interrupt los. (Ganz ohne Assambler :P ) Und zwar haben die Timer die Möglichkeit, ein Triggersignal (TRGO) auszusenden. Wann dies passiert kann sogar im CubeMX konfiguriert werden. Hierfür muss im Reference Manual die "internal trigger connection" der verschiedenen Timer untereinander angeschaut werden und freie Timer ausgesucht werden, welche diese Trigger aufnehmen können. Anhand der angehängten Tabelle habe ich mich für Timer 5 als Slave für Timer 1 entschieden, und Timer 8 als Slave für Timer 2. Als Trigger habe ich das "Update Event" ausgesucht (man kann auch auf das Capture Compare Event eines Channels triggern, das ergab bei mir allerdings nur die halbe Zählfrequenz, da ich ja den Pin Toggle, und immer nur entweder auf steigende oder fallende Flanke getriggert werden kann). Den Slave auf "Slave Mode" auf "External Clock Mode 1" stellen, und als Triggerquelle den ITR aus der tabelle eintragen. Funktioniert :)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.