home | area personale         schemi | tutorial | robotica | pic micro | recensioni         forum | chat irc         faq | contatti         store | Ordina PCB
username
password
cerca

 
FORUM: Pic Micro
Tutto quanto riguarda questi microprocessori... progetti, suggerimenti, aiuti, discussioni...ecc


Controllo motore passo passo
     
Autore Messaggio opzioni
Vidica





postato il:
23.08.2016, alle ore 20:29
Controllo motore passo passo 

Buonasera,

Sono nuovo del forum , mi sono presentato poc'anzi.
Ho creato il topic qui , ma spero di non aver sbagliato perchè la domanda che sto per fare tratta la programmazione in C per microcontrollori ma non pic , bensì atmel (arduino). Visto che tale concetto è valido per tutti i micro , ho scelto questa sezione.
Ora mi spiego:

Ho fatto semplicemente muovere un motorino passo passo con un driver L298.
Fin qui tutto bene, il motorino compie movimenti di n gradi ogni volta che è necessario.
Il vero problema è farlo accelerare gradualmente per evitare che perda i passi.
Il motorino è un bipolare a 9V che viene pilotato alimentando due fasi per volta rispettando la giusta sequenza.
Ora a prescindere per quale micro è indirizzato questo sorgente , posto il codice in C. La mia domanda è quindi sul moto uniformemente accelerato , su un motorino stepper ed il codice in C.


vel = 4000;
while (true)
{
      step(id);  
      id++; 
      if (id >3) id = 0;
      delayMicroseconds(vel);
      vel--;
}


Il codice non fa altro che muovere in senso orario il motorino.
id rappresenta l'indice di una array dove sono memorizzati i byte da inviare alla porta per far girare il motorino

byte avanti[] = {B00000101, B00000110, B00001010, B00001001};    // Avanti.
byte indietro[] = {B00001001, B00001010, B00000110, B00000101};    // Indietro.


Terminata la sequenza id viene azzerata per riprendere il ciclo.

delayMicroseconds(vel);

delayMicroseconds() rappresenta il tempo o pausa tra un passo è l'altro
Infatti l'array contiene un byte per passo , con le dovute sequenze. (4)
Il ritardo è pari a
vel
il quale variando , varia le velocità.

Qui la mia domanda:
Il codice sopra anche se non completo , mi permette di variare la velocità arrivando con 'val' fino a meno di 1000us. Se impostassi 1000us da subito il motorino impazzirebbe.

Come faccio a variare l'accelerazione ?Sto confondendo accelerazione con velocità.
Non sto chiedendo il codice , ma un aiuto nel ragionamento.
Se è vero che l'accelerazione non è altro che la variazione della velocità (v2-v1)per ogni secondo per un certo lasso di tempo (t2-t1) , esempio:

V0 = velocità iniziale = 0 step/sec (zero)

Se dovessi imprimere una accelerazione di 25 step/sec^2 per 5 secondi, la velocità aumenterebbe di 25 passi ogni secondo per 5 secondi ?

Scusate la lunga introduzione, qualcuno di voi ha mai provato con microcontrollore ed un driver l298 ?


agric





postato il:
23.08.2016, alle ore 21:51
Devi modificare il valore de VEL nella delayMicroseconds(vel);
Se vuoi accelerare diminuisci vel mentre per rallentare lo aumenti
Le variazioni maggiori imprimono più accel/decel . I passo passo soffrono l\'eccesso di accelerazione al punto di perdere il passo o di fermarsi


sistemato
roberto



meglio essere un granello di pepe che una cacca d'asino
Vidica





postato il:
24.08.2016, alle ore 00:04
Buonasera Agric,
Grazie credo di aver capito. Il prossimo passo sarebbe quello di applicare la legge
del moto per determinare l'accelerazione in base al tempo e allo spazio.
Quest'ultimo l'ho interpretato come il numero di Step.
Considerare eventuale velocita' iniziale ecc.

Visto che mi ha gentilmente risposto , riporto il codice
Non calcola l'accelerazione in base al tempo o spazio, è giusto una prova
con delle costanti casuali

void loop()
{
        
      step(id);  
      id++; 
      if (id >3) id = 0; 
      delayMicroseconds(vel);
      ;
      // Aggiorna uno step ogni Delay(ms) : Velocità
        Serial.print("Delay -->");
        Serial.println(vel);
        
      // Quanto dura l'accelerazione ( 9 secondi)
        Serial.print("Tempo -->");
        Serial.println(tme);
        
      // accelerazione
        Serial.print("Accelerazione ---->");
        Serial_print_Float(acc,10);


}
// timerIsr() // overflow ogni 1 ms
// --------------------------// --------------------------
void timerIsr()
{
     tmr++; // tempo
     if (tmr<9000) {  acc =5; vel -=acc;} //ogni ms decrementa di 5us la velocità per 9 secondi
            else
            {
              acc = 0; // scaduti i 9 secondi , stop accelerazione 
            }

     if (vel< 1000) tmr = 9000; // non avendo fatto nessun calcolo , se raggiunge la velocità massima forza l'accelerazione a zero
}


Per quanto riguarda la perdita del passo credo sia da imputare all corrente che viene limitata dagli avvolgimeni essendo induttori.
Ho letto infatti che ci sono tre modi per pilotare uno stepper:

1) gestire l'accelerazione come sto cercando di fare io
2) sovralimentare il motorino e dimensionare due resistenze sulle fasi ( ma non so come)
3) il terzo è la regolazione di corrente (chopper) ma occorre un feedback dal motorino
Vidica





postato il:
24.08.2016, alle ore 00:06
c'e un errore nel Serial.Print() si chiama tmr non tme :)
agric





postato il:
24.08.2016, alle ore 12:33
guardiamo il software...lo potresti spiegare a parole qual'è il risultato che ti aspetti ?
osservazioni:
- Vel in delayMicroseconds(vel) valore iniziale ? (poco importante)
- ogni quanto tempo VEL viene caricata nella delayMicroseconds(vel) ?
- qual'è la variazione di valore tra la prima delayMicroseconds(vel) e le successive delayMicroseconds(vel) ? Prova a fare una tabella

A prescindere dal modo in cui sceglierai di gestire il P/P (1,2,3) le rampe di acc/dec saranno obbligatorie per raggiungere determinate prestazioni e precisione nei posizionamenti con alte velocità angolari.



meglio essere un granello di pepe che una cacca d'asino
pippodue




una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli una ogni 10 livelli


postato il:
24.08.2016, alle ore 18:48
Vel non e' la velocita' ma il tempo fra due step successivi, cioe' si tratta del reciproco della velocita' a meno di una costante di proporzionalita'. Se vuoi una accelerazione costante devi istituire un'altra variabile che rappresenti davvero la velocita', incrementare quella e poi farne il reciproco. Ovviamente se usi variabili intere devi partire da un valore grande e poi dividere.


anche i grandi uomini, come gli uomini comuni, possono talvolta cadere in errore (Voltaire)
Vidica





postato il:
25.08.2016, alle ore 00:45
agric:
guardiamo il software...lo potresti spiegare a parole qual'è il risultato che ti aspetti ?
osservazioni:
- Vel in delayMicroseconds(vel) valore iniziale ? (poco importante)
- ogni quanto tempo VEL viene caricata nella delayMicroseconds(vel) ?
- qual'è la variazione di valore tra la prima delayMicroseconds(vel) e le successive delayMicroseconds(vel) ? Prova a fare una tabella

A prescindere dal modo in cui sceglierai di gestire il P/P (1,2,3) le rampe di acc/dec saranno obbligatorie per raggiungere determinate prestazioni e precisione nei posizionamenti con alte velocità angolari.


Buonasera , il risultato che mi aspetto o che cerco e basato su questa idea:
Ho montato sull'albero del motorino un sensore che misura la distanza con il metodo "time to fly".Ho una versione di codice che mi legge la distanza quando incontra un ostacolo.La distanza viene letta ad ogni passo ( 0,9DEG).
Il motorino è fissato su una base e compie una escursione di 180 DEG ( 200 passi).Quindi "fa uno scan" alla ricerca di un ostacolo.
Aumentando la velocità di scan, il motorino perde passi , sopratutto sul cambio di direzine ovvero quando da 180DEG compiuti inizia a decrementare verso lo zero( 180,179,178,177 eccc). Documentandomi ho letto che è una cosa normale risolvibile variando l'accelerazione ad ogni cambio di direzione (il passaggio da destra a sinistra e da sinistra a destra).
Ora per semplicità ho creato un codice a parte solo per muovere il motorino in una sola direzione (oraria) facendolo girare a 360°.
Di seguito riporto codice commentato e flowchart.
Quello che fa ora è accelerare e deccelerare mentre gira continuamente in senso orario.
Quindi desumo che la velocità iniziale sia pari a zero quando accelera e sempre pari a zero quando cambia direzione in quando la precedente deccelerazione a portato la velocità a zero.
- Vel in delayMicroseconds(vel) valore iniziale ? (poco importante)

15000 microsecondi
ogni quanto tempo VEL viene caricata nella delayMicroseconds(vel) ?

Circa ogni 1ms
qual'è la variazione di valore tra la prima delayMicroseconds(vel) e le successive delayMicroseconds(vel) ? Prova a fare una tabella

Proverò a fare una tabella , ma la variazione è pari a 8us. Ogni 1 ms a vel viene sottratto 8us (la variabile accelerazione 'acc' contiene 8)

pippodue:
Vel non e' la velocita' ma il tempo fra due step successivi, cioe' si tratta del reciproco della velocita' a meno di una costante di proporzionalita'. Se vuoi una accelerazione costante devi istituire un'altra variabile che rappresenti davvero la velocita', incrementare quella e poi farne il reciproco. Ovviamente se usi variabili intere devi partire da un valore grande e poi dividere.


Esatto 'vel' è il tempo fra due step; minore è il tempo, maggiore sarà la velocità di rotazione. Mentre il valore di 'vel' viene aggiornato ogni 1ms circa.
Se vuoi una accelerazione costante devi istituire un'altra variabile che rappresenti davvero la velocita', incrementare quella e poi farne il reciproco.

cioè vuoi dire creare una frequenza variabile?Ma non ho capito come , visto che devo comunque agire sul tempo tra un passo e l'altro per aumentare la velocità di rotazione

di seguito riporto il codice e il flowchart aggiornato

http://pastebin.com/wjQVNP8w
http://oi67.tinypic.com/ir42m9.jpg
Vidica





postato il:
25.08.2016, alle ore 00:49
Sarebbe utile anche avere un grafico , provo a fare la tabella ma devo recuperare i dati dalla seriale e metterli su excel :)
grazie per qualsiasi altra dritta
Vidica





postato il:
25.08.2016, alle ore 01:19
Vidica:
Sarebbe utile anche avere un grafico , provo a fare la tabella ma devo recuperare i dati dalla seriale e metterli su excel :)
grazie per qualsiasi altra dritta


Scusate non so come si edita il post.
Il problema è applicare una legge oraria per determinare quale accelerazione sia necessaria per raggiungere un certo numero di step senza perdere il passo :)
agric





postato il:
25.08.2016, alle ore 05:08
Quello che fa ora è accelerare e deccelerare mentre gira continuamente in senso orario.
Quindi desumo che la velocità iniziale sia pari a zero quando accelera e sempre pari a zero quando cambia direzione in quando la precedente deccelerazione a portato la velocità a zero.

Questo tuo concetto lo devi rivedere.
In ogni momento, durante un'accelerazione o decelerazione la velocità di rotazione del motore non è uguale a zero ma è proporzionale.

In riguardo al software:
Se avviene un'interrupt ogni 1 mS (1000 Us) VEL non cambierà se non dopo il tempo impostato in delay_ms , di conseguenza le rampe di ACC/DEC perdono linearità.
Nel tuo caso specifico l'uso dell'interupt in questo modo non rispetta la tua idea . Un semplice loop dove incrementi/decrementi VEL dopo ogni delay_Us è piu corretta .
La perdita di passi è anche legata alle caratteristiche del motore di conseguenza devi lavorare nel suo range: anche se metti in pratica tutti gli accorgimenti possibili, oltre i suoi limiti la perdita del passo è inevitabile.





meglio essere un granello di pepe che una cacca d'asino
segui questo thread con grixFC, per questa funzione devi aver installato il software grixFC

torna su
     

Come utente anonimo puoi leggere il contenuto di questo forum ma per aprire una discussione
o per partecipare ad una discussione esistente devi essere registrato ed accedere al sito




 







 
 
indietro | homepage | torna su copyright © 2004/2024 GRIX.IT - La community dell'elettronica Amatoriale