Sto facendo delle prove e cercando di pilotare 2 motori stepper contemporaneamente con due drivere diversi e i rispettivi motori stepper di diversa potenza e alimentati da due alimentatori differenti, facendoli muovere con differenti velocità (giusto per intenderci).
Io li voglio pilotare solo con i segnali Step e Dir "dati in pasto" al rispettivo driver.
Il problema è che in giro trovo solo tutorial in cui impiegano 4 pin per motore come se di pin ce ne fossero in abbondanza da buttare.
Non è più semplice utilizzare solo 2 segnali di OUTOPUT?
Comunque per ora sono riuscito a scrivere solo questo sketch ma non riesco a farli muovere in contemporanea.
Cosa posso cambiare nello sketch per far si che si muovano contemporaneamente? grazie!
//Su motorino stepper MITSUMI M35SP-11TK calcolo su pignone grande num step = 576
//Velocità in microsecondi tra un impulso e l'altro sul pin STEP = 1000
//Su motorino stepper Floppy calcolo corsa totale num step = 200
//Velocità in microsecondi tra un impulso e l'altro sul pin STEP = 600
//Definizione dei PIN
int pinDir1 = 2;
int pinStep1 = 3;
int pinDir2 = 5;
int pinStep2 = 4;
int numStepMotore1 = 1728; //E' il numero di step per rotazione del motore (potrebbe differire in base al modello)
long velocita1 = 1000; //Si tratta di microsecondi tra un impulso e l'altro sul pin STEP
int numStepMotore2 = 100; //E' il numero di step per rotazione del motore (potrebbe differire in base al modello)
long velocita2 = 600; //Si tratta di microsecondi tra un impulso e l'altro sul pin STEP
void setup() {
//inizializzo i PIN come OUTPUT
Serial.begin(9600);
pinMode(pinStep2, OUTPUT);
pinMode(pinDir2, OUTPUT);
pinMode(pinStep1, OUTPUT);
pinMode(pinDir1, OUTPUT);
}
void loop() {
//SP2 inizio parte dedicata al motore step n2 per sincronizzare
//definiamo la direzione del motore
digitalWrite(pinDir2, HIGH);
//esegue un giro completo in un senso
for (int x = 0; x < numStepMotore2; x++) {
delay(3);
digitalWrite(pinStep2, HIGH);
delayMicroseconds(velocita2);
digitalWrite(pinStep2, LOW);
delayMicroseconds(velocita2);
}
//aspetto 2 secondi
delay(2000);
//cambio la direzione di marcia
digitalWrite(pinDir2, LOW);
//esegue un giro completo in un senso
for (int x = 0; x < numStepMotore2; x++) {
delay(3);
digitalWrite(pinStep2, HIGH);
delayMicroseconds(velocita2);
digitalWrite(pinStep2, LOW);
delayMicroseconds(velocita2);
}
//SP1 inizio parte dedicata al motore step n1 per sincronizzare
//definiamo la direzione del motore
digitalWrite(pinDir1, HIGH);
//esegue n3 giro completo in un senso
for (int x = 0; x < numStepMotore1; x++) {
delay(0.5);
digitalWrite(pinStep1, HIGH);
delayMicroseconds(velocita1);
digitalWrite(pinStep1, LOW);
delayMicroseconds(velocita1);
}
//aspetto 2 secondi
delay(2000);
//cambio la direzione di marcia
digitalWrite(pinDir1, LOW);
//esegue n3 giro completo in un senso
for (int x = 0; x < numStepMotore1; x++) {
delay(0.5);
digitalWrite(pinStep1, HIGH);
delayMicroseconds(velocita1);
digitalWrite(pinStep1, LOW);
delayMicroseconds(velocita1);
}
while (true);
}
Utilizzando For per muovere il motore difficilmente potrai controllarne due contemporaneamente a diverse velocità, ogni ciclo for blocca la continuazione del programma finché quel ciclo non è terminato, per fare ciò che vuoi devi utilizzare millis() o meglio ancora micros() solo così puoi avere due motori che effettuano giri diversi a velocità diverse. Di millis() se fai una ricerca sul forum se ne è parlato un'infinità di volte, le stesse cose valgono anche per micros() cambia solo l'unità di tempo utilizzata, millisecondi e microsecondi.
Quindi bisogna riformulare l'intero sketch, diciamo che non va bene niente del codice...
Nel caso avresti qualche link da indicarmi dove si vede uno sketch, lo chiedo perchè è sempre meglio studiare su di un codice già utilizzato e testato che controlli più di un motore...
Se vuoi avere un'indipendenza di velocità dei motori mi sa che devi proprio riscrivere da zero tutto il programma, ma prima di complicarti la vita ti consiglio di prendere dimestichezza con millis() facendo lampeggiare due led a diversa frequenza, magari con l'aggiunta di due pulsanti o petenziometri per cambiare al volo i tempi.
Di esempi da consigliarti non ne ho purtroppo, come ti dicevo è un tema trattato parecchie volte sul forum e anche su internet di esempi ce ne sono tantissimi su cui avere una base per sperimentare.
>DottorSlump: per la sola parte relativa alla funzione millis(), studia prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina ... dovrebbe bastare a chiarirtene l'uso
Lo so direte "vuoi troppo" però quello che cerco è un esempio dove si pilotano 2 motori stepper solo con segnale Step e Dir in contemporanea.
Questi esempi si mi danno un bello spunto per studiarci su ma d'altra parte mi mandano un po in confusione...
Poi ci sono gli esempi dove vengono pilotati si più motori step ma con sketch che magari danno gli stessi risultati però con una compilazione diversa...
...In altre parole stò andando un po in confusione
...In tanto studio e cerco di scrivere uno sketch funzionante poi chi sa che nel frattempo non salti fuori qualcosa di più sugli stepper...
Cercando e studiando un po in giro per il web...ho trovato vari sketch che utilizzano "librerie"
Vi chiedo, lascio perdere perchè posso fare a meno di queste librerie da includere nell'IDE o è meglio che inizio a studiarle perchè sono fondamentali...??!
Impara l'arte e mettila da parte proverbio popolare a parte imparare ad usare millis() è un ottimo investimento di tempo, nella programmazione è utilizzato moltissimo per gestire temporizzazioni senza bloccare l'esecusione del programma ad un singolo compito. Anche le librerie sono importanti da saper utilizzare oltre che indispensabili il più delle volte, ma avere se non altro un'infarinatura di tutti i comandi di arduino è senz'altro importante, QUI il reference dove poter vederli e studiarli.
Certo -zef- infatti il link che mi hai suggerito è stato il primo ad essere segnato nei preferiti del browser
E approposito di questo riferimento il codice run() (che non trovo nei riferimenti) mi sembra appartenga a Linux o sbaglio...?!! io uso Windows7,
Lo chiedo perchè si trova nello sketch e nella libreria che ho utilizzato per delle prove.
Qui sotto posto lo sketch citato prima che mi fa muovere 2 stepper in contemporanea come intendevo, l'unica pecca che richiede la seguente libreria ma non vorrei complicarmi troppo la vita, preferirei inizialmente farli muovere utilizzando solo lo sketch "puro"....
Sketch:
#include <AccelStepper.h>
// Definisci due stepper e i pin che useranno
AccelStepper stepper1(AccelStepper::DRIVER, 3, 2);
AccelStepper stepper2(AccelStepper::DRIVER, 4, 5);
int pos1 = 576;
int pos2 = 50;
void setup()
{
stepper1.setMaxSpeed(1050);
stepper1.setAcceleration(950);
stepper2.setMaxSpeed(650);
stepper2.setAcceleration(550);
}
void loop()
{
if (stepper1.distanceToGo() == 0)
{
pos1 = -pos1;
stepper1.moveTo(pos1);
}
if (stepper2.distanceToGo() == 0)
{
pos2 = -pos2;
stepper2.moveTo(pos2);
}
stepper1.run();
stepper2.run();
}
La libreria non entra la devo postare come file...
DottorSlump:
E approposito di questo riferimento il codice run() (che non trovo nei riferimenti) mi sembra appartenga a Linux o sbaglio...?!! io uso Windows7...
Non lo trovi nel reference in quanto è una funzione della libreria, infatti initializi la libreria con:
DottorSlump:
richiede la seguente libreria ma non vorrei complicarmi troppo la vita, preferirei inizialmente farli muovere utilizzando solo lo sketch "puro"....
Allora per non complicarti la vita con la libreria puoi studiare lo sketch puro, che fa le stesse cose del primo post ma tutte in contemporanea... anzi no, fa anche lampeggiare il LED
// DottorSlump
//http://forum.arduino.cc/index.php?topic=602662.msg4091136#msg4091136
const byte pinDir1 = 2;
const byte pinStep1 = 3;
const byte pinDir2 = 5;
const byte pinStep2 = 4;
const int numStepMotore1 = 1728; //step per rotazione del motore
const unsigned long velocita1 = 1000; //microsecondi tra impulsi pin STEP
const int numStepMotore2 = 100;
const unsigned long velocita2 = 600;
bool enableMotore1 = false;
bool enableMotore2 = false;
//-----------------------------------------------------------
// FUNZIONE: ruotaMotore1
// DESCRIZIONE: Quando la variabile di controllo 'enableMotore1'
// diventa true ' Compie 'numStepMotore1' passi,
// poi rimette a false la variabile di controllo.
// Questa funzione e` un processo, va richiamata
// continuamente dal loop.
// PARAMETRI: Nessuno, usa le variabili globali e locali
// RETURN CODE: Ignorato
//-----------------------------------------------------------
void ruotaMotore1(void)
{
static byte fase = 0;
static int contatore;
static unsigned long tempo;
if ((0 == fase) and enableMotore1){
contatore = 0;
tempo = micros();
fase = 1;
}else if ((1 == fase) and (micros()-tempo >= velocita1)){
tempo += velocita1;
fase = 2;
}else if ((2 == fase) and (micros()-tempo >= velocita1)){
contatore++;
if (numStepMotore1 == contatore)
{
enableMotore1 = false;
fase = 0;
}
else
{
tempo += velocita1;
fase = 1;
}
}
if (1 == fase) { digitalWrite(pinStep1, HIGH); }
else { digitalWrite(pinStep1, LOW); }
}
//-----------------------------------------------------------
// FUNZIONE: ruotaMotore2
// DESCRIZIONE: Quando la variabile di controllo 'enableMotore2'
// diventa true ' Compie 'numStepMotore2' passi,
// poi rimette a false la variabile di controllo.
// Questa funzione e` un processo, va richiamata
// continuamente dal loop.
// PARAMETRI: Nessuno, usa le variabili globali e locali
// RETURN CODE: Ignorato
//-----------------------------------------------------------
void ruotaMotore2(void)
{
static byte fase = 0;
static int contatore;
static unsigned long tempo;
if ((0 == fase) and enableMotore2){
contatore = 0;
tempo = micros();
fase = 1;
}else if ((1 == fase) and (micros()-tempo >= velocita2)){
tempo += velocita2;
fase = 2;
}else if ((2 == fase) and (micros()-tempo >= velocita2)){
contatore++;
if (numStepMotore2 == contatore)
{
enableMotore2 = false;
fase = 0;
}
else
{
tempo += velocita2;
fase = 1;
}
}
if (1 == fase) { digitalWrite(pinStep2, HIGH); }
else { digitalWrite(pinStep2, LOW); }
}
//-----------------------------------------------------------
// FUNZIONE: controllaMotore1
// DESCRIZIONE: Comanda il processo 'ruotaMotore1' tramite
// la variabile di controllo 'enableMotore1'.
// Dopo un giro attende due secondi, inverte
// la direzione e riavvia il motore, poi non
// fa piu` nulla come da codice originale.
// Questa funzione e` un processo, va richiamata
// continuamente dal loop.
// PARAMETRI: Nessuno, usa le variabili globali e locali
// RETURN CODE: Ignorato
//-----------------------------------------------------------
void controllaMotore1(void)
{
static byte fase = 0;
static unsigned long tempo;
if (0 == fase){
enableMotore1 = true;
fase = 1;
}else if ((1 == fase) and (not enableMotore1)){
tempo = millis();
fase = 2;
}else if ((2 == fase) and (millis()-tempo >= 2000)){
//cambio la direzione di marcia
digitalWrite(pinDir1, LOW);
enableMotore1 = true;
fase = 255;
}else{
// nothing
}
}
//-----------------------------------------------------------
// FUNZIONE: controllaMotore2
// DESCRIZIONE: Comanda il processo 'ruotaMotore2' tramite
// la variabile di controllo 'enableMotore2'.
// Dopo un giro attende due secondi, inverte
// la direzione e riavvia il motore, poi non
// fa piu` nulla come da codice originale.
// Questa funzione e` un processo, va richiamata
// continuamente dal loop.
// PARAMETRI: Nessuno, usa le variabili globali e locali
// RETURN CODE: Ignorato
//-----------------------------------------------------------
void controllaMotore2(void)
{
static byte fase = 0;
static unsigned long tempo;
if (0 == fase){
enableMotore2 = true;
fase = 1;
}else if ((1 == fase) and (not enableMotore2)){
tempo = millis();
fase = 2;
}else if ((2 == fase) and (millis()-tempo >= 2000)){
//cambio la direzione di marcia
digitalWrite(pinDir2, LOW);
enableMotore2 = true;
fase = 255;
}else{
// nothing
}
}
//-----------------------------------------------------------
// FUNZIONE: blinca
// DESCRIZIONE: Fa lampeggiare il LED del pin 13 a 1Hz
// Questa funzione e` un processo, va richiamata
// continuamente dal loop.
// PARAMETRI: Nessuno, usa le variabili locali
// RETURN CODE: Ignorato
//-----------------------------------------------------------
void blinca(void)
{
static unsigned long tempo = millis();
if (millis()-tempo >= 500)
{
tempo += 500;
digitalWrite(13, not digitalRead(13));
}
}
//-----------------------------------------------------------
void setup(void)
{
Serial.begin(9600);
pinMode(pinStep2, OUTPUT);
pinMode(pinDir2, OUTPUT);
pinMode(pinStep1, OUTPUT);
pinMode(pinDir1, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
}
//-----------------------------------------------------------
void loop(void)
{
// processi richiamati migliaia di volte al secondo
controllaMotore1();
controllaMotore2();
ruotaMotore1();
ruotaMotore2();
blinca();
}
//-----------------------------------------------------------
:o :o Grazie ancora Claudio addirittura la spiegazione fase per fase :o in giro di già scritti non ho trovato nulla di simile cosi dettagliato ed è proprio quello che intendevo io.
Però visto che sono sotto zero con il software ho visto che il motore2 fa uno scatto solo di pochi millisecondi a Dx e Sx ho provato a cambiare qualche parametro ma non riesco anche se cambio la velocità non succede nulla... l'ho riportato uguale ma ho fatto più prove
const unsigned long velocita2 = 600;
...dimenticavo ho provato anche a smanettare qui ma niente...
void controllaMotore2(void)
{
static byte fase = 0;
static unsigned long tempo;
if (0 == fase){
enableMotore2 = true;
fase = 1;
}else if ((1 == fase) and (not enableMotore2)){
tempo = millis();
fase = 2;
}else if ((2 == fase) and (millis()-tempo >= 2000)){
//cambio la direzione di marcia
digitalWrite(pinDir2, LOW);
enableMotore2 = true;
fase = 255;
}else{
// nothing
}
}
...figo il led che lampeggia, era una cosa che avevo visto studiando qua e la che il led L è collegato con il Pin 13 per poter provare gli Arduini senza avere nessun altro componente hardwer oltre la scheda Arduino... dai qualcosa l'ho imparata
DottorSlump:
Però visto che sono sotto zero con il software ho visto che il motore2 fa uno scatto solo
[/quoie]
E invece il motore 1 va bene?
Da quello che vedo nel setup (che ho lasciato uguale al tuo aggiungendo solo il pin per il LED) manca l'impostazione dei livelli iniziali delle uscite (impostazione che invece per il LED c'è).