Dolly Photo – quinta parte: la conclusione

I miei progetti sono sempre in divenire quindi parlare di “conclusione” del Dolly Photo non è del tutto corretta diciamo più che si tratta di un punto fermo nello sviluppo del progetto.

Dolly Photo

Con le informazioni raccolte fino a questo punto puoi già realizzare il tuo Dolly Photo funzionante.

Ho composto anche un kit Dolly Photo che puoi acquistare sul sito robotics-3d che offrono la possibilità ad appassionati come te di vendere i propri progetti sul loro store.

Avvio del Dolly Photo

in questo articolo puoi seguire passo passo la reaizzazione della funzione “Avvio” del Dolly Photo.

L’Avvio è la fase di lavoro del Dolly Photo, quella in cui esegue il ciclo di lavoro con le pause impostate, il numero di passi e gli scatti.

Unica premessa ho usato il pin 2 per lo scatto, a questo pin devi collegare l’optoisolatore a sua volta collegato allo scatto della tua macchina fotografica.

La realizzazione del Dolly Photo

Parti con il collegamento del motore:

Dolly Photo motore

come indicato in figura:

Dolly Photo connessioni

i cavi del motore passo-passo sono colorati per aiutarti a collegarli in modo corretto, le coppie di cavi sono rispettivamente bleu/giallo per la fase A e rosso/verde per la fase B.

Lo sketch del Dolly Photo

lo sketch per la maggior parte è identico a quello visto negli articoli precedenti sul Dolly Photo, leggerai in questo articolo la spiegazione delle sole linee differenti:

/**********************************************************
 * 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 BUTTON A0
#define BACKLIGHT 10
#define MOTDTIME 2000
#define LCDTIME  3000
#define SETMODETIME 2000
#define TIMESCATTO 500
#define DEBUG

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

#define PWMA 3
#define PWMB 11
#define DIRA 12
#define DIRB 13
#define TIMEFASE 35
#define SCATTO 2

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

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;
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[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 intervalloScatto  = 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 );

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

  pinMode( SCATTO,OUTPUT );
  digitalWrite( SCATTO,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 );
  lcd.clear();
  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(); 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 < 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 ) && intervalloScatto <= 9999999)  { intervalloScatto++; lcd.clear();  }
        if ( (ctrlButton( analogRead( BUTTON )) == 2 ) && intervalloScatto >=     1)    { intervalloScatto--; lcd.clear();  }

        sprintf(buffer, "%s %ds", secondario[(setModeLevel+1)], intervalloScatto);
      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)], intervalloScatto);
      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 );
  
  /**********************************************************/
  
  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 * 1000);
      if ( !ctrlDelay( _intervallo )) return;
      
    }
    
    /**********************************************************/
    
    int _tempo = (tempoAltPrima * 1000);
    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 * 1000);
    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 ) {
      return false;
      stop();
      dtime = 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);
}

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

Ho riportato tutto lo sketch per completezza e pubblicato su GitHub

Le principali differenze riguardano:

linea 32: definisci la costante SCATTO impostata a 2 il pin che utilizzi per inviare alla macchina fotografica il segnale di scatto;

linee 49-50: definisci due nuove variabili di tipo integer in cui memorizzare il numero di passi e di scatti eseguiti nella fase di Avvio;

linea 57: definisci la variabile di tipo unsigned long timeDelay il cui uso lo comprenderai quando leggerai la funzione ctrlDelay();

linee 103-104: imposta il pin 2 ( SCATTO ) come modalità di OUTPUT e impostalo a LOW;

linee 188-192: definisci la funzione lcdBlacklightOff() il cui scopo è spegnere il display quando viene richiamata e impostare a false il valore di blacklightStatus che potrai controllare per conoscere lo stato della retroilluminazione del display;

linee 196-200: definisci la funzione lcdBlacklightOn() che ha funzione inversa alla lcdBlacklightOff() ossia accende la retroilluminazione del display quando richiamata e imposta a true il valore della variabile blacklightStatus di controllo;

linea 534: definisci la funzione “Avvo”;

linee 536-540: pulisci il display e scrivi sulla prima linea “Menu” e sulla seconda “Avvio” ( vedi video );

linea 544: attendi il tempo definito nella costante SETMODETIME prima di passare oltre nell’eseguzione della funzione Avvio del Dolly Photo;

linee 548-557: imposta dei messaggi sul display, scrivi nella posizione 0 della riga 0 “Go” e nella posizione 3 della riga 0 il simbolo PAUSA. Sulla riga 1 scrivi in posizione 0 il simbolo STOP e in posizione 5 il PLAY;

linea 651: richiama la funzione pausa() e valuta il suo valore di ritorno, se è false esci dalla funzione Avvio del Dolly Photo. E’ un passaggio semplice ma importante, la funzione pausa() oltre a mettere in pausa il Dolly Photo valuta anche i tasti che premi, lo vedrai nelle linee dedicate alla funzione, e se ritorna il valore true indica che devi proseguire nel ciclo di Avvio, se ritorna false ti dice di uscire dal ciclo;

linea 565: inizia un ciclo for basato sul numero di scatti impostati ed esegue il codice contenuto tra le {} per ciascuno scatto, ricorda che scatto parte da 0;

linee 567-570: scrivi sul display il testo “scatto:” ed il numero di scatto corrente;

linea 574: per ogni ciclo del for scatti, imposta un nuovo ciclo basato sui passi da eseguire per ciascuno scatto;

linee 576-579: scrivi sulla seconda riga del display ( riga 1 ) il testo “passo:” ed il numero di passi eseguiti;

linea 581: controlla se il pulsante RIGHT è stato premuto ed in tal caso richiama la funzione pausa() che come già visto ritorna un valore true o false che ti dice se continuare dopo la sua esecuzione o uscire;

linea 583: è la linea che esegue il passo vero e proprio, richiama la funzione fase() passandole il numero di fase a cui portarsi, essendo richiamata ad ogni ciclo for dei passi esegue un passo per ciclo;

linea 584: incrementa il valore di nFase dopo averlo eseguito;

linea 585: calcola l’intervallo di tempo da attendere tar un passo ed il successivo. Poiché l’intervallo è impostato in secondi e Arduino ragiona in millisecondi ti è sufficente molyiplicare il valore di intervallo per 1000 per ottenere gli effettivi secondi di pausa tra un passo ed il successivo;

linea 586: potresti impostare il tempo di attesa con un semplice delay( _intervallo ); tuttavia questa soluzione ti impedirebbe nella fase di attesa di inviare comandi ad Arduino, ad esempio non potresti mettere in pausa lo sketch o stoppare la sequenza in corso. Ho deciso quindi di realizzare la funzione ctrlDelay( tempo ) il cui scopo è proprio attendere il tempo definito e controllare la pressione dei pulsanti anche durante l’attesa;

linee 592-593;

: calcola ed imposta il tempo di attesa prima dello scatto, questo tempo ti garantisce che il carrello si sia fermato e che la macchina fotografica sia effettivamente ferma;

linee 597-599: porta a livello HIGH il pin 2 ( SCATTO ), attendi il tempo TIMESCATTO definito alla linea 22 e riporta a LOW il pin SCATTO. Se vuoi aumentare questo tempo puoi farlo modificando il valore 500 alla linea 22;

linee 603-606: scrivi sul display il vaolore di scatto raggiunto sulla prima riga ( 0 );

linee 610-611: imposta il tempo di attesa dopo lo scatto calcolandolo come alle linee 592-593;

linea 623: definisci la funzione pausa() come di tipo boolean ossia una funzione in grado di restituire un valore di tipo booleano ( true o false ) userai il valore true per indicare allo sketch di proseguire dopo la pausa e false per interrompere il ciclo di Avvio, vedi linea 561;

linea 625: accendi la retro illuminazione del display;

linea 629: imposta una variabile di tipo booleano chiamata play;

linee 633-637: scrivi sulla prima riga alla posizione 3 il simbolo PAUSA ed alla seconda riga posizione 5 il simbolo PLAY;

linea 641: fino a quando il valore della variabile play definita alla linea 629 sarà false il ciclo continuerà all’infinito;

line642-650: controlla, per ogni ciclo, se è stato premuto il pulsante RIGHT, quello che hai definito per uscire dalla modalità PAUSA e tornare alla modalità PLAY. In caso venga premuto inverti i simboli play e pausa sulle rispettive righe, imposta a true il valore della variabile play e attendi 500 millisecondi per evitare che il tempo in cui rilasci il pulsante sia considerato come nuova pressione. In elettronica questo comportamento si chiama anche anti-rimbalzo;

linee 652-656: sono simili alle linee appena viste, con la differenza che il Dolly Photo reagisce alla pressione del pulsante LEFT, designato a STOP. La pressione di tale pulsante richiama la funzione stop(), imposta a true il valore di play e ritorna false alla funzione che ti aveva chiamato;

linea 657: imposta un tempo di 100 millisecondi tra un ciclo while() ed il successivo, serve a limitare il numero di cicli eseguiti in un secondo a 10;

linea 662: se tutte le condizioni descritte sopre sono verificate ed hai premuto il pulsante RIGHT, arrivi a questa linea che restituisce true alla funzione chiamante;

linea 667: definisci la funzione booleana ctrlDelay( tempo ) il cui funzionamento è simile alla funzione pausa() ma non identico, infatti il ciclo contenuto termina dopo un tempo stabilito e non alla pressione di un pulsante;

linea 669: puoi decommentare questa linea se desideri che durante la fase di attesa il display resti spento, resterà spento anche durante tutto il tempo di esecuzione della modalità “Avvio” a meno che tu non prema il pulsante RIGHT che mette in pausa il tutto;

linee 670-671: assegna alla variabile timedelay il valore corrente di millis() ti serve per verificare quanto tempo è passato dall’inizio del ciclo di controllo. Definisci anche una variabile di controllo dtime su cui basi il ciclo while( dtime ) successivo;

linea 681: fino a quando il valore di dtime sarà true il ciclo continuerà all’infinito;

linea 682: controlla quanto tempo è passato. Con la formula matematica ( millis() – timedelay ) sai quanto tempo è passato dall’impostazione della variabile timedelay, se questo tempo è maggiore del tempo che hai impostato nella variabile tempo allora imposta dtime a false: questo comporta l’uscita dal ciclo while();

linea 684: se premi il pulsante RIGHT questo richiama la funzione pausa;

linee 685-689: sono simili alle linee 652-656, cambiano solo le variabili utilizzate;

linea 694: ha la stessa funzione della linea 662;

Il video del Dolly Photo

ho preparato anche un video demo del Dolly Photo:

Buon divertimento

Prima di inserire un commento, per favore, leggi il regolamento

Permanent link to this article: https://www.mauroalfieri.it/elettronica/dolly-photo-conclusione.html

Lascia un commento

Your email address will not be published.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.