Questo articolo riprende e continua il filone del progetto Dolly Photo la nuova versione del Dolly Project che ho realizzato sulla base delle richieste giunte da molti appassionati fotografi e makers come te.
Nella quarta parte del progetto troverai come collegare la motor shield arduino, il motore stepper ed il keypad LCD e provi il reset del motore.
L’operazione di reset ti consente di verificare che il progetto funzioni e che i collegamenti tra arduino-motor shield-keypad lcd-motore siano corretti.
Il montaggio del Dolly Photo
Questa versione del Dolly Photo è studiata per essere decisamente più semplice da montare rispetto al suo predecessore infatti tutte le shield sono già vendute pre-assemblate.
Puoi semplicemente comporle come in figura:
una sull’altra nell’ordine, partendo dal basso verso l’alto:
- Arduino Uno R3
- Motor shield Arduino
- Keypad LCD
Nella figura sopra vedi anche che l’alimentazione arriva dall’esterno attraverso un trasformatore stabilizzato da 12v che fornisce allo stesso tempo alimentazione a tutto lo stack di schede o panettone ( come alcuni appassionati lo chiamano )
Il motore passo-passo del Dolly Photo
Il motore passo-passo che vedi in figura è quelo che ho utilizzato come dimostrazione e test, quello che trovi nel kit Dolly Photo è lo stesso motore previsto per la versione precedente del Dolly Project:
in cui puoi riconoscere le fasi osservando questo video:
Il motore passo-passo che ho utilizzato per i test è questo:
il modo in cui i due motori sono connessi alla motor shield è lo stesso, cambiano i colori dei fili ma le coppie A e B del motore sono le medesime.
La motor shield arduino per il Dolly Photo
La motor shield 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 Photo:
Collega i fili della coppia A sul canale 1 e i fili della coppia B sul canale 2, ricordati di alimentare la shield e tutto arduino con un alimentatore esterno da 12v ed esegui i tuoi test senza la connessione al Pc, ossia con la porta USb scollegata:
questa situazione ti premette di evitare inconvenienti dovuti a carico eccessivo delle porte USB del tuo computer o peggio di bruciarle se qualche componente non si comporta in modo adeguato.
Lo sketch del DollyPhoto con funzione reset
Ho arricchito lo sketch aggiungendo righe di codice nella funzione reset:
/**********************************************************
* Dolly Photo Arduino
*
* Data creazione 25 febbraio 2013
*
* autore: Mauro Alfieri
* web: mauroalfieri.it
* tw: @mauroalfieri
*
*
/**********************************************************/
#include <LiquidCrystal.h>
/**********************************************************/
#define BUTTON A0
#define BACKLIGHT 10
#define MOTDTIME 2000
#define LCDTIME 3000
#define SETMODETIME 2000
#define DEBUG
/**********************************************************/
#define PWMA 3
#define PWMB 11
#define DIRA 12
#define DIRB 13
#define TIMEFASE 35
/**********************************************************/
char line0[16] = "Dolly Foto ver1";
char line1[16] = "mauroalfieri.it";
/**********************************************************/
int SELECT[] = {720,760};
int LEFT[] = {480,520};
int RIGTH[] = {0,20};
int UP[] = {120,160};
int DOWN[] = {300,350};
int buttonPress = 0;
int nFase = 0;
/**********************************************************/
unsigned long timeToBlacklight = 0;
unsigned long timeToSetMode = 0;
unsigned long timeSetting = 0;
/**********************************************************/
boolean blacklightStatus = false;
/**********************************************************/
byte symbolselect[8] = {B00001,B00011,B00111,B01111,B00111,B00011,B00001};
byte symbolplay[8] = {B10000,B11000,B11100,B11110,B11100,B11000,B10000};
byte symbolstop[8] = {B00000,B11111,B11111,B11111,B11111,B11111,B00000};
byte symbolpause[8] = {B00000,B10001,B10001,B10001,B10001,B10001,B00000};
/**********************************************************/
char* principale[4] = {"Impostazioni","Verifica","Reset Carrello","Avvio"};
char* secondario[10] = {"Numero passi","per scatto","Intervallo tra","i passi","Tempo di ALT","prima","Tempo di ALT","dopo","Numero scatti","totali"};
char buffer[16];
/**********************************************************/
int passiXscatto = 0;
int intervaloScatto = 0;
int tempoAltPrima = 0;
int tempoAltDopo = 0;
int numeroScatti = 0;
/**********************************************************/
LiquidCrystal lcd(8,9,4,5,6,7);
/**********************************************************/
void setup() {
#ifdef DEBUG
Serial.begin( 9600 );
Serial.println("Avvio");
#endif
/**********************************************************/
pinMode( BACKLIGHT,OUTPUT );
digitalWrite( BACKLIGHT,LOW );
/**********************************************************/
lcd.begin(16, 2);
lcd.createChar(1, symbolselect);
lcd.createChar(2, symbolplay);
lcd.createChar(3, symbolstop);
lcd.createChar(4, symbolpause);
/**********************************************************/
digitalWrite( BACKLIGHT,HIGH );
lcd.setCursor(0,0);
lcd.print(line0);
lcd.setCursor(0,1);
lcd.print(line1);
delay( MOTDTIME );
lcdBlacklightOff();
}
/**********************************************************/
void loop() {
/**********************************************************/
#ifdef DEBUG
Serial.print( " Button: " ); Serial.print( analogRead( BUTTON ) );
Serial.print( " TimeToBlecklight " ); Serial.print( timeToBlacklight );
Serial.print( " TimeToSetHour " ); Serial.println( timeToSetMode );
#endif
/**********************************************************/
if ( ctrlButton( analogRead( BUTTON ) ) == 0 || ctrlButton( analogRead( BUTTON ) ) > 1 ) { timeToSetMode = millis(); }
if (timeToSetMode > 0 && SETMODETIME < (millis() - timeToSetMode) ) { menuMode(); timeToSetMode = 0; }
/**********************************************************/
buttonPress = ctrlButton( analogRead( BUTTON ) );
/**********************************************************/
if ( (blacklightStatus) && LCDTIME < (millis() - timeToBlacklight) ) { lcdBlacklightOff(); }
/**********************************************************/
char line0[16] = " in attesa di ";
char line1[16] = " comandi ...";
/**********************************************************/
lcd.setCursor(0,0);
lcd.print(line0);
lcd.setCursor(0,1);
lcd.print(line1);
/**********************************************************/
}
/**********************************************************/
int ctrlButton( int button ) {
buttonPress = 0;
if ( SELECT[0] <= button && button <= SELECT[1] ) { buttonPress = 1; }
if ( LEFT[0] <= button && button <= LEFT[1] ) { buttonPress = 2; }
if ( RIGTH[0] <= button && button <= RIGTH[1] ) { buttonPress = 3; }
if ( UP[0] <= button && button <= UP[1] ) { buttonPress = 4; }
if ( DOWN[0] <= button && button <= DOWN[1] ) { buttonPress = 5; }
if (buttonPress > 0) {
analogWrite( BACKLIGHT,128 );
blacklightStatus = true;
timeToBlacklight = millis();
}
return buttonPress;
}
/**********************************************************/
void lcdBlacklightOff() {
digitalWrite( BACKLIGHT,LOW );
blacklightStatus = false;
timeToBlacklight = 0;
lcd.clear();
}
/**********************************************************/
void menuMode() {
/**********************************************************/
#ifdef DEBUG
Serial.println( "Menu Mode" );
#endif
/**********************************************************/
boolean setMode = true;
int setModeLevel = 0;
timeSetting = 0;
lcd.clear();
/**********************************************************/
delay( 1000 );
/**********************************************************/
while ( setMode ) {
/**********************************************************/
if ( ctrlButton( analogRead( BUTTON ) ) != 0 ) { timeSetting = millis(); }
if ( (ctrlButton( analogRead( BUTTON )) == 5 ) && setModeLevel < 3 ) { lcd.clear(); setModeLevel++; }
if ( (ctrlButton( analogRead( BUTTON )) == 4 ) && setModeLevel > 0 ) { lcd.clear(); setModeLevel--; }
if ( (setModeLevel % 2) == 0 ) {
lcd.setCursor(0,0);
lcd.print( principale[setModeLevel] );
lcd.setCursor(0,1);
lcd.print( principale[(setModeLevel+1)] );
lcd.setCursor(15,0);
lcd.write(1);
lcd.setCursor(15,1);
lcd.print(" ");
} else {
lcd.setCursor(0,0);
lcd.print( principale[(setModeLevel-1)] );
lcd.setCursor(0,1);
lcd.print( principale[setModeLevel] );
lcd.setCursor(15,0);
lcd.print(" ");
lcd.setCursor(15,1);
lcd.write(1);
}
if ( ctrlButton( analogRead( BUTTON )) == 1 ) {
if ( setModeLevel == 0 ) { impostazioni(); }
if ( setModeLevel == 1 ) { verifica(); }
if ( setModeLevel == 2 ) { reset(); }
if ( setModeLevel == 3 ) { avvio(); }
setMode = false;
timeSetting = 0;
}
if (timeSetting > 0 && (SETMODETIME*2) < (millis() - timeSetting) ) { setMode = false; }
delay(200);
}
/**********************************************************/
lcd.clear();
}
/**********************************************************/
void impostazioni() {
/**********************************************************/
#ifdef DEBUG
Serial.println( "Menu Impostazioni" );
#endif
/**********************************************************/
lcd.clear();
lcd.setCursor(0,0);
lcd.print( "Menu " );
lcd.setCursor(0,1);
lcd.print( "Impostazioni" );
/**********************************************************/
delay( SETMODETIME );
/**********************************************************/
boolean impostazioniMode = true;
int setModeLevel = 0;
lcd.clear();
/**********************************************************/
while ( impostazioniMode ) {
/**********************************************************/
if ( (ctrlButton( analogRead( BUTTON )) == 5 ) && setModeLevel < 8 ) { lcd.clear(); setModeLevel = (setModeLevel+2); }
if ( (ctrlButton( analogRead( BUTTON )) == 4 ) && setModeLevel > 0 ) { lcd.clear(); setModeLevel = (setModeLevel-2); }
if ( ctrlButton( analogRead( BUTTON )) == 1 ) { impostazioniMode = false; }
/**********************************************************/
#ifdef DEBUG
Serial.print( "setMenuLevel: " );
Serial.println( setModeLevel );
#endif
/**********************************************************/
switch ( setModeLevel ) {
case 0:
if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && passiXscatto <= 99999) { passiXscatto++; lcd.clear(); }
if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && passiXscatto >= 1) { passiXscatto--; lcd.clear(); }
sprintf(buffer, "%s %d", secondario[(setModeLevel+1)], passiXscatto);
break;
case 2:
if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && passiXscatto <= 9999999) { intervaloScatto++; lcd.clear(); }
if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && passiXscatto >= 1) { intervaloScatto--; lcd.clear(); }
sprintf(buffer, "%s %ds", secondario[(setModeLevel+1)], intervaloScatto);
break;
case 4:
if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && tempoAltPrima <= 9999999) { tempoAltPrima++; lcd.clear(); }
if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && tempoAltPrima >= 1) { tempoAltPrima--; lcd.clear(); }
sprintf(buffer, "%s %ds", secondario[(setModeLevel+1)], tempoAltPrima);
break;
case 6:
if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && tempoAltDopo <= 9999999) { tempoAltDopo++; lcd.clear(); }
if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && tempoAltDopo >= 1) { tempoAltDopo--; lcd.clear(); }
sprintf(buffer, "%s %ds", secondario[(setModeLevel+1)], tempoAltDopo);
break;
case 8:
if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && numeroScatti <= 9999999) { numeroScatti++; lcd.clear(); }
if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && numeroScatti >= 1) { numeroScatti--; lcd.clear(); }
sprintf(buffer, "%s %d", secondario[(setModeLevel+1)], numeroScatti);
break;
}
/**********************************************************/
lcd.setCursor(0,0);
lcd.print( secondario[setModeLevel] );
lcd.setCursor(0,1);
lcd.print( buffer );
/**********************************************************/
delay( 200 );
}
/**********************************************************/
lcd.clear();
}
/**********************************************************/
void verifica() {
/**********************************************************/
#ifdef DEBUG
Serial.println( "Menu Verifica" );
#endif
/**********************************************************/
lcd.clear();
lcd.setCursor(0,0);
lcd.print( "Menu " );
lcd.setCursor(0,1);
lcd.print( "Verifica" );
/**********************************************************/
delay( SETMODETIME );
/**********************************************************/
boolean verificaMode = true;
int setModeLevel = 0;
lcd.clear();
/**********************************************************/
while ( verificaMode ) {
/**********************************************************/
if ( (ctrlButton( analogRead( BUTTON )) == 5 ) && setModeLevel < 8 ) { lcd.clear(); setModeLevel = (setModeLevel+2); }
if ( (ctrlButton( analogRead( BUTTON )) == 4 ) && setModeLevel > 0 ) { lcd.clear(); setModeLevel = (setModeLevel-2); }
if ( ctrlButton( analogRead( BUTTON )) == 1 ) { verificaMode = false; }
/**********************************************************/
#ifdef DEBUG
Serial.print( "setMenuLevel: " );
Serial.println( setModeLevel );
#endif
/**********************************************************/
switch ( setModeLevel ) {
case 0:
sprintf(buffer, "%s %d", secondario[(setModeLevel+1)], passiXscatto);
break;
case 2:
sprintf(buffer, "%s %ds", secondario[(setModeLevel+1)], intervaloScatto);
break;
case 4:
sprintf(buffer, "%s %ds", secondario[(setModeLevel+1)], tempoAltPrima);
break;
case 6:
sprintf(buffer, "%s %ds", secondario[(setModeLevel+1)], tempoAltDopo);
break;
case 8:
sprintf(buffer, "%s %d", secondario[(setModeLevel+1)], numeroScatti);
break;
}
/**********************************************************/
lcd.setCursor(0,0);
lcd.print( secondario[setModeLevel] );
lcd.setCursor(0,1);
lcd.print( buffer );
/**********************************************************/
delay( 200 );
}
/**********************************************************/
lcd.clear();
}
/**********************************************************/
void reset() {
/**********************************************************/
#ifdef DEBUG
Serial.println( "Menu Reset" );
#endif
/**********************************************************/
lcd.clear();
lcd.setCursor(0,0);
lcd.print( "Menu " );
lcd.setCursor(0,1);
lcd.print( "Reset" );
/**********************************************************/
delay( SETMODETIME );
/**********************************************************/
boolean resetMode = true;
lcd.clear();
/**********************************************************/
lcd.clear();
lcd.setCursor(0,0);
lcd.print( "LEFT antiorario" );
lcd.setCursor(0,1);
lcd.print( "RIGTH orario" );
/**********************************************************/
while ( resetMode ) {
/**********************************************************/
if ( ctrlButton( analogRead( BUTTON )) == 3 ) { nFase++; }
if ( ctrlButton( analogRead( BUTTON )) == 2 ) { nFase--; }
if ( ctrlButton( analogRead( BUTTON )) == 1 ) { resetMode = false; }
/**********************************************************/
nFase = fase( nFase );
/**********************************************************/
delay( 100 );
}
/**********************************************************/
stop();
/**********************************************************/
lcd.clear();
}
/**********************************************************/
void avvio() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print( "Menu " );
lcd.setCursor(0,1);
lcd.print( "Avvio" );
delay( SETMODETIME );
}
/**********************************************************/
int fase( int nFase ) {
if ( nFase > 4 ) { nFase = 1; }
if ( nFase < 1 ) { nFase = 4; }
#ifdef DEBUG
Serial.print( "fase() - nFase: " );
Serial.println( nFase );
#endif
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() {
digitalWrite(DIRA, LOW);
digitalWrite(DIRB, LOW);
digitalWrite(PWMA, LOW);
digitalWrite(PWMB, LOW);
}
/**********************************************************/
ci sono delle nuove funzioni che ho aggiunto e servono per controllare il motore o fermarlo durante la fase di reset e la prossima fase: Avvio.
Le nuove funzioni sono:
reset()
linea 453: definisci la funzione reset() richiamata alla linea 241 dalla menuMode();
linee 457-459: imposta il controllo sulla definizione di DEBUG per scrivere sul monitor seriale il testo “Menu Reset()”;
linee 463-467: scrivi sul display il testo “Menu” sulla prima linea e “Reset” sulla seconda;
linea 471: attendi il tempo definito nella costante SETMODETIME prima di cancellare il testo dall’LCD;
linea 475: inizializza una variabile di tipo boolean ( il cui valore può essere true o false ) denominata resetMode e impostala a true;
linea 476: cancella ogni linea di testo dal Display LCD;
linee 480-484: scrivi sulla prima riga del display del Dolly Photo il testo “LEFT antiorario” e sulla seconda riga il testo “RIGHT orario”;
linea 488: verifica che il valore di restMode sia true e fino a quando non diventa false esegui un ciclo while();
linea 492: controlla quale bottone della keypad LCD viene premuto e se premi RIGHT che la ctrlButton trasforma in 3 allora incrementa la variabile nFase. Utilizzerai tale variabile per far avanzare alla fase successiva il motore;
linea 493: decrementa la variabile nFase se il pulsante che hai premuto è LEFT, tradotto dalla ctrlButton in 2;
linea 494: controlla che il pulsante premuto sia SELECT ( 1 per la ctrlButton ) ed in tal caso imposta la variabile resetMode a false;
linea 498: richiama la funzione fase() passandole il numero di fase da seseguire ed impostando l’output restituito dalla funzione nella medesima variabile nFase. Vedrai in seguito perchè;
linea 502: attendi 200 millisecondi prima di procedere al ciclo while successivo;
linea 507: richiama la funzione stop() che toglie corrente a tutte le fasi del motore fermandolo;
linea 511: cancella dal display LCD tutto il testo per lasciar posto al testo successivo.
fase( nFase )
rispetto alle precedenti versioni di questa funzione troverai alcune differenze che aiutano a rendere il codice esterno più semplice e demandano il controllo della rotazione del motore a questa funzione;
linea 530: verifica che il valore di nFase non sia superiore a 4 in tal caso imposta la variabile a 1 essendo 4 le fasi ( da 1 a 4 );
linea 531: verifica che il valore di nFase non sia inferiore a 1 per evitare che in caso di rotazione inversa il motore finisca in una fase che non può controllare;
linee 533-536: imposta il DEBUG scrivendo sul monitor seriale il valore di nFase ogni volta che questa funzione viene richiamata;
linee 540-543: per la fase 1 del motore imposta la sequenza: HIGH,LOW,HIGH,LOW sui rispettivi pin della motor shield arduino;
linee 547-564: imposta le altre 3 fasi del motore;
linea 568: attendi per ogni eseguzione di questa funzione un tempo definito nella costante TIMEFASE. Questa attesa serve ad evitare che la velocità con cui Arduino richiama la funzione si rifletta sul motore che non è in grado dieseguirla e resta fermo o peggio oscilla su se stesso. Dovrai variare il valore di TIMEFASE alla linea 30 in funzione del motore che scegli, se ti attieni al motore del kit tale valore è già corretto;
linea 570: ritorna alla funzione chiamante, ossia la reset() in questo caso, il valore di nFase. Avrai quindi capito il perché della ri assegnazione di tale valore alla medesima variabile ( nFase ) alla linea 498. Se nFase è 5 quando avviva alla funzione fase() viene automaticamente corretta in 1, si posiziona il motore in fase 1 e restituisci il nuovo valore.
stop()
è una funzione abbastanza semplice, il cui scopo è evitare che il motore resti alimentato anche nelle fasi di stop, evitando consumo di corrente e sopratutto di surriscaldarlo:
linee 576-579: imposti a LOW tutti i pin relativi alla motor shield arduino;
Il video della funzione reset del Dolly Photo
Come per tutta la serie di articoli dedicati al Dolly Photo ho realizzato anche per questo un video demo:
Buon reset !!!












7 comments
michele
9 maggio 2013 a 22:42 (UTC 2) Link to this comment
perdonami l’ignoranza ma i fili della motor shield in alimenentazione intravedo che sono collegati insieme?
Mauro Alfieri
10 maggio 2013 a 16:44 (UTC 2) Link to this comment
Ciao Michele,
nessuna ignoranza, nelle foto non è sempre chiaro.
Quello che vedi è del termo retrattile che tiene uniti i due fili, i contatti sono separati
Mauro
Owen
15 maggio 2013 a 11:54 (UTC 2) Link to this comment
Ciao Mauro, ho assemblato tutto il dolly, per evitare che la keypad shield e la motor shield andassero in conflitto ho “tagliato” il contatto su A0 della motor shield ed anche i 2 brake (8 e 9)
il problema ora è che il motore se imposto 10step e 5 scatti, ruota un po a sinistra, un po a destra e poi si ferma
il motore è stato recuperato da una vecchia stampante, ma è un comune nema 17 bipolare
le fasi le ho divise con il tuo metodo, ma non sono riuscito a capire come individuare i rispettivi + e – delle 2 fasi
potrebbe essere quello il problema?
colgo l’occasione per farti un’altra domanda: se volessi sostituire la motorshield con un pololu, come posso dividere le fasi avendo su quest’ultimo solo STEP e DIR e non i PWMA e PWMB?
praticamente, questa parte di codice come andrebbe modificata?
/**********************************************************/
int fase( int nFase ) {
if ( nFase > 4 ) { nFase = 1; }
if ( nFase < 1 ) { nFase = 4; }
#ifdef DEBUG
Serial.print( "fase() - nFase: " );
Serial.println( nFase );
#endif
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;
}
/**********************************************************/
Mauro Alfieri
15 maggio 2013 a 12:51 (UTC 2) Link to this comment
Ciao Owen,
si vede che ti sei impegnato e non arreso alla prima difficoltà.
hai fatto un ottimo lavoro
Per individuare + e – delle fasi puoi seguire un altro articolo, che non so se hai già letto:
http://www.mauroalfieri.it/elettronica/tutorial-motore-bipolare-passo-passo-riconoscere-le-fasi.html
Se ancora non funziona potrebbe essere dovuto alle correnti delle fasi troppo elevate che mandano in tilt il controllore.
Per la modifica allo sketch hai individuato perfettamente la funzione, puoi prendere spunto dal Dolly che ho realizzato per Matteo e pubblicato qualche giorno fa.
Mauro
Owen
15 maggio 2013 a 18:13 (UTC 2) Link to this comment
ciao Mauro, sono riuscito ad individuare le fasi corrette, ma il problema persiste, come controprova ho caricato uno sketch base che faccia semplicemente ruotare il motore
/*************************************************************
Motor Shield Stepper Demo
by Randy Sarafan
For more information see:
http://www.instructables.com/id/Arduino-Motor-Shield-Tutorial/
*************************************************************/
int delaylegnth = 30;
void setup() {
//establish motor direction toggle pins
pinMode(12, OUTPUT); //CH A -- HIGH = forwards and LOW = backwards???
pinMode(13, OUTPUT); //CH B -- HIGH = forwards and LOW = backwards???
//establish motor brake pins
pinMode(9, OUTPUT); //brake (disable) CH A
pinMode(8, OUTPUT); //brake (disable) CH B
}
void loop(){
digitalWrite(9, LOW); //ENABLE CH A
digitalWrite(8, HIGH); //DISABLE CH B
digitalWrite(12, HIGH); //Sets direction of CH A
analogWrite(3, 255); //Moves CH A
delay(delaylegnth);
digitalWrite(9, HIGH); //DISABLE CH A
digitalWrite(8, LOW); //ENABLE CH B
digitalWrite(13, LOW); //Sets direction of CH B
analogWrite(11, 255); //Moves CH B
delay(delaylegnth);
digitalWrite(9, LOW); //ENABLE CH A
digitalWrite(8, HIGH); //DISABLE CH B
digitalWrite(12, LOW); //Sets direction of CH A
analogWrite(3, 255); //Moves CH A
delay(delaylegnth);
digitalWrite(9, HIGH); //DISABLE CH A
digitalWrite(8, LOW); //ENABLE CH B
digitalWrite(13, HIGH); //Sets direction of CH B
analogWrite(11, 255); //Moves CH B
delay(delaylegnth);
}
e tutto funziona bene, ricarico il tuo sketch e il motore continua a fare un po di step da un lato e un po dall’altro
Owen
16 maggio 2013 a 23:35 (UTC 2) Link to this comment
Ciao Mauro, ti aggiorno… ho fatto l’ultima prova a mia disposizione… ho sostituito l’arduino uno con un leonardo che avevo a disposizione… ed ora funziona tutto!!!
ora però da bravo maker vorrei migliorarlo… ad esempio un fattore fondamentale secondo me è la rumorosità degli step del motore, purtroppo non so da cosa sia dovuta… uso lo stesso motore che ho su una stampante 3d ma li è molto silenzioso eppure è alimentato sempre a 12v, potrebbe essere la velocità di rotazione? nel caso, come si potrebbe aumentare? non ho notato nello sketch nessun delay tra uno step ed il successivo
Mauro Alfieri
17 maggio 2013 a 07:26 (UTC 2) Link to this comment
Ciao Owen,
ben fatto !!!
Mi stupisci sei così bravo e attento e non ti sei accorto del delay nella funzione fasi(), puoi regolarlo dalla costante TIMEFASE che pensavo fosse un nome parlante
Continua così che stai facendo un ottimo lavoro.
Mauro