Stepper motor non si muove ma ronza

Salve ragazzi,
sto realizzando una guida lineare pilotata da uno stepper con DVR8825 e arduino e i suoi finecorsa.

Su breadboard il tutto funzionava anche se il motore ronzava.
Successivamante, ho montato il DVR8825 su un piccolo PCB e l’Arduino Nano su una shield.

Purtroppo ora il motore è in presa ma ronza soltanto andando avanti e indietro di un solo passo come si vede nel filmato allegato.

Il software dalla porta seriale mi fa intendere che tutto va bene mandandomi i giusti feedback ma il motore non si muove. Devo per caso regolare la vref? ma come si fa? Opppure può essere altro?

Grazie a tutti

guida_lineare.mpg (946 KB)

dugajimi:
Devo per caso regolare la vref? ma come si fa? Opppure può essere altro?

Grazie a tutti

Se il driver è adeguato al motore (a occhio direi di si) probabilmente il problema è quello.

San Google ha tutte le risposte :smiley:

i motivi percui un motore passo passo ronza invece di girare possono essere molteplici, tra cui:

  1. vref regolata per una corrente troppo bassa
  2. alimentatore che non riesce ad erogare corrente a sufficienza
  3. velocità degli step troppo alta e il motore va in stallo ronzando
  4. qualche filo che va al motore interrotto
  5. booh non mi viene niente altro in mente :confused:

Ragazzi:

  • l’alimentazione è apposto visto che uso un alimentatore 12V a 20 A
  • la vref l’ho appena regolata
  • ho controllatato anche il circuito

Invece è il software che ha problemi visto che nel mio script uso la libreria: https://github.com/laurb9/StepperDriver e non va mentre se uso uno script che non fa uso di libreria invece va. Qui sotto il codice al confronto:

Mio codice completo di gestione dei finecorsa:

#include <Arduino.h>

// POTENTIOMETER
//  Pin +5V           -> Pin laterale del potenziometro
//  Pin GND           -> Pin GND modulo e pin laterale potenz.
#define POT A7

//BUTTON SWITCH
#define BUTTONPIN 2

// ENDSTOP PIN
#define ENDSTOP_0 5  // Pin 5 connected to ENDSTOP_0 switch out
#define ENDSTOP_1 6  // Pin 6 connected to ENDSTOP_1 switch out

// Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step
#define MOTOR_STEPS 200
#define RPM 50

#define DIR 8
#define STEP 9
#define ENABLE 13 // optional (just delete ENABLE from everywhere if not used)

// SERIAL COMUNICATION PARAMETERS
#define SERIAL_PORT 0
#define BAUDRATE 9600  //57600


int incomingByte = 0;   // for incoming serial data

// INITIAL STEPPER SPEED
int motorSpeed = RPM;     // velocità del motore
int stepCount = 0   ;     // numero di passi del motore
int carriagedir = 1 ;     // direzione del carrello

#include "DRV8825.h"
#define MODE0 12
#define MODE1 11
#define MODE2 10
DRV8825 stepper(MOTOR_STEPS, DIR, STEP, ENABLE, MODE0, MODE1, MODE2);

void setup() {
  Serial.begin(BAUDRATE); // Start serial comunication

  pinMode(BUTTONPIN, INPUT);
  pinMode(ENDSTOP_0, INPUT);
  pinMode(ENDSTOP_1, INPUT);
  delay(1);  // Wait for Driver wake up


  delay(500);
}

void loop() {

  int PotValue = analogRead(POT);// Legge il valore della tensione fornito dal potenziometro:
  motorSpeed = map(PotValue, 0, 1023, 20, 100);   // mappa il valore nel range da 0 a 100

  if (motorSpeed > 0) {
    stepper.enable();
    stepper.begin(motorSpeed);
    if (!digitalRead(ENDSTOP_0) && !digitalRead(ENDSTOP_1)) {
      // Move carriage
      switch (carriagedir) {
        case 0:    // move carriage on dir 0
          stepper.rotate(5);     // forward revolution
          stepCount--;
          break;
        case 1:    // move carriage on dir 1
          stepper.rotate(-5);     //  reverse revolution
          stepCount++;
          break;
      }
      //delay(1);        // delay in between reads for stability
    }
    else if (digitalRead(ENDSTOP_0))
    {
      // Change direction and move carriage of 5 step
      carriagedir = 1;
      stepper.move(-5);    // forward revolution
      stepCount = 0;
      //delay(10);
    }
    else if (digitalRead(ENDSTOP_1))
    {
      // Change direction and move carriage of 5 step
      carriagedir = 0;
      stepper.move(5);     //  reverse revolution
      stepCount = 0;
      //delay(10);
    }
    else
    {
      Serial.println("Houston there is a problem!");
    }
  }
  else if (motorSpeed < 1) {
    stepper.disable();    // disable motor
  }

}

Codice trovato su internet (funziona ma non riesco a modificare la velocità):

int M1dirpin = 8;  //Motor X direction pin
int M1steppin = 9; //Motor X step pin
int M1en=13;  //Motor X enable pin

void setup()
{
  pinMode(M1dirpin,OUTPUT);
  pinMode(M1steppin,OUTPUT);
  pinMode(M1en,OUTPUT);
  digitalWrite(M1en,LOW);// Low Level Enable 
}
void loop()
{
    int j;
  delayMicroseconds(2);
  digitalWrite(M1dirpin,LOW);
  for(j=0;j<=500;j++){
    digitalWrite(M1steppin,LOW);
    delayMicroseconds(2);
    digitalWrite(M1steppin,HIGH); //Rising step
    delay(1);
  }
}

Variando anche di poco il delayMicroseconds() oppure il delay() il motore comincia a ronzare e va a scatti.

Purtoppo vedo che usando anche altro codice trovato qua e la su internet non funziona.
Mi piacerebbe capire: cosa c’è che non va nel codice?

gli stepper non possono raggiungere immediatamente alte velocità devono avere rampe di accelerazione e decelerazione pena il blocco e ronzii

nel secondo codice non devi variare il delaymicroseconds ma il delay(1) 1 millisec= 1000 microsec

Patrick_M:
gli stepper non possono raggiungere immediatamente alte velocità devono avere rampe di accelerazione e decelerazione pena il blocco e ronzii

nel secondo codice non devi variare il delaymicroseconds ma il delay(1) 1 millisec= 1000 microsec

Guarda anche cambiando il delay da 1 a 2 il motore non si muove più

ciao:
delay(1): funziona
delay(2): non funziona

dugajimi:
Guarda anche cambiando il delay da 1 a 2 il motore non si muove più

ciao:
delay(1): funziona
delay(2): non funziona

casomai dalay(1) -> delayMicroseconds(900) o meno...
per aumentare la velocità
con delay(2) dimezzi la velocità

Patrick_M:
casomai dalay(1) -> delayMicroseconds(900) o meno...
per aumentare la velocità
con delay(2) dimezzi la velocità

Ho provato a variare il delayMicroseconds(X) con un potenziometro e ho trovato che un valore intorno a 1000-1050 il motore viaggia bene. Se scendo sotto i 900 non gira cosi come se salgo a 1300.

Comunque non riesco a variare la velocità in maniera corretta.

Da quello che ho capito è un problema di clock di arduino che è troppo veloce affinche il driver esegua il comando.

Datemi una mano perchè non so più che pesci pigliare.

Prova con la libreria Accelstepper

EDIT: e magari con la libreria StepperDriver prova ad aggiungere le #define per l'accelerazione e a modificare i valori

// Acceleration and deceleration values are always in FULL steps / s^2
#define MOTOR_ACCEL 2000
#define MOTOR_DECEL 1000

doppiozero:
EDIT: e magari con la libreria StepperDriver prova ad aggiungere le #define per l'accelerazione e a modificare i valori

// Acceleration and deceleration values are always in FULL steps / s^2

#define MOTOR_ACCEL 2000
#define MOTOR_DECEL 1000

anche in questo caso il motore gratta

Come consigliato da doppiozero sto provando la libreria Accelstepper.
Il motore si muove ma fa un ronzio insopportabile.
Ho provata a giocare con alcuni parametri ma non riesco ad abbassare la velocità più di tanto. Infatti se porto stepper.setSpeed(600) sotto il 600 il motore si ferma e comincia a gracchiare.

Il codice è il seguente:

#include <AccelStepper.h>

AccelStepper stepper(1, 9, 8); // driver usage = 1 step pin = 9 dir pin = 8

void setup()
{
  stepper.setMaxSpeed(4000);
  stepper.setAcceleration(1500);
  stepper.setMinPulseWidth(10);
  stepper.setSpeed(600);
}

void loop()
{
  stepper.runSpeed();
}

Usa un altro driver come per esempio un L293

Ciao Uwe

link al motore?

doppiozero:
link al motore?

Il motore che sto usando attualmente è il seguente:
KS42STH40 -1204A
quindi con le seguenti caratteristiche:

Step Angle 1.8 degree
Rated Voltage 2 VDC
Rated Current DC 1.2 A/Phase
Resistance(20℃) 1.7 Ω/phase

Poi ho provato anche con Nema 17 42BYGHM809
con le seguenti caratteristiche:

Step Angle (degrees) : 0.9
2-Phase
Rated Voltage: 3V
Rated Current: 1.7A/Phase
400 steps/rev

In tutte e due i casi usando la libreria <Accelstepper.h> se imposto:

stepper.setSpeed(1000); → ma anche 950 tutto sommato gira bene.

Probanilmente azzardo un ipotesi:
il comando stepper.setSpeed(1000) non serve a variare la velocità del motore
ma va impostato per ogni motore una volta e basta. Il passo-passo va gestito in questa maniera:

  • tu gli dici ruota di tot passi e lui;
  • ruota di altri tot pasi e si ferma;
  • la velocità si regola impostanto un delay tra una rotazione e l’altra

Se la rotazione deve risultare fluida bisogna ridurre il numero degli step.

Spero di non aver detto fesserie perche mi rimane come ultima ipotesi.

Ciao Dugajimi

Con la libreria non ti serve impostare nessun delay, io sospetto un problema di codice.

prova questo (io non l’ho provato però) dovrebbe muoversi avanti e indietro ogni 5 secondi di 200passi

#include <AccelStepper.h>

AccelStepper stepper(1, 9, 8); // driver usage = 1 step pin = 9 dir pin = 8

unsigned long int previousMillis = 0;
bool direzione = true;
bool flag = true;

void setup()
{
  stepper.setMaxSpeed(200.0);
  stepper.setAcceleration(100.0);
}

void loop()
{
  if (millis() - previousMillis > 5000) {
    direzione = !direzione;
    previousMillis = millis();
  }

  if (direzione == true && flag == true) {
    stepper.move(200);
    flag = false;
  }
  if (direzione == false && flag == false) {
    stepper.move(-200);
    flag = true;
  }
  stepper.run();
}

certamente non basta controllare solo la velocità, mi sembra che qui sia l'accelerazione che la velocità massime siano "leggermente" alte

stepper.setMaxSpeed(4000);
stepper.setAcceleration(1500);

doppiozero:
Con la libreria non ti serve impostare nessun delay, io sospetto un problema di codice.

prova questo (io non l’ho provato però) dovrebbe muoversi avanti e indietro ogni 5 secondi di 200passi

#include <AccelStepper.h>

AccelStepper stepper(1, 9, 8); // driver usage = 1 step pin = 9 dir pin = 8

unsigned long int previousMillis = 0;
bool direzione = true;
bool flag = true;

void setup()
{
 stepper.setMaxSpeed(200.0);
 stepper.setAcceleration(100.0);
}

void loop()
{
 if (millis() - previousMillis > 5000) {
   direzione = !direzione;
   previousMillis = millis();
 }

if (direzione == true && flag == true) {
   stepper.move(200);
   flag = false;
 }
 if (direzione == false && flag == false) {
   stepper.move(-200);
   flag = true;
 }
 stepper.run();
}

Il risultato è un motore che gracchia e non ruota

movie.mpg (1.13 MB)

Patrick_M:
certamente non basta controllare solo la velocità, mi sembra che qui sia l’accelerazione che la velocità massime siano “leggermente” alte

stepper.setMaxSpeed(4000);
stepper.setAcceleration(1500);

Riassumendo per ora l’unico codice che funziona è questo:

#include <AccelStepper.h>

AccelStepper stepper(1, 9, 8); // driver usage = 1 step pin = 9 dir pin = 8

void setup()
{
  stepper.setMaxSpeed(2000);
  stepper.setAcceleration(100);
  stepper.setMinPulseWidth(20);
  stepper.setSpeed(1000);

}

void loop()
{
  stepper.runSpeed();
}
  1. Posso variare la velocita tramite setSpeed(900-1100) con valori tra 900 e 1100 altrimenti non ruota.
  2. Ho abbassato l’accelerazione a 100 e va bene.
  3. setMaxSpeed() ovviamente non può essere inferiore a 1000 perchè si trascina setSpeed()

A livello hardware ho anche provato un altro driver DVR8825 e controllato tutti i collegamanti ma niente.

Hai provato anche staccando il motore dalla guida?

doppiozero:
Hai provato anche staccando il motore dalla guida?

Ho staccato il motore e sto usando il Nema 17 42BYGHM809 per le prove con la vref regolata.