Profilo triangolare della velocità

Buonasera,

Sto utilizzando da diversi giorni un driver senza controller per motore passo-passo bipolare e dopo aver giocato con le variazioni di velocità, vorrei poter descrivere con il codice quanto riportato in oggetto.

Dopo aver letto varie cose , ho deciso di affidarmi a questo articolo :

http://www.linearmotiontips.com/how-to-calculate-triangular-trapezoidal-move-profile/

e quest’ altra pagina :
( http://www.womackmachine.com/)

Vorrei qui riportare i passaggi che sto implementando nell sketch sperando di confrontarli con qualcuno di voi.

Trovare velocità e accelerazione per un movimento di 200 passi in 3 secondi
Ovvero come far girarare il motorino di 180° ( 0.9°/step) in 3 secondi

Ho provato a ragionare in passi , non in gradi e non in radianti.

  • Step_totali = 400 passi
  • Accelerazione = - Deccelerazione
  • Interrupt Timer1
    L’interrupt del timer1 interviene ogni Dti (ms) ed esegue 1 passo. Il tempo tra un passo e l’altro determina la velocità del motorino, per cui Dti verrà calcolato in base alla velocità richiesta.

quindi osservando il grafico di cui sopra

=> X = 200 passi
=> T = 3 secondi

Vmax = 2Vavg = 2X/T = 2(200 passi/3 sec) = 133,3 passi /sec

ta = td = T/2 = 3sec/2 = 1,5 sec

A = -D = 2Vmax/T = 4X/T^2 = 200 passi*4/3^2 = 88,8 passi /sec^2

Dti = 1/133,3 = 0,0075 sec = 7,5ms

Quindi nel codice scriverò : Timer1.inizitialize(Dti);

Con quest’ultimo passaggio trovo ( senza considerare gli errori) quanti overflow devo contare prima di raggiungere la velocità richiesta.

Verifica:
dt = 1/2 T Vmax = 1/23s133,3 step/s = 1,5*133,3 = 199,5 ( circa 200)
A quella velocità raggiungo i 200 passi ( ovvero X ) in 3 secondi.

proseguo:
da = 1/2 ta Vmax = 1/2*(3s/2)*133,3 = 99,9 step → ‘acceleration distance’

Ora quello che non capisco è come implementare l’accelerazione A
e se ‘da’ si riferisce alla spazio percorsa durante l’accelerazione ? :confused:

Qualcuno di voi ha già provato ? avete qualche suggerimento ?
Grazie per qualsiasi delucidazione

C'è un errore di logica iniziale, non è che devi trovare velocità e accelerazione, devi decidere che accelerazione vuoi usare e quale velocità vuoi raggiungere, sono dati iniziali del problema e li devi stabilire tu, è possibile stabilire varie coppie di valori da usare a seconda delle condizioni operative.
Fatto quanto sopra, ogni volta che devi azionare il motore, tocca verificare se per percorrere una certa distanza, intesa come movimento espresso con l'unità di misura più adatta per il caso specifico, è possibile usare un profilo trapezoidale, accelerazione seguito da movimento a velocità costante e poi la decelerazione a zero, oppure serve solo una accelerazione, non fino alla velocità massima possibile/prevista, con subito dopo la decelerazione.

Grazie per aver risposto,forse ho capito, spero di non scrivere troppe cavolate:
Io impongo velocità e accelerazione secondo dei ragionamenti sul sistema precedenti , quindi trovo
il tempo e volendo anche lo spazio percorso ?


Tralasciando per un attimo limiti del motorino e del sistema in genere
scegliamo ( per ora a caso giusto per fare un esempio):

A = 88,8 passi/sec^2
Vmax = 133,3 passi/sec

mentre cerco:
X = ? (spazio percorso)
T = ? (tempo totale necessario per raggiungere Vmax)
da = ? ( è il numero di passi durante l’accelerazione)
Dti = ? ( quanto deve essere il mio overflow per rispettare i valori sopra richiesti e/o assunti ?)

Calcolo T
Siccome a = 2Vmax/T => T= 2Vmax/a = (2*133,3 passi/sec)/88 passi/sec^2
= 266,6/88 sec = 3 sec

Impiegherò quindi 3 sec per raggiungere 133,3 passi/sec con a = 88,8 passi/sec^2

Calcolo distanza percorsa
X = 1/2TVmax = 1,5*133,3 = 199 passi percorsi in 3 secondi

Calcola da
da = 1/2 TaVmax , dove Ta = 1/2T => da = 1/21,5133,3 = 99,9 passi
Calcolo Dti
mentre per raggiungere la velocità Vmax con l’accelerazione a , devo caricare il mio timer1 con Dti nuovo:
=>Dti = 3 sec/133,3 = 0,00225 sec = 22,5ms (Il nuovo overflow del mio timer)
Quindi dopo 3 sec dovrei raggiungere i 200 passi ,dovrei… :o con vmax = 133,3 passi/sec

Edit:
ma non credo sia giusto :slight_smile:
In realtà ci mette un pò piu di tempo
Mi sono accorto che devo anche considerare il tempo trascorso all’interno dell’interrupt,ma
sembra irrisorio

// timerIsr()  ovvero Dti

// ------------------------------// ------------------------------------------------
void timerIsr()
{
        passi++;         
                PORTB = (PORTB &~bitMask) |  modeF[id];
                id++;         
                if (id >3) id = 0;
       
}

Buonasera,

Avrei un'altra domanda :slight_smile:

Ho seguito questo articolo dell'atmel
http://www.atmel.com/images/doc8017.pdf - Linear speed control of stepper motor e mi sono aiutato anche con il codice di esempio anche se è stato scritto per il compilatore IAR.

Il codice è stato scritto per un quarzo 3,686Mhz mentre arduino monta un 16Mhz
Senza dilungarmi troppo il timer1 si occupa di ricalcolare il tempo di ogni step e di utilizzarlo per rimpostare ogni volta OCR1A.
Il timer1 è configurato in CTC mode con prescaler 1/8.
Il motorino accelera e deccelera ma devo aver fatto qualche errore perchè aggiornando OCR1A attraverso la scrittura diretta del registro il motorino sembra andare in "stallo"

mentre con

Timer1.initialize(srd.step_delay)

funziona anche se con una piccola escursione di valori.
Purtroppo non ho il datasheet del motorino essendo di recupero ma ho intenzione di comprarne uno nuovo.

Ora però mi viene un dubbio e chiedo a qualcuno di voi se ha già avuto esperienza in merito

In una applicazione di posizionamento il profilo della velocità è sufficiente per prevenire la perdita di passi oppure occorre per forza Anche aumentare la tensione di alimentazione e limitare conseguentemente la corrente come fa ad esempio questa scadina da voi già consigliata ?

Personalmente penso che dipende dalla caratteristiche del motorino e dal carico applicato e dalla velocità, ma ho il sospetto di avere anche questo problema :o :o

quindi dopo questa piccola esperienza con la keyes l298 sarei intenzionato a comprare un'altra

Voi cosa pensate ?:slight_smile:

grazie mille