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:
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.
La motor shield r3 arduino originale
Trovi sul sito ufficiale arduino la descrizione della scheda descritta in modo eccellente, incluso il DataSheet.
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:
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.
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 !!!
35 commenti
2 ping
Vai al modulo dei commenti
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
Autore
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
Ciao Mauro
Scusami se faccio un passo indietro, purtroppo sono un meccanico e di programmazione
ahimè ne so proprio poco. Ho tentato di trovare l’errore nell’inversione di marcia del passo passo
ma non ci sono proprio riuscito. Potresti darmi un aiuto nel trovare la strada giusta? Grazie Luca
Ho preso come spunto il tuo sketch da cui vorrei poi arrivare a far fare al motore 10 step a destra e successivamente altri 10 a sinistra per una applicazione che sto studiando.
Ciao grazie.
Autore
Ciao Luca,
certo, è provando e riprovando che si ottengono i migliori risultati.
Se ho compreso la tua difficoltà non riesci a far retrocedere il motore ma sei riuscito a farlo avanzare, il concetto è più semplice di quanto credi, se in avanti la sequenza delle fasi è A-B-C-D per far girare il motore in senso inverso non devi far altro che invertirla D-C-B-A io per farlo memorizzo a che fase sono arrivato e quando deve invertire il verso di rotazione parto da quella e conto al contrario le fasi in un ciclo continuo come per il primo verso.
Mauro
Ciao Mauro
scusa ancora, ma in effetti quello che da subito ho provato di fare
è un seconda funzione giradx(nfase=nfase-1). Credi sia una strada
percorribile, o ne vedi una piu indicata.
Grazie Luca
Autore
Ciao Luca,
ogni problema da affrontare può essere risolto in 100 modi diversi con arduino.
La tua strada è valida ma dipende cosa implementi nello sketch, la prova definitiva te la da il: funziona/non funziona.
Mauro
Salve,
complimenti per l’ottimo sito, in molti ti siamo debitori..
Cosi funzia:
[[ codice rimosso in automtico ]]
nk84
Autore
Ciao Niki,
grazie per i complimenti, purtroppo sai che non è possibile inserire nei commenti il codice degli sketch.
Puoi descrivere che errore ottieni ed eventualmente cosa correggere.
Lo sketch postato nel mio articolo funziona, tu hai rilevato delle differenze?
Niente da fare, continua a inviare il messaggio come vuole lui. Pazienza
Autore
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
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
Autore
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
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à
Autore
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
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 );
}
}
Autore
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
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
Autore
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
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
Ciao Mauro
complimenti per i tuoi tutorial, premetto che di elettronica non ci capisco molto anzi niente,
ma ho dovuto avvicinarmi per forza di cose (costruzione di un dolly fotografico) .
Ho comprato le schede ARDUINO uno rew3 -motor shield R3 originali e finalmente grazie
ai tuoi tutorial sono riuscito a far girare un motore unipolare. Quello che ti chiedo, dato che in questo video
non si vede come ci si comporta con una alimentazione esterna vedi batteria 12V alla scheda shield R3 ?
Cordiali saluti Mario B.
Autore
Ciao Mario,
ho dedicato alcuni video e tutorial specifici al Dolly ed io stesso ne realizzo su commissione oltre a collaborare con dei professionistici ad un prodotto che a breve proporrò.
Ti consiglio di leggere i miei articoli sul dolly per time lapse e approfondire i componenti che ti occorrono e cosa puoi farci.
Mauro
Grazie Mauro per la tempestiva risposta,
ma il mia domanda riguardava esclusivamente sull’alimentazione di quella specifica shield,
dato che sul sito ufficiale di Arduino consigliano onde evitare danni al microcontrollore di
eseguire dei piccoli accorgimenti (Questo è possibile tagliando il “Vin Connect” ponticello posto sul retro dello scudo) che non capisco.
di nuovo grazie e scusa la mia ignoranza.
P.S. notevoli gli articoli riguardi i Dolly anche se troppo impegnativi per le mie capacità. 🙁
Autore
Ciao Mario,
perdonami ma non ho capito e continuo a non comprendere la tua richiesta.
In merito a quale argomento e contesto viene rilasciato il consiglio sul sito arduino?
Io l’unico accorgimento che ho fatto riguarda le piazzole in prossimità di A0 ed A1 che servirebbero come indicatori di assorbimento per i motori in cc e con il passo-passo non occorrono.
Mauro
Ciao Mauro, mi sono da poco avvicinato al mondo Arduino.
Sto utilizzando la motor shield su arduino 2 per muovere un passo passo a 6 pin. Ho utilizzato il tuo esempio e funzionava tutto alimentando arduino attraverso usb. Poi mentre stava girando il programma ho attaccato l’alimentazione alla motorshield (6 volt) che è il voltaggio del mio passo passo ed era tutto ok! stacco l’alimentazione dalla motorshield, E vedo dai led di stato che il canale a rimane sempre acceso e ovviamente il motore nn gira più ma fa uno scatto in avanti e uno indietro. può essere che si sia bruciato il canale a della motor shield ? e rimane sempre su high?purtroppo non ho led per provare i pin di arduino su cui è collegato il canale a!
Autore
Ciao Alberto,
il comportamento che mi descrivi è anomalo se tutto funzionava sia con l’usb connessa sia con i 6v collegati dovrebbe funzionare anche quando togli i 6v.
Considera che l’Arduino Due lavora con i pin a 3,3v, causa di incompatibilità con la maggior parte delle shield in commercio inclusa la motor shield. Tuttavia se si fosse bruciato arduino due a causa dei 6v non avrebbe dovuto funzionare nulla.
Puoi provare a verificare che l’Arduino due sia ancora funzionante con uno sketch di esempio e successivamente provare con due motori in CC per verificare se uno dei due canali risulta malfunzionante.
Mauro
Salve Mauro,
le volevo chiedere un’ ultima cosa riguardo alla Motor Shield di Arduino.
Mi hanno dato il compito di finire il progetto che le avevo detto una settimana fa, però mi hanno anche dato un motore unipolare M35SP-7, e volevo sapere se si poteva fare con la Motor Shield o no, poichè ha 5 cavi.
Motore unipolare : http://www.alldatasheet.com/datasheet-pdf/pdf/176481/MITSUMI/M35SP-7.html
Grazie
Autore
Ciao Marco,
Puoi chiedere tutte le volte che hai un dubbio lecito 🙂
Il motore unipolare é il più semplice da usare con tutte le chiesa perché il comune va a massa e ciascuna fase ad uno dei 4 pin della motor shield.
Grazie intanto per la risposta, ma ancora non ho capito perfettamente.
Nel caso del motore M35SP-7 ho i seguenti colori dei cavi : giallo, arancione, rosso, marrone e nero; e le volevo chiedere a cosa corrisponde ogni cavo???
E quale sarebbe il comune??
Grazie in anticipo
Autore
Ciao Marco, i colori dicono poco, dal datasheet del produttore puoi verificare se ti indica la composizione delle fasi.
Se non é riportata devi procedere come descritto nel mio articolo sui “motori passo passo riconoscerne le fasi” che trovi nel blog.
Ciao . E’ possibile usare questo progetto per pilotare le ventole del PC ?
Autore
Ciao Nicola,
i motori passo-passo sono i meno indicati per quel tipo di controllo.
Io ti consiglio i motori DC
Ciao Mauro,
complimenti per il tuo blog!
Ho sistemato il codice per il problema dell’inversione (fammi sapere se posso postarlo).
Non riesco invece a venire a capo con la perdita dei passi sopratutto a bassa velocità.
Ho provato anche ad usare il delay (della TIMEFASE) con i microsecondi quindi: delayMicroseconds(TIMEFASE);
Ma niete da fare. Se imposto ad esempio 1000 il motore gira bene e non perde passi se provo a mettere 2000 è un delirio. Perde passi/vibra ecc.
Uso come motore un 42byghw811 ed ho collegato il tutto a una power shield della velleman la VMA03.
Sai darmi qualche suggerimento? Thanks!
P.s.
Non so se può essere utile ma utilizzo un alimentatore da 12V 2Amp per il motore anche se l’assorbimento max è di 2.5 (ma in questo momento gira a vuoto!)
Grazie
Autore
Ciao Alessandro,
a quale problema dell’inversione ti riferisci? E’ un problema presente nel mio sketch, non lo ricordo.
Gli sketch non possono essere pubblicati direttamente nei commenti, se è una correzione del mio sketch o una miglioria puoi mandarmelo via email come descritto nella sezione “collebora al blog”
Il secondo problema non mi è chiaro: aumentando il delay tra i passi ottieni perdita di passi e vibrazione ? di solito è il contrario.
Ciao Mauro, avrei bisogno di aiuto per un problema che riguarda il passo passo bipolare con arduino UNO + motor shield avendo intrapreso il mondo arduino da pochissimo tempo.
Dovrei scrivere uno sketch in cui possa realizzare una rotazione di “n passi” in un senso dopo il mio consenso tramite un pulsante normalmente aperto; eseguita la rotazione deve fermarsi e riprendere il moto in verso opposto SOLO dopo il mio consenso con il medesimo pulsante. Ci tengo a precisare che meccanicamente, dopo aver effettuato la prima rotazione viene chiuso un fine corsa che dia il consenso di poter ruotare nel verso opposto per “n passi”.
riusciresti a darmi una mano con tanta gentilezza?
grazie in anticipo
Autore
Ciao Simone,
io realizzo progetti su commissione ed il tuo è certamente fattibile.
Se sei interessato ad una commissione puoi scrivermi sulla casella info di questo blog, quella da cui ti arrivano le notifiche.
[…] 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 […]
[…] qualche tempo a questa parte ho pubblicato degli articoli che usano diverse motor shield oggi ti mostro le foto della Motor Shield Arduino […]