Go Down

Topic: Programmare un motore passo passo (Read 11181 times) previous topic - next topic

-zef-

Vorrei ribadire il fatto che non ho mai usato la libreria stepper, i driver del link che ti ho inserito non so se sono compatibili con tale libreria, vista la semplicità nel pilotarli preferisco fare tutto dal programma che scrivo, informati prima di comprarli  ;) 

Enry1995

Vedi che il driver deve essere anche alimentato a 5 volt, per la forza controlla se sul driver non ci sia un trimmer che regola la corrente al motore, se troppo bassa il motore non ha forza, ma attento che se troppo alta scalda come una stufa per poi andare in fumo.

Code: [Select]

void loop() {

 mioMotore.step(stepDaPercorrere);
 delay(50);
 mioMotore.step(-stepDaPercorrere);
 delay(50);
}   

Non conosco la libreria ma provo a leggere il loop

-vai al passo successivo;
-aspetta 50 millisecondi;
-torna indietro di un passo;
-aspetta 50 millisecondi;

Se ho letto bene stai giocando a Ping Pong con 2 bobine invece che far girare il motore

Hai almeno una vaga idea di com'è fatto dentro il tuo motore passopasso???




Ma il motore lo hai collegato nella giusta sequenza

Connection:
 Black(A+), Green(A-), Red(B+), Blue(B-)


Su un morsetto : Nero e Verde
Sull'altro : Rosso e Blu

Sinceramente non ho ancora visto una schedina con il L297 e il L298. Sono integrati vecchi di 40 anni e oggigiorno si usano dei integrati con MOSFET come stadio di uscita che hanno molto meno perdite.

Ho acquistato i driver che mi avete indicato (A4988) e li ho collegati in questo modo








(Avendo 2 motori ho collegato 2 driver allo stesso modo variando solo i PIN dell'arduino).

Poi ho collegato un pulsante in questo modo (senza mettere il LED)



Utilizzando questo programma che muove soltanto un motore quest'ultimo fa quello che desidero in modo corretto.

Code: [Select]
//Definizione dei PIN
const int pulsante = 13;
const int pinDir = 2;
const int pinStep = 3;
const int analog = A5;


int passi = 0;
int valore1 = 10;
int valore2 = 0;
int INDIETRO=0;
int ciclo= 0;


const int numStepMotore = 200; //E' il numero di step per rotazione del motore (potrebbe differire in base al modello)
const long velocita = 10000 ; //Si tratta di microsecondi tra un impulso e l'altro sul pin STEP
 
void setup() {
  Serial.begin(9600);
  //inizializzo i PIN come OUTPUT
  pinMode(pinStep, OUTPUT);
  pinMode(pinDir, OUTPUT);
  pinMode(pulsante, INPUT);
 


 
 
}
void loop() { 


  if (digitalRead(pulsante)==HIGH) ciclo=ciclo+1;
 
 
  delay(20);
 
 
  if (ciclo == 1) {
 
 
  //definiamo la direzione del motore
  digitalWrite(pinDir, HIGH);
 
  //esegue un giro completo in un senso
  for (int x = 0; x <= numStepMotore; x++) {
    digitalWrite(pinStep, HIGH);
    delayMicroseconds(velocita);
    digitalWrite(pinStep, LOW);
    delayMicroseconds(velocita);
    delay(50);
     valore2 = analogRead(analog);
      Serial.print("valore2 = " );
  Serial.println(valore2);
     delay(50);
   if( valore2>valore1)
   
   {
    valore1=valore2; passi=x;
   }
   
     Serial.print("x = " );
    Serial.print(x);
 
     Serial.print("");
     
  Serial.print("valore1 = " );
  Serial.println(valore1);
  Serial.print("passi = " );
  Serial.println(passi);   
   
  }
 
 INDIETRO = 200-passi;
 
  Serial.print("**************");
  Serial.print("valore1 = " );
  Serial.println(valore1);
  Serial.print("passi = " );
  Serial.println(passi);   
  Serial.print("INDIETRO = " );
  Serial.println(INDIETRO);   
  //aspetto 2 secondi
  delay(3000);
 
 
  //cambio la direzione di marcia
  digitalWrite(pinDir, LOW);


 
  //rieseguo un altro giro completo nel senso opposto
  for (int y = 0; y <= INDIETRO; y++) {
    digitalWrite(pinStep, HIGH);
    delayMicroseconds(velocita);
    digitalWrite(pinStep, LOW);
    delayMicroseconds(velocita);
  }
 
  //aspetto altri 2 secondi
  delay(10);
  ciclo=0;
  }

 else
 {
  delay(10);
 
  }

}


Poi ho voluto aggiungere anche il movimento di un secondo motore nella funzione if quando il pulsante viene premuto

Code: [Select]
//Definizione dei PIN
const int pulsante = 13;
const int pinDir = 2;
const int pinStep = 3;
const int analog = A5;

const int pinDirV = 4;
const int pinStepV = 5;
int passiV = 0;
int valore1V = 10;
int valore2V = 0;
int indietroV = 0;
int INDIETROV = 0;

int passi = 0;
int valore1 = 10;
int valore2 = 0;
int INDIETRO=0;
int ciclo= 0;

const int numStepMotoreV = 40;
const int numStepMotore = 200; //E' il numero di step per rotazione del motore (potrebbe differire in base al modello)
const long velocita = 30000 ; //Si tratta di microsecondi tra un impulso e l'altro sul pin STEP
 const long velocita2 = 20000 ; //Si tratta di microsecondi tra un impulso e l'altro sul pin STEP
void setup() {
  Serial.begin(9600);
  //inizializzo i PIN come OUTPUT
  pinMode(pinStep, OUTPUT);
  pinMode(pinDir, OUTPUT);
  pinMode(pulsante, INPUT);
 


 
 
}
void loop() { 


  if (digitalRead(pulsante)==HIGH) ciclo=ciclo+1;
 
  Serial.print("ciclo= " );
  Serial.println(ciclo);
  delay(1000);
 
 
  if (ciclo == 1) {

 digitalWrite(pinDirV, HIGH);
 Serial.print("ciclo= " );
  Serial.println(ciclo);
delay(100);

     for (int z = 0; z <= numStepMotoreV; z++) {
    digitalWrite(pinStepV, HIGH);
    delayMicroseconds(velocita2);
    digitalWrite(pinStepV, LOW);
    delayMicroseconds(velocita2);
  }
 
  delay(20000);
 
  //definiamo la direzione del motore
  digitalWrite(pinDir, HIGH);
 
  //esegue un giro completo in un senso
  for (int x = 0; x <= numStepMotore; x++) {
    digitalWrite(pinStep, HIGH);
    delayMicroseconds(velocita);
    digitalWrite(pinStep, LOW);
    delayMicroseconds(velocita);
  delay(1);
     valore2 = analogRead(analog);
      Serial.print("valore2 = " );
  Serial.println(valore2);
     delay(1);
   if( valore2>valore1)
   
   {
    valore1=valore2; passi=x;
   }
   
     Serial.print("x = " );
    Serial.print(x);
 
     Serial.print("");
     
  Serial.print("valore1 = " );
  Serial.println(valore1);
  Serial.print("passi = " );
  Serial.println(passi);   
   
  }
 
 INDIETRO = 200-passi;
 
  Serial.print("**************");
  Serial.print("valore1 = " );
  Serial.println(valore1);
  Serial.print("passi = " );
  Serial.println(passi);   
  Serial.print("INDIETRO = " );
  Serial.println(INDIETRO);   
  //aspetto 2 secondi
  delay(3000);
 
 
  //cambio la direzione di marcia
  digitalWrite(pinDir, LOW);


 
  //rieseguo un altro giro completo nel senso opposto
  for (int y = 0; y <= INDIETRO; y++) {
    digitalWrite(pinStep, HIGH);
    delayMicroseconds(velocita);
    digitalWrite(pinStep, LOW);
    delayMicroseconds(velocita);
  }
 
  //aspetto altri 2 secondi
  delay(10);
  ciclo=0;
  }

 else
 {
  delay(10);
 
  }

}


In questo caso se aspetto qualche secondo senza premere il pulsante il secondo motore si muove da solo a caso. Se invce lo premo il secondo motore non si muove e sembra che il movimento che dovrebbe fare il secondo motore venga invece effettuato dal primo.

Chi può aiutarmi? Grazie in anticipo.

-zef-

ho dato solo un'occhiata veloce e quindi non so se corretto ma dove hai scritto INDIETRO = 200-passi; se passi è maggiore di 200, INDIETRO sarà un numero negativo e quindi nel for (int y = 0; y <= INDIETRO; y++)   Y essendo 0 non sarà minore di INDIETRO (che è un numero negativo) e il ciclo for non farà nulla.

Enry1995

ho dato solo un'occhiata veloce e quindi non so se corretto ma dove hai scritto INDIETRO = 200-passi; se passi è maggiore di 200, INDIETRO sarà un numero negativo e quindi nel for (int y = 0; y <= INDIETRO; y++)   Y essendo 0 non sarà minore di INDIETRO (che è un numero negativo) e il ciclo for non farà nulla.
Ho aggiunto l'if come hai consigliato=

Code: [Select]
//Definizione dei PIN
const int pulsante = 13;
const int pinDir = 2;
const int pinStep = 3;
const int analog = A5;

const int pinDirV = 4;
const int pinStepV = 5;
int passiV = 0;
int valore1V = 10;
int valore2V = 0;
int indietroV = 0;
int INDIETROV = 0;

int passi = 0;
int valore1 = 10;
int valore2 = 0;
int INDIETRO=0;
int ciclo= 0;

const int numStepMotoreV = 40;
const int numStepMotore = 200; //E' il numero di step per rotazione del motore (potrebbe differire in base al modello)
const long velocita = 30000 ; //Si tratta di microsecondi tra un impulso e l'altro sul pin STEP
 const long velocita2 = 20000 ; //Si tratta di microsecondi tra un impulso e l'altro sul pin STEP
void setup() {
  Serial.begin(9600);
  //inizializzo i PIN come OUTPUT
  pinMode(pinStep, OUTPUT);
  pinMode(pinDir, OUTPUT);
  pinMode(pulsante, INPUT);
 


 
 
}
void loop() { 


  if (digitalRead(pulsante)==HIGH) ciclo=ciclo+1;
 
  Serial.print("ciclo= " );
  Serial.println(ciclo);
  delay(100);
 
 
  if (ciclo == 1) {

 digitalWrite(pinDirV, HIGH);
 Serial.print("ciclo= " );
  Serial.println(ciclo);
delay(20);

     for (int z = 0; z <= numStepMotoreV; z++) {
    digitalWrite(pinStepV, HIGH);
    delayMicroseconds(velocita2);
    digitalWrite(pinStepV, LOW);
    delayMicroseconds(velocita2);
  }
 
  delay(20);
 
  //definiamo la direzione del motore
  digitalWrite(pinDir, HIGH);
 
  //esegue un giro completo in un senso
  for (int x = 0; x <= numStepMotore; x++) {
    digitalWrite(pinStep, HIGH);
    delayMicroseconds(velocita);
    digitalWrite(pinStep, LOW);
    delayMicroseconds(velocita);
  delay(1);
     valore2 = analogRead(analog);
      Serial.print("valore2 = " );
  Serial.println(valore2);
     delay(1);
   if( valore2>valore1)
   
   {
    valore1=valore2; passi=x;
   }
   
     Serial.print("x = " );
    Serial.print(x);
 
     Serial.print("");
     
  Serial.print("valore1 = " );
  Serial.println(valore1);
  Serial.print("passi = " );
  Serial.println(passi);   
   
  }
 
 INDIETRO = 200-passi;

 if (INDIETRO<=0){

  INDIETRO=0;
 }
 
  Serial.print("**************");
  Serial.print("valore1 = " );
  Serial.println(valore1);
  Serial.print("passi = " );
  Serial.println(passi);   
  Serial.print("INDIETRO = " );
  Serial.println(INDIETRO);   
  //aspetto 2 secondi
  delay(3000);
 
 
  //cambio la direzione di marcia
  digitalWrite(pinDir, LOW);


 
  //rieseguo un altro giro completo nel senso opposto
  for (int y = 0; y <= INDIETRO; y++) {
    digitalWrite(pinStep, HIGH);
    delayMicroseconds(velocita);
    digitalWrite(pinStep, LOW);
    delayMicroseconds(velocita);
  }
 
  //aspetto altri 2 secondi
  delay(10);
  ciclo=0;
  }

 else
 {
  delay(10);
 
  }

}





In questo modo=


 INDIETRO = 200-passi;

 if (INDIETRO<=0){

  INDIETRO=0;
 }
 
  Serial.print("**************");
  Serial.print("valore1 = " );
  Serial.println(valore1);
  Serial.print("passi = " );
  Serial.println(passi);   
  Serial.print("INDIETRO = " );
  Serial.println(INDIETRO);   
  //aspetto 2 secondi
  delay(3000);
 


La mia tesina è composta da 2 motori che devono muoversi solamente dopo aver premuto il pulsante, prima quello dell'asse orizzontale (un giro completo dove ricerca il sole seguito da un ritorno verso la fonte della luce), poi quello verticale (partendo da una posizione di 45° deve salire di 15° e poi scendere di 30°, per poi tornare dalla fonte di luce). Il mio problema è che il motore dell'asse verticale si muove casualmente dopo qualche secondo che alimento il circuito, senza che io prema il pulsante.
Per il momento ho fatto il programma della parte orizzontale completamente, mentre della parte verticale solo il primo movimento che porta il pannello a 45°.
Come posso risolvere?


PS:Le foto le trovate nei post precedenti.

Grazie mille in anticipo

-zef-

ho dato una lettura con più calma, ci sono cose che non capisco se errori o voluti, intanto controllando meglio mi sono reso conto di aver sbagliato prima in quanto passi non potrà mai avere un valore maggiore di 200 visto che numStepMotore vale massimo 200.... ma questo mi porta a non capire il senso di fare ad esempio un tot di step in una direzione e poi assegnare ad indietro i rimanenti per arrivare a 200, mi spiego meglio (se ci riesco  :smiley-confuse: ) supponiamo che in passi = x; passi diventi 50, poi nel calcolo INDIETRO = 200 - passi; INDIETRO diventa 150 quindi avrai fatto 200 passi in avanti in quanto la for viene comunque eseguita per tutti i 200 passi di numStepMotore.
Altra cosa, sicuro che queste istruzioni sortiscano l'effetto voluto?

Code: [Select]
if ( valore2 > valore1)

      {
        valore1 = valore2; passi = x;
      }


ho come l'impressione che alla fine passi ti vale 200 e di conseguenza INDIETRO sarà uguale a 0.

I vari print di controllo riportano valori che ti aspetti?

il pulsante prova a metterlo in modo che la resistenza vada al positivo e il contatto chiuda sul negativo e invece dello stato high leggi se è low.

Enry1995

ho dato una lettura con più calma, ci sono cose che non capisco se errori o voluti, intanto controllando meglio mi sono reso conto di aver sbagliato prima in quanto passi non potrà mai avere un valore maggiore di 200 visto che numStepMotore vale massimo 200.... ma questo mi porta a non capire il senso di fare ad esempio un tot di step in una direzione e poi assegnare ad indietro i rimanenti per arrivare a 200, mi spiego meglio (se ci riesco  :smiley-confuse: ) supponiamo che in passi = x; passi diventi 50, poi nel calcolo INDIETRO = 200 - passi; INDIETRO diventa 150 quindi avrai fatto 200 passi in avanti in quanto la for viene comunque eseguita per tutti i 200 passi di numStepMotore.
Altra cosa, sicuro che queste istruzioni sortiscano l'effetto voluto?

Code: [Select]
if ( valore2 > valore1)

      {
        valore1 = valore2; passi = x;
      }


ho come l'impressione che alla fine passi ti vale 200 e di conseguenza INDIETRO sarà uguale a 0.

I vari print di controllo riportano valori che ti aspetti?

il pulsante prova a metterlo in modo che la resistenza vada al positivo e il contatto chiuda sul negativo e invece dello stato high leggi se è low.
La parte di cui parli te funziona e i parametri che leggo sono corretti. Per evitare avvolgimenti ho deciso di far fare al motore orizzontale un giro completo da una parte e il ritorno dall'altra. Il pulsate (senza aggiungere il motore verticale) funziona bene, anche controllando il monitor seriale. la parte problematica è questa

Code: [Select]
 if (digitalRead(pulsante)==HIGH) ciclo=ciclo+1;
  
  Serial.print("ciclo= " );
  Serial.println(ciclo);
  delay(100);
  
  
  if (ciclo == 1) {

 digitalWrite(pinDirV, HIGH);
 Serial.print("ciclo= " );
  Serial.println(ciclo);
delay(20);

     for (int z = 0; z <= numStepMotoreV; z++) {
    digitalWrite(pinStepV, HIGH);
    delayMicroseconds(velocita2);
    digitalWrite(pinStepV, LOW);
    delayMicroseconds(velocita2);
  }
  
  delay(20);




Quella che riguarda appunto il motore verticale, che reagisce all'alimentazione muovendosi in modo casuale. La parte che hai indicato tu (quella con i 200 numStepMotore) riguarda invece il motore orizzontale, che funziona correttamente.

-zef-

un pulsante è meglio tenerlo in pullup e leggerne il valore quando è low, dal codice non vedo errori percui venga eseguito in modo casuale quindi presumo che il problema sia il pulsante che capta un qualche disturbo e lo interpreta come un segnale high, altro non saprei le mie conoscenze sono molto limitate  :smiley-confuse:

Go Up