Stepper e Arduino

Sezione dedicata all'elettronica in generale.
Rispondi
Avatar utente
leomonti
Senior
Senior
Messaggi: 2110
Iscritto il: mercoledì 20 dicembre 2006, 19:04

Re: Stepper e Arduino

Messaggio da leomonti » lunedì 4 marzo 2024, 19:22

E' quello il punto. Dovrei potermi spostare elettricamente in senso opposto. C'è modo?
Altra domanda: che tipo di potenziometro (o encoder) e con quale valore?
Il cervello è l'organo più sopravvalutato...(W.Allen)

umbez
Member
Member
Messaggi: 295
Iscritto il: martedì 14 novembre 2006, 20:59
Località: Cologno Monzese

Re: Stepper e Arduino

Messaggio da umbez » lunedì 4 marzo 2024, 19:27

I finecorsa prendili NC. Se per caso si guastasse e non hai scelto il nc, il sistema non se ne accorge e va oltre facendo un disastro
U.

Avatar utente
leomonti
Senior
Senior
Messaggi: 2110
Iscritto il: mercoledì 20 dicembre 2006, 19:04

Re: Stepper e Arduino

Messaggio da leomonti » lunedì 4 marzo 2024, 19:46

Sulle cnc uso sempre i NC, ma ricordavo che Arduino volesse i NO. Ricordavo male...
Comunque, credo si debba specificarlo nel codice se fermare quando alti o bassi. Sbaglio?
Il cervello è l'organo più sopravvalutato...(W.Allen)

Avatar utente
hellfire39
God
God
Messaggi: 3416
Iscritto il: domenica 16 dicembre 2012, 9:04
Località: AN

Re: Stepper e Arduino

Messaggio da hellfire39 » martedì 5 marzo 2024, 7:54

I finecorsa li puoi scegliere come ti pare. Se li scegli NC dovrai metterli in serie, se li scegli NO dovrai metterli in parallelo.
Visto che il codice lo scriviamo noi, possiamo fare come ci pare e non siamo obbligati ad una scelta fissa.

L'utilizzo dei finecorsa NC ha due vantaggi:
- sicurezza: se il sensore si scollega, si apre il circuito e sei in sicurezza, la macchina non si muove
- disturbi: i sensori NC fanno si che ci sia un segnale a bassa impedenza sul pin di ingresso e minimizza il rischio di prendere disturbi


P.S: ieri sera ho fatto delle prove per farti muovere l'asse in direzione opposta quando impegni un finecorsa, ma devo sistemare il codice in modo che sia più leggibile.

Avatar utente
hellfire39
God
God
Messaggi: 3416
Iscritto il: domenica 16 dicembre 2012, 9:04
Località: AN

Re: Stepper e Arduino

Messaggio da hellfire39 » martedì 5 marzo 2024, 21:54

Ho ripulito un po' il codice, se qualcosa non è chiaro, chiedi pure.
Premetto che il codice potrebbe essere migliorato utilizzando una classe al posto della struttura DatiAsse e della funzione gestisciAsse().
Dopotutto Arduino utilizza il C++ mentre il codice che ho scritto è più in stile C.

Io l'ho provato con un singolo asse e con arduino nano.
Andrebbe provato con tutti e tre gli assi, con un micro adeguato come il PRO MICRO. Purtroppo ho in casa un solo PRO MICRO ma l'ho utilizzato per fare una tastiera e ci ho saldato direttamente i fili, quindi non riesco ad utilizzarlo.
Potrei provare un ESP32, ma solo nel weekend.

Se vuoi provare lo scketch con più assi devi solo scommentare le parti commentate relative agli assi Y e Z ed assegnare i pin corretti.
Ricorda che con la libreria FastAccelStepper puoi usare solamente determinati pin per il segnale STEP.
La pagina del manuale che ho linkato i giorni scorsi spiega bene quali sono i pin utilizzabili.

Per la velocità ho utilizzato un potenziometro lineare da 10 kOhm. Vanno bene anche valori differenti, ma non scenderei sotto 1 kOhm.
Né salirei sopra i 47 kOhm.

Codice: Seleziona tutto

#include "FastAccelStepper.h"
#include <Bounce2.h>

#define dirPinStepperX 2
#define enablePinStepperX 4
#define stepPinStepperX 9
#define avantiX 7
#define indietroX 6
#define pinFinecorsaX 8

/*
#define dirPinStepperY 2
#define enablePinStepperY 4
#define stepPinStepperY 9
#define avantiY 7
#define indietroY 6
#define pinFinecorsaY 8

#define dirPinStepperZ 2
#define enablePinStepperZ 4
#define stepPinStepperZ 9
#define avantiZ 7
#define indietroZ 6
#define pinFinecorsaZ 8
*/



enum direzione {avanti, indietro, nessuna};

// memorizza lo stato di un asse
typedef struct DatiAsse {
  direzione ultimaDirezione;      // direzione in cui si sta muovendo l'asse  
  direzione finecorsaImpegnato;   // finecorsa impegato
  bool comandoAttivo;             // c'è un comando attivo
};

// class factory per gli stepper
FastAccelStepperEngine engine = FastAccelStepperEngine();

// creazione di uno stepper (da configurare in setup())
FastAccelStepper *stepperX = NULL;
//FastAccelStepper *stepperY = NULL;
//FastAccelStepper *stepperZ = NULL;


// antirimbalzo software per pulsanti e finecorsa (da configurare in setup())
Bounce2::Button buttonXplus = Bounce2::Button();
Bounce2::Button buttonXminus = Bounce2::Button();
Bounce finecorsaX = Bounce();

/*
Bounce2::Button buttonYplus = Bounce2::Button();
Bounce2::Button buttonYminus = Bounce2::Button();
Bounce finecorsaZ = Bounce();

Bounce2::Button buttonZplus = Bounce2::Button();
Bounce2::Button buttonZminus = Bounce2::Button();
Bounce finecorsaZ = Bounce();
*/

// dichiarazione della funzione implementata più sotto
void gestisciAsse(FastAccelStepper *stepper, DatiAsse &datiAsse, Bounce2::Button &dirAvanti, Bounce2::Button &dirIndietro, Bounce &finecorsa);


void setup() {
  engine.init();

  stepperX = engine.stepperConnectToPin(stepPinStepperX);
  if (stepperX) {
    stepperX->setDirectionPin(dirPinStepperX);
    stepperX->setEnablePin(enablePinStepperX);
    stepperX->setAutoEnable(true);

    // If auto enable/disable need delays, just add (one or both):
    // stepper->setDelayToEnable(50);
    // stepper->setDelayToDisable(1000);

    stepperX->setSpeedInUs(1000);       // the parameter is us/step !!!
    stepperX->setAcceleration(10000);   // step/s^2
  }

  /*
  stepperY = engine.stepperConnectToPin(stepPinStepperY);
  if (stepperY) {
    stepperY->setDirectionPin(dirPinStepperY);
    stepperY->setEnablePin(enablePinStepperY);
    stepperY->setAutoEnable(true);

    // If auto enable/disable need delays, just add (one or both):
    // stepper->setDelayToEnable(50);
    // stepper->setDelayToDisable(1000);

    stepperY->setSpeedInUs(1000);       // the parameter is us/step !!!
    stepperY->setAcceleration(10000);   // step/s^2
  }

  stepperZ = engine.stepperConnectToPin(stepPinStepperZ);
  if (stepperZ) {
    stepperZ->setDirectionPin(dirPinStepperZ);
    stepperZ->setEnablePin(enablePinStepperZ);
    stepperZ->setAutoEnable(true);

    // If auto enable/disable need delays, just add (one or both):
    // stepper->setDelayToEnable(50);
    // stepper->setDelayToDisable(1000);

    stepperZ->setSpeedInUs(1000);       // the parameter is us/step !!!
    stepperZ->setAcceleration(10000);   // step/s^2
  }
  */


  // impostazioni antirimbalzo
  finecorsaX.attach( pinFinecorsaX, INPUT_PULLUP);
  finecorsaX.interval(20);

  buttonXplus.attach( avantiX, INPUT_PULLUP );  // USE EXTERNAL PULL-UP
  buttonXplus.interval(5);                         // DEBOUNCE INTERVAL IN MILLISECONDS
  buttonXplus.setPressedState(LOW);                // LOW = TASTO PREMUTO

  buttonXminus.attach( indietroX, INPUT_PULLUP ); // USE EXTERNAL PULL-UP
  buttonXminus.interval(5);                        // DEBOUNCE INTERVAL IN MILLISECONDS
  buttonXminus.setPressedState(LOW);               // LOW = TASTO PREMUTO

/*
  finecorsaY.attach( pinFinecorsaY, INPUT_PULLUP);
  finecorsaY.interval(20);

  buttonYplus.attach( avantiY, INPUT_PULLUP );  // USE EXTERNAL PULL-UP
  buttonYplus.interval(5);                         // DEBOUNCE INTERVAL IN MILLISECONDS
  buttonYplus.setPressedState(LOW);                // LOW = TASTO PREMUTO

  buttonYminus.attach( indietroY, INPUT_PULLUP ); // USE EXTERNAL PULL-UP
  buttonYminus.interval(5);                        // DEBOUNCE INTERVAL IN MILLISECONDS
  buttonYminus.setPressedState(LOW);               // LOW = TASTO PREMUTO

  finecorsaZ.attach( pinFinecorsaZ, INPUT_PULLUP);
  finecorsaZ.interval(20);

  buttonZplus.attach( avantiY, INPUT_PULLUP );  // USE EXTERNAL PULL-UP
  buttonZplus.interval(5);                         // DEBOUNCE INTERVAL IN MILLISECONDS
  buttonZplus.setPressedState(LOW);                // LOW = TASTO PREMUTO

  buttonZminus.attach( indietroY, INPUT_PULLUP ); // USE EXTERNAL PULL-UP
  buttonZminus.interval(5);                        // DEBOUNCE INTERVAL IN MILLISECONDS
  buttonZminus.setPressedState(LOW);               // LOW = TASTO PREMUTO
*/



  // solo per debug
  Serial.begin(115200);
}


DatiAsse datiAsseX;
//DatiAsse datiAsseY;
//DatiAsse datiAsseZ;

uint32_t speedStep;

void loop() {
  
  int speedIn = analogRead(A0);
  speedStep = map(speedIn, 1023, 0, 50, 1000);

  gestisciAsse(stepperX, datiAsseX, buttonXplus, buttonXminus, finecorsaX);
  //gestisciAsse(stepperY, datiAsseY, buttonYplus, buttonZminus, finecorsaY);
  //gestisciAsse(stepperZ, datiAsseZ, buttonZplus, buttonZminus, finecorsaZ);


}


// questa funzione, da richiamare periodicamente in loop(), 
// si occupa di gestire un singolo asse.
// Va richiamata per ogni asse che deve essee gestito.
void gestisciAsse(FastAccelStepper *stepper, DatiAsse &datiAsse, Bounce2::Button &dirAvanti, Bounce2::Button &dirIndietro, Bounce &finecorsa) {

  // aggiornamento stato ingressi
  dirAvanti.update();
  dirIndietro.update();
  finecorsa.update();

  // il finecorsa è impegnato?
  bool finecorsaPremuto = finecorsa.read() == HIGH;

  // movimento avanti 
  bool possoMuovermi = !datiAsse.comandoAttivo && (!finecorsaPremuto || (finecorsaPremuto && (datiAsse.finecorsaImpegnato == indietro)));
  if (dirAvanti.isPressed() && possoMuovermi) {
    stepper->setSpeedInUs(speedStep);
    stepper->runForward();
    Serial.println("forward");
    datiAsse.comandoAttivo = true;
    datiAsse.ultimaDirezione = avanti;
  }

  // movimento indietro
  possoMuovermi = !datiAsse.comandoAttivo && (!finecorsaPremuto || (finecorsaPremuto && (datiAsse.finecorsaImpegnato == avanti)));
  if (dirIndietro.isPressed() && possoMuovermi) {
    stepper->setSpeedInUs(speedStep);
    stepper->runBackward();
    Serial.println("backward");
    datiAsse.comandoAttivo = true;
    datiAsse.ultimaDirezione = indietro;
  }

  // stop in rampa
  if ((!dirAvanti.isPressed()) && (!dirIndietro.isPressed()) && datiAsse.comandoAttivo) {
    stepper->stopMove();            
    Serial.println("stopMove");
    datiAsse.comandoAttivo = false;
  }
  
  // se sono fermo, resetto la direzione corrente
  if (!stepper->isRunning()) {
    datiAsse.ultimaDirezione = nessuna;
  }
  
  // stop immediato per impegno finecorsa
  if (finecorsaPremuto && (datiAsse.finecorsaImpegnato == nessuna)) {
    stepper->forceStop();           // forceStop == fermata immediata
    Serial.println("forceStop");

    datiAsse.comandoAttivo = false;
    datiAsse.finecorsaImpegnato = datiAsse.ultimaDirezione;
  }

  // rilascio finecorsa, resetto la memoria del finecorsa impegnato
  if (!finecorsaPremuto && (datiAsse.finecorsaImpegnato != nessuna)) {
    datiAsse.finecorsaImpegnato = nessuna;
    Serial.println("reset flag finecorsa");
  }

}



Avatar utente
leomonti
Senior
Senior
Messaggi: 2110
Iscritto il: mercoledì 20 dicembre 2006, 19:04

Re: Stepper e Arduino

Messaggio da leomonti » martedì 5 marzo 2024, 23:56

Ordino la Mega 2560 e provo tutto.
N.B. Aprire i file .md fuori da github è un discreto casino......Solo con Notepad++ son riuscito a mantenere una decente formattazione.
Il cervello è l'organo più sopravvalutato...(W.Allen)

Avatar utente
hellfire39
God
God
Messaggi: 3416
Iscritto il: domenica 16 dicembre 2012, 9:04
Località: AN

Re: Stepper e Arduino

Messaggio da hellfire39 » mercoledì 6 marzo 2024, 7:40

i file readme contengono dei tag per la formattazione.
È logico che se li apri con un editor di testo semplice, vedi parecchi caratteri strani.

Personalmente preferisco aprire direttamente la pagina di github, visto che il file readme è quello che viene visualizzato automaticamente in calce all'elenco dei file.
Non hai i permessi necessari per visualizzare i file e le foto allegati in questo messaggio. Per visualizzare tali file devi registrarti ed effettuare il Login

Avatar utente
leomonti
Senior
Senior
Messaggi: 2110
Iscritto il: mercoledì 20 dicembre 2006, 19:04

Re: Stepper e Arduino

Messaggio da leomonti » mercoledì 6 marzo 2024, 12:19

@hellfire39
- Dallo sketch non capisco la piedinatura del potenziometro
- Ma quell'avviso di "libreria rotta" lo devo considerare o no? Ho scaricato da lì il file zip contenente la libreria.
Il cervello è l'organo più sopravvalutato...(W.Allen)

Avatar utente
hellfire39
God
God
Messaggi: 3416
Iscritto il: domenica 16 dicembre 2012, 9:04
Località: AN

Re: Stepper e Arduino

Messaggio da hellfire39 » mercoledì 6 marzo 2024, 12:32

Se usi l'IDE di Arduino, lascia che sia arduino stesso a scaricare le librerie, non farlo a mano.
Apri il libray manager, utilizza la casella di ricerca per filtrare il contenuto e premi install.

Il potenziometro ha i due capi collegati a 0V e 5V e il cursore all'ingresso analogico che hai scelto (pin A0, nel mio codice).
Non hai i permessi necessari per visualizzare i file e le foto allegati in questo messaggio. Per visualizzare tali file devi registrarti ed effettuare il Login

Avatar utente
leomonti
Senior
Senior
Messaggi: 2110
Iscritto il: mercoledì 20 dicembre 2006, 19:04

Re: Stepper e Arduino

Messaggio da leomonti » mercoledì 6 marzo 2024, 13:19

Si, carico sempre le librerie dall'Ide, ma ho scaricato quello .zip per avere a disposizione il pacchetto. L'importante è che l'Ide lo vado a prelevare dal repository giusto..... :D :D
Il cervello è l'organo più sopravvalutato...(W.Allen)

Avatar utente
leomonti
Senior
Senior
Messaggi: 2110
Iscritto il: mercoledì 20 dicembre 2006, 19:04

Re: Stepper e Arduino

Messaggio da leomonti » lunedì 11 marzo 2024, 9:49

Oggi dovrebbe arriva la Arduino Mega. Nei prossimi giorni comincerò a sperimentare....
Il cervello è l'organo più sopravvalutato...(W.Allen)

Avatar utente
leomonti
Senior
Senior
Messaggi: 2110
Iscritto il: mercoledì 20 dicembre 2006, 19:04

Re: Stepper e Arduino

Messaggio da leomonti » lunedì 11 marzo 2024, 15:31

@hellfire39: sei poi riuscito a riscrivere lo sketch in modo che l'asse possa muoversi in direzione opposta a quella del limit impegnato?
Oggi è arrivata la Mega e vorrei incominciare gli esperimenti.
Il cervello è l'organo più sopravvalutato...(W.Allen)

Avatar utente
hellfire39
God
God
Messaggi: 3416
Iscritto il: domenica 16 dicembre 2012, 9:04
Località: AN

Re: Stepper e Arduino

Messaggio da hellfire39 » lunedì 11 marzo 2024, 15:45

L'ultima versione dello sketch che ho postato permette di disimpegnare il finecorsa muovendosi in direzione opposta.

Avatar utente
leomonti
Senior
Senior
Messaggi: 2110
Iscritto il: mercoledì 20 dicembre 2006, 19:04

Re: Stepper e Arduino

Messaggio da leomonti » lunedì 11 marzo 2024, 16:29

Lo sapevo che era superiore alle mie forze.....
Allora, la Mega2560 può usare, come out PWM, i pin da 2 a 13 (teoricamente, anche 14 e 15, ma pare sia problematico), quindi 3 motori step,dir,ena x 3 occupanpo 9 pin. E ci siamo.
Ma nello sketch vedo che sia i pulsanti per il movimento, sia i limiti vanno ad impegnare anch'essi in/out digitali. E i conti non tornano più....
Mi chiedo, almeno i fine corsa non possono essere letti dagli ingressi analogici A0-A15? Come pure i pulsanti movimento e potenziometro? (Si, vabbeh, quello è già su A0).
O per limit e pulsanti movimento posso usare i pin digitali non PWM da da 22 a 53?
Diversamente dovrò usare una Nano per ogni asse.....
Il cervello è l'organo più sopravvalutato...(W.Allen)

Avatar utente
hellfire39
God
God
Messaggi: 3416
Iscritto il: domenica 16 dicembre 2012, 9:04
Località: AN

Re: Stepper e Arduino

Messaggio da hellfire39 » lunedì 11 marzo 2024, 17:06

Aspetta, non facciamo confusione, io non ho mai detto "PWM"...
avr atmega2560: only Pin 6, 7 and 8. On platformio, this can be changed to other triples: 11/12/13 Timer 1, 5/2/3 Timer 3 or 46/45/44 Timer 5 with FAS_TIMER_MODULE setting.
FastAccelStepper ti impone di utilizzare dei pin specifici solo per le uscite STEP dei tre assi.

Tutti gli altri pin che possono essere utilizzati come digitali, li puoi utilizzare per le altre funzioni (DIR, ENABLE, pulsanti, finecorsa).
Se cerchi su google il pinout della MEGA, puoi vedere quali pin possono essere utilizzati come digitali (e sono davvero tanti).
Vedi ad esempio in fondo a questa pagina:

https://www.electronicshub.org/arduino-mega-pinout/

La legenda ti indica le funzioni associate ad ogni pin (in marrone DIGITAL PIN).

Rispondi

Torna a “Elettronica”