Moin ;D Mein Ziel: Ich möchte 3 Schrittmotoren meiner Fräsmaschine mit einem Arduino (Mega) steuern und die Position auf einem LCD ausgeben (Steuerung über Potis). Die benötigte Frequenz, die für die Motoren erzeugt werden muss, liegt bei 3,5 kHz, damit ich nicht einschlafe beim verfahren ;D Mein Problem: Damit es keine Schrittverluste gibt, benutze ich die AccelStepper Library zum Ansteuern. Bei dieser muss ich regelmäßig eine run()-Methode ausführen, damit 1 Puls bzw. Step erzeugt wird, falls genug Zeit verstrichen ist. Die Frequenz mit der ich diese Funktion ausführe, muss also deutlich höher als 3,5 kHz liegen. Der Arduino braucht aber zu lange, um die Koordinaten per i2C-Protokoll auf das LCD zu übertragen und die Pins einzulesen, sodass mein Programm mit maximal 340 Hz läuft. :((( Die Pulserzeugung auf einen zweiten Controller auszulagern funktioniert leider nicht, da ich dann die gezählten Schritte auch wieder übertragen müsste, und das dauert ja leider zu lange. Hat jemand irgendeine Idee ? Ich habe noch 2 STM32 mit 72 MHz da. Der Arduino hat nur 16MHz, aber die i2C-Übertragung braucht doch genauso lange oder ? Abgesehen davon ist die 4fache Geschwindigkeit auch noch nicht ganz genug. Braucht es einen ganz anderen Controller ? Viele Grüße von einem bastelnden Maschinenbau-Studenten, der sich an Software versucht :O
:
Bearbeitet durch User
Daniel H. schrieb: > Die Frequenz mit der ich diese Funktion ausführe, muss > also deutlich höher als 3,5 kHz liegen. Der Arduino braucht aber zu > lange, um die Koordinaten per i2C-Protokoll auf das LCD zu übertragen > und die Pins einzulesen, sodass mein Programm mit maximal 340 Hz läuft. Du musst den Ablauf der Funktionen entkoppeln. Die Anzeige kann ruhig langsamer laufen. Eine Library wie Tasker oder TaskScheduler hilft dabei. Der Arduino ist sicher nicht zu langsam. leo
Hey Danke ;D Und dann werden die Steps nicht unterbrochen ? Wenn die Wiederholung von step() unterbrochen wird, ruckelt der Motor und es kommt zu Schrittverlusten
Daniel H. schrieb: > Und dann werden die Steps nicht unterbrochen ? Dein Programm bestimmt den Ablauf, es liegt an dir, was die CPU mit den 16 MHz macht. leo
als abgehangenen Standard gibt es doch grbl, das läuft auf einem Mega2560 und auch auf den Bluepills mit STM32F103. Schrittfrequenzen habe ich nicht mehr genau im Kopf, aber 30 kHz sollten beim Mega2560 drin sein.
Je nachdem welchen LCD Controller du verwendest könntest du auch die I2C Bittrate erhöhen. Besser wäre es aber das ganze versuchen Intelligent zu lösen. z.B. über Interrupts.
OK, Ich versuche es mal mit der TaskScheduler Library. Die Frequenz an sich ist ja kein Problem, nur muss der Arduino, während der i2C Übertragung an das LCD mehrfach step() ausführen. Wie das gehen soll auf einem Board mit nur einem CPU kann ich mir gerade nicht vorstellen, da fehlt mir das Verständnis
Interrupts sind das Zauberwort, ausgelöst von einem Hardwaretimer.
Funktionieren Interrupts auch innerhalb der i2c-Übertragung ? Ideal wäre dass die Übertragung zB. alle 100us unterbrochen wird.
Entweder man verwendet eine Hardware I2C Schnitte, oder man unterbricht die I2C Übertragung ein paar mal. Denn bei einem 400kHz I2C kann man z.B. Nach jedem 10 Bit unterbrechen und ist dann immer noch 10x schneller als 3,5kHz... Daniel H. schrieb: > Funktionieren Interrupts auch innerhalb der i2c-Übertragung ? Ideal wäre > dass die Übertragung zB. alle 100us unterbrochen wird Kommt auf die Implementierung des I2C an. Bei halbwegs sinnvoller Umsetzung geht das. Aber warum willst du da so oft unterbrechen?
:
Bearbeitet durch Moderator
Dass hört sich echt toll an, aber wie programmiert man sowas ? Wird das sehr kompliziert ? Lothar M. schrieb: > Aber warum willst du da so oft unterbrechen? Weil die Pulse an den Motor an den Motor nicht unterbrochen werden dürfen, und der Motor halbwegs flüssig laufen soll, sonst gehen Steps verloren
:
Bearbeitet durch User
Daniel H. schrieb: > Dass hört sich echt toll an, aber wie programmiert man sowas ? Wird das > sehr kompliziert ? kommt drauf an... Hier ist ein Beispiel mit Lib: https://playground.arduino.cc/Deutsch/HalloWeltMitInterruptUndTimerlibrary/ In der Interrupt Service Routine (ISR) sollte aber nur wenig Code rein der schnell abgearbeitet wird, also keine Print Ausgaben oder Float Berechnungen. Auch digitalWrite ist nicht das schnellste, das sollte durch Portzugriffe ersetzt werden.
Wenn ich die TaskScheduler-Library richtig verstanden habe, reiht die die einzelnen Tasks ja nur in eine Liste ein und arbeitet diese nacheinander ab, also werden die Tasks doch nicht gleichzeitig ausgeführt, oder ?
Johannes S. schrieb: > kommt drauf an... Hier ist ein Beispiel mit Lib: Hey Danke !! ich schaue es mir an. Im Interrupt wird nur ein Pin aktiviert und deaktiviert. Ich hoffe mal das klappt
Daniel H. schrieb: > Wenn ich die TaskScheduler-Library richtig verstanden habe, reiht die > die einzelnen Tasks ja nur in eine Liste ein und arbeitet diese > nacheinander ab, also werden die Tasks doch nicht gleichzeitig > ausgeführt, oder ? Natuerlich hintereinander, du hast ja nur einen Prozessor. Die Tasks sollten halt kurz sein. delay() et al sind verboten. Du musst umdenken und das Programm in kleine Stuecke aufteilen. leo
Daniel H. schrieb: > leo schrieb: >> Programm in kleine Stuecke aufteilen. > > aber wie teile ich LCD.print(variable) auf ? Einzelne print() sind sicher schnell genug. Teile die Anzeige in kleinere Stuecke auf. Stichwort "State-Machine". leo
Prinzipiell kann man sowas mit einem TaskScheduler machen, aber der Luxus kostet auch wieder Laufzeit. Und je häufiger die Tasks aufgerufen werden, desto mehr verbrätst du mit diesem Overhead. Für die genannte Aufgabe würde ich das mit der Timer/Interrupt Lösung machen: das Hauptprogramm bedient LCD und Schnittstelle, in der Timer ISR werden die Pulse generiert. Wenn es in den kHz Bereich geht musst du nur kontrollieren ob das digitalWrite nicht zuviel Zeit kostet, das ist nicht sehr effizient. Wenn die Verarbeitung in der ISR zulange dauert dann kommt dein Hauptprogramm nicht mehr dran und die Ausgabezyklen werden nicht eingehalten. Da sollte ein Oszi oder LA zur Kontrolle vorhanden sein.
Was spricht dagegen gleich GRBL zu verwenden? Du musst das Rad nicht neu erfinden, kannst deine eigenen Anpassungen vornehmen und der Community ggf. zurückgeben.
Daniel H. schrieb: > Der Arduino braucht aber zu > lange, um die Koordinaten per i2C-Protokoll auf das LCD zu übertragen LCD ist nicht zeitkritisch und darf ruhig unterbrochen werden, z.B. durch einen Timerinterrupt, der dann das Stepperzeugs macht. Man darf nur keine Angst vor Interrupts haben, die sind die Stärke von MCs gegenüber komplexen Betriebssystemen auf GHZ-Multicore CPUs.
Das ist super zu wissen ;D dann ist die Sache für mich klar: Ich benutze jetzt den schnelleren STM32 Controller mit Interrupts, die abfragen, ob jetzt jetzt ein Step nötig ist. Vielleicht kann mir jemand noch eine Frage beantworten: für den Arduino benutze ich: #include "TimerOne.h" Timer1.initialize(100); Timer1.attachInterrupt(FUNKTION); funktionieren meine Libraries für den Arduino auch auf dem STM32 ? Ich frage vor allem, weil hier ja der Timer verwendet wird !? An Alle - Vielen Dank, das hat mich sehr viel weiter gebracht ;D
Daniel H. schrieb: > funktionieren meine Libraries für den Arduino auch auf dem STM32 ? Highlevel Libs eventuell, andere wie Timer sicher nicht. Lies halt mal die Doku. leo
Daniel H. schrieb: > Ich benutze jetzt den schnelleren STM32 Controller mit Interrupts, BTW: - du brauchst keinen schnelleren Prozessor. - die AVR 8-Bitter haben natuerlich auch Interrupts - mit den Arduinos hast du eine viel breitere Library Basis leo
Das System ist fertig und die Interrupts können alle 50us laufen, ohne dass es das LCD stört. SUPER ! Mit der Geschwindigkeit hat der Arduino dank Interrupts überhaupt kein Problem mehr ! TOP Hilfe -- Vielen Dank euch !!!
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.