Hallo liebe Freunde der Mikrocontroller
Ich habe bis jetzt meine Schrittmotoren immer mit tone; gefahren was
auch ganz gut funktioniert hat ( außer das Problem das ich kein GND auf
den tone Ausgang bekommen habe um den Motor zum stehen und halten zu
bekommen).
Aber da ich für mein Projekt zwei Motoren gleichzeitig fahren will
brauch jetzt ein ein neuen Sketch. ( tone; kann gleichzeitig nur auf
einem Pin rausgegeben werden ).
Auf der suchen nach einer praktischen library bin ich auf AccelStepper
gestoßen.
Schien mir eigentlich als eine umfangreiche library und durch die
Dokumentation auch erlernbare Möglichkeit meine Motoren zu fahren.
Jetzt bin ich aber auf ein paar Haare in der Suppe gestoßen und würde
geren wissen ob Fehler von mir dem zu Grunde liegen oder nicht:
Ein paar Daten:
Schrittmotor: Nema 17, 59Ncm , 1,8°Schritte (2x)
Schrittmotortreiber: TB6560 3A Controller (2x)
Arduino board : Nano V3.0
Zielgeschwindigkeit: 2-3U./Sek = 3x200Schrittex16Mikroschritte= 9,6 kHz
am Arduino Ausgang.
Ich muss keine Wege fahren aber mit den zwei Motoren sehr genaue
unterschiedliche Geschwindigkeiten fahren.
Im Programm will ich später noch die Umdrehungen überprüfen können ( mit
mindestens 2x2 Hall -sensoren ).
Die Spätere Geschwindigkeits-Regelung: 2 Poti´s mit den ich über ein LCD
die Geschwindigkeit einstelle und dann mit Taster „übergebe „ kann ich
auch auf einem zweiten Arduino machen, da ich sowieso einen zweiten
verwenden werde.
Probleme/Haare:
- Mit AccelStepper im folgenden Sketch bekomme ich nur ca. 4,5 kHz auf
den Ausgang ( durch manuelle Eingabe der Geschwindigkeit bekomme ich
noch ein bisschen mehr )
-Wenn ich ein serial monitor programmiere gibt der Arduino nur noch
misst an den Treiber weiter.
-Wenn ich mir den Ausgang mit dem Oszi ansehen dann sieht es so aus als
ob AccelStepper nur wenig verschiedene Geschwindigkeiten kennt und bei
Mittelwerten einfach immer zwischen zwei bist drei punkten hin und her
schwankt. ( Mein podi habe ich per hard und software geglättet). Das
sieht auf dem Oszi nicht nur komisch aus das hört sich auch komisch beim
Motor an.
-All diese Problem habe ich bei tone; auf dem gleichen Pin nicht gehabt.
1
#include<AccelStepper.h>
2
3
AccelStepperstepper(1,2,3);
4
5
#define ANALOG_IN A0 // kann auch durch int ... ersetzt werden (noch keine veränderung fesgestellt)
6
voidsetup()
7
{
8
stepper.setMaxSpeed(10000);
9
}
10
voidloop()
11
{
12
intanalog_in=analogRead(ANALOG_IN)*10;
13
14
stepper.setSpeed(analog_in);
15
stepper.runSpeed();;
16
}
Frage:
-Mache ich da ein Fehler oder ist der AccelStepper doch nicht so
ausgereift wie es den Anschein macht. ( Konnte das Programm auch nicht
direkt von der Arduinoseite bekommen was auch seine Gründe haben kann )
-Gibt es eine bessere library um 2 Frequenzen im 5-10kHz zu steuern
außer mit einem „delay without delay“ Sketch der mir noch als Notlösung
vorschwebt( noch nicht getestet ).
Scheit nicht so bekannt zu sein !
Kann mir jemand eine library oder eine andere Lösung empfehlen wie 2
Frequenzen bis 10kHz regelbar aus dem Arduino bekomme.
Es ist immer entmutigend wenn ich Stunden, mit schlechten Englisch,
versuche eine library zu verstehen und dann merke das sie nicht für
meine Zwecke verwendbar ist.
Dog G. schrieb:> Ich muss keine Wege fahren aber mit den zwei Motoren sehr genaue> unterschiedliche Geschwindigkeiten fahren.
Nimm Hardwarekomponenten des uC.
Hier wären Timer, die Portpins toggeln, genau das Richtige...
Was du schreibst ist schwer verstaendlich, du solltest etwas mehr auf
Grammatik und Rechtschreibung achten. :-(
Zu deinem Problem so viel: Arduino-Code ist bequem, aber
leistungshungrig. Du musst dich also nicht wundern, wenn du schnell an
die Leistungsgrenze des Controllers kommst. Und schon gar nicht, wenn du
die Arduino-Serial benutzt. Die schmeisst dir gerne das Timing von
anderen, sowieso schon kritisch getimten Bibliotheken durcheinander. Da
hilft nur: Selbst ist der Mann.
Wenn 'tone' alle deine Ansprüche erfüllt, dann schau dir am besten an,
wie die es machen und erweitere den Code um die zusätzliche Funktion.
Schrittmotoren am Arduino sind ja nichts grundsätzlich neues, es sollte
evtl. also sogar Leute geben, die genau vor dem gleichen Problem
standen.
Jetzt habe ich versucht ein Programm von der Pike auf zu schreiben!
Leider ist da irgendwo „Sand“ im Programm !
Ich hab immer keine Aussetzer b.z.w. frequenzabhänge Störungen.
Ich kann jetzt leider kein Bild zeigen und versuch deswegen das Bild auf
dem Oszi. Zu erklären:
Zwischen den deutlich zu erkennen Flanken blitzen in unregelmäßigen
Abständen ( unter einer Sekunde ) immer wieder keine Schatten der
Flanken auf.
Diese Schatten haben eine nur fast ähnliche Frequenz wie ich vorgebe, so
daß sich die Schatten mit den richtigen Flanken bei bestimmten
Frequenzen überschneiden und nicht mehr relevant sind.
Diese Überschneiden passiert z.b.bei ca. 6kHz, 10kHz, 19kHz.
Habe es mit Timer 0 und Timer 1 probiert
Auch schon mit verschiedenen Prescaler
Fehler treten auch ohne Last am Pin auf
Arduino wird vom USB versorgt !
Ist dir schon Grbl aufgefallen?
http://dank.bengler.no/-/page/show/5470_grbl
Die steuern in einer ISR mit mehreren Motoren eine Bahn. Der Trick - der
Timer läuft mit sehr hoher Frequenz und schaut jedes mal nach, ob es
wieder Zeit wird, den nächsten Schritt zu machen.
Vom Umfang nicht abschrecken lassen. Alles Modular und übersichtlich
programmiert.
@ Noch einer (Gast)
Hast du schon Erfahrung mit Grbl ?
Noch einer schrieb:> Die steuern in einer ISR mit mehreren Motoren eine Bahn.
Meinst du das die aus einem Timer mehrere Frequenzen raus holen die sie
auch regeln können?
Hört sich ja interessant an und ich habe es mir unter dem Order
Fräse/3D-Drucker gespeichert.
Aber jetzt zu versuchen aus dem Programm eine Lösung für meine (simple)
Aufgabe zu finden wird mir zu weit gehen. Ich brauche Stunden um
überhaupt den gesuchten Code raus zu filtern und nutzbar zu machen.
Ich bin übrigens Elektriker und will mit meinen kleinen Projekten was
dazu lehren um irgendwann eine Fräse aufbauen ( Habe das so ein großen
Koordinaten-Tisch vererbt bekommen )
Mir würde es schon helfen wenn mir jemand sagen kann ob dieses zittern
ein Software Problem ist oder die Störungen durch die Hardware auf dem
Arduino entstehen.
Dog G. schrieb:> Habe es mit Timer 0 und Timer 1 probiert
Sobald Du beim Arduino setup() verwendest, hast Du keinen freien Zugriff
mehr auf die Timer. Timer0 wird wohl für delay() verwendet und was weiß
ich noch.
Eine einfache Routine für den ATmega328 findest Du hier
http://mino-elektronik.de/Generator/takte_impulse.htm#bsp7 und
nachfolgend eine Anpassung für den UNO R3. Diese müßte bei passender
Verdrahtung bei Dir sofort laufen und den Motor musizieren lassen ;-)
Es wird ein einzelner Motor angesteuert. Die Hauptroutine dafür ist
ISR(TIMER1_COMPB_vect). Die Schrittimpulse werden an OC1B ausgegeben.
Einen weiteren Motor kann man über ISR(TIMER1_COMPA_vect) ansteuern, die
man aus der Vorlage zu COMPB generiert. Die Schritte erscheinen dann an
OC1A, den man dafür reservieren muß.
Abschließend sollte es kein Problem sein, die Laufgeschwindigkeit per
Poti+ADC einzustellen.
m.n. schrieb:> Sobald Du beim Arduino setup() verwendest, hast Du keinen freien Zugriff> mehr auf die Timer. Timer0 wird wohl für delay() verwendet und was weiß> ich noch.
Das ist jetzt aber blöd :-(
Ich brauch das Arduino setup() da das Programm ja noch weiter gehen
soll.
Wenn ich mir jetzt die richtigen Teile aus deinem Code raus klau bin ich
wahrscheinlich auch bei einer weiteren Arduino Programmierung
eingeschränkt oder ?
Dog G. schrieb:> Wenn ich mir jetzt die richtigen Teile aus deinem Code raus klau bin ich> wahrscheinlich auch bei einer weiteren Arduino Programmierung> eingeschränkt oder ?
Du verwechselst Ursache und Wirkung: Arduino schränkt Dich ein ;-)
Timer1 sollte aber noch weitgehend frei sein. Du mußt bei jeder Funktion
nachsehen, welche AVR-Hardware von ihr in Beschlag genommen wird.
m.n. schrieb:> Du verwechselst Ursache und Wirkung: Arduino schränkt Dich ein ;-)
Ja ich weiß ich bin nicht im Arduinoforum.
( aber hier gibt es die Köpfe die schon vor Arduino Mikrocontroller
blind programmiert haben ;-)
Aber ist für mich als Anfänger und Hobbytüftler ist Arduino der beste
Weg die Materie in Bewegung zu bekommen.
Dog G. schrieb:> Aber ist für mich als Anfänger und Hobbytüftler ist Arduino der beste> Weg die Materie in Bewegung zu bekommen.
Und? Hast Du meinen Code getestet?
> Meinst du das die aus einem Timer mehrere Frequenzen raus holen
Ja. Das zentrale Problem: Die Schrittmotoren musst du von Start-Stop
Frequenz auf die maximale Frequenz beschleunigen. Bei einer Fräse müssen
auch während der Beschleunigung die drei Motoren eine gerade Bahn
abfahren.
Bei den langsameren Motoren kannst du nicht einfach jeden 3. Schritt
weglassen. Da kommen sie durcheinander - summen nur mehr, laufen aber
nicht.
> Ich brauche Stunden
Ich brauchte 3 Anläufe und Jahre, bis es vernünftig lief.
> ob dieses zittern ein Software Problem ist
Wahrscheinlich verzögert eine andere ISR aus der Arduino Lib deine ISR.
So richtig Spaß macht das nur mit einem Speicheroszilloskop. So wird
selbst bauen teurer als eine CNC-Steuerung vom Chinesen.
m.n. schrieb:> Und? Hast Du meinen Code getestet?
Ich habe erst einmal versucht zu verstehen !
Heute Nachmittag werde ich ihn mal drauf laden und versuchen zu
verändere.
Noch einer schrieb:> selbst bauen teurer als eine CNC-Steuerung vom Chinesen.
Drauf wird ist möglicherweise auch später hinaus laufen wenn ich den
Koordinatentisch bestücke.
Aber ich will mich in die Materie mit diesem Projekt einarbeiten und
verstehen.
Ich gehe davon aus das die Fräse später ein fortlaufendes Projekt wird
und bin jetzt schon am überlegen ob ich sie nicht gleich mit Servos
aufbauen soll. Das kann ich erst entscheiden wenn ich die Grenzen eines
Schrittmotors kenne. Und da bin ich noch lange nicht.
Außerdem habe ich jetzt schon die Schrittmotoren + Treiber!
PS: Bitte noch keine Ratschläge zur Entscheidung: Schrittmotor oder
Servo
Gibt es eine simple Möglichkeit mit einem Schieberegister ein
Quarz-“Zähler“ zu regeln. Hab jetzt keine Schaltung gefunden mit der
ich eine Frequenz von 10- 15kHz regeln könnte und erst recht nix wo ich
Schieberegister verwenden könnte.
Wenn ich sichergehen kann das die Geschwindigkeiten nicht schwanken und
digital ohne Abweichung übermittelt werden können.
Für die Fahrtgeschwindigkeit brauch ich ja keine Auflösung von 1-15.000
mir würde locker 1-1024 reichen.
Ein Stichwort zu Suche würde mir reichen.
Oder ist es sinniger mir 2 Arduino´s für 6 € zu kaufen und die nur für
den Zweck zu verwenden.
@ m.n. (Gast)
Wäre es möglich in dein Programm noch ein I2C Eingang rein zu bekommen?
Dann kann ich den Rest mit einem Zweiten Arduino regeln und muss nicht
auf C++ umsteigen.
Dog G. schrieb:> @ m.n. (Gast)> Wäre es möglich in dein Programm noch ein I2C Eingang rein zu bekommen?> Dann kann ich den Rest mit einem Zweiten Arduino regeln und muss nicht> auf C++ umsteigen.
Im Prinzip ja. Das müßte ich bei Gelegenheit mal testen.
Dog G. schrieb:> Für die Fahrtgeschwindigkeit brauch ich ja keine Auflösung von 1-15.000> mir würde locker 1-1024 reichen.
Beim ATmega mit 16 MHz und Verwendung von Timer1 beträgt die Auflösung
62,5 ns für die Abstufung. 10 kHz Schrittfrequenz wären 100 µs; die
nächst höhere Frequenz wäre 10,006 kHz (99,9375 µs).
Dog G. schrieb:> Außerdem habe ich jetzt schon die Schrittmotoren + Treiber!
Hast Du eine genaue Bezeichnung?
>Für die Fahrtgeschwindigkeit brauch ich ja keine Auflösung von 1-15.000
Die Auflösung brauchst du für Beschleunigung und Abbremsen. Wenn du die
Frequenz in zu großen Schritten änderst, verliert der Motor Schritte
oder bleibt sogar ganz stehen.
>Wenn ich sichergehen kann das die Geschwindigkeiten nicht schwanken
Deine ISR muss sofort aufgerufen werden. Entweder müssen alle anderen
ISRs extrem kurz sein, oder deine ISR muss eine höhere Priorität haben.
Hier liegt der Grund, warum so viele Leute auf Arduino schimpfen. Die
Lib macht fast alles einfacher. Nur bei so einem Problem bring die Lib
mehr Komplexität als Nutzen.
>Oder ist es sinniger mir 2 Arduino´s für 6 € zu kaufen
Hat schon seine Gründe, warum man die ganze Steuerung in einen
Controller quetscht. Du willst die Erfahrungen, die zu solchen
Grundregeln führten, selbst sammeln. Lass dich nicht daran hindern.
Noch einer schrieb:> Du willst die Erfahrungen, die zu solchen> Grundregeln führten, selbst sammeln. Lass dich nicht daran hindern.
Ich will nicht den Eindruck machen das ich hier mein Kopf auf biegen und
brechen durchsetzen will. Ich lass euch nur an meinen Gedanken
teilhaben. Ich bin über jeden Tip dankbar und wenn ich auf den Weg bin
ein groben Fehler zu machen:
dann haltet mich bitte auf!!!
Dog G. schrieb:> Zielgeschwindigkeit: 2-3U./Sek = 3x200Schrittex16Mikroschritte= 9,6 kHz> am Arduino Ausgang.> Ich muss keine Wege fahren aber mit den zwei Motoren sehr genaue> unterschiedliche Geschwindigkeiten fahren.
Die Lib arbeitet ohne Timer. Mal ein Auszug aus dem changelog: "Use of
microsecond steps and other speed improvements to increase max stepping
speed to about 4kHz."
Deine 9 KHz sind zu viel dafür. Entweder verringerst du die Anzahl der
Mikroschritte aus 4 oder du musst es anders lösen.
Was soll den genau geschehen? Wie wichtig ist es dir eine genau
definierte Rampe zu fahren? Wie muss die Synchronität zwischen den
Motoren sein?
Ich habe mal folgendes gemacht:
Timer 2 läuft mit 100 Hz und setzt ein Falg. In der loop wird, wenn das
flag gesetzt ist die SOLLgeschwindigkeit/frequenz gelesen und die
ISTgeschwindigkeit/frequenz entsprechend erhöht bzw. abgesenkt,
allerdings nur um eine maximal zulässige Beschleunigung.
Kurzes Zahlenbeispiel:
ISTgeschwindigkeit 1 U/s -> 3200 Schritte/s
SOLLgeschwindigkeit 3 U/s -> 9600 Schritte/s
max. Beschleunigung 0,5 U/s² -> macht bei 100 Hz 16 Schritte pro Zyklus
-> Neuer "Stellwert" 3216 Schritte/s (3,216 kHz -> 0,311 µS)
Nachdem der Stellwert berechnet ist wird mit diesem der Timer 1
eingestellt. Das macht die Timer 1 Lib.
ggf. Hilft dir das weiter.
Karl schrieb:> Die Lib arbeitet ohne Timer.
Du meinst AccelStepper oder ?
Ist die Erkenntnis mit der schwankenden Frequenz von AccelStepper
gewollt um Frequenzen zu simulieren die er nicht so rausgeben kann?
In meinem ersten Text versuche ich das zu beschreiben...
Wäre zwar schaden die 16 Mikroschritte zu haben aber nicht zu nutzen
aber was tut mann nicht alles für ein Erfolgserlebnis...
Dog G. schrieb:> Du meinst AccelStepper oder ?
Ja.
Dog G. schrieb:> Ist die Erkenntnis mit der schwankenden Frequenz von AccelStepper> gewollt um Frequenzen zu simulieren die er nicht so rausgeben kann?
Nein, sie ist das Ergebnis der Programmierung egal was du eingestellt
hast, die Lib gibt nur Impulse aus, wenn du stepper.runSpeed() aufrufst:
"Poll the motor and step it if a step is due, implementing a constant
speed as set by the most recent call to setSpeed(). You must call this
as frequently as possible, but at least once per step interval,"
Bei geringen Frequenzen funktioniert dass. Wenn die Frequenz zu groß
wird, dauer der "Arduino-Overhead" zu lange und die Impulse kommen nicht
mehr regelmäßig.
Sag doch mal, was du vor hast.
Karl schrieb:> Sag doch mal, was du vor hast.
Mit den beiden Motoren soll später ein Kettenradantrieb realisiert
werden können.
( Ich will nicht damit sagen das Schrittmotoren dafür die beste Wahl
sind)
Es hat sich einfach so ergeben weil ein Spezi die Mechanik hat und ich
was zum üben suchte.
Karl schrieb:> Wie wichtig ist es dir eine genau> definierte Rampe zu fahren?
Der Plan ist erst mal die mit einem Poti zu regeln. Später wäre aber
eine „Beschleunigungsregler“ eine schicke Sache.
Dog G. schrieb:> Mit den beiden Motoren soll später ein Kettenradantrieb realisiert> werden können.
Ein Kettenantrieb und 2 Motore?
Sollen die Schrittmotoren im gleichen Takt laufen oder nicht?
Was passiert, wenn ein Schrittmotor z.B. 10 Schritte zu wenig macht?
Karl schrieb:> Was passiert, wenn ein Schrittmotor z.B. 10 Schritte zu wenig macht?
Dann fährt das Gestell nach links/rechts
Je ein Schrittmotor für eine Kette ( wie ein Panzer )
Und wenn ich genauer überlege brauche ich für den ersten Testaufbau auch
gewisse Rampen um die Schrittmotoren nicht zu überlasten.
m.n. schrieb:> Und? Hast Du meinen Code getestet?
Bin jetzt dran !
Aber schaff es nicht den Motor mit eigenen Poti fahren zu lassen
m.n. schrieb:> Abschließend sollte es kein Problem sein, die Laufgeschwindigkeit per> Poti+ADC einzustellen.
Ich kann kein C++ :-(
Ich komme einfach nicht dahinter wie ich die Vorgabe einer neuen
Endgeschwindigkeit
verwenden soll !
Für ähnliche Probleme habe ich mal Versionen gemacht, mit denen 2 x
Stepper entweder per Poti oder mit Befehlen über eine RS232 (USART) in
der Drehzahl gesteuert werden können.
Die Lösung mit Potis ist für Joysticks geeignet
http://mino-elektronik.de/Generator/takte_impulse.htm#bsp3a, kann aber
wegen des 10-Bit ADCs Frequenzen nicht so fein auflösen.
Bei der Steuerung mit RS232 kann man genaue Frequenzen vorgeben, wobei
die Taktfrequenz die Auflösung vorgibt:
62,5 ns @ 16 MHz oder besser 50 ns @ 20 MHz.
http://mino-elektronik.de/Generator/takte_impulse.htm#bsp3b
Die angegebenen Obergrenzen für die Frequenz sind mit 30 kHz
konservativ, hängen aber auch davon ab, ob Programmerweiterungen die
Interruptverarbeitung nicht noch ausbremsen.
Für Arduino-Liebhaber sind noch .ino-Dateien vorhanden, die die Suche
nach 'setup()' und 'loop()' zu einem erfolgreichen Ende führen ;-)