Motore Stepper e rampe accelerazione/decelerazione

Ciao a tutti,

mi ritrovo con un "problema" da risolvere...
ho:

Arduino nano
DRV8825
Stepper 17 da 400 step

come codice per muovere il motore utilizzo un semplice ma efficace ciclo:

     while (a < passo && digitalRead(limitSwitches) == HIGH)
    {
      digitalWrite(doStep, HIGH);   
      digitalWrite(doStep, LOW);
      delayMicroseconds (ASpeed / steps);  
      a = a + 1;
    }

dove "passo" è il mio incremento e la velocità del motore è calcolata dalla formula (ASpeed / steps)

il progetto consiste nel muovere un asse tramite una vite a ricircolo di sfere con passo 6.0mm e 1.0mm
l'incrementi partono da 0.02mm e vanno al massimo 0,80mm

diciamo che va tutto bene ma ora vorrei affinare e rendere questi movimenti più dolci con delle rampe...

ho provato varie librerie e varie impostazioni ma i movimenti mi risultano sempre "nervosi"...
e comunque utilizzarle mi complicherebbe la gestione di vari calcoli che non stò a spiegarvi per non dediarvi...

quindi in sintesi esiste un modo magari già collaudato dove con delle variabili/contatori si può modificare la parte di codice che vi ho allegato?

grazie mille per qualsiasi dritta
Roberto

>0101001000: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice (... e la cosa vale anche per una sola riga) all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

gpb01:
>0101001000: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice (... e la cosa vale anche per una sola riga) all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

Ciao Guglielmo,
scusate e spero di aver fatto giusto...

0101001000:
scusate e spero di aver fatto giusto...

Guglielmo

0101001000:
velocità del motore è calcolata dalla formula (ASpeed / steps)

Purtroppo ho le batterie scariche nella sfera di cristallo e posso solo provare ad indovinare cosa siano precisamente ASpeed e steps, comunque...

0101001000:
quindi in sintesi esiste un modo magari già collaudato dove con delle variabili/contatori si può modificare la parte di codice che vi ho allegato?

Può andare qualcosa così?

int rallenta_da_qui = 200; // step mancanti all'arrivo
int non_rallentare_troppo = 2; // costante per avere una v_min non tendente a zero
while (a < passo && digitalRead(limitSwitches) == HIGH)
    {
      	digitalWrite(doStep, HIGH);   
      	digitalWrite(doStep, LOW);
  	if ( a  < (passo - rallenta_da_qui)){
		delayMicroseconds( (ASpeed / steps));
	} else {		
		delayMicroseconds( (ASpeed / steps) * ( passo - rallenta_da_qui + non_rallentare_troppo) / (passo - a + non_rallentare_troppo) );  
  	}
	a = a + 1;
}

Questo ti dovrebbe generare una rampa di decelerazione, per l'accelerazione il discorso è "simmetrico", basta aggiungere un altro caso all'IF per quando "a" è tra zero e "rallenta_da_qui", che in questo caso sarebbe più corretto chiamare "accelera fino a qui". :slight_smile:

PS: i valori 200 e 2 sono buttati proprio a caso, eh!

Ciao daysleeper...

grazie mille per la risposta...:

faccio dei test nel fine settimana e ti faccio sapere se "siamo" sulla giusta strada...

tante grazie ancora
Roberto

Ciao,
nel WK ho fatto i test e devo dire che funziona bene... ho fatto alcune prove e i risultati sono molto simili (noise)
a quelli della libreria Accelstepper...

ho modificato e aggiunto una variabile per "dividere" i miei passi da fare in accelerazione, velocità normale, decelerazione...

i test gli stò facendo al 33% ma poi vedrò se modificarli o meno
adesso con lo stesso principio mi rimane da mettere a posto i movimenti "manuali"

dove, tramite due pulsanti, che finché sono premuti la slitta mi smuoverà o in un senso o nell'altro...

ancora una domanda se posso:
esiste un tutorial o spiegazioni su come gestire al meglio le rampe con Arduino/driver/stepper?

grazie ancora per i suggerimenti
Roberto

0101001000:
esiste un tutorial o spiegazioni su come gestire al meglio le rampe con Arduino/driver/stepper?

Sicuro.

Comunque la libreria AccelStepper ti potrebbe semplificare molto la vita: si chiama accelstepper e non solo stepper per un motivo! :slight_smile:

daysleeper:
Sicuro.

Comunque la libreria AccelStepper ti potrebbe semplificare molto la vita: si chiama accelstepper e non solo stepper per un motivo! :slight_smile:

Ciao e grazie per il costante aiuto...

non l'ho usata per due motivi:

  1. all'inizio mi sembrava, per i miei scopi, non adatta in quanto i movimenti erano molto "nervosi" poi facendo varie prove e settaggi vari ho risolto abbastanza
  2. ho il "problema" che devo muovere, tramite due pulsanti, in avanti ed indietro una slitta
    deve muoversi solo quando i pulsante è premuto, quando lo rilascio deve fermarsi... con l'AccelStepper non riesco a gestire le rampe, o meglio io non ci sono riuscito...

grazie ancora
Roberto

Di niente.
Ma mi sa che non hai letto bene la sua documentazione perchè entrambe i punti che hai scritto sono gestibilissimi. O, almeno, lo erano anni fa quando l'ho usata, non ho progetti stepper sottomano ora, ma non credo sia cambiato tanto.

Per la gestione della "nervosità" dei movimenti hai:

stepper.setMaxSpeed(xxx);
stepper.setAcceleration(yyy);

Per il comando con i bottoni hai:

stepper.run();
stepper.stop();

Aiutandoti a definire la direzione con uno "stepper.moveTo(step_sicuramente_oltre_gli_endstop);" da impostare alla pressione del pulsante, in una dozzina di righe avevi fatto tutto.

Ciao e grazie ancora...

si ho utilizzato i due parametri da te indicati ma probabilmente i piccoli movimenti che devo fare inducono "vibrazioni" al motore... sono migliorabili e alla fine il risultato che ottengo è pari pari al tuo codice

per il movimento "manuale" ho provato come da te detto ma se non ricordo male (ho provato svariati programmi e impostazioni) mi sembra che lo stop "freni di blocco" il motore e non decelerando... oppure c'era un qualcosa che non faceva al mio caso...

comunque se con la libreria c'è una soluzione ottimale "BENINO" ma siccome dovrei riscrivere una miriade di variabili e relativi calcoli preferirei rimanere sul codice che attualmente utilizzo...

grazie Roberto

0101001000:
mi sembra che lo stop "freni di blocco" il motore e non decelerando...

In teoria no, se imposti un valore di accelerazione il vincolo viene rispettato anche nello stop.

0101001000:
preferirei rimanere sul codice che attualmente utilizzo...

Figurati, sono scelte, solo occhio che se aggiungi un asse poi non funziona più niente: delayMicroseconds è bloccante.

daysleeper:
In teoria no, se imposti un valore di accelerazione il vincolo viene rispettato anche nello stop.

Figurati, sono scelte, solo occhio che se aggiungi un asse poi non funziona più niente: delayMicroseconds è bloccante.

ho solo un asse.. il mio "sistema" comanda una slitta per il Focus Stack (macro fotografia)

con tutto quello che ho provato nell'ultima settimana magari ho fatto casino... stasera riprovo e se va magari riscrivo tutto da capo ma ti fischieranno parecchio le orecchie... HEHEHE

grazie
Roberto

Dipende da come vuoi che agiscano i pulsanti per il comando manuale.

Ovviamente il programma non può sapere quando rilascerai il pulsante, quindi se vuoi che il moto si arresti al momento del rilascio, non potrai avere decelerazione. A meno che tu non intenda arrestarlo "dopo X passi" successivamente al rilascio del pulsante, ma trattandosi di una messa a fuoco probabilmente rilasci quando vedi che sei alla giusta distanza.
In questo caso, potresti fare procedere il motore avanti di X passi dopo il rilascio facendolo fermare con la rampa e poi lo fai indietreggiare di X passi compiendo questo spostamento con le due rampe.

paulus1969:
Dipende da come vuoi che agiscano i pulsanti per il comando manuale.

Ovviamente il programma non può sapere quando rilascerai il pulsante, quindi se vuoi che il moto si arresti al momento del rilascio, non potrai avere decelerazione. A meno che tu non intenda arrestarlo "dopo X passi" successivamente al rilascio del pulsante, ma trattandosi di una messa a fuoco probabilmente rilasci quando vedi che sei alla giusta distanza.
In questo caso, potresti fare procedere il motore avanti di X passi dopo il rilascio facendolo fermare con la rampa e poi lo fai indietreggiare di X passi compiendo questo spostamento con le due rampe.

Ciao e grazie anche a te per l'aiuto...
si è tutto corretto... ora stò usando il "sistema" con fermo immediato ma vorrei implementarlo con appunto queste benedette rampe (che tanto mi stanno facendo impazzire)... che poi se sforo il traguardo è un bene
dato che è sempre preferibile, in questo caso averlo oltrepassato che esserei fermati un "centimetro" prima

e comuqneu potrei "decidere" di quanto accelerare e decellerare... ma devo riuscirci... piccolo/grande problema...

P.S. con le Accelstepper non si riesce in "manuale" a fermarsi con la decelerazione... sempre se non ho fatto errori di codice

Anche con la accelstepper, per usare le due rampe in avvio ed arresto, devi sapere prima quanta strada farai; la libreria calcola i profili in base allo spostamento totale ed ai parametri maxspeed ed accel che imposti.
Ma in certi casi puoi anche muoverti passo dopo passo.

Ecco come lo farei io:

Metti un sensore di distanza (o due, uno ultrasonico ed uno ottico per la regolazione fine) che ti misura la distanza dell'oggetto da fotografare, in base a quella fai lo spostamento principale, poi passi ad un valore di microstep più fine in modo da fare piccoli spostamenti più precisi. Alcuni stepper controller ti permettono di variare via software il valore del parametro microstep (ed anche altre cose come la corrente del motore).

ATTENZIONE, per la parte relativa a software, questa discussione prosegue nella sezione Software.

Qui solo discussione sull'hardware. Grazie.

Guglielmo