«

»

mar 28

Motori passo-passo, pilotarli con arduino – quinta parte

In questo articolo realizzeremo un listato per pilotare il nostro motore, nel mio caso i due motori, inviando comandi dalla tastiera del pc, il listato originale è quello riportato sul sito arduino, al quale ho applicato alcune modifiche per pilotare 2 motori e non uno solo, come nell’esempio.

Nel prossimo, ed ultimo, articolo di questa serie ti mostrerò un simpatico video in cui due motori compiono in simultanea dei movimenti in base ad una sequenza di comandi inviati dal pc collegato ad arduino.

Passiamo subito all’analisi del codice che ho modificato per pilotare 2 motori:

int motorPinx[] = {8, 9, 10, 11};
int motorPiny[] = {4, 5, 6, 7};
int countX = 0;
int count2X = 0;
int countY = 0;
int count2Y = 0;
int delayTime = 10;
int val = 0;
int lettura = 0;
int letturaX = 0;
int letturaY = 0;
int pLetturaX = 0;
int pLetturaY = 0;

void setup() {
  Serial.begin(9600);
  for (countX=0; countX<4; countX++)
  {
    pinMode(motorPinx[countX], OUTPUT);
  }

  for (countY=0; countY<4; countY++)   {     pinMode(motorPiny[countY], OUTPUT);   }
}

void moveForwardX() {   if ((count2X == 0) || (count2X == 1)) {     count2X = 16;   }   count2X>>=1;
  for (countX = 3; countX >= 0; countX--) {
    digitalWrite(motorPinx[countX], count2X>>countX&0x01);
  }
  delay(delayTime);
}

void moveBackwardX() {
  if ((count2X == 0) || (count2X == 1)) {
    count2X = 16;
  }
  count2X>>=1;
  for (countX = 3; countX >= 0; countX--) {
    digitalWrite(motorPinx[3 - countX], count2X>>countX&0x01);
  }
  delay(delayTime);
}

void stopX() {
  for (countX=0; countX<4; countX++)   {     digitalWrite(motorPinx[countX], LOW);   }
} 

void moveForwardY() {
  if ((count2Y == 0) || (count2Y == 1)) {
      count2Y = 16;
  }
  count2Y>>=1;

  for (countY = 3; countY >= 0; countY--) {
    digitalWrite(motorPiny[countY], count2Y>>countY&0x01);
  }
  delay(delayTime);
}

void moveBackwardY() {
  if ((count2Y == 0) || (count2Y == 1)) {
    count2Y = 16;
  }
  count2Y>>=1;
  for (countY = 3; countY >= 0; countY--) {
    digitalWrite(motorPiny[3 - countY], count2Y>>countY&0x01);
  }
  delay(delayTime);
}

void stopY() {
  for (countY=0; countY<4; countY++)   {     digitalWrite(motorPiny[countY], LOW);   }
}

 void loop() {        lettura = Serial.read();     if ( lettura > 0)
    {
      Serial.print(delayTime);
      Serial.print('X: ', BYTE);
      Serial.print(letturaX, BYTE);
      Serial.print('Y: ', BYTE);
      Serial.print(letturaY, BYTE);
      Serial.print(' ', BYTE);
      Serial.println(lettura, BYTE);

      if ( lettura == 'q' || lettura == 'w' || lettura == 'e' ) { letturaX = lettura; } else { letturaX = pLetturaX; }
      if ( lettura == 'a' || lettura == 's' || lettura == 'd' ) { letturaY = lettura; } else { letturaY = pLetturaY; }
    }

    switch (letturaX) {

        case 'q':
          moveForwardX();
          break;

        case 'w':
          moveBackwardX();
          break;

        case 'e':
          stopX();
          break;
    }

    switch (letturaY) {

        case 'a':
          moveForwardY();
          break;

        case 's':
          moveBackwardY();
          break;

        case 'd':
          stopY();
          break;
    }  

    pLetturaX = letturaX;
    pLetturaY = letturaY;

}

Premetto che la mia idea è di pilotare 2 assi X e Y di una CNC, a tal proposito mi irferirò a ciascun motore con la lettera dell’asse corrispondente.
Le prime righe 1-13 settano le variabili che utilizzeremo per nel resto del codice, in particolare la riga 1 e 2 impostatno i pin che utilizzeremo per pilotare i due motori: 4,5,6 e 7 per l’asse Y e ,9,10 e 11 per l’asse X.
Anche le variabili che seguono sono distinte secondo l’assse di riferimento, fatta eccezione per “delayTime” che definisce la velocità di rotazione i funzione del tempo di attesa tra gli step dei motori, “val” e “lettura” che utilizzerò per memorizzare valori temporanei durante la rotazione.
Le linee 15-27 compongono la funzione di “setup” necessaria ad Arduino a inizializzare le variabili e predisporre, in questo caso, la comunicazione seriale, che utilizzerò per inviare i dati dal pc ad Arduino.

Il codice che segue è composto da funzioni per essere gestito facilmente e per duplicarlo agevolmente per i due assi.
La funzione moveForwardX() ( linee 25-30 ) farà ruotare di un un verso, che per convenzione di trattazione definiremo: avanti, l’albero del nostro motore. Il principio di funzionamento è quello dei numeri binari facendo shiftare ( >> ) il valore del contatore trasferito ai pin di arduino in modo continuo.
Allo stesso modo la funzione moveBackwardX() ( linee 32-41 ) imprimerà all’albero del nostro motore una rotazione nel verso contrario.
La funzione stopX() ( linee 43-45 ) ferma il motore portando a livello logico basso ( LOW ) tutti i pin della scheda Arduino.

Per l’asse Y ho duplicato le funzioni appena descritte cambiando l’array di pin in modo da imprimere comndi all’altro motore.

La funzione loop ( linee 69-126 ), defult Arduino, è eseguita ciclicamente e attende l’invio di una lettera dal pc mediante segnale seriale, le lettere q,w,e inviano comandi all’asse X; le lettere a,s,d inviano comandi all’asse Y.
Le linee 123 e 124 insieme alle righe 79 e 80 si assicurano che a cicli successivi eseguiti dalla funzione loop se non ci sono nuovi comandi restino validi quelli del cisclo precedente, in caso di variazione provvedono a impostarla verso i motori.

Curiosità: per la natura specifica del programma e dei comndi seriali gestiti da Arduino è possibile inviare contemporaneamente ( in un unico invio ) sia comandi all’asse X sia comandi all’asse Y (es.: qa -> rotazione di emtrambi gli assi in avanti, ws -> rotazione di entrambi gli assi indietro, qs -> rotazione X avanti e rotazione Y indietro, ecc… )

Important!


Gentilmente NON incollare sketch nei commenti, usa la casella info del blog che trovi nella pagina contatti.ù

Ti è stato utile questo articolo?
Sostienimi cliccando sugli sponsor, io potrò continuare ad acquistare materiale per scrivere articoli e aiutarti nei tuoi progetti.

Basta un solo click al giorno.

Be Sociable, Share!

28 comments

  1. Massimo

    Complimenti per i tutorial molto chiari e completi… e comprensibili anche da un neofita!

    sono un un principiante con Arduino (ero presente all’Arduino Camp pero’ solo sabato 18).

    ti volevo fare qualche domanda sui motori passo-passo. vorrei smontare una vecchia stampante e utilizzare i motori passo-passo.

    mi puoi chiarire i parametri di datasheet dei motori passo-passo, quali sono i piu’ importanti per poterli pilotare con la scheda Arduino +integrato ULN2003A ?

    grazie

    massimo

    1. Mauro Alfieri

      Ciao Massimo,
      mi spiace non esserci stato il 18, magari ci saremmo conosciuti.

      Non mi ritengo un esperto, sto imparando ogni giorno cose nuove, come te e tanti altri
      conosciuti all’Arduino Camp, e le condivido perchè i nostri passi siano di aiuto a chi
      vuole iniziare.

      Anche io ho smontato delle vecchie stampanti, la discarica di paese è un ottima fonte di
      materiale a costo zero, ciò che ho trovato sono piccoli motori bipolari, non ho ancora
      provato il loro uso in quanto l’ULN2003A non sembra ideale per questi motori, sto
      studiando altri integrati, spero di poterti dare maggiori dettagli presto, magari in un
      articolo.

      Sulle caratteristiche di un motore passo-passo, ho imparato, che sono importanti il
      numero di passi (step), es.: 200 è ottimale, a volte lo indicano in gradi (dec) 1.8 ( 360
      / 1.8 = 200 ), il voltaggio e l’amperaggio, quelli nel tutorial sono 12v 0.44A un po’
      piccoli se devi muovere grossi carichi, nelle Cnc ad esempio si usano solitamente quelli
      con attacco Nema23 da 2/2,5 A con una coppia da 1,2 o 1,8 Nm considera i dati con le
      pinze, io li ho appresi documentandomi in Internet non ho ancora avuto modo di provarli.

      Mauro

  2. paolo

    caio!
    ho visto un tuo progetto riguardante i motori passo passo.

    sarei interessato a costruire un mini centro di a 3 assi e muoverlo con i motori passo passo.

    per quanto riguarda la parte fisica (meccanica) non ho problemi …sono in grado di costruire quasiasi cosa, ma a riguardo la parte elettrica e il modo di programmare sono molto scarso.

    sei disposto a darmi una mano?
    che tipo di motori devo comperare?
    tutti i componenti che mi sevono?
    e come devo collegarli?
    e naturalmante la parte del programma?
    quella che hai fatto con 2 motori va bene ma vorrei mettere anche il 3°

    Paolo

    1. Mauro Alfieri

      Ciao Paolo, sono sempre contento quando si può collaborare, anche io vorrei realizzare una cnc con 3 assi e la parte meccanica un po’ mi crea problemi come il disegno CAD.
      Per questo cerco collaborazioni come la tua. Ora sono lontano da casa e riprenderò i progetti al rientro 1/2 agosto. Se ti va possiamo aggiornarci dopo questa data.

      Ciao Mauro

  3. Paolo

    se il fatto che non sono laureato per te non è un problema si puo fare.
    Io per quanto riguarda il disegno Cad, programmazione cnc e realizare quasiasi cosa con macchine utensili, ho veramente pochi limiti, mentre la programmazione C o simili sono alle prime armi e forse non riuscirò mai tanto di più.

    Comunque io un cnc l’ho iniziato…

    mi farebbe veramente piacere collaborare a qualche iniziativa

    saluti Paolo

    1. Mauro Alfieri

      Ciao Paolo,
      laurea??? nenache io lo sono :-) e non me la cavo male.
      Per la programmazione non è un problema anche se io sto pensando a qualcosa di un po’ più immediato per una cnc.
      Mi invii foto, disegni o qualche altra info sulla CNC che stai già realizzando? così procediamo assieme nelle fasi successive, invia pure tutto a info at mauroalfieri dot it.

      Attendo tue info
      Ciao

  4. paolo

    ciao mauro,
    avrei bisogno di un grosso favore;
    ho visto che con paolo state provando a realizzare una cnc a tre assi, potrei avare anche io qualche informazione in più riguardo alla programmazione, e potrei anche sapere se è possibile fare un programma per arduino che legga il codice g?
    grazi anticipatamente

    1. Mauro Alfieri

      Ciao Paolo,
      stiamo ancora lavorando al progetto e per adesso non abbiamo ancora nulla di pubblicabile e da condividere.
      Per l’interpretazione del “gcode” con Arduino cerca il progetto RepRap con Arduino, sto seguendo anche io quella stada.
      Quando avrai realizzato qualcosa di pubblicabile, e se lo vorrai, sono a tua disposizione per aiutarti a scrivere uno o più articicoli in merito.

      Buon lavoro
      Mauro

  5. paolo

    ciao mauro, in internet ho trovato un programma per arduino per una cnc a tre assi con arduino uno, l’ho provato, pero non mi fa caricare la libreria ad arduino.
    Il sito è:http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293881339/all
    spero che tu ci riesca, e se vuoi mi fai sapere come hai fatto.
    grazie..
    paolo

    1. Mauro Alfieri

      Ciao Paolo,
      di quelli presenti nel link che mi indichi quale è il sw su cui mi chiedi un aiuto?
      Puoi darmi il link diretto? lo provo volentieri e se vuoi poi scriviamo un articolo in italiano a 4 mani su questo sw e qualche esperimento che avrai eseguito.

      Grazie

  6. paolo

    ciao mauro,
    questi 2 sono i link:il 1° http://www.mmcpix.com/CNC/CNCdriver.zip
    è il programma per il computer ed il 2° http://www.mmcpix.com/CNC/GCode_Interpreter.zip è la libreria per arduino.Io li ho scaricati, il programma funziona, arduino xo non vuole accettare la libreria =(…. non so che fare… spero che tu ci riesca.Comunque per l’articolo per me va benissimo…

  7. paolo

    ciao mauro,
    oggi sono riuscito a caricare ad arduino la libreria, però ho il motore che mi va a scatti, cosa può essere?

    1. Mauro Alfieri

      Ciao Paolo,
      mi fa piacere che tu si sia riuscito autonomamente se vuoi aggiungi qual’era l’errore cos’ che altri amici appassionati possano risolvere con i tuoi suggerimenti.
      I motori stepper si muovono per loro natura con scatti continui, da cui il nome stepper o passo-passo, se ritieni che si muovano troppo lentamente probabilmente esiste nello sketch un parametro che regola il deplay ( o ritardo ) nella rotazione e abbassando quel valore vedrai un movimento più fluido.
      Io ticonsiglio di cercare quel parametro e modificarlo secondo la tua necessità, attenzione solo che in alcuni ambiti tipo le CNC la velocità ha molte controindicazioni, alcune pericolose.
      Quando lo avrai finito mi farebbe piacere pubblicare il tuo progetto se mi mandi un piccolo articolo e le foto.

      Ciao

  8. paolo

    ciao mauro,
    l’errore stava solo nel fatto di aggiornare il programma di arduino, comunque non ho il problema della lentezza del motore, ma quella che al primo impulso fa un passo avanti e nel secondo uno in dietro. Ho provato anche a mudificare il posizionamento dei cavi in tutte le soluzioni possibili. però il risultato è uguale : avanti, indietro, avanti, indietro ecc… a te che ne sai, ti è mai capitato??

    1. Mauro Alfieri

      Ciao Paolo,
      quello che desrivi è il più classico degli errori e dipende solitamente dal collegamento delle bobine, prova a seguire i miei articoli sui motori stepper troverai una tabella che ti aiuta a capire come identifiare le bobine del tuo motore, e come eseguire i primi semplici test di rotazione, copresi quelli puoi collegare il motore ad Arduino e uplodare lo sketch.
      Se hai dubbi dopo aver letto e compilato la tua tabella, inviamela e provo a decifrarla io.

      Ciao

  9. paolo

    ciao mauro, grazie mille adesso ci proverò e ti farò sapere…

  10. paolo

    ciao mauro,
    è normale che ho valori diversi, tipo 18.8 , 37.4 , e poi nei miei motori i cavi sono a coppie, cioè (rosso,rossobianco) (giallo,giallobianco) e poi 2 soli nero e bianco.

    1. Mauro Alfieri

      Ciao Paolo,
      si è corretto, ha eseguito le corrette misurazioni. Da quello che leggo il tuo motore è a 6 fili quindi simile a quello descritto in questo articolo:
      http://www.mauroalfieri.it/elettronica/motori-passo-passo-unipolari-riconoscerne-le-fasi-seconda-parte.html
      Come vedi dalla tabella i valori misurati sulla singola fase nel mio caso erano 20 ohm e sugli estremi di 2 fasi di 40 ohm, i valori che leggi tu sono del tutto simili, 18.8 dove io ho 20 e 37.4 dove ho 40.
      Copila la tua tabella mettendo i dati come ti ho descritto e troverai le tue fasi.
      Leggendo quello che mi scrivi direi che il tuo nero e nero e bianco sono i comuni, ma potrei sbagliare, se così fosse uno sarà il pin A e l’altro il pin B della mia illustrazione.

      Come ti ho indicato in precedenza dopo aver compilato la tabella inviamela in jpg o altro formato ed io posso provare a dirti quali sono le fasi.

      Ciao
      Mauro

  11. paolo

    ciao mauro, come non detto , grazie alla tabella , ho riflettuto un po e ci sono riuscito . grazie per l’aiuto….

    1. Mauro Alfieri

      Sono contento, sia che i miei consigli ti siano stati utili sia che applicando un po’ di ragionamento sia diventato tutto più chiaro, è una conoscenza che ti rimarrà per sempre, e non solo per questo progetto, per questo ti ho invitato a ragionarci da solo.
      La soddisfazione è maggiore se capisci tutto il meccanismo.
      Mauro

  12. paolo

    i comuni erano il rosso bianco e il giallobianco, la tabella te l’ho inviata su facebook xk qui non ci riuscivo, comunque mi sapresti indicare un driver che abbia in ingresso step e dir e all’uscita le fasi del mio motore?
    grazie infinitamente per l’aiuto….

    1. Mauro Alfieri

      Ottimo Paolo, dalla tabella che mi hai inviato sono giunto anche io alla stessa conclusione.

  13. Lorenzo

    Cao Mauro complimenti per tutto quello che fai
    io sono ancora alle prese con i motori possibile che ci siano motori non compatibili con l’arduino tipo m42sp-13nk Mitsumi 96 passi unipolare 4 fili non riesco proprio a farli girare ne con ULN2003 e tanto meno con la motorsheild_fe di futura elettronica vorrei proprio sapere dove commetto l’errore
    il listato che proponi nella quinta parte mi da errore
    sketch_dec26a.cpp: In function ‘void setup()’:
    sketch_dec26a:16: error: ‘lt’ was not declared in this scope
    sketch_dec26a:16: error: expected `)’ before ‘;’ token
    sketch_dec26a:16: error: expected `;’ before ‘)’ token
    sketch_dec26a:21: error: ‘lt’ was not declared in this scope
    mi puoi spegare gentilmente
    ciao a presto

    1. Mauro Alfieri

      Ciao Lorenzo,
      grazie per i complimenti.
      Non posso mettere la mano sul fuoco in merito alla compatibilità di Arduino con tutti i motori passo passo, anche perchè molto dipende da V e A di pilotaggio.
      Tuttavia Arduino si limita ad inviare sol segnali alto e basso alle bobine, al max ti server un driver adatto per quel motore.
      Un primo dubbio sei certo di possedere un unipolare? con 4 fili non ricordo esistano unipolari, al max bipolari.

      Prima di iniziare qualsiasi epserimento leggi tutti i miei articoli sui motori passo-passo, in questo: http://www.mauroalfieri.it/elettronica/motori-passo-passo-come-riconoscerli.html ad esempio trovi la classificazione e come funzionano.

      Vedrai che dopo aver letto gli articoli ti sarà più chiaro come funzionano, come pilotarli e perchè a te non funziona il driver acquistato.
      Per il codice si tratta solo di un errore di copia e incolla dei caratteri sul web: < è in realtà un < mentre > è >, grazie per la segnalazione correggo il codice mostrato.

      Ciao

  14. Lorenzo

    Ciao si in effetti volevo dire bipolari
    i tuoi articoli li ho letti ma non ne ne vado fuori continuerò a provare. ciao e grazie

    riguardo il codice e andato avanti un pezzo
    con la versione arduino 022 funziona
    mentre con la 1.0 non riconosce la parola BYTE
    As of Arduino 1.0, the ‘BYTE’ keyword is no longer supported.
    Please use Serial.write() instead.

    ciao ciao

    1. Mauro Alfieri

      I miei articoli si riferiscono a motori unipolari, i bipolari non puoi pilotarli con l’ULN2003 io ho acquistato degli SN754410NE come mostrato in questo post: http://www.arduino.cc/en/Reference/StepperBipolarCircuit su sito ufficiale, appena riesco provo i motori bipolari e scrivo un articolo.
      Se risolvi prima tu e vuoi condividere con il tutti noi la tua esperienza inviami qualche riga di codice, foto e se riesci un video che pubblico volentieri la tua esperienza.

      Ciao

  15. Federico

    Ho visto i tuoi lavori. Complimenti veramente! Premetto che ho scoperto il mondo di arduino da pochi mesi. Sto costruendo una stampante 3d che sfrutta la proiezione dlp e usa una resina uv. Penso di avere risolto tutto tranne un banale problema, che per me non è semplice da risolvere. Devo muovere un piano sull’asse z. Ho trovato tutto tranne la possibilità di posizionare ad un punto di partenza prestabilito il piano (uno zero relativo). Il software che uso non ha la possibilità, almeno io no sono capace di fare questa operazione che per me è indispensabile. Come posso programmare un movimento di un motore passo passo in modo che si posizioni sempre in quel punto? Se mi puoi aiutare te ne sarei grato.

    Ciao Federico

    1. Mauro Alfieri

      Ciao Federico,
      ho riportato la tue email in un commento per condividere con tutti gli utenti la tua richiesta e il tuo progetto, molto interessante.
      Il problema che hai riscontrato pensa abbia origine dal fatto che per riportare in posizione zero il l’asse è necessario che arduino sappia di quanto si è spostato tale asse, in pratica quanti passi ha compiuto il motore.
      Se questa info non arriva dal sw che stai usando, o se non riesci a ricavarla, penso che la soluzione sia lo spostamento manuale, potresti optare per 2 pulsanti con cui riposizionare il piano Z dopo la lavorazione.

      Sul blog ci sono numerosi esempi su come pilotare i motori passo-passo e c’è sicuramente un articolo dedicato al pilotaggio con pulsanti.

      L’alternativa che mi viene in mente è un sensore di finecorsa in posizione 0, potrebbe essere un semplice pulsante o un finecorsa ottico che dica ad Arduino “sei arrivato al punto 0″.

      Se mi dici che tipo di motore stai utilizzando e quale soluzione pensi possa fare al caso tuo posso provare a darti qualche dritta.

      Mauro

Lascia un Commento

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

Puoi usare i seguenti tag HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>