Hilfe (Arduino) bei Schrittmotor Steuerung - Arduino zu langsam ?

OP #5855931
Lesenswert?

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
Gast #5855957
Lesenswert?

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
Gast #5855974
Lesenswert?

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.
OP #5855976
Lesenswert?

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
Moderator (Firma: Titel) Persönliche Seite #5855985
Lesenswert?

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?
Gast #5855990
Lesenswert?

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.
Gast #5856005
Lesenswert?

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
Gast #5856021
Lesenswert?

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.
#5856304
Lesenswert?

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.
OP #5856458
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren