Stepper Motor zu langsam

Hallo zusammen,

ich möchte mit einer Platine, die als Arduino Uno konfiguriert ist, einen Schrittmotor (den QSH4218 von
TRIAC) steuern. Motorsteuerung ist derzeit Adafruit Motor Shield V2.

Das Problem ist nun, dass die Motorgeschwindigkeit viel zu gering ist. Ich habe eine ältere Software (nur noch als Hex) ausgelesen, unter der der Motor für eine Umdrehung ca. 6 Sekunden braucht. Unter der neuen Software benötigt er doppelt so lange. Ich nutze dafür die Libraries AccelStepper (v.Mike McCauley) und Adafruit Motorshield V2.

Ich habe bereits an der Geschwindigkeit gedreht - alles über 270 bewirkt keine Änderung mehr - sowie ebenfalls erfolglos an der Maximalgeschwindigkeit, dem Schrittintervall und der Inkrementierung der Schritte in der Library. Gemäß den FAQ von Adafruit habe ich außerdem den I2C-Timer auf 400 kHz gestellt: TWBR = ((F_CPU /400000l) - 16) / 2; //

Vielleicht hat jemand eine Idee, woran man noch schrauben könnte. Ich hoffe, die Frage ist mittels des angefügten Codes verständlich.

Grüße

Der Code vom Anfahren des Motors:

axis.move(move_mm*microsteps_per_step*steps_per_mm); //sets target position
      		

			if(move_mm < 0){
				axis.setSpeed(-270); //Speed Setup anticlockwise
			}
			else{
				axis.setSpeed(270); //clockwise
			}
			while (axis.distanceToGo() != 0){
				axis.runSpeedToPosition(); //
			}

Und hier aus AccelStepper der Befehl runSpeed(), der letztlich die Schritte für runSpeedToPosition() implementiert

boolean AccelStepper::runSpeedToPosition()
{
    return _targetPos!=_currentPos ? AccelStepper::runSpeed() : false;
}

…


boolean AccelStepper::runSpeed()
{
    unsigned long time = millis();
  
    if (time > _lastStepTime + _stepInterval)
    {
	if (_speed > 0)
	{
	    // Clockwise
	    _currentPos += 1;
	}
	else if (_speed < 0)
	{
	    // Anticlockwise  
	    _currentPos -= 1;
	}
	step(_currentPos & 0x3); // Bottom 2 bits (same as mod 4, but works with + and - numbers) 

	_lastStepTime = time;
	return true;
    }
    else
	return false;
}

Was sollen wir Dir jetzt antworten?

Du gibst uns keine genauen Informationen und auch nur Auszüge aus dem Sketch.
Was hat die i2C Schnittstelle mit dem Schrittmotor zu tun?

Grüße Uwe

Okay, dann versuche ich das noch mal ausführlicher und bitte um Nachsicht.

Das Motorshield V2 vereint ja den TB6612 Motortreiber IC mit dem PCA9685 PWM-Treiberchip, der über den I2C Bus angesprochen wird, damit wird der Motor letztlich gesteuert. Ich hatte hier im Forum schon nach Lösungen gesucht, da wurde (Schrittmotor dreht zu langsam) aus den FAQ von Adafruit zitiert

Why won't my stepper motor go any faster?
Since the shield is controlled by i2c, the maximum step rate is limited by the i2c bus speed. The default bus speed is 100KHz and can be increased to 400KHz by editing the library file in your Arduino installation folder. The file can be found in hardware/libraries/wire/utility/twi.h.
Find the line with: "#define TWI_FREQ 100000L"
and change it to "#define TWI_FREQ 400000L"
Or, you can add the following code to your setup() function:
TWBR = ((F_CPU /400000l) - 16) / 2; // Change the i2c clock to 400KHz

Und eben daran liegt es jedenfalls nicht, da die Frequenz schon passend eingestellt ist.

Der Code nochmals im Kontext

#include <Arduino.h>
#include <Wire.h>
#include <AccelStepper.h>
#include <PID_v1.h>
#include <Adafruit_MotorShield.h>
#include <OneWire.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

…

void setup() {
 TWBR = ((F_CPU /400000l) - 16) / 2; // Change the i2c clock to 400KHz
 
// PWM SETUP 30Hz Signal
 TCCR1B = TCCR1B & B11111000 | B00000101; // set timer 1 divisor to  1024 for PWM frequency of 30.64 Hz (PIN 9)
 pinMode(PWM, output);

 
 // Initialize Stepper
 AFMS.begin(); //from Library Arduino Motorshield V2
 axis.setSpeed(set_speed);
}
…


void manDrive(){
  bool run = false;
  uint8_t buttons = 0;
  
  
 while(true)
 {
   buttons=readButtons(); //reads Buttons from Display

   …
    
    if(buttons & button_up)
    {
          run=true;
          axis.setSpeed(270);

          while (buttons & button_up)
          {
             axis.move(move_mm*microsteps_per_step*steps_per_mm);
             while (axis.distanceToGo() != 0)
             {
                 axis.runSpeedToPosition();
             }          
             buttons=readButtons();
          }
          run = false;

In diesem Menü soll der Motor einfach mit maximaler Geschwindigkeit (Begrenzung eigentlich die 270 Mikrosteps/Sekunde) in eine Richtung anfahren, solange der Button getätigt wird. Dafür wird dann in der Schleife solange der Befehl runSpeedToPosition ausgeführt, bis die Position erreicht ist. Meine Vermutung ist, dass das PWM Signal falsch eingestellt ist, aber ich weiß an dieser Stelle auch nicht mehr wirklich weiter. Falls noch weitere Informationen gewünscht sind, lass es mich wissen.

Grüße

AccelStepper.cpp (7.1 KB)

AccelStepper.h (15.4 KB)

Meine Vermutung ist das du keinen Plan hast was ein Steppermotor ist.

PWM dient dazu DC-Motoren mit Bürsten/Kohle in der Drehzahl zu regeln.

Für Steppermotoren benötigt man dagegen eine Ansteuerung der einzelnen Spulen in der richtigen Reihenfolge.

Google dir mal den Unterschied zwischen Steppermotor, seine Ansteuerung und DC Motoren mit PWM Ansteuerung. Wenn du den Unterschied begriffen hast, dürfte auch dein Problem gelöst sein. Alleine das du im Setup deines Sketch einen PWM-Pin definierst zeigt doch, das du den Motor falsch ansteuerst.

Du musst dir dann Beispiele zum Steppermotor und die passenden Bibliotheken laden. Und dann wird die Drehzahl mit der Frequenz eingestellt und nicht mit der Pulslänge. Deswegen hast du auch mehr oder weniger eine unveränderliche Geschwindigkeit, da PWM eine feste Frequenz aber variables Puls/Pauseverhältniss benutzt. Und wenn du genug rumgespielt hast, wird irgendwann der Motor so wenig angesteuert, das er Schritte verliert und langsamer wird bzw stehen bleibt. Das ist keine Drehzahlregelung sondern Motor abwürgen.

  //TCCR2B = TCCR2B & B11111000 | B00000001;    // set timer 2 divisor to     1 for PWM frequency of 31372.55 Hz
  //TCCR2B = TCCR2B & B11111000 | B00000010;    // set timer 2 divisor to     8 for PWM frequency of  3921.16 Hz
  //TCCR2B = TCCR2B & B11111000 | B00000011;    // set timer 2 divisor to    32 for PWM frequency of   980.39 Hz
    TCCR2B = TCCR2B & B11111000 | B00000100;    // set timer 2 divisor to    64 for PWM frequency of   490.20 Hz (The DEFAULT)
  //TCCR2B = TCCR2B & B11111000 | B00000101;    // set timer 2 divisor to   128 for PWM frequency of   245.10 Hz
  //TCCR2B = TCCR2B & B11111000 | B00000110;    // set timer 2 divisor to   256 for PWM frequency of   122.55 Hz
  //TCCR2B = TCCR2B & B11111000 | B00000111;    // set timer 2 divisor to  1024 for PWM frequency of    30.64 Hz

Damit kann man die PWM-Frequenz verändern.

@chefin warum soll man mit einem PWM-Signal auf den Takteingang (oder STEP-Eingang) keinen Schrittmotor bewegen können? Man müsste vermutlich eine Anfahrrampe programmieren, denn ohne könnte der Motor stehen bleiben

Hausknecht:
@chefin warum soll man mit einem PWM-Signal auf den Takteingang (oder STEP-Eingang) keinen Schrittmotor bewegen können?

Wieso fragst Du überhaupt noch, wenn Du schon alles besser weißt?

Deine Frage klingt wie: Warum kann ich eine Schraube nicht mit einem Hammer reinschlagen? Natürlich geht das auch, irgendwie, mit genügend Kraft, hat aber möglicherweise doch nicht das gewünschte Ergebnis.

Oder meinst Du garkeinen Schrittmotor, sondern einen Servomotor? Der Servo wird natürlich mit PWM angesteuert, das würde passen.

Das hab ich wohl verwechselt, sorry.

Es ist in der Tat das erste Mal, dass ich mit einem Steppermotor arbeite. Die grundsätzliche Ansteuerung über PWM habe ich von meinem Vorgänger übernommen, und in der Tat funktioniert das Gerät mit dem Motor und der alten Software auch ganz gut. Ich werde die Ratschläge beherzigen und am PWM-Signal basteln und mir noch weitere Beispiele ansehen.

Danke!