AccelStepper homing

sto testando la homing usando la libreria AccelStepper, il problema e che lo stepper parte e altocco con lo swich si arresta, fin qui tutto bene, ma quando gli invio tramite il monitor seriale una nuova posizione da raggiungere lo stapper rimane fermo ma il codice va avanti ecco `Homing Completed

Enter Travel distance (Positive for CW / Negative for CCW and Zero for back to Home):
Mo���stepper into position: 300
Moving stepper into position: 0
COMPLETED!`

ecco il codice

#include "AccelStepper.h" 


// AccelStepper Setup
AccelStepper stepperX(1, 5, 4);   // 1 = Easy Driver interface
                                  // NANO Pin 2 connected to STEP pin of Easy Driver
                                  // NANO Pin 3 connected to DIR pin of Easy Driver

// Define the Pins used
#define home_switch 6 // Pin 9 connected to Home Switch (MicroSwitch)

// Stepper Travel Variables
long TravelX;  // Used to store the X value entered in the Serial Monitor
int move_finished=1;  // Used to check if move is completed
long initial_homing=-1;  // Used to Home Stepper at startup


void setup() {
   Serial.begin(9600);  // Start the Serial monitor with speed of 9600 Bauds
   
   pinMode(home_switch, INPUT_PULLUP);
   
   delay(5);  // Wait for EasyDriver wake up

   //  Set Max Speed and Acceleration of each Steppers at startup for homing
  stepperX.setMaxSpeed(100.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  stepperX.setAcceleration(100.0);  // Set Acceleration of Stepper
 

// Start Homing procedure of Stepper Motor at startup

  Serial.print("Stepper is Homing . . . . . . . . . . . ");

  while (digitalRead(home_switch)) {  // Make the Stepper move CCW until the switch is activated   
    stepperX.moveTo(initial_homing);  // Set the position to move to
    initial_homing--;  // Decrease by 1 for next move if needed
    stepperX.run();  // Start moving the stepper
    delay(5);
}

  stepperX.setCurrentPosition(0);  // Set the current position as zero for now
  stepperX.setMaxSpeed(100.0);      // Set Max Speed of Stepper (Slower to get better accuracy)
  stepperX.setAcceleration(100.0);  // Set Acceleration of Stepper
  initial_homing=1;

  while (!digitalRead(home_switch)) { // Make the Stepper move CW until the switch is deactivated
    stepperX.moveTo(initial_homing);  
    stepperX.run();
    initial_homing++;
    delay(5);
  }
  
  stepperX.setCurrentPosition(0);
  Serial.println("Homing Completed");
  Serial.println("");
  stepperX.setMaxSpeed(1000.0);      // Set Max Speed of Stepper (Faster for regular movements)
  stepperX.setAcceleration(1000.0);  // Set Acceleration of Stepper

// Print out Instructions on the Serial Monitor at Start
  Serial.println("Enter Travel distance (Positive for CW / Negative for CCW and Zero for back to Home): ");
}

void loop() {

 while (Serial.available()>0)  { // Check if values are available in the Serial Buffer

  move_finished=0;  // Set variable for checking move of the Stepper
  
  TravelX= Serial.parseInt();  // Put numeric value from buffer in TravelX variable
  if (TravelX < 0 || TravelX > 1350) {  // Make sure the position entered is not beyond the HOME or MAX position
    Serial.println("");
    Serial.println("Please enter a value greater than zero and smaller or equal to 1350.....");
    Serial.println("");
  } else {
    Serial.print("Moving stepper into position: ");
    Serial.println(TravelX);
  
  stepperX.moveTo(TravelX);  // Set new moveto position of Stepper
  
  delay(1000);  // Wait 1 seconds before moving the Stepper
  }
  }

  if (TravelX >= 0 && TravelX <= 1350) {

// Check if the Stepper has reached desired position
  if ((stepperX.distanceToGo() != 0)) {
    
    stepperX.run();  // Move Stepper into position
    
  }

// If move is completed display message on Serial Monitor
  if ((move_finished == 0) && (stepperX.distanceToGo() == 0)) {
    Serial.println("COMPLETED!");
    Serial.println("");
     Serial.println("Enter Travel distance (Positive for CW / Negative for CCW and Zero for back to Home): ");
    move_finished=1;  // Reset move variable
  }
  }
}

uso drive TB6600 e stepper Nema 17, grazie

Qualche suggerimento?

quindi riassumendo ti fa correttamente lo homing e poi non si muove più?

si esattamente, mi dice anche Homing Completed, non riesco a capire dove sbaglio

Io quel programma lo ho provato

Senza gli stepper, perché non li ho

Secondo me funziona

Non è ben scritto, ma funziona

Enter Travel distance (Positive for CW / Negative for CCW and Zero for back to Home):
Moving stepper into position: 150
Moving stepper into position: 0
COMPLETED!

ecco il mio output seriale

potrebbe essere qui l' errore, perché dovrebbe dirmi 150 al posto di 0

Ti dice 150 infatti

E muove il motore?

Poi, ma solo poi, ti dice zero, circa due secondi dopo, o sbaglio?

Confermo

Quel programma è scritto coi piedi

Se fosse stato scritto meglio il problema sarebbe chiaro...

il motore va solo nella posizione di homing , una volta raggiunto il finecorsa rimane li.
quando da monitor seriale invio una nuova posizione da raggiungere, lui non si muove.

Vedere cablaggio

A me al simulatore non funge. Mi resta nel while(Serial.available) a causa di '\n' che resta nel buffer.

Mettendo un Serial.read() dopo parseInt funziona.

Ora non so se è un problema del simulatore o un comportamento normale di parseInt.

Funziona anche così:

TravelX = Serial.parseInt(SKIP_ALL, '\n');

Ciao.

come dicevo quel programma è scritto coi piedi
se si usa una parseint() seguita da un terminatore di riga il terminatore rimane
se poi ogni volta che la seriale ha qualcosa da leggere, anche non fossero numeri, si azzera la variabile di posizione e si interrompe il movimento...

ma queste sono cose che dovrebbero "apparire" evidenti, sia a chi scrive programmi, sia a chi li "copia"

ammetto comunque che non sempre alle prime prove queste cose si riconoscono subito

non è il solo problema di quel programma
a partire da tipi dati inutilmente grandi
passando per un controllo dei limiti che non prevede valori negativi, che invece sono esplicitamente richiamati dal prompt...
e commenti sbagliati...

vabbè, dai, abbiamo capito cosa ha il programma

magari partire da una cosa del genere....

#include "AccelStepper.h"


byte homing[] = {6,6,6}; // pin dei micro di homing
int limitisup[] = {2500}; // limite superiore corsa assi
int limitiinf[] = { -2500}; // limite inferiore corsa assi
#define ASSI sizeof homing / sizeof homing[0]
AccelStepper motore[ASSI] = {{1, 11, 13}}; // 1 = Easy Driver interface



void setup()
{
   Serial.begin(9600);  // Start the Serial monitor with speed of 9600 Bauds
   int initial_homing = -1; // Used to Home Stepper at startup

   for (byte i = 0; i < ASSI; i++)
   {
      pinMode(homing[i], INPUT_PULLUP);
   }

   for (byte i = 0; i < ASSI; i++)
   {
      int h = 0;
      Serial.print("Inizio Homing asse: ");
      Serial.println((char)('X' + i));
      motore[i].setMaxSpeed(100);
      motore[i].setAcceleration(100);

      while (digitalRead(homing[i]))
      {
         motore[i].moveTo(h--);
         motore[i].run();
         delay(5);
      }

      motore[i].setCurrentPosition(0);
      motore[i].setMaxSpeed(50);
      motore[i].setAcceleration(50);
      h = 0;

      while (!digitalRead(homing[i]))
      {
         motore[i].moveTo(h++);
         motore[i].run();
         delay(5);
      }

      Serial.print("Termine Homing asse: ");
      Serial.println((char)('X' + i));
      motore[i].setCurrentPosition(0);
      motore[i].setMaxSpeed(1000);
      motore[i].setAcceleration(1000);
      delay(100);
   }
}

void loop()
{
   static int attuale = 0;
   static char stato = 0; // 0 non in ricezione, 1 in ricezione asse X (assi maiuscoli)...

   if (Serial.available())
   {
      // leggo la seriale e tento di interpretarla, al volo
      char c = Serial.read();
      byte asse = c - 'X';

      if (asse > 0 && asse < ASSI)
      {
         attuale = 0;
         stato = asse;
      }

      if (isdigit(c))
      {
         attuale = attuale * 10 + c - '0';
      }

      if (c == '#')
      {
         motore[stato].moveTo(attuale);
         Serial.print("Asse: ");
         Serial.print((char)('X' + stato));
         Serial.print(" muove fino a : ");
         Serial.println(attuale);
         attuale = 0;
      }
   }

   bool arrivato = 1;

   for (byte i = 0; i < ASSI; i++)
   {
      if (motore[i].distanceToGo())
      {
         arrivato = 0;
         break;
      }

      motore[i].run();
   }
}

manca ancora la parte movimento, e sopratutto la parte di comunicazione è da completare, poi serve di aggiungere il controllo dei limiti meccanici dell'asse e poi non so ancora ben cosa, ma diciamo che il lavoro è ben avviato, secondo me

Occhio che AccelStepper non gradisce delay(). Per rispettare la velocità e l'accelerazione impostata la mcu deve esguire molto spesso il metodo .run() che se non ha passi da eseguire ritorna senza fare nulla.

È il metodo .run() che esegue gli step, per cui maggiore è la velocità impostata più frequentemente deve essere eseguito il metodo ,run().

Io con parseInt non ci ho confidenza, comunque funziona quando si specificano i due argomenti, ma non ho indagato più di tanto.

Sarebbe proprio il caso di usare la SerialCmd di @gpb01, se si desidera una interfaccia a comandi.

Ciao.

... eccola QUI (è installabile anche dal "Library Manager" di Arduino IDE) e ne abbiamo a suo tempo parlato QUI. :grin:

Guglielmo

Cose di questo tipo, in poche righe, le scrivo dal 2017, prima di iscrivermi

In effetti già così è quasi finita
Manca il controllo di fine corsa, ma non fa parte della comunicazione
Anticipare il reset della variabile temporanea
E definire lo stato di "non ricezione"

Non serve usare tante librerie
Serve piuttosto definire bene il protocollo...

ragazzi, sono riuscito a fare una cosa di questo tipo :

posx = 2600;
digitalWrite(ledOutGiallo, HIGH);
       move_finished=0; 

  stepperX.setMaxSpeed(200.0);     
  stepperX.setAcceleration(200.0);  
 
  while (digitalRead(home_switch)) {  /
    stepperX.moveTo(initial_homing);  
    initial_homing--;
         // Decrease by 1 for next move if needed
   // stepperX.setSpeed(50000);
  //stepperX.setAcceleration(50000.0);
    stepperX.run(); 
    
   // Start moving the stepper
   delay(5);
 }

  stepperX.setCurrentPosition(0);  
  stepperX.setMaxSpeed(100.0);      
  stepperX.setAcceleration(100.0);  
  initial_homing=1;

  while (!digitalRead(home_switch)) { deactivated
    stepperX.moveTo(initial_homing); 
   // stepperX.setMaxSpeed(50000.0);      
  //stepperX.setAcceleration(50000.0);  
    stepperX.run();
    initial_homing++;
   delay(5);
    } 

digitalWrite(dirPin,LOW); // fai partire il motore in una determinata direzione
  
  for(int x = 0; x < posx; x++) {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(500); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(500); 
  }  
  digitalWrite(ledOutGiallo, LOW);  

dove posx e la posizione da raggiungere, capisco che potevo fare tutto con la libreria accelstepper ma mi e risultato piu veloce scriverlo così, comunque funziona, il problema adesso ne che quando effettua l' homing impiega molto tempo per tornare indietro verso lo swich e non riesco ad accellerarlo.
immagino che dovrei settare la velocita qui:

stepperX.setMaxSpeed(200.0);      
  stepperX.setAcceleration(200.0); 

ma non accellera perche?
invece quando va nella posizione scelta va molto veloce.
grazie anticipatamente

Magari "togliere" i delay() che lo rallentano aiuterebbe...

1 Like

ok grazie, ho tolto il "delay" e tutto ok