Aggiungiamo una pulsantiera

Aggiungiamo ora una pulsantiera. Per gestire un progetto per motorizzare uno slider, possiamo tranquillamente usare solamente 4 bottoni. Vedremo in seguito come utilizzarli.
Per il momento vediamo di aggiungerli allo schema:

Schema 05 Tastiera_bb

Per gestirli dobbiamo aggiungere un po’ di righe di codice:
Le righe che aggiungiamo, con poche modifiche, possono essere utilizzate per gestire un numero maggiore di pulsanti. Sono dotate inoltre, di un sistema per evitare i falsi contatti, un sistema per avere un certo ritardo tra la pressione di un bottone e l’altro, e la possibilità di “capire” la durata della pressione del bottone in modo da capire le intenzioni dell’utente.
Al momento, Il programma sottostante non fa nulla per la gestione dello slider, ma serve per testare la pulsantiera.

#include <Wire.h> // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C LCD(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address



#define MotoreDir 3
#define MotoreStep 4
#define MotoreEnable 5
#define Led 13
#define Scatto 2

#define Bottone1 11
#define Bottone2 12
#define Bottone3 9
#define Bottone4 10 
#define PaginaBottoni 0
#define PaginaStart 1
#define PaginaSet 2

//definiamo le variabili che useremo

boolean Stato=false;//variabile che contiene true se si sta eseguendo un set oppure false se no.
int PaginaVisualizzata=0;

int NumeroPassi=200;//Il motore dovrebbe fare un giro 200×1,8°=360°
int Attesa=5000;//1 secondo tra un giro e l’altro
int Velocita=5;//Tempo di attesa tra uno step e l’altro. Più è basso questo valore più è veloce il motore
boolean Direzione = false;//variabile per gestire la direzione del motore
int NumeroFotoDaScattare = 300;//variabile per gestire il numero di foto da scattare
int NumeroFotoScattata = 0;
int AttesaDopoMovimento = 300;//per evitare vibrazioni, possiamo mettere una piccola pausa subito dopo il movimento
int DurataScatto=400;//Variabile per indicare quanto tempo (in millisecondi) deve essere simulata la pressione dello scatto
int AttesaDopoScatto = 300;//per evitare vibrazioni, possiamo mettere una piccola pausa prima di ricominciare a muovere
unsigned long TempoInizioPasso;//variabile per morizzare il tempo di inizio di un nuovo passo


//dati dello slider
unsigned long LgBinarioInMm=920;//!< Lunghezza utile del binario in millimetri (utile perchè dobbiamo togliere lo spazio occupato dal carrello)
float MotorStepSize = 1.8f;//!< l'angolo di step del motore , solitamente 1,8°
float PassoCinghia = 5;//!< Il passo della cinghia, solitamente T5
float DentiPuleggiaMotrice = 16;//!< Il numero di denti della puleggia motrice
float Riduttore = 14; // Se abbiamo interposto un riduttore tra motore e puleggia, inserire qui il valore

//calcoliamo ora il numero di passi necessari per compiere 
float StepNecessari = LgBinarioInMm * Riduttore * (360.0f /  MotorStepSize) / (PassoCinghia * DentiPuleggiaMotrice);
//dividendo questo valore trovato per il numero di foto da scattare si ha il numero di passi da far eseguire per muovere ogni volta il motore.
//poichè il risultato ottenuto potrebbe essere un numero decimale, arrotondiamo direttamente il valore.
//in questo modo evitiamo eventuali differenze di arrotondamento che possono capitare ma soprattutto
//manteniamo costante lo spazio percorso.
//Con questo arrotondamento, può succedere che lo spazio percorso non sia tutto lo spazio utile, ma in teoria si dovrebbero perdere solamente alcuni 
//millimetri.
float NumeroPassiStep= StepNecessari / (float) NumeroFotoDaScattare;

unsigned long TempoBottoniInizio[5];                       //!< Per memorizzare quando sono stati premuti i tasti
unsigned long RitardoFiltraggio = 50;                      //!< Ritardo per filtraggio di falsi contatti. Se è il caso aumentarlo


void setup() {
      pinMode(MotoreDir, OUTPUT); // imposto il pin indicato come uscita
      pinMode(MotoreStep, OUTPUT); // imposto il pin indicato come uscita
      pinMode(MotoreEnable, OUTPUT); // imposto il pin indicato come uscita
      pinMode(Scatto, OUTPUT); // imposto il pin indicato come uscita
      pinMode(Led, OUTPUT); // imposto il pin indicato come uscita
      LCD.begin(20,4); // initialize the lcd for 20 chars 4 lines and turn on backlight
      pinMode(A4, OUTPUT);
      pinMode(A5, OUTPUT);

      pinMode(Bottone1, INPUT);
      pinMode(Bottone2, INPUT);
      pinMode(Bottone3, INPUT);
      pinMode(Bottone4, INPUT);
      
      TempoInizioPasso=millis();
      NumeroPassi = NumeroPassiStep;

      ScriviPagina();


/*      
      LCD.clear();//cancelliamo lo schermo
      LCD.print("Intervallometro ");//un titolo
      LCD.print(NumeroFotoDaScattare-NumeroFotoScattata);//numero di foto mancanti
      
      LCD.setCursor(0,1);//spostiamo il punto di scrittura del testo alla colonna 0 riga 1
      LCD.print("Movimento:");
      LCD.setCursor(0,2);//spostiamo il punto di scrittura del testo alla colonna 0 riga 2
      LCD.print("Scatto   :");
      LCD.setCursor(0,3);//spostiamo il punto di scrittura del testo alla colonna 0 riga 3
      LCD.print("Num.Foto :");
*/      

}

void loop(){

  int Bottone;
  Bottone=LetturaTastiera();
  if (Bottone==1)
  {
      ScriviPagina();
      LCD.setCursor(0,2);//spostiamo il punto di scrittura del testo alla colonna 0 riga 1
      LCD.print("Bottone 1");
  }
  if (Bottone==2)
  {
      ScriviPagina();
      LCD.setCursor(0,2);//spostiamo il punto di scrittura del testo alla colonna 0 riga 1
      LCD.print("Bottone 2");
  }
  if (Bottone==3)
  {
      ScriviPagina();
      LCD.setCursor(0,2);//spostiamo il punto di scrittura del testo alla colonna 0 riga 1
      LCD.print("Bottone 3");
  }
  if (Bottone==4)
  {
      ScriviPagina();
      LCD.setCursor(0,2);//spostiamo il punto di scrittura del testo alla colonna 0 riga 1
      LCD.print("Bottone 4");
  }

      if (NumeroFotoScattata && Stato)
      {
        if (millis() - TempoInizioPasso > Attesa)
        {
            //cancelliamo i testi precedenti
            LCD.setCursor(10,1);//spostiamo il punto di scrittura del testo alla colonna 10 riga 1
            LCD.print("          ");
            LCD.setCursor(10,2);//spostiamo il punto di scrittura del testo alla colonna 10 riga 2
            LCD.print("          ");

            TempoInizioPasso = millis();
            AccendiLed();
            Motore();
            SpegniLed();
            LCD.setCursor(10,1);//spostiamo il punto di scrittura del testo alla colonna 10 riga 1
            LCD.print("Effettuato");
            Scatta();
            LCD.setCursor(10,2);//spostiamo il punto di scrittura del testo alla colonna 10 riga 1
            LCD.print("Effettuato");
            NumeroFotoScattata++;//Incrementiamo il numero di foto scattate. 
                                 //Scritta in questo modo, questa riga equivale a 
                                 //NumeroFotoScattata = NumeroFotoScattata + 1
            LCD.setCursor(10,3);//spostiamo il punto di scrittura del testo alla colonna 10 riga 3
            LCD.print("          ");
            LCD.setCursor(10,3);//spostiamo il punto di scrittura del testo alla colonna 10 riga 1
            LCD.print(NumeroFotoScattata);
            LCD.print(" di ");
            LCD.print(NumeroFotoDaScattare);

            LCD.setCursor(16,0);//spostiamo il punto di scrittura del testo alla colonna 16 riga 0
            LCD.print(NumeroFotoDaScattare-NumeroFotoScattata);//numero di foto mancanti
            LCD.print(" ");//scriviamo questo spazio per cancellare eventuali residui
         }
      }        
}

void AccendiLed(void){
      digitalWrite(Led, HIGH);//accendiamo il led
}
void SpegniLed(void){
      digitalWrite(Led, LOW);//spegnamo il led
}

void Motore(void){
      if (Direzione==true) digitalWrite(MotoreDir, HIGH);//Abilitiamo un senso di rotazione
      if (Direzione==false) digitalWrite(MotoreDir, LOW);//Abilitiamo il senso opposto
      digitalWrite(MotoreEnable, LOW);//Abilitiamo la scheda passo passo abbassando il livello logico dell’uscita
      for (int ciclo=0;ciclo//diamo un impulso al motore
            digitalWrite(MotoreStep, LOW);
            delayMicroseconds(2);
            digitalWrite(MotoreStep, HIGH);
            delayMicroseconds(2);
            delay(Velocita);//attesa per il prossimo impulso
      }
      digitalWrite(MotoreEnable, HIGH);//Disabilitiamo la scheda passo passo alzando il livello logico dell’uscita
}

void Scatta(void){
  delay(AttesaDopoMovimento);
  digitalWrite(Scatto, HIGH);//Iniziamo a simulare la pressione dello scatto
  delay(DurataScatto);
  digitalWrite(Scatto, LOW);//terminiamo lo scatto
  delay(AttesaDopoScatto);
}



int LetturaTastiera(void) // restituisce il bottone premuto
{
       int Bottone;
       int StatoBottone;
       int ritorno;
       ritorno=0;
       for (int ciclo=0;ciclo<4;ciclo++)
       {
              switch(ciclo)
              {
                     case 0:Bottone=Bottone1;break;
                     case 1:Bottone=Bottone2;break;
                     case 2:Bottone=Bottone3;break;
                     case 3:Bottone=Bottone4;break;
              }
              StatoBottone=digitalRead(Bottone);
              if (StatoBottone)
              {
                     if (TempoBottoniInizio[ciclo]==0)
                     {
                            TempoBottoniInizio[ciclo]=millis();
                     }
                     else
                     {
                            if ((millis() - TempoBottoniInizio[ciclo]) > RitardoFiltraggio)
                            {
                                     ritorno=ciclo+1;
                            }
                            if (ciclo>1 )
                            {
                                   if ((millis() - TempoBottoniInizio[ciclo]) > RitardoFiltraggio+3000)
                                   {
                                          ritorno=ciclo*10+10;
                                   }
                            }
                     }
              }
              else
              {
                     TempoBottoniInizio[ciclo]=0;
              }
       }
       return ritorno;
}

void ScriviPagina(void)
{
    LCD.clear();//cancelliamo lo schermo
    if (PaginaVisualizzata==PaginaBottoni)
    {
      LCD.print("Test Bottoni ");//un titolo
      LCD.setCursor(0,1);//spostiamo il punto di scrittura del testo alla colonna 0 riga 1
      LCD.print("Premi i bottoni");
    }  
    if (PaginaVisualizzata==PaginaStart)
    {
      LCD.print("Intervallometro ");//un titolo
      LCD.setCursor(0,1);//spostiamo il punto di scrittura del testo alla colonna 0 riga 1
      LCD.print("Per iniziare premi 2");
      LCD.setCursor(0,2);//spostiamo il punto di scrittura del testo alla colonna 0 riga 1
      LCD.print("Per fermare premi 1");
      LCD.setCursor(0,3);//spostiamo il punto di scrittura del testo alla colonna 0 riga 1
      LCD.print("Per pausa premi 3");
    }  
    if (PaginaVisualizzata==PaginaSet)
    {
      LCD.print("Intervallometro ");//un titolo
      LCD.print(NumeroFotoDaScattare-NumeroFotoScattata);//numero di foto mancanti
      LCD.setCursor(0,1);//spostiamo il punto di scrittura del testo alla colonna 0 riga 1
      LCD.print("Movimento:");
      LCD.setCursor(0,2);//spostiamo il punto di scrittura del testo alla colonna 0 riga 2
      LCD.print("Scatto   :");
      LCD.setCursor(0,3);//spostiamo il punto di scrittura del testo alla colonna 0 riga 3
      LCD.print("Num.Foto :");
    }  
}

Leave a Reply

Your email address will not be published. Required fields are marked *

Donate

Support TLTools, Make A Donation

Please make a donation if you enjoy using our software and believe in the importance of what the ciemmesoft is working to accomplish.

PayPal Donate Button

Fai una donazione!

Sostieni il progetto, fai una donazione TLTools è un progetto gratuito. Fai una donazione se ti piace utilizzare il nostro software e se credi nell'importanza di ciò a cui il progetto lavora.

PayPal Donate Button