ho cercato questo argumento un po su internet , ma senza trovare nulla di interessante e completamente esaustivo , devo comandare più di un motore stepper , con arduino uno , il problema è che essendo in loop il programma sente il delay dei passi del primo motore e di conseguenza in cascata vanno a finire anche sul secondo ..... scusate la poca chairezza .....
Esempio : Se imposto 50 microsecond tra gli step del primo motore , e 50 microsecond tra gli step del secondo motore , i due motori non gireranno a 50 microsecond ma a 100 microsecond , in pratica vorrei che il tempo tra gli step del primo motore sia indipendente dal tempo degli step del secondo motore .
ho cercato questo argumento un po su internet , ma senza trovare nulla di interessante e completamente esaustivo , devo comandare più di un motore stepper , con arduino uno , il problema è che essendo in loop il programma sente il delay dei passi del primo motore e di conseguenza in cascata vanno a finire anche sul secondo ..... scusate la poca chairezza .....
Esempio : Se imposto 50 microsecond tra gli step del primo motore , e 50 microsecond tra gli step del secondo motore , i due motori non gireranno a 50 microsecond ma a 100 microsecond , in pratica vorrei che il tempo tra gli step del primo motore sia indipendente dal tempo degli step del secondo motore .
Grazie.
Ovvero tu usi delle delay(50) ? Devi sostituire le delay() con millis().
Prova a vedere l'esempio BlinkWithoutDelay, li c'e' solo un led. Poi prova a pensarlo per 2 led indipendenti con tempo di blink diverso tra i due.
comunque a livello pratico non puoi fare una semplice sostituzione millis al posto del delay.
In molti tutorial usati per gli stepper si comanda un passo, si aspetta tot, si comanda l'altro passo, si aspetta ecc.
In questa configurazione millis non si riesce a usare.
Se però ti crei una funzione " stepper avanti di 1 " che decide quale "fase" dello stepper attivare e alterni questa funzione a una pausa gestita da millis la cosa diventa fattibile.
Adesso non riesco a buttare giù un codice (o pseudo tale). vedo se più avanti trovo il tempo.
pippo72
p.s. a seconda di come è collegato lo stepper ad arduino la funzione "stepper avanti di 1" può cambiare e di molto.
[/quote]
Ovvero tu usi delle delay(50) ? Devi sostituire le delay() con millis().
Prova a vedere l'esempio BlinkWithoutDelay, li c'e' solo un led. Poi prova a pensarlo per 2 led indipendenti con tempo di blink diverso tra i due.
[/quote]
bello l'esempio però devo poter gestire il tempo tra gli step , quindi la velocità del motore con un encoder rotativo , si può fare ??+
pippo72:
Adesso non riesco a buttare giù un codice (o pseudo tale). vedo se più avanti trovo il tempo.
Ho trovato il tempo.
Ho scritto una bozza tanto per provare se funziona. Una premessa: lo stepper lo comandi con 4 pin di arduino (naturalmente tramite driver):
int ledState = LOW; // BlinkWithoutDelay
long previousMillis = 0;
int passo = 0;
//const byte motpin1 = 2; //pin dove collegato stepper
//const byte motpin2 = 3; //pin dove collegato stepper
//const byte motpin3 = 4; //pin dove collegato stepper
//const byte motpin4 = 5; //pin dove collegato stepper
long interval = 1000; // pausa in millisecondi
void setup() {
delay(2000);
Serial.begin(9600);
//pinMode(ledPin, OUTPUT);
}
void loop()
{
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
muovi_stepper(-1); // -1 gira in un senso, 1 gira nell'altro
//
//
}
}
void muovi_stepper(int a) {
passo = passo + a;
if (passo > 3) passo = 0;
if (passo < 0 ) passo = 3;
switch (passo) {
case 0 :
Serial.println(F("caso 0"));// uscita step 1
break;
case 1 :
Serial.println(F("caso 1"));// uscita step 2
break;
case 2 :
Serial.println(F("caso 2"));// uscita step 3
break;
case 3 :
Serial.println(F("caso 3"));// uscita step 4
break;
default :
Serial.print(F("non previsto"));// uscita step 4
Serial.println(passo);
}
}
La funzione muovi_stepper() è quella che sceglie quale uscita attivare per muovere lo stepper. Naturalmente con questo codice non si muove niente ma scrivo sulla seriale qualcosa.
Da qui per estendere il controllo su 2 stepper non é difficile.
Io per comandare uno stepper l297 l298 ho preso spunto da quahttp://www.schmalzhaus.com/EasyDriver/Examples/EasyDriverExamples.html usando la libreria AccelStepper che fa un sacco di cose.
Leandro
Io non ho esplorato a fondo la libreria ma la velocità come l'accelerazione sono delle variabili che puoi aggiornare prima di fare la chiamata
alla libreria.
leandro
Tutto funziona alla perfezione e vi ringrazio per il supporto , veramente figo sto forum in mezzagiornata ho risolto un tot di problemi ... Grazie a tutti !!
Un ultima cosa però , quando vado a printare delle variabili sull'lcd mi rallenta di molto la velocità dei motori , come se ci fosse un ritardo fisso sul loop , ho provato ad ovviare questo problema inserendo un ritardo nel print su lcd con millis , ma niente da fare quando printa si sente sempre uno scatto nello stepper ... Si può ovviare in qualche modo ???
Ginozor:
...quando vado a printare delle variabili sull'lcd mi rallenta di molto la velocità dei motori , come se ci fosse un ritardo fisso sul loop , ho provato ad ovviare questo problema inserendo un ritardo nel print su lcd con millis , ma niente da fare quando printa si sente sempre uno scatto nello stepper ... Si può ovviare in qualche modo ???
Per quanto ne so arduino esegue una sola istruzione alla volta, non riesce a fare 2 cose contemporaneamente.
Anche se il tempo tra uno step e l'altro tu lo gestisci con millis fare un print sull'LCD ci mette del tempo (non so quanto), se questo tempo è maggiore della pausa che ti serve per lo stepper, è chiaro che questo si "fermi".
prova a misurare quanto ci mette arduino a scrivere sull'LCD e a lavorare sul codice per ridurre il più possibile questo tempo ma se ci mette 5 millisecondi (sparo a caso) questa è il tempo minimo tra un passo e l'altro senza avere problemi.
ok , però nelle stampanti 3d sono sicuramente riusciti ad ovviare questo problema , anche perchè usano un arduino mega , e lcd si aggiorna continuamente temperature , posizioni assi etc etc , ma non vedo rallentamenti nei motori anche perchè l'oggetto che stai stampando presenterebbe dei segni di trim con il cambio di velocità , invece tutto fila liscio anche quando agisco su parametri da lcd ....
c'e' poco da fare, usi una libreria che invia il comando di Step " xxxx.runSpeed() " quando questa funzione viene richiamata.
Normalmente deve avvenire entro il tempo impostato con " xxxx.setSpeed(valore) ".
Questo valore lo hai impostato a 250, quindi ogni 4mS. E' chiaro che se la routine di stampa sull'LCD ci mette di piu' ( a cui va' aggiunto il tempo di esecusione del resto )..... si perdono dei colpi, o meglio si ritarda l'invio dello Step
Per la precisione la sola stampa di quelle 4 righe provoca un ritardo di 4,8 mS )
Intanto puoi provare a cambiare la libreria dell'LCD . Questa e' molto piu' veloce. ( informazioni sulla libreria le trovi Qui
( Ricordati di togliere prima l'attuale libreria LiquidCrystal dall'IDE di Arduino )
Brunello:
c'e' poco da fare, usi una libreria che invia il comando di Step " xxxx.runSpeed() " quando questa funzione viene richiamata.
Normalmente deve avvenire entro il tempo impostato con " xxxx.setSpeed(valore) ".
Questo valore lo hai impostato a 250, quindi ogni 4mS. E' chiaro che se la routine di stampa sull'LCD ci mette di piu' ( a cui va' aggiunto il tempo di esecusione del resto )..... si perdono dei colpi, o meglio si ritarda l'invio dello Step
Per la precisione la sola stampa di quelle 4 righe provoca un ritardo di 4,8 mS )
Intanto puoi provare a cambiare la libreria dell'LCD . Questa e' molto piu' veloce. ( informazioni sulla libreria le trovi Qui
( Ricordati di togliere prima l'attuale libreria LiquidCrystal dall'IDE di Arduino )
Però guardando un un po su Sangoogle ho trovato questa discossione : http://forum.arduino.cc/index.php?topic=28388.0
molto interessante e sembra addirittura che abbiano risolto il problema , ma aimè non ho capito come