Forum: Mikrocontroller und Digitale Elektronik Microstepping am Limit?!


von Hans H. (hahi)


Lesenswert?

Hallo, ich betreibe einen Stepper Motor mit einem Rduino Mega2560. Der 
Stepper läuft mit 80rpm und 1/32-stepping, um ihm mehr Laufruhe zu 
geben. Allerdings kommt der AVR Chip des Meha da an seine Grenzen. 
Deshalb meine Idee: gibt es eine elektrische Schaltung bzw. Einen IC, 
der eine vorhandene Frequenz um einen fixen Faktor multipliziert (z.b. 
Um den Faktor 10)? dass würde meinen Controller entlasten.

Danke!

von Rene S. (Firma: BfEHS) (rschube)


Lesenswert?

Hallo,

es gibt etliche Schrittmotor Treiber (auch als einzelne ICs) die 
bekommen von deinem Controller "nur" Takt und Richtung und machen den 
Rest selber.

Oder solche Module:
http://www.watterott.com/de/EasyDriver-v4-Schrittmotor-Treiber

http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=237

Grüße aus Berlin

von spess53 (Gast)


Lesenswert?

Hi

>Der Stepper läuft mit 80rpm und 1/32-stepping, um ihm mehr Laufruhe zu
>geben.

Wie ist die Ansteuerung?

Es fehlen zwar einige Angaben, aber überschlagsweise braucht man dazu 
einen Ausgabetakt im einstelligen kHz-Bereich. Da würde ich eher davon 
ausgehen, das deine Programmierkenntnisse ihre Grenzen überschritten 
haben. Ein ATMega2560 bei 16 MHz lacht da eher drüber.

MfG Spess

von H.Joachim S. (crazyhorse)


Lesenswert?

Vollschrittwinkel 1,8° (?) -> 200 Vollschritte/Umdrehung
*32 Microschritte -> 6400/Umdrehung
Bei deinen 80 rpm liegst du unter 10kHz.

von Hans H. (hahi)


Lesenswert?

H.Joachim Seifert schrieb:
> Vollschrittwinkel 1,8° (?) -> 200 Vollschritte/Umdrehung
> *32 Microschritte -> 6400/Umdrehung
> Bei deinen 80 rpm liegst du unter 10kHz.


Ja, genau bei 8533 Hz.
Das Problem ist, dass ich eine Art von Multitasking brauche, also kleine 
Grafiken auf ein Display laden etc. Diese Funktionen sind teilweise 
blockend, d.h., der Loop des Sketches braucht einfach zu lange. Ich war 
vielleicht nicht ganz präzise: die Taktfrequenz reicht für den Stepper 
allene schon aus, aber selbst wenn ich den Sketch noch optimiere bleibt 
die Zeit, die es dauert, um z.b. Ein Icon darzustellen. Das liegt auf 
jeden Fall im Bereich von einigen Millisekunden, und da komme ich schon 
an die Grenze von 8.5 Millis, die ein Loop dauern dürfte, wenn sonst 
nichts zu tun ist...

von Peter II (Gast)


Lesenswert?

Hans Hinterseer schrieb:
> Ein Icon darzustellen. Das liegt auf
> jeden Fall im Bereich von einigen Millisekunden, und da komme ich schon
> an die Grenze von 8.5 Millis, die ein Loop dauern dürfte, wenn sonst
> nichts zu tun ist...

dann mach das Stepping in einer ISR, die Grafik in der main. Schon 
blockiert nichts mehr.

von jonas biensack (Gast)


Lesenswert?

Dann hau deine Takterzeugung in einen Interrupt. Wo ist das Problem?

gruß Jonas

von Hans H. (hahi)


Lesenswert?

Danke, ich verwende einen ähnlichen Treiber, und zwar Dieen hier:

http://www.pololu.com/product/2133

Das Problem ist, dass ich keine stabile Taktfrequenz zusammenbringe, 
weil mein controllerboard durch zusätzliche Tanks aufgehalten wird. 
Deswegen würde ich gerne einen Multiplikator dazwischenschalten, damit 
mein Mega2560 z.b.um den Faktor 10 entlastet ist. Ich habe es 
ausprobiert: wenn ich den Stepper Motor im Full step- Modus laufen 
lasse, geht sich alles gut aus...

von MaWin (Gast)


Lesenswert?

Hans Hinterseer schrieb:
> gibt es eine elektrische Schaltung bzw. Einen IC,
> der eine vorhandene Frequenz um einen fixen Faktor multipliziert

Verringere den Teilerfaktor bei Microstepping auf 8, das ist die 
einfachste Lösung. denn eine PLL willst du nicht, das weiss ich.

von Hans H. (hahi)


Lesenswert?

Hallo,

Warum will ich keine pll?

Es ist so:

Meine Konstruktion hat geräuschreduktion als oberste priorität, es soll 
möglichst kein sinuston hörbar sein, und das ganze befindet ich in einem 
MDF-gehäuse, ähnlich einer lautsprecherbox, neigt also zur Resonanz. Ich 
habe Hirschen einiges zu lärmreduktion getan. Das letzte, was noch 
bleibt, ist die soft- bzw. hardwaremäßige Optimierung, nach der ich hier 
frage. 1/8 step ist also für mich nicht die Lösung, weil immer noch zu 
deutlicher sinuston. Hab ich schon ausprobiert...

von H.Joachim S. (crazyhorse)


Lesenswert?

Die Lösung steht oben, Timerinterrupt für die Motoransteuerung.

von abc.def (Gast)


Lesenswert?

Da würde ich mich auch fragen, ob man da nur mit Software weiterkommt. 
Übrigens, Du hast nicht kundgetan, was Du machst (zB Schaltbild), wir 
raten nur. Überlege, ob LC-Glieder zwischen Treiber und Motor helfen. 
Letztlich muß der PWM-Takt in eine 2-Phasen-Sinusschwingung gewandelt 
werden. Wobei die Spannung am Motor unerheblich ist, der Strom macht das 
Magnetfeld.
Schaue Dir mal dieses Ding an:
http://www.ebay.de/itm/A4988-Stepper-StepStick-Motor-Driver-Fur-3D-Drucker-Arduino-RepRap-Ramps-Prusa-/181458773073?pt=Wissenschaftliche_Ger%C3%A4te&hash=item2a3fc92451
Der macht Microstep allerdings nur bis 16.. Stromregelung eingebaut. 
Controller liefert nur Takt und Richtung. Die Motoren laufen mechanisch 
ruhig, piepsen aber. Dieser Chip ist für bipolare Motoren. Hast Du 
unipolaren Motor, dann könntest Du vllt je 1 Wicklung benutzen, der Rest 
bleibt frei.
Wenn Du den Takt softwaremäßig generierst, solltest Du wissen, was Du 
tust, und das ist bei Arduino meist nicht der Fall. Teste den Treiber, 
indem Du einen Takt von einem 555 generierst, der ist dann gleichmäßig. 
Die anderen Interrupts, die im Ard. laufen, können die 
Takterzeugungssoftware unterbrechen, das Ergebnis ist ruckelig.

von Stefan (Gast)


Lesenswert?

Da brauchst Du doch noch nicht mal einen Interrupt. Nimm einen OC-Timer, 
der erzeugt Dir Dein 8,5khz Signal ganz ohne CPU. Nur beim Ändern der 
Geschwindigkeit muß die CPU eingreifen.

Bdw.:
Bei 8,5khz hast Du nicht 8,5ms zur Verfügung, sondern ~ 115us.

Viele Grüße, Stefan

von Hans H. (hahi)


Lesenswert?

Also der verlinkte Treiber ist dem polou ja ziemlich ähnlich, oder?
Nur zur Sicherheit: ich muss softwareseitig nicht den ganzen taktverlauf 
bereitstellen, nur den impuls, den Rest macht der treiber. Aber bei 1/32 
stepping braucht der Treiber ja auch 32x so viele impulse...

> Schaue Dir mal dieses Ding an:
> 
http://www.ebay.de/itm/A4988-Stepper-StepStick-Motor-Driver-Fur-3D-Drucker-Arduino-RepRap-Ramps-Prusa-/181458773073?pt=Wissenschaftliche_Ger%C3%A4te&hash=item2a3fc92451
> Der macht Microstep allerdings nur bis 16.. Stromregelung eingebaut.
> Controller liefert nur Takt und Richtung. Die Motoren laufen mechanisch

von jonas biensack (Gast)


Lesenswert?

An deiner Stelle würde ich doch erstmal den Weg übere eine ISR gehen 
(welche natürlich von einem Timer getriggert wird @Joachim). 
Hardwareänderungen mag doch keiner. Du kannst die 50 khz laufen lassen 
da hörst du nichts und dein avr langweiligt sich immer noch. Mach dir 
doch das Leben einfach...

Gruß Jonas

von Hans H. (hahi)


Lesenswert?

Du meinst einen externen Oszillator? der hat dann eine fixe Frequenz, 
oder? Wie könnte die CPU zum ändern der Geschwindigkeit verwendet 
werden?


Stefan schrieb:
> Da brauchst Du doch noch nicht mal einen Interrupt. Nimm einen OC-Timer,
> der erzeugt Dir Dein 8,5khz Signal ganz ohne CPU. Nur beim Ändern der
> Geschwindigkeit muß die CPU eingreifen.
>
> Bdw.:
> Bei 8,5khz hast Du nicht 8,5ms zur Verfügung, sondern ~ 115us.
>
> Viele Grüße, Stefan

von abc.def (Gast)


Lesenswert?

Hans Hinterseer schrieb im Beitrag #3730102:
> Also der verlinkten Treiber ist dem polou ja ziemlich ähnlich, oder?

sollte der gleiche sein. Der Chip als solches ist hobbymäßig schlecht zu 
löten. Mit der Trägerplatine wird es aber einfach. Microstepping ist 
wählbar auf 1,2,4,8,16. Mehr geht nicht. Ansonsten ist es so, wie Du 
sagst.
Der Takt läßt sich dann über die counter des m2560 erzeugen, so daß bei 
einfacher Geschwindigkeit gar keine CPU Belastung ist.
Übrigens: Da dieses Verfahren bei 3D-Druckern opensource angewendet 
wird, gibt es einiges an China-zubehör. RAMPS ist ein Shield für 5 
dieser Motortreiber, und ein paar dig. und analoge Eingänge; dann gibt 
es noch ein LCD über Flachband ansteckbar, mit 4*16 
Zeichen+Eingabe+SD_slot; als Grafik-LCD habe ich es auch schon gesehen.
einfach mal ebayern.
Übrigens: Motoren auf Gummidämpfern montieren, dann piepst es nicht so.

von abc.def (Gast)


Lesenswert?

Nachtrag:
Der Controller kann unheimlich viel. Bei Arduino wird das meiste nicht 
verwendet, und wenn Du mehrere Beispielsketche zusammenkopierst, dann 
streiten sie sich um dieselbe Hardware. Langsam und speicherfüllend sind 
sie außerdem noch. (Port setzen: in C ist es ca. 0.1µs, in 'Arduino' mit 
dieser seltsamen Nummerierung sind es 10µs)
Lese Dir doch einmal das ATMEL-Datenblatt dazu durch. Es sind ja nur 400 
Seiten in Englisch. Dann weißt Du, wie Du zeitkritische Dinge 
hinbekommen kannst, und was das Ding überhaupt kann.

von Hans H. (hahi)


Lesenswert?

Also vielleicht kann mir hier jemand mal ein paar Zusammenhänge in 
einfachen Worten zusammenfassen?

Mein derzeitiger wissenstand:

1)Die gewünschte Taktfrequenz, die an den Stepper-Treiber geschickt 
werden muss, scheint prinzipiell kein Problem für den Mega darzustellen.

2) gleichzeitig ausgeführte Tasks, die blockierend sind, können mit der 
loopgeschwindigkeit in Konkurrenz treten.

3) man empfiehlt mit die Verwendung eines anderen Hardware-Timers, der 
sich ja an Bord des Mega befindet.

Meine frage dazu aber: ist nicht letztlich doch die CPU wenn die CPU für 
einen Task gebraucht wird, steht sie für nichts anderes zur Verfügung. 
Gehe ich richtig in der Annahme, dass ein anderer Timer gleichmäßig 
läuft, egal, was die CPU gerade macht? Aber ich muss ja das taktsignal 
dieses Timers auch noch auf einen I/O- Pin schalten? Ist dazu nicht die 
CPU notwendig?

jonas biensack schrieb:
> An deiner Stelle würde ich doch erstmal den Weg übere eine ISR gehen
> (welche natürlich von einem Timer getriggert wird @Joachim).
> Hardwareänderungen mag doch keiner. Du kannst die 50 khz laufen lassen
> da hörst du nichts und dein avr langweiligt sich immer noch. Mach dir
> doch das Leben einfach...
>
> Gruß Jonas

von Stefan (Gast)


Lesenswert?

Wenn Du komplett in der Arduino-Umgebung bleiben willst, dann probier 
doch mal, den clk Deines Steppers mit tone() anzusteuern:

http://arduino.cc/en/Reference/Tone

Damit kannst Du eine Frequenz an einem Pin ausgeben, ohne daß Dein 
Main-Programm dadurch blockiert wird. Arduino-intern wird das wohl eine 
interrupt-gesteuerte PWM sein. Der Vorteil für Dich: das kannst Du mit 
jedem Arduiono-Pin machen.

Gruß, Stefan

von H.Joachim S. (crazyhorse)


Lesenswert?

Oh, Arduino seh ich jetzt erst...

von abc.def (Gast)


Lesenswert?

Stefan schrieb:
> das kannst Du mit
> jedem Arduiono-Pin machen.

Beim Uno gibt es die Ausgänge mit einem Wellensymbol. Da ist Die 
Hardware in der Lage, den Timer direkt auf den Ausgang zu legen. Die 
normalen Ausgangs-Befehle sind in diesem Moment abgeschaltet. Kann sein, 
daß Tone() das auch auf nicht-Wellen-Pins kann. Das sind aber dann 
interne Verrenkungen, wo Du Dich dann wunderst, was alles andere dann 
nicht mehr funktioniert. Leider verleitet Ard. dazu, sofort viel zu 
können, aber nichts zu verstehen. Ist wie bei Lego.
Beim m2560 sind auf dem shield diese Wellen nicht. Möglicherweise kann 
der die Timer auf alle Pins schalten. Dann braucht die CPU nur 
entsprechende Steuerregister einzustellen, der Rest geht ohne 
CPU-Belastung, bis zur nächsten Änderung.

von Hans H. (hahi)


Lesenswert?

Ok, soweit ich weiß, kann man auch im arduino den Port direkt ansteuern, 
um dann auf eine us zu kommen. Allerdings muss diese eine us von der CPU 
abgearbeitet werden, oder? Nicht, dass diese ins Gewicht fällt, aber 
solange die CPU von einem anderen task blockiert ist, kann sie diese 
eine us halt auch nicht "investieren", oder?

def schrieb:
> Nachtrag:
> Der Controller kann unheimlich viel. Bei Arduino wird das meiste nicht
> verwendet, und wenn Du mehrere Beispielsketche zusammenkopierst, dann
> streiten sie sich um dieselbe Hardware. Langsam und speicherfüllend sind
> sie außerdem noch. (Port setzen: in C ist es ca. 0.1µs, in 'Arduino' mit
> dieser seltsamen Nummerierung sind es 10µs)
> Lese Dir doch einmal das ATMEL-Datenblatt dazu durch. Es sind ja nur 400
> Seiten in Englisch. Dann weißt Du, wie Du zeitkritische Dinge
> hinbekommen kannst, und was das Ding überhaupt kann.

von Stefan (Gast)


Lesenswert?

Deine ATmega besteht aus mehreren Teilen, der CPU und der verschiedenen 
Arten von Peripherie. Alle diese Teile laufen parallel. Die Peripherie 
kann viele Aufgaben komplett ohne die CPU ausführen, z.B. Zeichen über 
den UART senden oder eine Pulsfolge über einen Timer ausgeben. Wenn eine 
Peripherie (UART, Timer, ..) eine Arbeit vollendet hat, kann sie das der 
CPU mitteilen über eine Interrupt-Anforderung.

Die CPU kann auf diese Interrupt-Anforderung reagieren (wenn Du diesen 
Interrupt freigeschaltet hast). In diesem Fall wird Dein "normales" 
Programm verlassen und ein davon komplett unabhängiges Programm, der 
Interrupt, ausgeführt. damit hast Du also eine Arbeitsebene über Deinem 
normalen main-System.

Das Task-Konzept des Arduino ist an sich schonmal nicht schlecht. Aber, 
wie Du bereits bemerkt hast, kann es in einigen Fällen zu langsam sein: 
ein task kann bei Arduino nicht von außen unterbrochen werden, sondern 
muß immer von selbst ein delay(9 aufrufen, damit andere Tasks 
drankommen. Dieses Problem hast Du bei Interrupts nicht: diese können 
Dein Task-System zu (fast*) jeder Zeit unterbrechen, so daß sie ein sehr 
exaktes Timing ermöglichen.

*
"fast" bedeutet: Arduino wird beim Umschalten von Tasks, beim Ausführen 
andererer Interrupts wahrscheinlich andere Interrupts für eine kurze 
Zeit sperren. Diese Zeiten bewegen sich aber im kleinen us-Bereich.

Wenn Dir die kleine Timing-Ungenauigkeit von Interrupts noch zuviel ist, 
dann kannst Du auf die reine Hardware-Funktion der Peripherie setzen: 
die ATmega-Timer können so programmiert werden, daß sie ganz ohne die 
CPU ein PWM-Signal ausgeben. das ist aber schon sehr weit vom 
Arduino-mainstream entfernt, probier liber erstmal die tone() Funktion 
oder ein Ansteuern des Pins per Interrupt.

Gruß, Stefan

von Hans H. (hahi)


Lesenswert?

Stefan schrieb:

Also das mit der tone()- Funktion klingt interessant. Soweit ich weiß, 
kann man die auf jeden digitalen Pin legen, sie erzeugt ja ein 
rechteck-Signal und keine sinuskurve.

Kann ich jetzt davon ausgehen, dass bei der tone()-Funktion während der 
Dauer des Tones keine CPU benötigt wird und das Signal eben direkt vom 
Timer an den i/o Pin geschickt wird? Das wäre ja dann genau das, was ich 
suche!



> *
> "fast" bedeutet: Arduino wird beim Umschalten von Tasks, beim Ausführen
> andererer Interrupts wahrscheinlich andere Interrupts für eine kurze
> Zeit sperren. Diese Zeiten bewegen sich aber im kleinen us-Bereich.
>
> Wenn Dir die kleine Timing-Ungenauigkeit von Interrupts noch zuviel ist,
> dann kannst Du auf die reine Hardware-Funktion der Peripherie setzen:
> die ATmega-Timer können so programmiert werden, daß sie ganz ohne die
> CPU ein PWM-Signal ausgeben. das ist aber schon sehr weit vom
> Arduino-mainstream entfernt, probier liber erstmal die tone() Funktion
> oder ein Ansteuern des Pins per Interrupt.
>
> Gruß, Stefan

von Stefan (Gast)


Lesenswert?

Die tone() Funktion benutzt ziemlich sicher Interrupts zur 
Signalerzeugung. Das erkennst Du daran, daß sie auf jeden Pin des 
Arduino anwendbar ist. Die reine Hardware-Erzeugung einer Frequenz ist 
auf Seiten des ATmega auf einige Pins beschränkt.

Ich denke aber, daß das für Dich keinen merklichen Unterschied macht - 
probiers einfach mal aus.

Gruß, Stefan

von spess53 (Gast)


Lesenswert?

Hi

>Kann ich jetzt davon ausgehen, dass bei der tone()-Funktion während der
>Dauer des Tones keine CPU benötigt wird und das Signal eben direkt vom
>Timer an den i/o Pin geschickt wird? Das wäre ja dann genau das, was ich
>suche!

Nein. Ein Timerausgang ist mit genau einem bestimmten Pin verbunden. 
Wenn dieses Signal auf einen anderen Pin umgeleitet wird, dann ist 
Software im Spiel.

MfG Spess

von Hans H. (hahi)


Lesenswert?

Entschuldige bitte, aber ich habe das mit den interrupts noch immer 
nicht kapiert. Ist es so verstehen:

Der interrupt läuft ohne CPU, nur wenn die gewünschte zeit verstrichen 
ist, meldet er sich bei der CPU, und die braucht dann eben eine oder 
auch 10 uSek., um den i/o- Pin zu schalten?

Wie gesagt, die eine uSek. Ist nicht das Problem, aber was, wenn die CPU 
Grade ein Icon aufs Display bringt- das würde eben dann den merklichen 
Unterschied für mich machen, nicht die eine uSek, aber die Blockierung 
durch andere Tanks...

CPU- unabhängig, also Frequenz Direktion Timer an dn Ausgang, wäre also 
vermutlich meine Lösung? Aber wie geht das denn mit dem Mega? Meinst du 
die PWM - Funktion? Die erzeugt eine sinuskurve, oder? Kann man die so 
einstellen, dass sie z.b. Vom pololu- steppertreiber als digitales 
step-Signal ausgewertet werden kann?

Stefan schrieb:
> Die tone() Funktion benutzt ziemlich sicher Interrupts zur
> Signalerzeugung. Das erkennst Du daran, daß sie auf jeden Pin des
> Arduino anwendbar ist. Die reine Hardware-Erzeugung einer Frequenz ist
> auf Seiten des ATmega auf einige Pins beschränkt.
>
> Ich denke aber, daß das für Dich keinen merklichen Unterschied macht -
> probiers einfach mal aus.
>
> Gruß, Stefan

von abc.def (Gast)


Lesenswert?

Hans Hinterseer schrieb:
> Die erzeugt eine sinuskurve, oder?

Wie kommst Du denn darauf? Wenn Du ein PWM-Signal benutzt, wird ein 
digitales Signal mit höherer Frequenz erzeugt, wasunterschiedliche L und 
H Zeiten hat. Analog wird es über ein RC Glied nachgeschaltet. Aber das 
wollen wir hier nicht.
tone() erzeugt eine variable Frequenz, ist nicht auf den Hörbereich 
angewiesen sondern kann auch höher. Die besteht aus digitalem L und H. 
Das gibst Du dann auf das Pol.... (schwieriger Name) Board und der macht 
den Rest, fast schon sinusförmig und richtig vorgekaut für 
Schrittmotoren.

von abc.def (Gast)


Lesenswert?

Hans Hinterseer schrieb:
> uSek. Ist nicht das Problem,

kann sehr wohl ein Problem sein, kommt drauf an, wo.

Wir wissen nicht, was Du für ein Display hast. Vermutlich über I2C? 
Arduino hat die Angewohnheit, aber das ist nicht dokumentiert:
Die Grafik-Software meldet sich nicht zurück und blockiert auch alle 
Interrupts, solange bis der Displayinhalt ausgegeben ist. Und da reden 
wir über millisek. Und das ist zu merken.
Wichtig zu wissen: Der Prozessor macht nur eine Sache gleichzeitig. 
Alles andere muß warten. Interrupts könnten abgeschaltet werden. Es 
steht in der Dokmentation geschrieben, aber die gibt es bei Arduino 
nicht. Darum wird dieses System auch so sehr beschimpft.
Hardware (im Prozessor) kann gleichzeitig weiterarbeiten. Aber inwieweit 
sie eingesetzt wird, ist auch in der (nicht vorhandenen) Doku 
beschrieben.

von Poritz (Gast)


Lesenswert?

Saß bis gestern an dem selben Problem und hab mir jetzt ne eigene Lösung 
dafür geschrieben. Ich glaube, dass du ebenfalls am Anfang mit delay() 
experimentiert hast, das Problem dabei ist, dass delay() ja alles 
blockiert. Bei den Beispielen auf der Arduino-Seite hat es aber den 
Sketch "Blink without Delay" oder so. Dieser läuft mit millis(), ich hab 
das ganze noch auf micros() abgeändert, dadurch kann man nochmal gut an 
Frequenz drauflegen. Bei dem Sketch hier musst du oben nur die Frequenz 
eintragen, die kommt dann am Port 9 raus. Bei sehr hohen Frequenzen 
wirds allerding etwas ungenau, habs aber noch nicht genau getestet! Für 
Änderungen und Verbesserungen bin ich immer zu haben, will ja auch nen 
Schrittmotor ansteuern, der allerdings noch gar nicht da ist^^


Hier der Sketch:

int frequenz=200;


int out = 9;
boolean active = LOW;
unsigned long previousmicros=0;
double interval=500000/frequenz;


void setup() {
  Serial.begin(9600);
  pinMode(out, OUTPUT);
}

void loop() {

  unsigned long currentmicros=micros();
  if(currentmicros-previousmicros>interval)
  {
    previousmicros=currentmicros;
    if(active==LOW)
    {
      digitalWrite(out, HIGH);
      active=HIGH;
    }
    else
    {
      digitalWrite(out, LOW);
      active=LOW;
    }

  }

}

von Poritz (Gast)


Lesenswert?

Nachtrag: Hab das Arduino mal kurz an ein Oszi gehängt, bei der Frequenz 
1000 kommen "nur" 970Hz raus, bei 10.000 sind es nur noch 8,2kHz. Im 
niedrigeren Frequenzbereich passt es aber ziemlich genau (so ca. bis 
500Hz).
Hoffe, ich konnte dir weiterhelfen!

Gruß,
der Ritz in eurem Po

von spess53 (Gast)


Lesenswert?

Hi

>Für
>Änderungen und Verbesserungen bin ich immer zu haben, will ja auch nen
>Schrittmotor ansteuern, der allerdings noch gar nicht da ist^^

Wenn du die IO-Register des AVR-Timers direkt beschreibst reduziert sich 
das Ganze auf fünf Codezeilen und der Rest läuft ohne CPU-Belastung.

MfG Spess

von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

Die TMC26x haben eine Option zur Taktvervielfachung. Das geht aber nur, 
wenn das Tastverhältnis 50:50 ist.

Aber wie schon vielfach erwähnt wurde sollten die 8,5kHz kein Problem 
für den Controller sein, wenn man ein vernünftiges Softwarekonzept hat. 
Ich lasse auf einem Mega128 zwei Schrittmotoren interpoliert bis 50kHz 
laufen. Nebenbei kommuniziert der per virtuellem COM-Port mit dem PC um 
sich neue Fahrbefehle zu holen, liest und schreibt I/Os und gibt die 
aktuellen Positionen auf dem LCD aus [1].

Mit freundlichen Grüßen
Thorsten Ostermann

[1] http://www.mechapro.de/schrittmotorensteuerung.html

von Poritz (Gast)


Lesenswert?

>Wenn du die IO-Register des AVR-Timers direkt beschreibst reduziert sich
>das Ganze auf fünf Codezeilen und der Rest läuft ohne CPU-Belastung.

Was meinst du mit "direkt beschreiben"? Könntest du das mal kurz 
anreissen, mit den 5 Zeilen? Ne grobe Übersicht wäre cool, "ausarbeiten" 
könnt ich das dann schon selber. Versteh nur nich so ganz, was du mit 
direkt meinst.

von Hans H. (hahi)


Lesenswert?

abc.def schrieb:

> Wir wissen nicht, was Du für ein Display hast. Vermutlich über I2C?


Ich verwende dieses touchdisplay:


http://www.aliexpress.com/item/New-2-4-Inch-TFT-LCD-Module-Display-240x320-Screen-ILI9325-IC-for-51-MSP430-AVR/1839618437.html

Es wird direkt über diverse i/o- pins angeschlossen. Ich verwende als 
Software-Schnittstelle die UTFT-Library von Henning Carlsen. Ich habe 
ihn auch schon diesbezüglich kontaktiert, er bestätigte, dass die 
funktionen zur grafischen Darstellung die CPU komplett blocken.

Daher ja auch meine suche nach einer CPU-unabhängigen Methode, um ein 
hochfrequentes Signal an den Ausgang zubekommen.

Also was gibt es nun für eine Möglichkeit? Scheidet tone() auch aus, 
weil die interrupts die CPU brauchen?

PWM direkt am i/o Ohne lässt sich realisieren?

In der arduino-Dokumentation steht bei der analogWrite()-Funktion:

"The PWM outputs generated on pins 5 and 6 will have 
higher-than-expected duty cycles. This is because of interactions with 
the millis() and delay() functions, which share the same internal timer 
used to generate those PWM outputs. "

Die UTFT Library greift sicher auch auf die millis()- Funktion zu. Ist 
die analogWrite() Funktion trotzdem die Lösung?

von abc.def (Gast)


Lesenswert?

Hans Hinterseer schrieb:
> die analogWrite() Funktion trotzdem die Lösung?

nein. Das gibt bei irgeneiner Frequenz ein einstellbares H und L 
Verhältnis aus.
http://de.wikipedia.org/wiki/Pulsweitenmodulation
Vergiß es bitte, für hier.

tone() braucht einen timer für sich, aber es sind ja mehrere vorhanden. 
Das Ratespielchen ist jetzt, einen timer zu finden, der nicht schon mit 
anderen Aufgaben belegt ist. Nimm einen Lautsprecher (oder Kopfhörer) in 
Reihe mit 100 Ohm, und hänge das an GND und den ausersehenen Pin. Dann 
laß tone() darauf los in einem sketch, der auch noch Display o.ä. 
benutzt. Wenn es geht mit verschiedenen Tonhöhen, dann ok, wenn nicht, 
dann anderer Ausgang.
Versuch macht kluch....

von Poritz (Gast)


Lesenswert?

abc.def schrieb:
> Dann
> laß tone() darauf los in einem sketch, der auch noch Display o.ä.
> benutzt. Wenn es geht mit verschiedenen Tonhöhen, dann ok, wenn nicht,
> dann anderer Ausgang.
> Versuch macht kluch....

Zu den einzelnen timern (quelle: 
http://playground.arduino.cc/Code/PwmFrequency):


Base frequencies:
 *      o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
 *      o The base frequency for pins 5 and 6 is 62500 Hz.
 *   - Divisors:
 *      o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
 *        256, and 1024.
 *      o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
 *        128, 256, and 1024.
 *
 * PWM frequencies are tied together in pairs of pins. If one in a
 * pair is changed, the other is also changed to match:
 *   - Pins 5 and 6 are paired on timer0
 *   - Pins 9 and 10 are paired on timer1
 *   - Pins 3 and 11 are paired on timer2
 *
 * Note that this function will have side effects on anything else
 * that uses timers:
 *   - Changes on pins 3, 5, 6, or 11 may cause the delay() and
 *     millis() functions to stop working. Other timing-related
 *     functions may also be affected.
 *   - Changes on pins 9 or 10 will cause the Servo library to function
 *     incorrectly.

Note: Das lässt sich jedoch nicht wirklich für die Anpassung der 
Frequenz nutzen, da die Divisoren nur sehr begrenzt sind!

von Stefan (Gast)


Lesenswert?

> Wenn es geht mit verschiedenen Tonhöhen, dann ok, wenn nicht,
> dann anderer Ausgang.

Ist dabei so zu verstehen: wenn Deine Display-Routine aktiv ist, sollte 
sich die Tonhöhe nicht wesentlich ändern.

Gruß, Stefan

von Einhart P. (einhart)


Lesenswert?

Was hindert dich einen Arduino Nano (4$ aus China) mit der 
Schritmotorsteuerung zu betrauen? Die beiden Controller kannst du z.B. 
über i2c verbinden.

von abc.def (Gast)


Lesenswert?

oritz schrieb:> Frequenz nutzen, da die Divisoren 
nur sehr begrenzt sind!

Donnerwetter, zum 100sten mal!
PWM und tone() sind grundverschiedene Dinge.

Aber diese Seite kannte ich noch nicht, danke. Allerdings befremdet es 
mich, daß ich keine offensichtliche Angabe fand, ob sich diese Doku auf 
den uno oder m2560 bezieht, denn die Hardware ist unterschiedlich. Ich 
vermute, es gilt nur für den uno328. Beim m2560 heißen alle Pin von 2-13 
"PWM", bei Uno sind da nur die 3,5,6,9,10,11 markiert.

http://playground.arduino.cc/Code/ToneAC
Ich würde lieber von dem hier reden, kenne allerdings nur das 
anscheinend ältere tone(), wie es auch in den examples steht.
Das, was da hinten herausplumpst, kommt dann zum Schrittmotor-Treiber 
(=Hardware). Und der macht Leistung und analog und microstepping.

von abc.def (Gast)


Lesenswert?

Einhart Pape schrieb:
> Arduino Nano (4$ aus China)

Es gibt viele Möglichkeiten der Problemlösung. Im Moment kenne ich das 
Problem nichtmal. Ich vermute, da soll sich ein Motor drehen, und 
nebenbei ein Display flimmern. Der Motor ist genau richtig am tone(). 
Aber man kann ja das aufgeben und anders weitermachen.
In meinem 3D-Drucker sitzt auch bloß ein Ard.m2560, der bearbeitet 3 
Schrittmotoren auf Geschwindigkeit und Position, einschließlich Kurven 
und Beschleunigung/Bremsrampen. Durchschnitt 10 neue Bahnen/sek, ohne 
Schrittverluste und ohne Ruckeln. Nebenbei Display und serielle 
SChnittstelle und SD-card. Der Controller kann das. Und da sollte dieser 
Thread nicht gleich aufgeben.

von Hans H. (hahi)


Lesenswert?

hallo,

ich war arbeitsbedingt auf standby. inzwischen konnte ich aber alle 
tipps durchackern und bin sehr dankbar über den Vorschlag mit der tone() 
-funktion. es ist einfach und elegant zu programmieren und funktioniert 
hervorragend. danke!

von uwe (Gast)


Lesenswert?

Es geht auch ganz ohne CPU
output Compare auf Timer 0 zur Geschwindigkeitseinstellung auf step 
clock und gleichzeitig auf T1 input clock von timer 1 für die Position, 
die Position wird ins Output compar Register von Timer 1 geschrieben. 
Dann kann man entscheiden ob man einen Interupt generiert bei Compare 
Match 1 und den Timer 0 stopt oder ob man ein output mit dem Compare 
match 1 automatisch generiert an OC1A und dort ein Logikgatter dranhaut 
welches den Clock unterbricht. Dann muß man nur noch die Richtung 
umschalten.

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
Noch kein Account? Hier anmelden.