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 !!!











13 comments
2 pings
domenico
25 marzo 2013 a 00:09 (UTC 2) Link to this comment
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
Mauro Alfieri
25 marzo 2013 a 07:38 (UTC 2) Link to this comment
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
domenico
30 marzo 2013 a 11:28 (UTC 2) Link to this comment
Niente da fare, continua a inviare il messaggio come vuole lui. Pazienza
Mauro Alfieri
1 aprile 2013 a 10:37 (UTC 2) Link to this comment
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
Antonio
7 aprile 2013 a 15:11 (UTC 2) Link to this comment
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
Mauro Alfieri
7 aprile 2013 a 18:16 (UTC 2) Link to this comment
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
Antonio
10 aprile 2013 a 23:58 (UTC 2) Link to this comment
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à
Mauro Alfieri
12 aprile 2013 a 09:59 (UTC 2) Link to this comment
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
Antonio
12 aprile 2013 a 22:11 (UTC 2) Link to this comment
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 );
}
}
Mauro Alfieri
13 aprile 2013 a 09:37 (UTC 2) Link to this comment
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
Antonio
24 aprile 2013 a 21:41 (UTC 2) Link to this comment
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
Mauro Alfieri
25 aprile 2013 a 07:39 (UTC 2) Link to this comment
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
Antonio
25 aprile 2013 a 19:36 (UTC 2) Link to this comment
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
Dolly Photo – quarta parte - Mauro Alfieri Elettronica Bricolage Robot
4 marzo 2013 a 08:29 (UTC 2) Link to this comment
[...] 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 [...]
Motor Shield Arduino - Mauro Alfieri Elettronica Robotica Bricolage
18 marzo 2013 a 08:30 (UTC 2) Link to this comment
[...] qualche tempo a questa parte ho pubblicato degli articoli che usano diverse motor shield oggi ti mostro le foto della Motor Shield Arduino [...]