Controllo attuatore lineare e finecorsa che non funziona

Salve ragazzi,

ho costruito un attuatore lineare con uno stepper e due finecorsa.
Il carrello deve muoversi alternativamante a destra e a sinistra tra i due finecorsa alla velocità impostata.
Con un potenziometro controllo la velocita e tutto ok.

Il problema è che i fine corsa non funzionano correttamente.

Come potete vedere dal filmato, quando il carrello sbatte contro il finecorsa, lo commuta ma non rilascia abbastanza velocemente il finecorsa e quindi rimane sempre schiaccato.

Il problema risiede certamente nel codice visto che se commuto con le dita il finecorsa tutto funziona.
Probabilemente forse c'è da inserire qualche interrupt ma non so come procedere.

Di seguito vi allego il codice

Spero nel vostro aiuto.

Dugajimi

#include <Arduino.h>

/* Include the library */
#include "HCMotor.h"
/* Create an instance of the library */
HCMotor HCMotor;


/*************************************************************************/
//                                 PIN CONFIGURATION
/*************************************************************************/

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

//BUTTON SWITCH
#define HOMEPIN 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 11
#define STEP 10
//#define ENABLE 13 // optional (just delete ENABLE from everywhere if not used)

#define MAXMOTORS 1

/****************************************************************************************************/
//                                 VARIABLES
/****************************************************************************************************/

// INITIAL STEPPER SPEED
int motorSpeed  = RPM;     // velocità del motore
int carriagedir = 1 ;      // direzione del carrello



void setup() {
  pinMode(HOMEPIN, INPUT_PULLUP);
  pinMode(ENDSTOP_0, INPUT_PULLUP);
  pinMode(ENDSTOP_1, INPUT_PULLUP);
  delay(5);  // Wait for Driver wake up

  /* Initialise the library */
  HCMotor.Init();

  /* Attach motor 0 to digital pins 8 & 9. The first parameter specifies the
     motor number, the second is the motor type, and the third and forth are the
     digital pins that will control the motor */
  HCMotor.attach(0, STEPPER, STEP, DIR);

  /* Set the number of steps to continuous so the the motor is always turning whilst
     not int he dead zone*/
  HCMotor.Steps(0, CONTINUOUS);

  delay(100);
}

void loop() {


  // read the input pin:
  int buttonState = digitalRead(HOMEPIN);
  if (!buttonState) {
    CarriagetoHome();
    delay(1);                                   // delay in between reads for stability   
  }


  int PotValue = analogRead(POT);                 // Legge il valore della tensione fornito dal potenziometro:
  motorSpeed = PotValue;
  motorSpeed = map(PotValue, 0, 1023, 0, 2046);   // mappa il valore nel range da 0 a 100
  //delay(1);                                     // delay in between reads for stability

  if (motorSpeed > 2) {
    HCMotor.attach(0, STEPPER, STEP, DIR);

    if (!digitalRead(ENDSTOP_0) && !digitalRead(ENDSTOP_1)) {
      // Move carriage
      switch (carriagedir) {
        case 0:    // move carriage on dir 0
          HCMotor.Direction(0, FORWARD);
          break;
        case 1:    // move carriage on dir 1
          HCMotor.Direction(0, REVERSE);
          break;
      }
      HCMotor.Steps(0, 1);
      delayMicroseconds(2046 - motorSpeed);
      //HCMotor.DutyCycle(0, motorSpeed);
    }

    else if (digitalRead(ENDSTOP_0))
    {
      // Change direction and move carriage slow
      carriagedir = 1;
      HCMotor.Direction(0, REVERSE);
      //HCMotor.DutyCycle(0, 5);
      HCMotor.Steps(0, 5);
    }
    else if (digitalRead(ENDSTOP_1))
    {
      // Change direction and move carriage slow
      carriagedir = 0;
      HCMotor.Direction(0, FORWARD);
      HCMotor.Steps(0, 5);
      //HCMotor.DutyCycle(0, 10);
    }
  }
  else if (motorSpeed <= 2 )
  {
    HCMotor.detach(0); //disattiva motore
  }
}

void CarriagetoHome() {
  carriagedir = 0;

  if (!digitalRead(HOMEPIN)) {
    HCMotor.Direction(0, REVERSE);
    //HCMotor.DutyCycle(0, 50);
    HCMotor.Steps(0, 5);
    stepCount = 0;
    delay(50);
  }
}

linear.mpg (1.1 MB)

be però se lo fai lavorare i finecorsa al contrario è normale, infatti quando va verso destra tu premi il finecorsa sinistro per farlo andare a sinistra, invece il carrello arriva e preme il finecorsa destro , torna indietro di 5 /200 di giro e poi procede nuovamente verso destra...

Ti ringrazio Patrick,
alle volte ci si perde dietro le stupidate che hai davanti agli occhi.

E chiedo ora se conosci la libreria HCMotor.h che ha un comando:

HCMotor.detach(0); //disattiva motore

che però ovviamante non funziona visto che il pin enable non viene definito da nessuna parte negli esempi.

Hai idea come fare?

PS: Riposto il codice corretto nel caso dovesse servire a qualcuno:

#include <Arduino.h>

/* Include the library */
#include "HCMotor.h"
/* Create an instance of the library */
HCMotor HCMotor;


/***************************************************************************************************/
//                                 PIN CONFIGURATION
/***************************************************************************************************/

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

//BUTTON SWITCH
#define HOMEPIN 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 11
#define STEP 10
//#define ENABLE 13 // optional (just delete ENABLE from everywhere if not used)

#define MAXMOTORS 1

/****************************************************************************************************/
//                                 VARIABLES
/****************************************************************************************************/

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



void setup() {
  pinMode(HOMEPIN, INPUT_PULLUP);
  pinMode(ENDSTOP_0, INPUT_PULLUP);
  pinMode(ENDSTOP_1, INPUT_PULLUP);
  delay(5);  // Wait for Driver wake up

  /* Initialise the library */
  HCMotor.Init();

  /* Attach motor 0 to digital pins 8 & 9. The first parameter specifies the
     motor number, the second is the motor type, and the third and forth are the
     digital pins that will control the motor */
  HCMotor.attach(0, STEPPER, STEP, DIR);

  /* Set the number of steps to continuous so the the motor is always turning whilst
     not int he dead zone*/
  HCMotor.Steps(0, CONTINUOUS);

  delay(100);
}

void loop() {


  // read the input pin:
  int buttonState = digitalRead(HOMEPIN);
  if (!buttonState) {
    CarriagetoHome();
    delay(1);                                   // delay in between reads for stability   
  }


  int PotValue = analogRead(POT);                 // Legge il valore della tensione fornito dal potenziometro:
  motorSpeed = PotValue;
  motorSpeed = map(PotValue, 0, 1023, 0, 2046);   // mappa il valore nel range da 0 a 100
  //delay(1);                                     // delay in between reads for stability

  if (motorSpeed > 2) {
    HCMotor.attach(0, STEPPER, STEP, DIR);

    if (!digitalRead(ENDSTOP_0) && !digitalRead(ENDSTOP_1)) {
      // Move carriage
      switch (carriagedir) {
        case 0:    // move carriage on dir 0
          HCMotor.Direction(0, REVERSE);
          stepCount--;
          break;
        case 1:    // move carriage on dir 1
          HCMotor.Direction(0, FORWARD);
          stepCount++;
          break;
      }
      HCMotor.Steps(0, 1);
      delayMicroseconds(2046 - motorSpeed);
      //HCMotor.DutyCycle(0, motorSpeed);
    }

    else if (digitalRead(ENDSTOP_0))
    {
      // Change direction and move carriage slow
      carriagedir = 1;
      HCMotor.Direction(0, FORWARD);
      //HCMotor.DutyCycle(0, 50);
      HCMotor.Steps(0, 5);
      stepCount = 0;
    }
    else if (digitalRead(ENDSTOP_1))
    {
      // Change direction and move carriage slow
      carriagedir = 0;
      HCMotor.Direction(0, REVERSE);
      HCMotor.Steps(0, 50);
      //HCMotor.DutyCycle(0, 10);
      stepCount = 0;
    }
  }
  else if (motorSpeed <= 2 )
  {
    HCMotor.detach(0); //disattiva motore
  }
}

void CarriagetoHome() {
  carriagedir = 1;
  stepCount = 0;
}
//detach 

HCMotor.detach(0); //disattiva motore

 // è esattamente l'opposto di attach

 HCMotor.attach(0, STEPPER, STEP, DIR);

quello che dici tu è l'enable
dipende dal controller che usi, se si tratta di un controller con l'ic L293 allora i pin 1 è l'enable delle uscite 1 e 2 mentre il pin 9 è l'enable delle uscite 3 e 4
per cui mettendoli a 0 o 1 disattivi/attivi il motore senza usare il detach. Con il detach poi devi rifare l'attach per poter usare nuovamente il motore
come fa correttamente lo sketch che hai postato, perchè dici che il detach non funziona?

Patrick_M:
quello che dici tu è l'enable
dipende dal controller che usi, se si tratta di un controller con l'ic L293 allora i pin 1 è l'enable delle uscite 1 e 2 mentre il pin 9 è l'enable delle uscite 3 e 4
per cui mettendoli a 0 o 1 disattivi/attivi il motore senza usare il detach. Con il detach poi devi rifare l'attach per poter usare nuovamente il motore
come fa correttamente lo sketch che hai postato, perchè dici che il detach non funziona?

Io sto usando il TB6600 che ha un pin taggato (-ENA) il quale ha esattamente la funzione di enable di cui parli.

Il problema è nella libreria che sembra abbia la funzione di abilitare/disabilitare il motore con il comando:

  • HCMotor.attach(numeromotore) e
  • HCMotor.detach(numeromotore)
    ma non si capisce quale sia il comando per definire il pin su arduino a meno che lo debba dare a mano bypassando la libreria con i comandi:

pinMode(13, INPUT_PULLUP); //presupponendo che 13 sia il pin arduino prepostao all?enable/disable

e poi:
digitalWrite(13, HIGH);
digitalWrite(13, LOW);

ma allora non si capisce a cosa serve il comando libreria:

  • HCMotor.detach(0); //disattiva motore
  • HCMotor.attach(0);

Spero di essermi spiegato.

... SE la libreria che stai usando è QUESTA, allora a cosa servono e la sintassi completa di quelle chiamate è ben descritta nella loro documentazione QUI.

Guglielmo

e inoltre come tutte le librerie se vai su file esempi e poi cerchi il nome della libreria troverai almeno 1 o 2 esempi dai quali puoi verificare come vengono usate le varie funzioni (magari non tutte) :slight_smile:

gpb01:
... SE la libreria che stai usando è QUESTA, allora a cosa servono e la sintassi completa di quelle chiamate è ben descritta nella loro documentazione QUI.

Guglielmo

Si avevo gia letto questa documentazione.
Quindi il detach non corrisponde ad un disable motor ma elimina soltanto il motore dall'array dei motori?

xche è poi la stessa cosa :slight_smile: