Dolly Photo incrementa la velocità di impostazione

Le modifiche e implementazioni fatte al Dolly Photo e presentate in questo articolo si concludono con questo articolo in cui trovi come il Dolly Photo incrementa la velocità di impostazione.

dolly photo versione 2

L’esigenza che mi è stat esposta da chi ha provato il Dolly Photo versione 1.0 è stata quella di poter essere più veloce in fase di impostazione del progetto fotografico.

In pratica quando sei su un campo e vuoi iniziare una nuova sequenza di fotografie con il Dolly Photo versione 1.0  impostare i parametri di avvio risulta molto lento in quanto ogni pressione dei pulsanti LEFT e RIGHT incrementa di un solo valore il contatore su cui stai agendo.

Nella versione 2.0 ho modificato questa impostazione anche in funzione del fatto che i tempi sono definiti in millisecondi e non in secondi come nella precedente vesione, ottieni così che il Dolly Photo incrementa la velocità di impostazione.

Principio di funzionamento

Il principio è banale: incrementi di 10 unità ad ogni pressione del pulsante RIGHT e decrementi di 1 alla pressione del pulsante LEFT.

Dolly Photo incrementa la velocità di impostazione

Se ti chiedi come mai RIGHT incrementa di 10 e LEFT decrementa di 1 la risposta è semplice: in questo modo sei certo di poter impostare tutti i valoro che desideri rapidamente.

Se ad esempio vuoi che il Dolly Photo incrementa la velocità di impostazione dell’intervallo tra i passi fino al valore 36 premerai quattro volte il pulsante RIGHT arrivando a 40 e quattro volte il pulsante LEFT indietreggiando a 36.

Sketch Dolly Photo incrementa la velocità di impostazione

Lo sketch che ti riporto presenta tutte le ultime funzioni descritte negli articoli precedenti ed aggiunge anche questa funzione:

/**********************************************************
 * Dolly Photo Arduino
 *
 * Data creazione 25 febbraio 2013
 * Ultima modifica 13 marzo 2013
 *
 * autore: Mauro Alfieri
 * web:    mauroalfieri.it
 * tw:     @mauroalfieri
 *
/**********************************************************/

#include <LiquidCrystal.h>

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

#define MOTDTIME 2000
#define LCDTIME  3000
#define SETMODETIME 2000
#define TIMESCATTO 500
#define TIMEFASE 35
#define TARATURA 800
#define DEBUG

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

#define SCATTO     2
#define PWMA       3
#define D4         4
#define D5         5
#define D6         6
#define D7         7
#define RS         8
#define EN         9
#define BACKLIGHT 10
#define PWMB      11
#define DIRA      12
#define DIRB      13
#define BUTTON    A0
#define SSTART    A1
#define SSTOP     A2

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

char line0[16] = "Dolly Foto ver2";
char line1[16] = "mauroalfieri.it";

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

int SELECT[]     =  {810,830};
int LEFT[]       =  {610,640};
int RIGTH[]      =  {0,20};
int UP[]         =  {190,210};
int DOWN[]       =  {390,420};

int buttonPress  = 0;
int nFase        = 0;
int scatto       = 0;
int passo        = 0;

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

unsigned long timeToBlacklight  =  0;
unsigned long timeToSetMode     =  0;
unsigned long timeSetting       =  0;
unsigned long timeDelay         =  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[6]   =  {"Impostazioni","Verifica","Reset Carrello","Reset Auto","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 intervalloScatto  = 30;
int tempoAltPrima     = 0;
int tempoAltDopo      = 0;
int numeroScatti      = 0;

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

LiquidCrystal lcd( RS,EN,D4,D5,D6,D7 );

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

void setup() {

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

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

  pinMode( BACKLIGHT,OUTPUT );
  digitalWrite( BACKLIGHT,LOW );

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

  pinMode( SCATTO,OUTPUT );
  digitalWrite( SCATTO,LOW );

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

  #ifdef SSTART
    pinMode( SSTART,INPUT );
    digitalWrite( SSTART,LOW );
  #endif

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

  #ifdef SSTOP
    pinMode( SSTOP,INPUT );
    digitalWrite( SSTOP,LOW );
  #endif

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

  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 );
  lcd.clear();
  lcdBlacklightOff();
}

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

void loop() {

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

  #ifdef DEBUG
    Serial.print( " Button: " );           Serial.print( analogRead( BUTTON ) );
    Serial.print( " TimeToBlecklight " );  Serial.print( timeToBlacklight );
    Serial.print( " TimeToSetMode " );     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(); lcd.clear(); }

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

  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) {
    digitalWrite( BACKLIGHT,HIGH );
    blacklightStatus = true;
    timeToBlacklight = millis();
  }

  return buttonPress;
}

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

void lcdBlacklightOff() {
  digitalWrite( BACKLIGHT,LOW );
  blacklightStatus = false;
  timeToBlacklight = 0;
}

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

void lcdBlacklightOn() {
  digitalWrite( BACKLIGHT,HIGH );
  blacklightStatus = true;
  timeToBlacklight = millis();
}

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

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 < 4 ) { 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 ) { autoreset();    }
      if ( setModeLevel == 4 ) { 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 += 10; lcd.clear(); }
        if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && passiXscatto >= 1)      { passiXscatto -= 1; lcd.clear();  }

        sprintf(buffer, "%s %d", secondario[(setModeLevel+1)], passiXscatto);
      break;

      case 2:
        if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && intervalloScatto <= 9999999)  { intervalloScatto += 10; lcd.clear();  }
        if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && intervalloScatto >= 1)        { intervalloScatto -= 1; lcd.clear();  }

        sprintf(buffer, "%s %dms", secondario[(setModeLevel+1)], intervalloScatto);
      break;

      case 4:
        if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && tempoAltPrima <= 9999999)  { tempoAltPrima += 10; lcd.clear();  }
        if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && tempoAltPrima >= 1)        { tempoAltPrima -= 1; lcd.clear();  }

        sprintf(buffer, "%s %dms", secondario[(setModeLevel+1)], tempoAltPrima);
      break;

      case 6:
        if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && tempoAltDopo <= 9999999)  { tempoAltDopo += 10; lcd.clear();  }
        if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && tempoAltDopo >= 1)        { tempoAltDopo -= 1; lcd.clear();  }

        sprintf(buffer, "%s %dms", secondario[(setModeLevel+1)], tempoAltDopo);
      break;

      case 8:
        if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && numeroScatti <= 9999999)  { numeroScatti += 10; lcd.clear();  }
        if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && numeroScatti >= 1)        { numeroScatti -= 1; 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 %dms", secondario[(setModeLevel+1)], intervalloScatto);
      break;

      case 4:
        sprintf(buffer, "%s %dms", secondario[(setModeLevel+1)], tempoAltPrima);
      break;

      case 6:
        sprintf(buffer, "%s %dms", 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( 10 );
  }

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

  stop();

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

  lcd.clear();
}

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

void autoreset()
{
  #ifdef SSTART

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

    stop();

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

    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print( "Menu " );
    lcd.setCursor(0,1);
    lcd.print( "Reset Automatico" );    

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

    delay( SETMODETIME );

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

    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print( "Reset in corso" );

    lcd.setCursor(0, 1);
    lcd.write(1);        // SELECT
    lcd.setCursor(1, 1);
    lcd.write(1);        // SELECT
    lcd.setCursor(5, 1);
    lcd.write(3);        // STOP

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

    while ( analogRead( SSTART ) > TARATURA ) {
      nFase = fase( nFase );
      nFase--;
      if ( ctrlButton( analogRead( BUTTON )) == 3 ) {
        stop();

        lcd.setCursor(0, 1);
        lcd.write(3);        // STOP
        lcd.setCursor(1, 1);
        lcd.write(" ");
        lcd.setCursor(5, 1);
        lcd.write(" ");

        return;
      }
    }

    delay( 500 );
  #endif
} 

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

void avvio() {

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print( "Menu " );
  lcd.setCursor(0,1);
  lcd.print( "Avvio" );    

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

  delay( SETMODETIME );

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

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print( "Go " );
  lcd.setCursor(3, 0);
  lcd.write(4);        // PAUSA

  lcd.setCursor(0, 1);
  lcd.write(3);        // STOP
  lcd.setCursor(5, 1);
  lcd.write(2);        // PLAY

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

  if ( !pausa() ) return;

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

  for ( scatto=0; scatto <= numeroScatti; scatto++ ) {

    lcd.setCursor(7, 0);
    lcd.print( "scatto:" );
    lcd.setCursor(14, 0);
    lcd.print( scatto );

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

    for ( int passo=1; passo <= passiXscatto; passo++ ) {

      lcd.setCursor(7, 1);
      lcd.print( "passo:" );
      lcd.setCursor(13, 1);
      lcd.print( passo );  

      if ( ctrlButton( analogRead( BUTTON )) == 3 ) { if ( !pausa() ) return; }

      nFase = fase( nFase );
      nFase++;
      int _intervallo = intervalloScatto;
      if ( !ctrlDelay( _intervallo )) return;

    }

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

    int _tempo = tempoAltPrima;
    if ( !ctrlDelay( _tempo )) return;

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

    digitalWrite( SCATTO, HIGH );
    delay( TIMESCATTO );
    digitalWrite( SCATTO, LOW );

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

    lcd.setCursor(7, 0);
    lcd.print( "scatto:" );
    lcd.setCursor(14, 0);
    lcd.print( scatto );    

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

    _tempo = tempoAltDopo;
    if ( !ctrlDelay( _tempo )) return;

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

  }

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

}

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

boolean pausa() {

  lcdBlacklightOn();

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

  boolean play  =  false;

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

  lcd.setCursor(3, 0);
  lcd.write(4);    // PAUSA

  lcd.setCursor(5, 1);
  lcd.write(2);    // PLAY

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

  while ( !play ) {
    if ( ctrlButton( analogRead( BUTTON )) == 3 ) {
      lcd.setCursor(3, 0);
      lcd.write(2);    // PLAY

      lcd.setCursor(5, 1);
      lcd.write(4);    // PAUSA
      delay( 500 );
      play = true;
    }

    if ( ctrlButton( analogRead( BUTTON )) == 2 ) {
      stop();
      play = true;
      return false;
    }
    delay( 100 );
  }

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

  return true;
}

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

boolean ctrlDelay(int tempo) {

  // lcdBlacklightOff(); // Decommenta per risparmio energetico
  timeDelay = millis();
  boolean dtime = true;

  #ifdef DEBUG
      Serial.print( "Delay: " );
      Serial.print( tempo );
      Serial.print( " Millis: " );
      Serial.print( timeDelay );
      Serial.print( " \n " );
  #endif

  while ( dtime ) {
    if ( tempo < (millis()-timeDelay)) { dtime = false; }

    if ( ctrlButton( analogRead( BUTTON )) == 3 ) { delay( 500 ); pausa(); }
    if ( ctrlButton( analogRead( BUTTON )) == 2 ) { stop(); dtime = false; return false; }
    if ( analogRead( SSTOP ) < TARATURA )         { stop(); dtime = false; return false; }

    Serial.print( (millis()-timeDelay) );
    Serial.print( "\n" );
  }

  return true;
}

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

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);
}

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

leggendolo troverai che le linee che si preoccupano di farti impostare i parametri del Dolly Photo incrementa la velocità di impostazione sono quelle contenute nella funzione impostazioni() ed in particolare le linee 346-383 che riporto per approfondirle meglio:

   switch ( setModeLevel ) {

      case 0:
        if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && passiXscatto <= 99999)  { passiXscatto += 10; lcd.clear(); }
        if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && passiXscatto >= 1)      { passiXscatto -= 1; lcd.clear();  }

        sprintf(buffer, "%s %d", secondario[(setModeLevel+1)], passiXscatto);
      break;

      case 2:
        if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && intervalloScatto <= 9999999)  { intervalloScatto += 10; lcd.clear();  }
        if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && intervalloScatto >= 1)        { intervalloScatto -= 1; lcd.clear();  }

        sprintf(buffer, "%s %dms", secondario[(setModeLevel+1)], intervalloScatto);
      break;

      case 4:
        if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && tempoAltPrima <= 9999999)  { tempoAltPrima += 10; lcd.clear();  }
        if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && tempoAltPrima >= 1)        { tempoAltPrima -= 1; lcd.clear();  }

        sprintf(buffer, "%s %dms", secondario[(setModeLevel+1)], tempoAltPrima);
      break;

      case 6:
        if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && tempoAltDopo <= 9999999)  { tempoAltDopo += 10; lcd.clear();  }
        if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && tempoAltDopo >= 1)        { tempoAltDopo -= 1; lcd.clear();  }

        sprintf(buffer, "%s %dms", secondario[(setModeLevel+1)], tempoAltDopo);
      break;

      case 8:
        if ( (ctrlButton( analogRead( BUTTON )) == 3 ) && numeroScatti <= 9999999)  { numeroScatti += 10; lcd.clear();  }
        if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && numeroScatti >= 1)        { numeroScatti -= 1; lcd.clear();  }

        sprintf(buffer, "%s %d", secondario[(setModeLevel+1)], numeroScatti);
      break;

il principio è descritto nel paragrafo precedente ed espresso nelle linee 04-05: noti che la prima linea controlla la pressione del bottone RIGHT mentre la linea 5 controlla la pressione del pulsante LEFT.

La pressione del pulsante RIGHT incrementa il contatore passiXscatto di 10 unità alla volta.

La pressione del pulsante LEFT decrementa il medesimo contatore di una sola unità alla volta.

Le linee 11-12: fanno la stessa operazione per il contatore intervalloScatto;

le linee 18-19: incrementano e decrementano il contatore tempoAltPrima che definisce il tempo in millisecondi da attendere prima di ciascuno scatto;

linee 25-26: agiscono sul contatore tempoAltDopo con cui definisci il tempo di attesa tra lo scatto ed il primo passo della successiva sequenza di passi del motore passo-passo;

linea 32-33: imposti i valori del contatore numeroScatti che definisce quanti scatti dovrai eseguire in tutto il progetto fotografico.

Video Dolly Photo incrementa la velocità di impostazione

Ecco il video che avrai già visto se hai seguito il blog e la serie di articoli sul Dolly Photo versione 2, se è il primo articolo che leggi su questo argomento ti consiglio di dare un occhio ai precedenti articoli dedicati all’argomento.

Buon divertimento !!!

Cortesemente, prima di inserire i commenti leggi il regolamento

Permanent link to this article: http://www.mauroalfieri.it/elettronica/dolly-photo-incrementa-la-velocita-di-impostazione.html

52 comments

Skip to comment form

  1. Ciao,
    Ho un po’ abbandonato il progetto, ma vedendo le migliorie mi e’ venuta voglia di riprenderlo 🙂
    Grande Mauro!!!

    • gianmaria on 22 agosto 2013 at 13:02
    • Reply

    ciao Mauro, due domande mi sorgono, il dolly di questo articolo è la diretta evoluzione di questo : http://www.mauroalfieri.it/elettronica/dolly-keypad-lcd-prima-parte.html ?
    Quindi mi viene il problema di dove collegare lo shutter che va alla reflex
    Grazie mille

    1. Ciao Gianmaria,
      più che di evoluzione io parlerei di serie di articoli collegati.
      Il progetto Dolly é più complesso di quello c’è sembra e per realizzarlo ho dedicato lacune settimane di esperimenti.

      Ad ogni esperimento riuscito ho pubblicato i risultati e le evoluzioni del progetto, quindi leggendo tutti gli articoli non solo imparerai come si realizza la parte elettronica e i corretti settaggi ma scoprirai anche il pin a cui collegare la reflex, é tutto descritto negli articoli.

      Ti do un suggerimento il pin che cerchi si chiama SCATTO nel mio sketch.

      Credimi, prendere solo l’ultimo sketch, non leggendo neppure tutto il materiale prodotto equivale a ottenere un prodotto mal funzionante e spesso un progetto fallimentare senza acquisire le competenze per usarlo e migliorarlo, che é ciò per cui scrivo articoli dettagliati.
      É come andare in un negozio e comprare un oggetto già fatto, nulla di deplorevole, ma non é una cosa ha hai realizzato e di cui conosci ogni singolo comportamento.

      Mauro

        • gianmaria on 23 agosto 2013 at 11:27
        • Reply

        concordo a pieno, grazie, sto attendendo gli ultimi pezzi poi in caso scrivo qui se ho problemi 😀

    • Lupo Solitario on 20 novembre 2014 at 11:05
    • Reply

    Ciao,
    trovo il tuo blog uno dei migliori per semplicità e chiarezza, ma ho un grosso problema con la lettura degli sketch, per spiegarmi meglio devo incollare quello che vedo io sul mio computer.
    Ecco una una parte che ho incollato dallo sketch sopra:

    [ codice rimosso in automatico ]

    Non riesco a risolvere l’errore, ho provato nelle impostazione del mio browser (firefox) ma niente, hai qualche idea?

    Grazie e continua così

    1. Ciao Lupo Solitario,
      come avrai letto in fondo ad ogni articolo non è possibile incollare codice nei commenti.

        • Lupo Solitario on 20 novembre 2014 at 12:10
        • Reply

        Grazie,

        per la risposta comunque ho risolto da solo.

    • Andrea on 9 febbraio 2015 at 10:54
    • Reply

    Ciao Mauro,
    Grazie per aver condiviso il progetto. Vorrei chiederti alcune cose.
    Sto usando un motore passo passo da 2.8V e 1.68A per fase.
    La scheda motor shield r3 ha un regolatore di tensione interno o devo alimentarla, ai morsetti per lo stepper, con la tensione corretta (2.8V)?
    Ti ringrazio in anticipo.

    Andrea

    1. Ciao Andrea,
      la motor shield r3 non ha un regolatore interno, devi fornirgli una tensione in ingresso che usa per il controllo del motore.
      Fai solo attenzione al voltaggio minimo che non ricordo quale sia.

        • Andrea on 9 febbraio 2015 at 16:40
        • Reply

        Ho capito, grazie mille per la risposta.
        Farò un tentativo allora.
        Buona giornata

        • Andrea on 15 febbraio 2015 at 12:26
        • Reply

        Ciao Mauro,
        ho ancora bisogno del tuo aiuto.
        Finalmente ho ricevuto tutto il materiale e ho iniziato ad implementare il tuo progetto. Uso :
        -Arduino UNO R3
        -Motor shield R3
        -LCD Keypad v 1.1
        Il problema è quello che ho letto anche in altri tuoi articoli, quando monto una sull’altra tutte e tre le schede ho un conflitto. Ho letto che consigli di tagliare i pin A0 che sono quelli per i tasti della scheda LCD. Innanzitutto volevo chiedere che cosa significa tagliare? Vedo però che nello sketch definisci A0 come button… Comunque, utilizzando il tuo ultimo programma, con gli stessi collegamenti ho il conflitto. A te invece nel video funziona… Cosa sbaglio?
        Ti ringrazio.

        Andrea

        1. Ciao Andrea,
          grazie per aver acquistato il kit, hai contribuito a sostenere il blog.
          In corrispondenza dei pin A0 ed A1 lato inferiore della motor shield trovi due piazzole circolari con una fenditura centrale.
          Con un taglierino devi incidere le due fenditure in modo che non ci sia continuità tra i due semicerchi.

            • Andrea on 16 febbraio 2015 at 12:56

            Grazie a te che hai condiviso con tutti il tuo progetto!!!
            Ah, perfetto. Allora separo il collegamento con il taglierino. Farò lo stesso anche con il pin Vin in modo da rendere indipendente l’alimentazione di Arduino da quella del motore esterno.
            Devo fare lo stesso anche con i contatti del pin 8 e 9 (Brake A e B)?
            Grazie

            Andrea

          1. Ciao Andrea,
            il Vin non va separato.
            Si se vuoi usare i pin 8 e 9 per altri scopi e non per il freno-motore.

            • Andrea on 16 febbraio 2015 at 16:54

            Ah, quindi il Vin dietro la scheda non va separato?
            Volevo separarlo perchè il motore passo passo è da 2.8V, mentre alimenterei Arduino a 7/9V.
            Facendo delle prove ho visto che se alimento Arduino a 9V anche ai morsetti Vin e GND della motor shield (quelli di fianco alle connessioni per il motore passo passo) ho la stessa tensione di 9V.
            Quindi ho pensato che separando il pin sul retro potrei avere 9V per arduino uno, il driver della motor shield e l’LCD, ed alimentare esternamente a 2.8V il motore passo passo.
            Grazie.

            Andrea

          2. Ciao Andrea,
            non avevo mai notato che ci fosse un collegamento e che questo fosse riportato sul connettore di alimentazione della shield.
            Trovo utile questa connessione se vuoi alimentare arduino dalla motor shield direttamente, tuttavia il contrario è pericoloso per la richiesta di corrente da parte dei motori.
            Incidi pure anche questa pista.
            Il motore del kit funziona a 12v e non a 2,8v

            • Andrea on 17 febbraio 2015 at 08:30

            Ok, perfetto.
            Non appena avrò ultimato il progetto ti farò sapere.
            Grazie mille. Una buona giornata.

            Andrea

          • Andrea on 18 febbraio 2015 at 22:55
          • Reply

          Ciao Mauro,
          Ho di nuovo bisogno del tuo aiuto. Ho risolto il problema del conflito dell’LCD ma ecco un’altro problemino. Il motore passo passo esegue uno step in un verso ed uno nel verso opposto. Ho letto del problema in un articolo in cui spiegavi come risolverlo. Ho separato le connessioni dei pin 8 e 9 ma il problema persiste. Ho caricato uno sketch che fa eseguire dei semplici step e tutto funziona. Mentre ricaricando lo sketch completo va avanti ed indietro..
          Dove sbaglio?
          Grazie mille!!!!

          Andrea

          1. Ciao Andrea,
            apparentemente il problema che riscontri è dovuto ad un errore di collegamento delle fasi, ma se hai provato con un altro mio sketch e funziona con le medesime connessioni direi che potrebbe esserci qualche errore nello sketch.
            Prova a confrontare i due sketch per capire se ci siano delle differenze nella parte di controllo del motore, se trovi qualcosa di poco chiaro indicami in quali righe e provo a verificare.

    • Paolo on 27 marzo 2015 at 18:19
    • Reply

    Una Domanda molto importante. Vorrei alimentare arduino dalla motor shiled con una batteria ricaricabile a lunga durata. Potete consigliarmi su cosa acquistare?

    1. Ciao Paolo,
      tutte le domande sono molto importanti.
      Io suggerirei una batteria da 12v per l’amperaggio dipende dall’assorbimento dei tuo progetto e dalle ore e modalità di funzionamento.

    • Paolo on 31 marzo 2015 at 17:41
    • Reply

    Ho scelto questo motore 42byghm809, è uno stepper a 400 passi.

    Angolo step: 0.9°
    2 fasi
    Tensione nominale: 3V
    Corrente nominale: 1.7A/Fase
    Diametro albero: 5mm
    Holding Torque: 48N.cm
    Form Factor NEMA 17
    400 step/giro

    Che batteria mi consigli a lunga durata non troppo voluminosa?

    1. Ciao Paolo,
      LiPo, devi solo far attenzione a come la maneggi perché tendono ad esplodere, guarda qualche video su youtube.

    • Paolo on 31 marzo 2015 at 21:32
    • Reply

    Si anche io pensavo per le lipo. Ma ho difficoltà con i voltaggi, Il motore lavora a 3v e arduino a 5v se non erro.

    1. Ciao Paolo,
      nel mio kit ho evitato alimentando tutto a 12v ed utilizzando motori adeguati.
      Se hai problemi con le tensioni puoi decidere di usare la doppia alimentazione o un DC-DC per convertire una delle tensioni in step-down, trovi alcuni articoli dedicati ai convertitori DC-DC nel blog

    • Paolo on 3 aprile 2015 at 22:17
    • Reply

    Letto tutto l’articolo dei convertitori DC-DC Che spettacolo! Risolto in problema! Grazie Ti Voglio Bene!!

    1. Ciao Paolo,
      sono contento che ti sia stato utile il mio articolo.

    • Paolo on 4 aprile 2015 at 12:07
    • Reply

    Vorrei avere qualche info o dritta su come hai gestito i Menu e Sotto Menu. Grazie infinite.

    1. Ciao Paolo,
      è tutto decritto nei miei articoli, linea per linea, prova a leggerli e se qualcosa non ti è chiara ponimi una domanda specifica.

    • Luigi on 26 aprile 2015 at 10:08
    • Reply

    Ho acquistato il kit, caricato il programma, ma il sistema parte e si ferma sulla scritta “in attesa di comandi”, da cui non si muove anche premendo il pulsante select (o altri) per due o più secondi. Ho ricaricato il programma più volte e cambiato l’arduino. Non so se possa essere di aiuto, ma noto che il led sull’arduino (non quello dell’alimentazione) rimane fisso giallo, mentre in altri progetti che funzionano regolarmente è rosso.
    Grazie in anticipo del supporto
    luigi

    1. Ciao Luigi,
      se controlli nei commenti troverai che altri hanno segnalato problemi simili e li abbiamo risolti tagliando le piste presenti sulla motor shield in corrispondenza dei pin A0 ed A1

    • Luigi on 26 aprile 2015 at 12:47
    • Reply

    Ho scoperto in un’altro thread (uMade) sullo stesso progetto che avrei dovuto sezionare le piste D0 e D1 sullo sketch controllo motori.
    Ora sembra funzionare.
    Grazie mille!
    Luigi

    1. Ciao Luigi,
      perfetto !!

    • Luigi on 26 aprile 2015 at 19:59
    • Reply

    Una (spero ultima) domanda: non mi è chiaro dove collegare i fili per l’attuazione dello scatto nella fotocamera: in una delle sezioni è previsto un fotoaccoppiatore, ma nella versione 2 non sono riuscito a trovare i riferimenti.
    Mi manca qualcosa?
    Grazie di nuovo

    Luigi

    1. Ciao Luigi,
      il sistema di connessione del foto accoppiatore o opto isolatore è sempre il medesimo.
      Nello sketch puoi leggere
      #define SCATTO 2
      quindi collegalo pure al pin 2

    • Luigi on 27 aprile 2015 at 21:59
    • Reply

    Grazie. Ho ordinato da robotics 3D i fotoaccoppiatori. Spero di riuscire a montare anche questa parte entro il weekend.
    Buona serata

    • dormopoco on 16 ottobre 2015 at 14:16
    • Reply

    Avrei una domanda, tutto funziona alla grande ma…
    se importo numero di passi 5, e nessuno tempo di pausa ne prima ne dopo. perché è comunque presente una pausa tra l’esecuzione dei passi e l’altra? come posso eliminare questo tempo?

    Se tutto è zero ovviamente.

    1. Ciao Paolo,
      il tempo che intercorre tra i passi è modificabile direttamente nella funzione che esegue i passi, leggi nella descrizione dello sketch come funziona per eseguire facilmente la modifica. Ricorda che i tempi li devi tarare bene sul tuo motore per evitare che il motore sibili e non esegua spostamenti.

    • Paolo on 21 ottobre 2015 at 03:10
    • Reply

    Sto utilizzando un nema 11 con una puleggia a 36 denti. E purtroppo sto impazzendo. Non riesco a farlo girare in rotazione continua senza pause. Nonostante il tempo di alt prima e dopo siano a impostati a zero. So che sei super impegnato ma potresti darmi qualche dritta in più per risolvere il problema. Sono quasi alla fine della parte meccanica. E mi dispiacerebbe moltissimo non per ultimare il progetto.

    1. Ciao Paolo,
      ti ho già risposto in un precedente commento, puoi leggere lo sketch e troverai il punto in cui modificare i tempi tra un passo ed il successivo.
      Scrivo gli sketch e li commento linea per linea proprio perché chiunque possa eseguire le modifiche che desidera.

    • Paolo on 21 ottobre 2015 at 15:02
    • Reply

    Grazie Mauro sempre paziente. Credo di aver capito. Mi trae in inganno il tempo di posta cioè il tempo dove il carrello rimane fermo per la fase scatto. Devo riuscire a mettere questo tempo che sia uguale al tempo “intervallo tra i passi”. Sicuramente è più semplice cosi che un nuovo menu che imposti il tempo di posa.

    Nulla da fare anche impostando TIMESCATTO 0 è sempre presente un 330ms circa di delay. Davvero Mauro non riesco a capire.

    1. Ciao Paolo,
      hai provato a impostare il numero di scatti a 1 e il numero di passi al massimo numero di passi che ti servono per percorrere lo spostamento desiderato.
      Se leggi il codice, e la mia descrizione, vedrai che in tal caso tutti i tempi di attesa relativa allo scatto non vengono presi in considerazione.
      Il mio dubbio a questo punto è “tu cosa stai cercando di ottenere ?”

      Se la risposta è uno slider video da un Dolly allora posso consigliarti di riscrivere lo sketch e non cercare di adattare questo che è pensato per fare tutt’altro.

    • Paolo on 21 ottobre 2015 at 21:26
    • Reply

    No Mauro mi serve per i Time Laps ma uso una Gopro, su questa non è possibile utilizzare un cavo per farla scattare. Quello che cerco di ottenere è azzerare il tempo di posa.

    Esempio:

    Numero Passi per Scatto 60
    Intervallo tra i Passi 100
    Tempo di Alt Prima 0
    Tempo di Alt Dopo 0
    Numero scatti 900

    Ecco cosa succede il motore fa 60 passi (tra un passo e l’altro trascorrono 100ms) poi scatta, bene perfetto pero qui fa una pausa di circa 330ms e poi il ciclo si ripete. Io vorrei che questo tempo fosse zero o uguale all’intervallo tra i passi.

    Non so se sono riuscito a spiegarmi.

    1. Ciao Paolo,
      puoi eliminiare il DEBUG commentando la linea 23, in questo modo i Serial.print non vengono eseguiti ed i tempi si riducono.
      Considera che ogni operazione eseguita dallo sketch impegna il processore per alcuni millisecondi e la comunicazione seriale è impegnativa.

      In ogni caso se non ti occorre avere il tempo di pausa per lo scatto puoi inserire:

      Numero Passi per Scatto 54000 // ( 60 x 900 )
      Intervallo tra i Passi 100
      Tempo di Alt Prima 0
      Tempo di Alt Dopo 0
      Numero scatti 1

      Come ti avevo suggerito nel precedente commento.

    • Paolo on 22 ottobre 2015 at 12:24
    • Reply

    Grazie, Grazie e ancora Grazie! Questa sera provo! Una volta ultimato ti mando le foto e video! Grazie ancora buon lavoro.

    1. Bene Paolo !!!

    • Paolo on 22 ottobre 2015 at 20:20
    • Reply

    Sono qui questa volta solo per dirti che…. FUNZIONAAAAA!!! Ho commentato tutti i DEBU e Serial.print. Ora è davvero funzionale. Lo posso usare sia per la GoPro che per La mia fotocamera (Aumentato Tempo di Alt Prima e e Dopo)

    Grazie ancora Mauro.

    1. Bene Paolo sono contento che tu sia riuscito ma sopratutto che ora sai come modificare da solo il codice per realizzare tutti i progetti fotografici che desideri.

    • Giovanni on 13 maggio 2016 at 17:22
    • Reply

    Ciao Mauro! Che motor shild hai usato?

    1. Ciao Giovanni,
      la motor shield ufficiale arduino.cc
      Trovi tutti i dettagli negli articoli dedicati al dolly presenti nel blog.

    • Giovanni on 3 giugno 2016 at 11:28
    • Reply

    Ciao Mauro! Utilizzo per il contenuto costo un driver pololu a4988 ed una shield LCD di questo tipo: [ link rimosso ]
    Sapresti dirmi per cortesia dove prendere dalla shield gli output del motore passo a passo? Inoltre facendo varie prove senza collegare nessun input dei motori al pololu ma soltanto alimentando il motore e il driver, il motore girava da solo facendo strani rumori e vibrando. Preciso che il motore è di una vecchia stampanta, nessun data sheet purtroppo.. L’ho alimentato a circa 11 v e ho utilizzato un condesatore 1500 6.5 v.. ti allego il collegamento del pololu che ho trovato online.. Grazie mille e scusa per le numerose domande. https://www.pololu.com/product/1182

    1. Ciao Giovanni,
      per shield intendi una su cui montare il driver A4988? se si penso ne esistano diverse che puoi scegliere dal catalogo robotics-3d.com
      La seconda domanda non l’ho compresa.

Lascia un commento

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.