Schrittmotor / TMC2130 / NeoPixel / Leistung bricht ein

Hallo,

für mein erstes „größeres“ Arduino Projekt benutzte ich u.A. einen Schrittmotor, welchen ich über ein TMC2130 ansteuere. Mir ist wichtig, dass der Motor absolut leise bleibt und das läuft auch alles so wie ich es mir vorstelle. Sobald ich aber in den loop() weiter Anweisungen ausführe (Sensoren-Werte lesen, LEDs steuern, etc.) bricht die Geschwindigkeit des Motors komplett ein.

Der loop() muss später auch einen strip.show(); aus der Adafruit_NeoPixel Bibliothek ausführen (32 adressierbare RGBW LEDs). Der Stepper läuft hier zwar noch aber wie gesagt nur noch sehr sehr langsam.

Meine Frage ist jetzt, ob ein Arduino Uno einfach zu leistungsschwach für diese Aufgabe ist oder ob ich bei der Programmierung doch etwas nicht verstehe / übersehe.

Ich verwende die TMC2130Stepper Bibliothek und habe es auch in der Kombination mit AccelStepper probiert. Der Motor soll weitestgehend mit konstanter Geschwindigkeit laufen und ich war eigentlich davon ausgegangen, dass der TMC2130 diese Aufgabe übernimmt ohne die Mikrocontroller Leistung zu beeinträchtigen.

Ich vermute jetzt also, dass der Uno einfach nicht schnell genug den Step Pin auf High/Low setzten kann um den Motor in der Geschwindigkeit laufen zu lassen. Würde ein Arduino Mega oder ein Teensy 3.6 das Problem lösen? Ansonsten müsste ich ja zwei Mikrocontroller laufen lassen (wäre natürlich möglich, aber scheint mir irgendwie übertrieben).

Lieben Dank und viel Spaß beim basteln!

Jan

Die Libs für die Neopixels schaltet alle Interrupts ab, weil das Zeitverhalten der LEDS sehr kritisch ist und beansprucht den ganzen MC während der Übertragung.

Gruß Tommy

Okay, das klingt schonmal hilfreich! Danke.

Also kann ich es vergessen die Neopixel und den Stepper mit einem MC zu steuern?

Hi

Kommt auf die Anzahl der Pixel und die Geschwindigkeit des Stepper an.
Solange Du 'direkt' mit den anstehenden Arbeiten fertig bist, spricht Nichts dagegen - aber wie Tommy schon schrieb, NeoPixel sind zeitlich sehr kritisch und Interrupt's sind während der Pixel-Ansteuerung auch nicht möglich (werden von der Lib abgeschaltet, Timing).

Was machst Du in loop(), daß Dir die Geschwindigkeit des Stepper wegbricht?

MfG

Das Problem tritt auf sobald ich einmal strip.show() aufrufe, habe mal den sketch aufs wesentliche minimiert ... da passiert eigentlich noch gar nichts:

#define PIN 5
#define NUM_LEDS 32
#define BRIGHTNESS 25

#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);

#define EN_PIN    7  // Enable
#define DIR_PIN   8  // Direction
#define STEP_PIN  9  // Step
#define CS_PIN    10  // Chip select

#include <TMC2130Stepper.h>
TMC2130Stepper driver = TMC2130Stepper(EN_PIN, DIR_PIN, STEP_PIN, CS_PIN);

unsigned long lastPass = 0;
int state = 0;

#define rly 2
                     
void setup() {

  strip.setBrightness(BRIGHTNESS);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

  pinMode(rly,OUTPUT);
  digitalWrite(rly,HIGH);

  SPI.begin();
  driver.begin();
  driver.rms_current(600);
  driver.stealthChop(1);     
  digitalWrite(EN_PIN, LOW);
  
}

void loop() {

  if (micros() >= lastPass + 250) {   
    digitalWrite(STEP_PIN, (state) ? HIGH : LOW);
    state = !state;
    lastPass = micros();    
  }
  
  for (int i = 0; i < NUM_LEDS; i++) strip.setPixelColor(i, 127, 127, 63, 255);
  strip.show();

}

Hier noch ein verkürzter Sketch mit AccelStepper:

wenn ich den strip.show(); rausnehme läuft alles glatt ...

#define PIN 5
#define NUM_LEDS 32
#define BRIGHTNESS 25

#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);

#define EN_PIN    7  // Enable
#define DIR_PIN   8  // Direction
#define STEP_PIN  9  // Step
#define CS_PIN    10  // Chip select

#include <TMC2130Stepper.h>
TMC2130Stepper driver = TMC2130Stepper(EN_PIN, DIR_PIN, STEP_PIN, CS_PIN);

#include <AccelStepper.h>
AccelStepper stepper = AccelStepper(stepper.DRIVER, STEP_PIN, DIR_PIN);
                     
unsigned long lastPass = 0;
int state = 0;

void setup() {

    SPI.begin();
    pinMode(CS_PIN, OUTPUT);
    digitalWrite(CS_PIN, HIGH);
    driver.begin();             
    driver.rms_current(600);    
    driver.stealthChop(1);      
    driver.stealth_autoscale(1);
    driver.microsteps(16);

    stepper.setMaxSpeed(2000); 
    stepper.setSpeed(2000);
    stepper.setEnablePin(EN_PIN);
    stepper.setPinsInverted(true, false, true);
    stepper.enableOutputs();
  
}

void loop() {

  stepper.runSpeed();

  for (int i = 0; i < NUM_LEDS; i++) strip.setPixelColor(i, 127, 127, 63, 255);
  strip.show();  
 
}

Hi

Klar - bei jedem loop()-Durchlauf schickst Du die Farben erneut zum Stripe - auch, wenn sich rein gar Nichts daran geändert hat.
32 LEDs macht Pi x Daumen 1,8µs x 32 ~>57,6µs für die Daten + 50µs, damit die Daten übernommen werden.
110µs oder 0,11ms.
Das dürfte eigentlich noch kein Problem darstellen, da Dein Stepper nur alle 250µs einen Step machen will.
Trotzdem würde ich das .show() nur aufrufen, wenn ich was an den LEDs geändert habe - jede ms, Die Du NICHTS zum Stripe schickst, hast Du Zeit für anderen Kram.

Bei der AcellStepper müssten Es sogar 500µs zwischen den Schritten sein (setSpeed(2000) würde ich als Schritte pro Sekunde interpretieren - aber noch nicht wirklich nachgeschaut).

MfG

Ok danke, also die Farben der LEDs werden über Potis gesteuert und sind zusätzlich in der Helligkeit animiert. Das hab ich hier alles rausgenommen um mich auf das Problem zu beschränken, aber später muss ich .show() schon in jedem Durchlauf haben.

Aber das Problem scheint ja auch irgendwo anders zu liegen :frowning:

Hi

DIr läuft die Zeit davon - weiß zwar noch nicht, wo genau, aber Sie ist weg.
Brauchst Du den MicroStep 16?
Bei 8 hättest Du die doppelte Zeit.

Sind Stepper und LEDs synchron? Oder kannst Du den Stepper extern füttern und Dich in diesem Sketch nur um die Befehle für den Stepper und die Animation der LEDs kümmern?

Wirf Mal versuchshalber die FOR raus und lasse dafür die .show() drin - wird's dann besser?
Wenn, ist die FOR zu langsam, Die muß schließlich 96 Byte Daten im RAM ablegen ... ich suche Strohhalme ...

MfG

postmaster-ino:
Sind Stepper und LEDs synchron? Oder kannst Du den Stepper extern füttern und Dich in diesem Sketch nur um die Befehle für den Stepper und die Animation der LEDs kümmern?

Synchron muss er nicht laufen, ich möchte ihn ab und zu über einen Hall Sensor ein/ausschalten (ca. alle 10-20 Sekunden). Ich vermute schon dass es am TMC StepStick liegt irgendwo, kenn mich nicht aus damit - wollte nur dass der Stepper leise läuft und bin darauf gestoßen - eigentlich sind die ja eher für 3D Drucker soweit ich das verstehe.

LG

So habe ich das Ding angeschlossen:
http://www.julian-h.de/sketch/tmc2130-arduino-wiring/

Ok, nach etlichen weiteren Versuchen bin ich mir ziemlich sicher, dass es an dem TMC2130 Treiber liegt. Ich bekomme ihn wohl nicht richtig verkabelt/konfiguriert so dass er vernünftig im Standalone auf Arduino läuft.

Ich schaue mich jetzt nach einem anderen Treiber um. Kann mir jemand einen Silent Step Stick empfehlen der einfach mir einem Arduino zu betreiben ist? Mein Ziel ist es nur einen Schrittmotor möglichst leise in konstanter Geschwindikeit zu fahren...

Ich verwende einen Usongshine NEMA 17:

Vielen Dank!

Diese Treiber sind alle ähnlich und zur Ansteuerung braucht es nur DIR un STEP. Alle anderen Signale kannst Du je nach Notwendigkeit fix mit H bzw L verbinden.

Grüße Uwe