Stepper Motor mit Silentstepstick und Raspberry - ruckelt

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
nico.engel
User
Beiträge: 11
Registriert: Samstag 24. Februar 2018, 18:11

Hallo zusammen,

ich bastle gerade an einer Linearachse und steuere den Steppertreiber von Wetterott Silentstepstick TMC2100 , über die GPIOs an. So wiet so gut läuft es auch schon. Aber der Stepper ruckelt ganz schön und läuft nicht rund und ich komme auf keine hohen Drehzahlen.

Kurz zu meinem Setup:
- Stepper mit Getriebe 1:14 - 1,8°/Schritt, 1,68A (https://nodna.de/NEMA-17-Planetengetrie ... hrittmotor)
- Silentstepstick TMC2100 (http://www.watterott.com/de/SilentStepStick)
- externes Netzteil MeanWell 12V/5V (https://goo.gl/SyhHK1)
- Silentstepstick eingestellt auf Vref1,2V entspricht ~1A für den Stepper

Kurzes Video, da hört man es ganz gut. Spürbar ist dies ebenfalls.
https://youtu.be/rPIi8GPov6I

Ansteuerung habe ich mit zwei versch. Vorgehensweisen ausprobiert.
Ganz simpel GPIO Ausgang HIGH/LOW setzen:

Code: Alles auswählen

while True:
    geschw = 0.001
    gpio.output(4, 0)
    time.sleep(geschw)
    gpio.output(4, 1)
    time.sleep(geschw)
Oder per PWM über die Frequenz:

Code: Alles auswählen

GPIO.setup(4, GPIO.OUT) 
GPIO.setup(17, GPIO.OUT)
GPIO.output(17, 0)

p = GPIO.PWM(4, 100)  #100 Hz
while True:
    p.start(50)  #Duty-Cycle 50%
Bei beiden Varianten ruckelt es, so wollte ich den Taktausgang an den GPIO ausschließen (habe leider kein Oszi um den Takt darzustellen).
Verschiedene Schrittauflösungen habe ich auch getestet Vollschritt, 1/2, 1/16 mit und ohne stealthchop. Es wird zwar ein angenehmerer Lauf aber das ruckeln ist dennoch vorhanden und auch spürbar. Und auf hohe Drehzahlen komme ich auch nicht, da verschluckt sich der Stepper ganz schön und dreht gar nicht und vibriert nur.

An was kann es noch liegen? Einen anderen Stepper mit gleichen Parametern (ohne Getriebe) gleiches Problem. Den Silentstepstick habe ich auch schon getauscht aber ebenfalls ohne Erfolg.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Vergiss sofort RPI.GPIO & benutz pigpio. Und dort das Wavetable Feature. Es kann auch sein, dass es schon direkt was für Stepper gibt, das wäre dann natürlich auch ok.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Das Ändern des Duty-Cycle wird diese "Ruckler" verursachen.

Code: Alles auswählen

GPIO.setup(4, GPIO.OUT)

p = GPIO.PWM(4, 100)  #100 Hz
p.start(50)  #Duty-Cycle 50%
sleep(100)
p.stop()
Lass den Code mal einfach ohne Endlosschleife laufen.

PS: Ich setzte die Library RPi.GPIO selbst ein und hab bisher damit die besten Erfahrungen gemacht und auch von den Performance her war die Library am besten. Pigpio kann ich nicht beurteilen. Vielleicht werde ich demnächst die Library mal ansehen, wenn ich beim derzeitigen Projekt den Antrieb neu implementieren muss.

PPS: https://www.henschel-robotics.ch/hdrive/ kostet zwar ein bisschen, ist aber letztendlich eine bessere Lösung.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

pigpio benutzt einen DMA Kanal um die gpios zu setzen und abzufragen. Damit entkoppelt es sich vom scheduling jitter des Linux Kernels. Gerade für sowas wie Stepper ist das deutlich besser. Aber eigentlich für alles :)
nico.engel
User
Beiträge: 11
Registriert: Samstag 24. Februar 2018, 18:11

DeaD_EyE hat geschrieben:Das Ändern des Duty-Cycle wird diese "Ruckler" verursachen.

Code: Alles auswählen

GPIO.setup(4, GPIO.OUT)

p = GPIO.PWM(4, 100)  #100 Hz
p.start(50)  #Duty-Cycle 50%
sleep(100)
p.stop()
Lass den Code mal einfach ohne Endlosschleife laufen.
Macht keinen Unterschied, gleiche ruckler wie gehabt.
Vergiss sofort RPI.GPIO & benutz pigpio. Und dort das Wavetable Feature. Es kann auch sein, dass es schon direkt was für Stepper gibt, das wäre dann natürlich auch ok.
Wollte ich gerade Testen, aber ich kann die pigpio Pakete nicht installieren.

E: Paket pigpio kann nicht gefunden werden.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da das schon oft genug geklappt hat musst du schon etwas detaillierter beschreiben was du versuchst und was nicht klappt.
nico.engel
User
Beiträge: 11
Registriert: Samstag 24. Februar 2018, 18:11

__deets__ hat geschrieben:Da das schon oft genug geklappt hat musst du schon etwas detaillierter beschreiben was du versuchst und was nicht klappt.
Ich weiß selbst noch nicht was es war, habe den Raspberry nochmal neu aufgesetzt mit DietPi. Das Paket pigpio lies sich jetzt auch installieren und auch starten. Habe ein Skript gefunden, der den Ausgang triggern soll, leider mit folgendendem Fehler:

Code: Alles auswählen

import pigpio
pio = pigpio.pi()
steppin=4
pio.set_mode(steppin,pigpio.OUTPUT)

tickrate = 100                           # ticks per second
ticktime=int(round(1000000 / tickrate))  # tick time in microseconds
pulsetime= 2                             # length of pulse to step motor
sleeptime=ticktime-pulsetime/1000000     # how long to sleep
try:
        while True:
                gpio_trigger(steppin, pulsetime, 0)
                time.sleep(sleeptime)
except KeyboardInterrupt:
        pass
pio.stop()

Code: Alles auswählen

  File "/usr/local/bin/stepper.py", line 12, in <module>
    gpio_trigger(steppin, pulsetime, 0)
NameError: name 'gpio_trigger' is not defined
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja, es gibt ja auch kein gpio_trigger. Weiß jetzt nicht was ich da tun soll. Ich kenne ja nicht dessen Funktion.

Vielleicht hilft dir das hier: https://www.raspberrypi.org/forums/view ... p?t=151592
nico.engel
User
Beiträge: 11
Registriert: Samstag 24. Februar 2018, 18:11

Den Thread habe ich bereits gelesen, Stepper dreht sich auch aber ich find den Code noch sehr riesig und komplex. Ich benötige viele Funktionen davon nicht.

Eigentlich benötige ich auf nur einem bestimmten GPIO einen getakteten Ausgang, mit gleichbleibender Frequenz. Und das als "sauberes" Signal. Und mittels deiner vorgeschalgenen pigpio Bibliothekt scheint es runder zu laufen als mit RPI.GPIO.

Hier habe ich noch ein anderes Beispiel, soagar mit einer Rampe, schaffe es aber nicht das soweit runter zu brechen, dass nur noch die waveform ausgebe.
Mit diesem Codeshcnipsel dreht sich der Motor sehr sauber und ich kann für die freq eine Drehzahl einstellen.

Code: Alles auswählen

import pigpio
import time

try:
  pi = pigpio.pi()
  GPIO_pin=4

  pi.set_mode(GPIO_pin, pigpio.OUTPUT)
  pi = pigpio.pi() # connect to local Pi

  freq = 30000 # Hz

  period = 1.0 / freq * 10**6

  print "period: %f" % period


  ramp_time = 0.9 # sec

  start_date = time.time()

  for i in range(1000):

    time_diff =  time.time() - start_date

    ramp_loc = time_diff / ramp_time
    #c = (i % 2) + 1
    if ramp_loc >= 1.0:
      break

    print "ramp location: ", ramp_loc

    if ramp_loc <= .001:
      ramp_loc = .001

    c = ramp_loc

    square = []
    #                          ON       OFF    MICROS
    square.append(pigpio.pulse(1<<GPIO_pin, 0,       period/2/c))
    square.append(pigpio.pulse(0,       1<<GPIO_pin, period/2/c))



    #pi.wave_clear()
    pi.wave_add_generic(square)

    wid = pi.wave_create()

    if wid >= 0:
      pi.wave_send_repeat(wid)

  time.sleep(5)

finally:
  pi.wave_clear()
  pi.wave_tx_stop() # <- important!
  pi.stop()
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich finde den Code in dem Thread nicht komplizierter als was du hier zeigst. Aber letztlich ist das ja dein Ding. Wenn es besser geht ist ja schon mal gut. Und mir fehlt jetzt die Frage, falls du noch eine hast.
nico.engel
User
Beiträge: 11
Registriert: Samstag 24. Februar 2018, 18:11

Ja, ich finde den unterschied zur RPI.GPIO Variante extrem gut und es läuft deutlich besser. Evtl. auch durch das schlankere OS dietpi.

Meine Frage war eigentlich die der Codeschnipsel in python für eine einfache Frequenzausgabe mit pigpio aussieht.

Sprich so:
- kontinuierliche ausgabe eines rechtecksignal oder takt
- mit einer Frequenz von X Hz
- duty cycle 50%
- auf GPIO Pin X
- bis beende der Schleife
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na das steht doch alles in deinem Code. Und in der Doku von pigpio. Du erstellst eine Tabelle mit an und aus zu schaltenden Bitmasken und definierter Länge in Mikrosekunden wie lange dieser Zustand gehalten werden soll. Und weist pigpio an, diese Tabelle dauerhaft laufen zu lassen. Was ist da unklar?
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Also mich würde noch interessieren wieso RPi.GPIO so schlecht läuft.
Am besten nimmst du auch den PWM Pin des Raspberry Pi.

https://de.pinout.xyz/pinout/pin12_gpio18

Software Interrupts belasten die CPU stark und die Qualität des Ausgangssignals hängt dann von der CPU-Last und der darunterliegenden Implementierung der Library ab. Wenn nun Pigpio besonders gut implementiert ist, wirst du dort sicherlich mittels SoftwarePWM akzeptable Ergebnisse erzielen. Die besten Ergebnisse erzielt man aber mit Hardware-PWM.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

RPI.GPIO ist ganz allgemein schlecht. Woran das liegt weiß ich auch nicht, aber in diversen Projekten hat es sowohl mäßig performt als auch einfach grundlos die Arbeit eingestellt nach ein paar Stunden.

Und pigpio benutzt DMA um die Waves auszugeben. Das sollte sich in der Qualität zur Hardware PWM nichts nehmen, und funktioniert dafür mit mehreren Pins.
nico.engel
User
Beiträge: 11
Registriert: Samstag 24. Februar 2018, 18:11

Ich melde mich nochmal zurück. Was __deets__ beschreibt, kann ich zumindest mit meinem Setup durchaus bestätigen.

Habe meinen Raspberry Model B nochmal komplett frisch aufgesetzt und alles Überflüssige abgeschalten.
Zum Vergleich habe ich mit RPI.GPIO und PWM versucht den Treiber an zu steuern, aber es ruckelt immer noch sehr stark und ich vermute, dass es einfach Aussetzer im Takt/Signalqualität sind.
Mit der erwähnten pigpio Methode und der Waveform klappt es wunderbar im gleichen Setup und das jetzt dauerhaft und damit lässt sich auch wunderbar die Drehzahl einstellen!

Das ist jetzt mein einfaches schlankes Script, falls mal jemand hier drüber stolpert:

Code: Alles auswählen

import time
import pigpio

GPIO=4              #STEP Eingang Silentstepstick
GPIO_EN=17          #ENA Eingang Silentstepstick
geschw = 166        #micros

# Rechtecksignal erzeugen
square = []               #ON       OFF      geschw
square.append(pigpio.pulse(1<<GPIO, 0,       geschw))
square.append(pigpio.pulse(0,       1<<GPIO, geschw))

pi = pigpio.pi()
pi.set_mode(GPIO, pigpio.OUTPUT)
pi.set_mode(GPIO_EN, pigpio.OUTPUT)
pi.write(GPIO_EN, 0)                    #ENA low=aktiv
pi.wave_add_generic(square)

wid = pi.wave_create()

if wid >= 0:
   pi.wave_send_repeat(wid)
   time.sleep(10)                       #wiederhole 10s
   pi.wave_tx_stop()
   pi.wave_delete(wid)
   pi.write(GPIO_EN, 1)                 #ENA high=inaktiv

pi.stop()
Wenn es klappt kann ich diese Woche ein Oszi ausleihen und das ganze mal aufzeichnen und gegenüberstellen. Mich interessiert das jetzt schon wo der Unterschied her kommt.
Antworten