Stepper e Arduino

Sezione dedicata all'elettronica in generale.
Rispondi
torn24
God
God
Messaggi: 5097
Iscritto il: venerdì 1 febbraio 2008, 11:28
Località: Modena

Re: Stepper e Arduino

Messaggio da torn24 » sabato 2 marzo 2024, 6:19

Quello + un potenziometro per la velocità. Ma, fondamentali, i limit...
Io non mi baserei sui finecorsa, che è una protezione utile ma, immagina di usare una cnc in MDI, non ti basi sul finecorsa non succede mai, imposti asse, avanzamento, e lunghezza da percorrere per uno specifico asse.

Un sistema con arduino, un display Lcd, un tastierino Keypad, due scermate menu, inserisco valore avanzamento, e inserisco asse e valore, valore positivo andrà in un verso, negativo in quello opposto.
Si cerca di fare con arduino e "elettronica", la funzione MDI di un cnc, se ci si accontenta di muovere un unico asse alla volta, e non 2 in contemporanea "interpolazione", penso che non presenti grandi difficoltà.
CIAO A TUTTI !

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

Re: Stepper e Arduino

Messaggio da leomonti » sabato 2 marzo 2024, 9:50

L'idea era quella di replicare i movimenti di avanzamento automatici tradizionali, e quindi, comandi analogici (il display, com dicevo è un optional da utilizzare solo per visualizzare il feed impostato). I fine corsa servono, eccome.
Se devo usare un sistema con interfaccia digitale, ed inserire ad ogni movimento i dati di corsa, feed, etc, come dicevo, sfrutto uno dei controller cnc che ho già con un display touch da 13" che ho già.
Il cervello è l'organo più sopravvalutato...(W.Allen)

torn24
God
God
Messaggi: 5097
Iscritto il: venerdì 1 febbraio 2008, 11:28
Località: Modena

Re: Stepper e Arduino

Messaggio da torn24 » sabato 2 marzo 2024, 13:04

Be io non ho visto solo macchine tradizionali o CNC ma tutto quello che c'è intermedio. :D
Restano memorizzati i valori precedenti, tre pulsanti per selezionare l asse x y o z, e inserire lunghezza. Stesso tempo di inserire un numero nella calcolatrice. Non ti convince perché non lo hai mai visto usato :) ma non mi interessa insistere...
CIAO A TUTTI !

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

Re: Stepper e Arduino

Messaggio da leomonti » sabato 2 marzo 2024, 13:41

@torn24
Per carità, ogni contributo è gradito e utile.
Mi par di capire che tu parli di un posizionatore.
Mi chiedo se, a quel punto, usando Arduino nel modo che tu suggerisci, non sia più sbrigativo ed altrettanto efficace usarlo con GRBL e UGS, sfruttando solo la parte MDI. E' già quasi tutto pronto e non devo inventarmi nulla.
Visto che ho tutto in casa, potrei usare il Raspberry col touch da 13" e CNCjs.
Dovrei, per comodità, riuscire ad implementare in GRBL i tasti fisici o un MPG pendant.
Mediterò....
Il cervello è l'organo più sopravvalutato...(W.Allen)

torn24
God
God
Messaggi: 5097
Iscritto il: venerdì 1 febbraio 2008, 11:28
Località: Modena

Re: Stepper e Arduino

Messaggio da torn24 » sabato 2 marzo 2024, 14:19

E' sicuramente piu sbrigativo e valido, è che con clone arduino, lcd i2c, keypad, costa meno di 20 euro, driver a parte.
CIAO A TUTTI !

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

Re: Stepper e Arduino

Messaggio da leomonti » sabato 2 marzo 2024, 14:21

Ho tutto in casa... :)
Il cervello è l'organo più sopravvalutato...(W.Allen)

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

Re: Stepper e Arduino

Messaggio da hellfire39 » sabato 2 marzo 2024, 17:45

Ho dato una occhiata alla libreria FastAccelStepper, cosa che volevo fare da un po' di tempo.
Rispetto alla libreria AccelStepper, riesce a generare frequenze più elevate, ed è più semplice da programmare.
Di contro, è più limitata nel numero di pin da utilizzare per il segnale step, in quanto utilizza delle funzioni speciali dei micro.
Questo significa che, con Arduino Uno o Nano, si possono pilotare al più due motori.
Con gli ESP32 non c'è questa limitazione.
Con Arduino MEGA o PRO MICRO, si possono pilotare fino a tre stepper.

Se ho capito bene, tu vorresti pilotare tre stepper.
Per ogni stepper:
- muovere il motore avanti/indietro fintanto che il relativo tasto è premuto;
- fermarsi immediatamente se viene impegnato un finecorsa;
- scegliere la velocità con un potenziometro (uno per tutti e tre i motori?)

È corretto?


P.S. La libreria FastAccelStepper permette di specificare una accelerazione, quindi la velocità viene raggiunta in modo graduale.

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

Re: Stepper e Arduino

Messaggio da leomonti » sabato 2 marzo 2024, 18:01

@hellfire39
Tutto corretto.
Che i potenziometri siano tre o uno è "quasi" indifferente. Se sono 3, magari, non devo cambiare velocità dell'asse a seconda di quello scelto.
Se è uno, se possibile, si potrebbe usare una sola terna di pulsanti avanti-stop-indietro con un selettore per gli assi.
Vedi tu come riesci meglio.
Se serve una Mega la prendo. Di ESP32 non saprei cosa prendere. Hai una indicazione?
Il cervello è l'organo più sopravvalutato...(W.Allen)

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

Re: Stepper e Arduino

Messaggio da hellfire39 » sabato 2 marzo 2024, 18:28

Boh?
Se non ho particolari esigenze (tipo ultra-low power per applicazioni a batteria), io vado su Amazon e ne scelgo una quasi a caso, spesso più per il prezzo e il tempo di consegna che per altro.
Tempo fa ho preso il modello di AZDelivery (il primo risultato che mi viene fuori cercando "esp32", ma non penso ci siano differenze sostanziali con altri modelli).

LA ESP32 consente frequenze più elevate rispetto a pro-micro e MEGA.
Attenzione però che lavora a 3,3V e bisogna vedere se sono suficienti per pilotare i fotoaccoppiatori dei driver, altrimenti ci devi mettere almeno un transistor in mezzo.

Nel frattempo ti metto qui un esempio con cui stavo sperimentando oggi pomeriggio (in questo caso il motore parte quando si preme il tasto ma poi continua a muoversi anche dopo averlo rilasciato, è solo una prova veloce che ho fatto per capire il funzionamento della libreria).

Codice: Seleziona tutto

#include "FastAccelStepper.h"

// As in StepperDemo for Motor 1 on AVR
//#define dirPinStepper    5
//#define enablePinStepper 6
//#define stepPinStepper   9  // OC1A in case of AVR

// As in StepperDemo for Motor 1 on ESP32
#define dirPinStepper 2
#define enablePinStepper 4
#define stepPinStepper 9
#define blueButton 7
#define grayButton 6
#define HARDLIMIT 8

FastAccelStepperEngine engine = FastAccelStepperEngine();
FastAccelStepper *stepper = NULL;

void setup() {
  Serial.begin(115200);

  pinMode(blueButton, INPUT_PULLUP);
  pinMode(grayButton, INPUT_PULLUP);
  pinMode(HARDLIMIT, INPUT_PULLUP);

  engine.init();
  stepper = engine.stepperConnectToPin(stepPinStepper);
  if (stepper) {
    stepper->setDirectionPin(dirPinStepper);
    stepper->setEnablePin(enablePinStepper);
    stepper->setAutoEnable(true);

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

    stepper->setSpeedInUs(1000);  // the parameter is us/step !!!
    stepper->setAcceleration(3000);
    //stepper->move(1000);
  }
}

void loop() {
  if (digitalRead(blueButton)==LOW) {
    stepper->setSpeedInUs(100);
    stepper->runBackward();
    Serial.println("backward");
  }

  if (digitalRead(grayButton)==LOW) {
    stepper->setSpeedInUs(200);
    stepper->runForward();
    Serial.println("forward");
  }

  if (digitalRead(HARDLIMIT) == LOW)
    stepper->forceStop();                  // forceStop == fermata immediata

}

torn24
God
God
Messaggi: 5097
Iscritto il: venerdì 1 febbraio 2008, 11:28
Località: Modena

Re: Stepper e Arduino

Messaggio da torn24 » domenica 3 marzo 2024, 7:10

A me era venuta l'idea del "posizionatore X Y Z" , Ma non mi era mai capitato di fare una cosa simile, allora nel dubbio per essere sicuro che sarei in grado di farlo, mi sono messo a provarci. A volte penso che sarebbe facile una cosa, poi basta un dado che non si svita e diventa impossibile.

Non so se è stata abbandonata l'idea del posizionatore con arduino, se interessa a qualcuno sono lieto di postare il codice, che non posso provare quindi potrebbe avere innumerevoli errori. Se non interessa fa lo stesso.
CIAO A TUTTI !

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

Re: Stepper e Arduino

Messaggio da hellfire39 » domenica 3 marzo 2024, 8:11

@torn24
che cavolo ci fai con un "posizionatore XYZ" con Arduino, quando esiste grbl?

torn24
God
God
Messaggi: 5097
Iscritto il: venerdì 1 febbraio 2008, 11:28
Località: Modena

Re: Stepper e Arduino

Messaggio da torn24 » domenica 3 marzo 2024, 8:21

Per me, nel senso cosa ci faccio io :D
L'ho fatto io ho una piccolina soddisfazione "mi accontento di poco", uso la fresatrice non come cnc ma forse rudimentale cn prima dei microprocessori, spendo poco perché non ho bisogno di computer o schermo ma scheda da pochi euro e lcd. Per esigenze in MDI sarei molto abile nell'usarlo, molto simile a macchina manuale, sei qui spostati di 100 mm da qui.

Poi se agli altri non serve, non piace, non insisto, ho offerto come un biscotto se non lo vuoi fa lo stesso non mi offendo :D
CIAO A TUTTI !

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

Re: Stepper e Arduino

Messaggio da leomonti » domenica 3 marzo 2024, 8:45

@hellfire39
Va benissimo start con il pulsante , purchè ci siano anche lo stop e il reverse. Diversamente ci vuole il commutatore a 3 posizione on-off-on DPDT
Non voglio complicazioni con i 3.3 V, per cui, scartiamo ESP32.

@torn24
posta pure il codice. Lo carico e lo provo volentieri
Il cervello è l'organo più sopravvalutato...(W.Allen)

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

Re: Stepper e Arduino

Messaggio da hellfire39 » domenica 3 marzo 2024, 8:56

@torn24
un biscotto abbastanza avariato, direi... :mrgreen:

@leomonti

ti metto il codice per un singolo asse. Stammattina non riesco a mettere tutti e tre gli assi, ma basta copiare il codice ed adattare gli ingressi e le uscite.
Ho aggiunto l'uso della libreria "bounce2" per avere un antirimbalzo sui pulsanti.
Metterei l'antirimbalzo anche sui finecorsa, in quanto potresti avere degli stop non voluti per dei disturbi (bastano anche pochi ms).
Hai due pulsanti, uno per avanti e uno per indietro. Puoi sostituirlo con un selettore a tre posizioni.

Purtroppo, se vuoi gestire 3 assi con velocità decenti, sei obbligato ad andare su ESP32.
Ma valuta tu la velocità che devi raggiungere.
Qui
https://github.com/gin66/FastAccelStepper
hai le informazioni sulle performance raggiungibili. Hai 20000 impulsi/secondo con tre stepper utilizzandoPRO MICRO mentre hai 200000 impulsi/secondo con ESP32.
Magari ti consiglio di non impostare più di 1000 o 1600 micropassi, ma non scendere sotto gli 800.

Come già scritto, con la libreria FastAccelStepper, gli assi hanno accelerazione e decellerazione, quindi riesci a raggiungere velocità superiori senza il rischio che i motori stallino.
Questa istruzione
stepper->setAcceleration(10000);
in setup() ti permette di specificare l'accelerazione in impulsi al secondo quadro.

Codice: Seleziona tutto

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

#define dirPinStepper 2
#define enablePinStepper 4
#define stepPinStepper 9
#define blueButton 7
#define grayButton 6
#define HARDLIMIT 8


FastAccelStepperEngine engine = FastAccelStepperEngine();
FastAccelStepper *stepper = NULL;

Bounce2::Button buttonXplus = Bounce2::Button();
Bounce2::Button buttonXminus = Bounce2::Button();


void setup() {
  engine.init();
  stepper = engine.stepperConnectToPin(stepPinStepper);
  if (stepper) {
    stepper->setDirectionPin(dirPinStepper);
    stepper->setEnablePin(enablePinStepper);
    stepper->setAutoEnable(true);

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

    stepper->setSpeedInUs(1000);  // the parameter is us/step !!!
    stepper->setAcceleration(10000);
  }

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

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

  // volendo, si può utilizzare bounce anche per i finecorsa
  pinMode(HARDLIMIT, INPUT_PULLUP);

  Serial.begin(115200);

}


bool XisMoving = false;  // evita che sia inviato ripetutamente il comando
bool YisMoving = false;
bool ZisMoving = false;

void loop() {
  // lettura potenziometro la velocità in uscita va da 50 us a impulso a 1000 us a impulso
  int speedIn = analogRead(A0);
  uint32_t speedStep = map(speedIn, 1023, 0, 50, 1000);

  // aggiorna lo stato dei pulsanti
  buttonXplus.update();
  buttonXminus.update();

  // se il pulsante X+ è premuto, muovo in avanti
  if (buttonXplus.isPressed() && !XisMoving) {
    stepper->setSpeedInUs(speedStep);
    stepper->runForward();
    Serial.println("forward");
    XisMoving = true;
  }

  if (buttonXminus.isPressed() && !XisMoving) {
    stepper->setSpeedInUs(speedStep);
    stepper->runBackward();
    Serial.println("backward");
    XisMoving = true;
  }

  if ((!buttonXplus.isPressed()) && (!buttonXminus.isPressed()) && XisMoving) {
    stepper->stopMove();            // stop con decellerazione
    Serial.println("stopMove");
    XisMoving = false;
  }
  
  if (digitalRead(HARDLIMIT) == LOW) {
    stepper->forceStop();           // forceStop == fermata immediata
    Serial.println("forceStop");
    XisMoving = false;
  }
}

torn24
God
God
Messaggi: 5097
Iscritto il: venerdì 1 febbraio 2008, 11:28
Località: Modena

Re: Stepper e Arduino

Messaggio da torn24 » domenica 3 marzo 2024, 10:36

Questo è il codice, ho corretto i BUG e compila senza errori, ma questo vuol dire solo che il linguaggio va bene, "quello che si dice con il linguaggio" potrebbe essere tutto sbagliato, un po come quando dico cazzate ma le parole sono giuste :D
Per le librerie mi sono basato sugli esempi perché non le uso e quindi non le ricordo a memoria.
La libreria lcd I2C non l'ho trovata con gestione librerie si vede che è una libreria vecchia, sono andato a cercare download zip.

La parte fisica è composta da LCD I2C, keypad numeri e caratteri A B C D, scheda compatibile arduino cha abbia almeno 17 pin digitali.


Il principio è questo,

1)Accendo il sistema, almeno una volta premo il tasto D del tastierino, e inserisco un valore di avanzamento F in millimetri al minuto
Resta memorizzata l'ultima F avanzamento inserito, per cui se non devo modificare dopo la prima volta non devo piu inserirlo.
2) Ho i pulsanti A B C sul tastierino, corrispondono alla selezione degli assi rispettivamente X Y X
3) Seleziono un asse e inserisco il valore di spostamento, positivo o negativo relativo, dal punto in cui si trova nel verso degli assi cartesiani completi x+ x- y+ y-


Preciso che il tasto cancelletto deve essere premuto per conferma "invio" dopo inserimento di valore numerico.
Valore positivo o negativo, sarà in un verso e nel verso opposto, ma poi dipende dai collegamenti se corrisponde a positivo e negativo degli assi cartesiani.

Ecco biscottino, se non funziona ma si puo correggere non è avariato, se non puo mai funzionare allora sono d'accordo che è avariato e da buttare, comunque non sono un pasticciere non si puo pretendere che sia sempre buono :D

Codice: Seleziona tutto

/* Un posizionatore fresatrice per gli assi X Y Z
Il pricipio è questo, sono su un punto sulla tavola è l'origene assi cartesiani 
Decido in che direzione mi devo spostare X+ X- Y+ Y-

Premo pulsante asse sul tastierino, e inserisco spostamento, positivo o negativo a seconda del verso.
il canencelleto nel tastierno è tato conferma.
*/





#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>
#include <Keypad.h>

#define PASSIAMM 100  //Quanti step per spostamento di un mm IN BASE a step e meccanica
// i pin della sceda mettere numero pin effettivamente utilizzato
#define STEPPIN1 11
#define DIRPIN1 10
#define STEPPIN2 9
#define DIRPIN2 8
#define STEPPIN3 7
#define DIRPIN3 6
#define XBUTTON 5
#define YBUTTON 4
#define ZBUTTON 3


AccelStepper stepper1(AccelStepper::DRIVER, STEPPIN1, DIRPIN1);
AccelStepper stepper2(AccelStepper::DRIVER, STEPPIN2, DIRPIN2);
AccelStepper stepper3(AccelStepper::DRIVER, STEPPIN3, DIRPIN3);

// Scegliere indirizzo giusto lcd
LiquidCrystal_I2C lcd(0x3f, 16, 2);
const byte ROWS = 4;
const byte COLS = 4;

char hexaKeys[ROWS][COLS] = {
  { '1', '2', '3', 'X' },
  { '4', '5', '6', 'Y' },
  { '7', '8', '9', 'Z' },
  { '.', '0', '#', 'D' }  // Ho sostituito * con il punto per numeri decimali, * su tastiera corrisponte a .
};

byte rowPins[ROWS] = { 9, 8, 7, 6 };  // METTERE I PIN USATI DAL KEYPAD
byte colPins[COLS] = { 5, 4, 3, 2 };

Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);


void setup() {
  lcd.begin(16, 2);
  pinMode(STEPPIN1, OUTPUT);
  pinMode(DIRPIN1, OUTPUT);
  pinMode(STEPPIN2, OUTPUT);
  pinMode(DIRPIN2, OUTPUT);
  pinMode(STEPPIN3, OUTPUT);
  pinMode(DIRPIN3, OUTPUT);
  pinMode(XBUTTON, INPUT_PULLUP);
  pinMode(YBUTTON, INPUT_PULLUP);
  pinMode(ZBUTTON, INPUT_PULLUP);

  // impostare valori accelerazione e maxspeed adatti 
  stepper1.setMaxSpeed(200.0);
  stepper1.setAcceleration(200.0);
  stepper2.setMaxSpeed(200.0);
  stepper2.setAcceleration(200.0);
  stepper3.setMaxSpeed(200.0);
  stepper3.setAcceleration(200.0);
}
char stato = 0;
char AsseSelezionato = 'X';
float Avanzamento = 0;
float spostamento = 0;
void loop() {


  if (digitalRead(XBUTTON) == LOW) {
    AsseSelezionato = 'X';
    stato = 1;
  } else if (digitalRead(YBUTTON) == LOW) {
    AsseSelezionato = 'Y';
    stato = 2;

  } else if (digitalRead(ZBUTTON) == LOW) {
    AsseSelezionato = 'Z';
    stato = 3;
  }

  //Impostazione avanzamento F solo se si preme tasto D tastierino TASTIERNO CON LETTERE A=x B=y C=z D
  if (customKeypad.getKey() == 'D') {
    display("cancella");
    display("F= ");
    Avanzamento = tastierino();

    // Calcolo velocita passi al secondo corrispondente ad avanzamento impostato in MM al minuto F
    // Millimetri al minuto/60=millimetri al secondo / passi a millimetro
    Avanzamento = (Avanzamento / 60) / PASSIAMM;
                                         
    //Imposto velocita setSpeed sui tre motori
                                         
    stepper1.setSpeed(Avanzamento);
    stepper2.setSpeed(Avanzamento);
    stepper3.setSpeed(Avanzamento);
  }
  switch (stato) {
    case 1:
      display("cancella");
      display("X= ");
      spostamento = tastierino();
      stato = 4;
    case 2:
      display("cancella");
      display("Y= ");
      spostamento = tastierino();
      stato = 4;
    case 3:
      display("cancella");
      display("Z= ");
      spostamento = tastierino();
      stato = 4;
    case 4:
      //In base all'asse selezionato con i pulsanti, comanda il movimento del driver associato
      if (AsseSelezionato = 'X') {
        stepper1.move((int)(spostamento * PASSIAMM));



      } else if (AsseSelezionato = 'Y') {
        stepper2.move((int)(spostamento * PASSIAMM));



      } else if (AsseSelezionato = 'Z') {
        stepper3.move((int)(spostamento * PASSIAMM));
        
      }
      stato = 0;  // In stato di attesa nuovo comando
  }

  //NEL loop richiamo continuamente il movimento dei motori
  stepper1.runSpeed();
  stepper2.runSpeed();
  stepper3.runSpeed();
}


void display(char* s) {
  if (strcmp(s, "cancella") == 0) {
    lcd.clear();
    lcd.setCursor(0, 1);
  }

  lcd.print(s);
}


float tastierino() {
  //Premere il tato cancelleto una volta terminato insermento dei valori numerici
  char carattere;
  char stringa[20];
  int i = 0;
  do {
    carattere = customKeypad.getKey();
    if (carattere != NO_KEY) {
      stringa[i++] = carattere;
      display(carattere);
    }


  } while (carattere != '#');

  stringa[--i] = '\0';
  return atof(stringa);
}



CIAO A TUTTI !

Rispondi

Torna a “Elettronica”