«

»

feb 18

Motor Shield R3 Arduino – motore passo-passo

A volte ritornano disse Stephen King. Ma non voglio scomodare personaggi così in alto, ultimamente mi è capitata tra le mani una Motor Shield R3 Arduino originale:

motor shield r3 arduino

ed ho pensato: per pilotare motori in CC ci sono migliaia di sketch nel web, del resto nasce per questo scopo, ma se volessi utilizzarla per pilotare un motore passo-passo?

Avevo già usato la  motor shield fe in modo improprio per pilotare un motore passo-passo bipolare e l’esperimento aveva riscosso grande successo tra gli appassionati dei motori passo-passo.

Purtroppo la  motor shield fe è venduta in kit da montare compreso il L298P in formato SMD che necessita di mano ferma, esperienza e strumentazione adeguata, insomma un vero incubo.

Da questa riflessione nasce l’idea di sostituirla nei miei tutorial con la motor shield r3 arduino e nei prossimi articoli mi procurerò anche altre shield simili che potrai utilizzare.

motor shield r3 arduino

La  motor shield r3 arduino originale

Trovi sul sito ufficiale arduino la descrizione della scheda descritta in modo eccellente, incluso il DataSheet.

motor shield r3 arduino

Con la motor shield r3 arduino può comandare due motori in cc, come leggi nel paragrafo summary riportato sopra, o un solo motore da 4A impostando l’alimentazione esterna.

Non si cita la possibilità di utilizzarla per i motori passo-passo, infatti questa shield non nasce con questo compito.

I pin della motor shield r3 arduino

i pin della motor shield r3 arduino a cui sono collegati i motori non sono impostabili, sono:

motor shield r3 arduino pin

come riportato sul sito ufficiale, nel tuo progetto con i motori passo passo useremo solo i pin di direzione e PWM tralasciando i pin Brake e current sending, valuteremo in un prossimo articolo come utilizzarli.

motor shield r3 arduino

Lo sketch per usare la motor shield r3 arduino con i passo-passo

Mi sento in dovere di fare una precisazione, il motore passo-passo che puoi usare in questo progetto è di tipo bipolare:

/**********************************************************/

#define TIMEFASE 20
#define DEBUG

#define PWMA 3
#define PWMB 11
#define DIRA 12
#define DIRB 13

/**********************************************************/

int nFase     = 0;

/**********************************************************/

void setup() {

  #ifdef DEBUG
    Serial.begin( 9600 );
    Serial.println("Avvio");
  #endif

  /**********************************************************/

  pinMode(PWMA, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(DIRA, OUTPUT);
  pinMode(DIRB, OUTPUT);

  /**********************************************************/

}

/**********************************************************/

void loop() {

  eseguiStep( 50,true );
  stop();
  delay( 1000 );
  eseguiStep( 100,true );
  stop();
  delay( 1000 );
  eseguiStep( 200,true );
  stop();
  delay( 3000 );

}

/**********************************************************/

int fase( int nFase ) {

  switch( nFase ) {
  case 1:
    digitalWrite(DIRA, HIGH);
    digitalWrite(DIRB, LOW);
    digitalWrite(PWMA, HIGH);
    digitalWrite(PWMB, LOW);
    break;

  case 2:
    digitalWrite(DIRA, LOW);
    digitalWrite(DIRB, HIGH);
    digitalWrite(PWMA, LOW);
    digitalWrite(PWMB, HIGH);
    break;

  case 3:
    digitalWrite(DIRA, LOW);
    digitalWrite(DIRB, LOW);
    digitalWrite(PWMA, HIGH);
    digitalWrite(PWMB, LOW);
    break;

  case 4:
    digitalWrite(DIRA, LOW);
    digitalWrite(DIRB, LOW);
    digitalWrite(PWMA, LOW);
    digitalWrite(PWMB, HIGH);
    break;
  }
  delay(TIMEFASE);

  return nFase;
}

/**********************************************************/

int stop() {
  delay( 500 );

  digitalWrite(DIRA, LOW);
  digitalWrite(DIRB, LOW);
  digitalWrite(PWMA, LOW);
  digitalWrite(PWMB, LOW);
}

/**********************************************************/

void eseguiStep( int passi, boolean dir ) {
  if ( passi <= 0 ) { return; }
  if ( dir ) { for ( int p=1; p<=passi; p++) { gira(); } }
  else       { for ( int p=passi; p>=1; p--) { gira(); } }
}

/**********************************************************/

void gira() {
  nFase = (nFase+1);
  if ( nFase > 4 ) { nFase=1; }
  fase( nFase );
}

/**********************************************************/

Gran parte dello sketch è descritto in questo mio precedente articolo, le differenze principali riguardano due nuove funzioni che trovi in fondo, ma parti con ordine:

linea 03: definisci una costante contenente il TIMEFASE ossia il tempo che deve trascorrere tra una fase e la successiva, questo valore determina la velocità di rotazione e può influire sul funzionamento o meno del motore;

linea 04: definisci la costate DEBUG che usi per visualizzare eventuali messaggi di debug sul monitor seriale, vedrai nella funzione setup() come viene utilizzata;

linee 06-09: definisci le costanti a cui sono connessi i pin della motor shield r3 arduino come visto nello specchietto riportato sopra;

linea 13: definisci la variabile nFase in cui memorizzi il valore della fase a cui sei arrivato.

linea 19: verifica se è definita la costante DEBUG il comando #ifdef verificca che esista e sia definita una costante, nel tuo progetto DEBUG, in caso affermativo esegue le linee di codice fino al comando #endif ( vedi linea 22 );

linee 20-21: Imposta la comunicazione con il monitor seriale a 9600 baud e scrivi “Avvio”;

linea 22: chiudi il blocco di codice #ifdef-#endif per il DEBUG;

linee 26-29: definisci la modalità di funzionamento dei pin a cui è connessa la motor shield r3 arduino come pin di tipo OUTPUT;

linea 39: richiami la funzione eseguiStep( step,verso ) questa funzione l’ho scritta io e te la descrivo di seguito, per adesso è necessario che tu comprenda i due parametri dda passare alla funzione, il primo è il numero di step da eseguire ed il secondo parametro è il verso di rotazione: true = orario, false = antiorario;

linee 40-41: ferma il motore richiamando la funzione stop() e attendi un secondo prima di procedere oltre;

linee 42-47: esegue le stesse operazioni delle linee 39-41 per un numero di differenti passi da far eseguire al motore passo-paso bipolare.

linea 53-87: è la funzione fase( nFase ) descritta nell’articolo citato, l’attività che compie è quella di spostare il motore al passo inviato tramite il parametro nFase. Ho aggiunto a questa funzione la linea 84 con il delay impostato sul TIMEFASE definito sopra. Ho anche aggiunto un return nFase (linea 86) che ritorna il valore della fase in cui è posizionato il motore alla funzione chiamante;

linee 91-98: definisci la funzione stop che attende 500 millisecondi ( linea 92 ) e poi invia il segnale LOW a tutti i pin della motor shield r3 arduino;

linee 102-106: è definita qui la funzione eseguiStep( step,direzione ) che hai richiamato alle linee 39,42,45 dello sketch. La sua caratteristica è controllare che il numero di passi da eseguire sia superiore a 0, ed in funzione del parametro dir definire un ciclo di n passi da far eseguire al motore richiamando la funzione gira();

linee 110-114: definisci una nuova funzione gira() il cui scopo è impostare la fase corrente, calcolare la fase successiva e inviare queste informazioni alla funzione fase() perchè li esegua. Per farlo alla linea 111 calcola nFase incrementando di uno il suo valore precedente, controlla che nFase non superi il valore 4 ( linea 112 ) ed infine richiama la funzione fase( nFase ) passandole il valore calcolato.

Il video demo della motor shield r3 arduino

Per mostrarti il risultato dello sketch che hai appena visto ho realizzato un video demo:

Buon divertimento !!!

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!

Related posts

13 comments

2 pings

  1. domenico

    Salve, ho provato lo scetch con il motor shield r3 ma mettendo false invece di true alle linee 39,42,45, non mi inverte il senso di marcia.
    Sbaglio qualcosa io ?
    Grazie, Domenico

    1. Mauro Alfieri

      Ciao Domenico,
      hai ragione, c’é un errore, lo correggerò. Grazie !!!
      Intanto ti sfidò a trovare l’errore e segnalamelo, se ti va, é un esercizio interessante.
      Puoi aiutarti anche con gli altri sketch per motori passo-passo presenti sul Blog.

      Mauro

  2. domenico

    Niente da fare, continua a inviare il messaggio come vuole lui. Pazienza

    1. Mauro Alfieri

      Ciao Domenico,
      comprendo, il commento non è fatto per postare codice, lo distorce :-)
      Se ti va inviami le modifiche alla casella info del blog, la trovi nella pagina contatti ed io le pubblicherò volentieri.

      Mauro

  3. Antonio

    Ciao Mauro
    complimenti per i tuoi lavori svolti e a dir la verità sono po invidioso, sei troppo bravo
    le faccio una piccola premessa mi è sempre piaciuta l’ elettronica ma per vari motivi no l’ho studiata abbastanza sono rimasta alla base .
    il mio sogno era quello di farmi un piccolo plastico ferroviario con scambi ,passaggio a livello e reed comandati manualmente tramite relè ,trasinstor diodi ect, etc . morale l’ho fatta con i due treni che andavano uno in un senso e l’altro nell’altro senso però non ho inserito il passaggio a livello perché non sono riuscito a comandare i servi, va bene , da poco ho scoperto arduino e ho visto che si possono fare tante cose di cui pilotare anche i servi .
    A questo punto vorrei automatizzarla .
    Domanda è una cosa fatibile ,si può fare come posso fare ?
    Lei sarebbe così gentile da darmi qualche consiglio.

    grazie fin ora e di nuovo complimenti

    1. Mauro Alfieri

      Ciao Antonio,
      anche io non ho studiato elettronica e non conosco tante cose che vorrei conoscere quindi siamo forse allo stesso livello :-)
      Io ogni giorno sperimento, provo e mi documento su ciò che mi piace e ciò che voglio realizzare, è questo mi da la soddisfazione di imparare sempre cose nuove e scoprire modi di realizzarle.

      Per il passaggio a livello sei fortunato, è possibile e sopratutto ho già scritto un articolo, o forse più di uno dedicato proprio ad un passaggiio a livello con l’aiuto di un modellista ferroviario che mi ha mandato dei bellissimi video :-)

      Cercali nel blog e consultali, se hai bisogno di qualche delucidazione in più commenta direttamente quegli articoli :-)
      Mauro

      1. Antonio

        Grazie di avermi scritto per il passaggio a livello ho trovato tutto quello che mi serviva è quello comandato da pulsanti o microswitch l’ho testato ed è funzionate solo che : vorrei sostituire i microswitch con i CNY70 o QRD1114
        ” sono sensori che fanno la sessa cosa ” oppure con sensori magnetici tipo SS411A op.SS443A, saresti così gentile da darmi qualche imput sullo sketch se non chiedo troppo
        per il motore e ok ho usato L293 e anche la motor shield di arduino . ps. “una cosa banale la basetta con il L293 la gestisco meglio della motor shileld” per vora va avanti e indietro .
        poi penserò ai scambi e ai semafori .
        Granzie ancora della sua disponibiltà

        1. Mauro Alfieri

          Ciao Antonio,
          ho dato un occhio ai sensori che mi hai indicato, i primi non sono dei normali interruttori, ma sensori ottici.
          Lo sketch non dovrebbe cambiare nulla, se li usi, ma le connessioni elettriche dovrai strutturarle diversamente.

          Non possedendo tali sensori mi è difficile comprenderne il funzionamento solo dai datasheet.

          Ti consiglio l’uso di interruttori magnetici, i secondi che mi indichi, dovrebbero avere un comportamento simile ai semplici pulsanti.
          In questo nodo non dovrai fare modifiche al circuito ed allo sketch.

          Mauro

          1. Antonio

            Ciao Mauro

            Questo è il sketch che o usato per il passaggio a livello che con i pulsanti va benissimo “e il tuo ”

            o provato a sostituire i pulsanti con i sensori magnetici ma dal pulsante uscivano le 5 volt e premendo chiudeva il contatto e dava 0 ,i sensori magnetici danno 0 e al passaggio della calamita danno 5 volt praticamente lavorano al contrario devo cambiare tipo di sensore o basta sostituire qualcosa nello sketch

            grazie e saluti Antonio

            #include

            #define servoPin 5
            #define swClose 2
            #define swOpen 3
            #define ledSemaf 4

            #define posMin 0
            #define posMax 55
            #define timePL 14

            boolean statoPL=false;
            int currentGrad=posMax;

            Servo myservo;

            void setup()
            {
            pinMode( swClose,INPUT );
            pinMode( swOpen,INPUT );
            pinMode( ledSemaf,OUTPUT );

            myservo.attach(servoPin);
            myservo.write(currentGrad);
            digitalWrite( ledSemaf,LOW );
            }

            void loop()
            {
            if ( digitalRead(swClose) == HIGH) { statoPL = true; }
            if ( digitalRead(swOpen) == HIGH) { statoPL = false; }

            if ( statoPL == true && currentGrad > posMin) {
            digitalWrite( ledSemaf,HIGH );
            while (currentGrad > posMin) {
            currentGrad–;
            myservo.write(currentGrad);
            delay(timePL);
            }
            }

            if ( statoPL == false && currentGrad < posMax) {
            while (currentGrad < posMax) {
            currentGrad++;
            myservo.write(currentGrad);
            delay(timePL);
            }
            digitalWrite( ledSemaf,LOW );
            }

            }

          2. Mauro Alfieri

            Ciao Antonio,
            puoi procedere in due direzioni:

            A. cambi lo sketch rilevano HIGH e LOW invertiti
            B. colleghi i sensori con apposite resistenze di pul-down per ottenere l’inversione dei valori restituiti.

            Mauro

  4. Antonio

    Ciao Mauro
    Scusa se ti scoccio ma non so dove sbattere la testa, il passaggio a livello con i sensori ottici QDR1114
    funziona alla grande ,ottimo ho sostituito o invertito HIGH e LOW , però il mio problema è il seguente :posso usare parte dello sketch per accendere un led e dopo tot secondi farlo spegnere sempre tramite sensori ottici e in un altro caso fare la viceversa
    1° caso il led inizialmente deve essere acceso poi passando davanti al sensore si deve spegnere per un determinato tempo e poi riaccendersi
    nel 2°caso il led deve essere spento passando davanti al sensore deve accendersi per poi spegnerlo da un altro sensore +avanti
    mi puoi aiutare ,per favore
    Grazie Antonio

    1. Mauro Alfieri

      Ciao Antonio,
      bene sono contento del tuo risultato.
      Certo che puoi usare parte dello sketch per fare quello che desideri.
      A leggere la tua descrizione mi sembra tu voglia realizzare il semaforo per plastico, devo aver scritto un articolo in merito qualche mese fa.

      quando avrai realizzato il tuo plastico, se ti va, inviami le foto, video, sketch e cercherò di pubblicarlo.

      Mauro

      1. Antonio

        Ciao Mauro
        Scusami ancora una volta nei tuoi appunti ho trovato questo sketch riguardante un sensore il codice è il seguente

        /**********************************************************
        * SHARP IA57HR
        *
        * Data creazione 17 marzo 2013
        * Ultima modifica 20 marzo 2013
        *
        * autore: Mauro Alfieri
        * web: mauroalfieri.it
        * tw: @mauroalfieri
        *
        /**********************************************************/

        #define pinSensore A0
        #define pinLed 13

        void setup() {
        Serial.begin( 9600 );

        pinMode( pinSensore,INPUT );
        pinMode( pinLed,OUTPUT );

        digitalWrite( pinSensore,LOW );
        digitalWrite( pinLed,LOW );

        Serial.println( “Fine Setup” );
        }

        void loop() {
        int valSensore = analogRead( pinSensore );
        digitalWrite( pinLed,LOW );

        Serial.print( “Valore Sensore: ” );
        Serial.println( valSensore );

        if ( valSensore < 1000 ) {
        digitalWrite( pinLed,HIGH );
        delay( 2000 );
        }
        delay( 100 );
        }

        con il sensore che uso io e precisamente qdr1114 che mi funziona regolarmente dopo aver messo delle resistenze al suo posto .
        la funzione che fa è la seguente mettendo qualcosa davanti al sensore mi spegne il led e fin qua tutto bene ,mi manca però , la seguente funzione ,sempre tenendo qualcosa davanti al sensore , dandogli non so un tot di secondi far riaccendere il led non so se mi sono spiegato spero di un piccolo aiuto

        Grazie e saluti Antonio

  1. Dolly Photo – quarta parte - Mauro Alfieri Elettronica Bricolage Robot

    [...] arduino hai già avuto modo di vederla all’opera con i motori passo-passo in questo articolo: “Motor Shield R3 Arduino – motore passo-passo” ho deciso di utilizzarla anche per il nuovo Dolly [...]

  2. Motor Shield Arduino - Mauro Alfieri Elettronica Robotica Bricolage

    [...] qualche tempo a questa parte ho pubblicato degli articoli che usano diverse motor shield oggi ti mostro le foto della Motor Shield Arduino [...]

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>