giovedì 15 gennaio 2015

Timer

Timer conto alla rovescia

Questo post nasce dalla modifica del post

Cronometro di Rubik

La modifica è solo nello sketch, che mostrerò più sotto.

Le caratteristiche:

Visualizza e conteggia su 6 ( sei) display a 7 segmenti, minuti, secondi e centesimi di secondo.
Un pulsante di Start e di Stop conteggio.
E' possibile alimentarlo con batteria o da USB.




Questo il materiale occorrente:
Arduino UNO
------------------------------------------------- 
n.6 -  Display 7 segmenti a catodo comune. 
(Io ho utilizzato questi ):
WD05212AUR-20.
VR = 5 V
IAF = 25mA
-------------------------------------------------
 n. 6 - Transistor NPN BC547.
n. 7 - resistenze da 560 omm.
n. 6 - resistenze da 1.2k.
un pulsante normalmente aperto.
una resistenza da 10k.
una resistenza da 100 omm.
un condensatore ceramico da 100nF.
materiale per collegamenti e o basette forate.
Eventuale uleriore pulsante per il reset.
Se si desidera l'alimentazione a batteria, un interruttore, un contenitore per pacco batterie, e attacco per alimentazione su arduino.

Questo lo schema dei collegamenti:



Le modifiche effettuate allo sketch sono evidenziate in blu.

Il tempo conteggio del timer si può impostare da un 1 minuto a 59 minuti.
Basterà  impostare questo valore nella variabile  TempoConteggio nel formato 1xx5999, sostituendo ad xx i minuti da 01 fino a 59.

La variabile TempoZero conterrà il valore da raggiungere per zero impostare 1000000

Le altre modifiche sono nel loop principale una if che controlla se raggiunto il tempozero e nella mostra tempo per poter effettuare il conteggio alla rovescia.

Il resto non cambia.

Qui sotto lo sketch

  in blù le parti modificate o aggiunte


/*
//--------------------------------------------------------------------------//
//********************************
  Sergio  & Adiano Prenleloup
 ********************************* 
 ***cronometro 6 display  ********
 *********  RUBIK- Modificato  ***
 **** Conteggio alla rovescia ****
 *********  **********   ***** *
 *** Versione 1.1.2 ***************
 ****** 15/01/2015 ***************
 *********************************

//--------------------------------------------------------------------------//

/* Programma che realizza il Multiplexing.
Invo bit alto ai pin corrispondenti ai segmenti a,b,c,d,e,f,g.
Si accendono inviando bit alto alle unità, poi, alle decine, centinaia,
migliaia, decine di migliaia, centinaia di migliaia.
//--------------------------------------------------------------------------//
Questa versione visualizza i centesimi di secondo, i secondi ed i minuti.
Realizzando un cronometro con start e stop tramite pulsante.
Allo start si avvia il conteggio (che viene visualizzato), allo STOP
si ferma il conteggio e si mostra il risultato.

Si utilizza la funzione millis per calcolare il tempo.
//--------------------------------------------------------------------------//

*/
// variabili aggiunte per conteggio alla rovescia
// con blocco arrivati al ( tempo zero )
//-------------------------------------------------------------------
unsigned long TempoConteggio = 1055999; // partenza del conto alla rovescia ( qui impostato a 5 minuti)
unsigned long TempoZero = 1000000; // Per tempo stop ( qui impostato a 0 )
unsigned long TempoCont = 0; // per controllare se raggiunto il tempo zero
//--------------------------------------------------------------------

const int MUXDELAY = 100; // tempo in microsecondi per multiplexing

// corrispondenza pin Unità, Decine, Centinaia, Migliaia
// con questi pin si comanda la base del transistor
// collegato al catodo comune del display

int Unit = 8;      // pin digitale unità
int Deci = 9;      // pin digitale decine
int Cent = 10;     // pin digitale centinaia
int Mill = 11;     // pin digitale migliaia
int DecMill = 12;  // pin digitale decine di migliaia
int CenMill = 13;  // pin digitale centinaia di migliaia



// corrispondenza segmenti display con pin
//-----------------------------------------
// Occorre rispettare la corrispondenza
// segmento pin associato come tabella.
// Altrimenti occorre apportare le opportune
// modifiche alle righe qui sotto.

int segA = 4;
int segB = 3;
int segC = 2;
int segD = 1;
int segE = 0;
int segF = 5;
int segG = 6;


//Associazione tra segmenti e pin arduino

int tabSegmentiPin[7] = {
  4, //seg a
  3, //seg b
  2, //seg c
  1, //seg d
  0, //seg e
  5, //seg f
  6  //seg g
};


//Associazione tra numeri rappresentabili e segmenti da accendere
int tabNumeriSegmenti[10][7] = 
 //a,b,c,d,e,f,g
  {1,1,1,1,1,1,0},  //zero
  {0,1,1,0,0,0,0},
  {1,1,0,1,1,0,1},
  {1,1,1,1,0,0,1},
  {0,1,1,0,0,1,1}, //quattro
  {1,0,1,1,0,1,1},
  {1,0,1,1,1,1,1},  
  {1,1,1,0,0,0,0},
  {1,1,1,1,1,1,1},
  {1,1,1,1,0,1,1}  //nove
};

//--------------------------------------------------------------------------//

//variabili del tempo di start e di stop
// si utilizzano per la lettura del tempo con millis()
unsigned long TempoStart = 0;
unsigned long TempoStop = 0;

//--------------------------------------------------------------------------//
// gestione pulsante
//
int Button = 7; // pin pulsante
// variabili gestione pulsante
int StatoPulsante = 0;
int old_Stato = 0;
int OnOff = 0; // cambia di stato ad ogni pressione del pulsante

//--------------------------------------------------------------------------//

void setup()
{
  

  pinMode (Button,INPUT); 
//---------------------------------  
  pinMode (segA, OUTPUT);
  pinMode (segB, OUTPUT);
  pinMode (segC, OUTPUT);
  pinMode (segD, OUTPUT);
  pinMode (segE, OUTPUT);
  pinMode (segF, OUTPUT);  
  pinMode (segG, OUTPUT);
//-------------------------------
  pinMode (Unit, OUTPUT);
  pinMode (Deci, OUTPUT);
  pinMode (Cent, OUTPUT);  
  pinMode (Mill, OUTPUT);
  pinMode (DecMill, OUTPUT);
  pinMode (CenMill, OUTPUT);
 //------------------------------- 
  digitalWrite (Unit, LOW);
  digitalWrite (Deci, LOW);
  digitalWrite (Cent, LOW);
  digitalWrite (Mill, LOW);
  digitalWrite (DecMill, LOW);
  digitalWrite (CenMill, LOW);
//--------------------------------  
  // controllo display
  // 
 start();  // si visualizza 888888
}
//-----------------------------------------
// fine setup
//-----------------------------------------

 //------------------------------------------------------------//
// Inizio loop
//------------------------------------------------------------//
void loop()
{
  TempoStop = 0; // azzero stop tempo
  OnOff = 0;   // azzero pressione tasto
  nonumero();  // visualizzo segmenti centrali
  spegniCifre(); // spengo le cifre
  //-------------------------------------------------------------// 
  Pulsante();   // attendo la pressione del pulstante per start
  
  if (OnOff == 1) // attesa di partenza conteggio
  {
    // E' partito il conteggio
    TempoStart = millis();  // memorizza inizio del conteggio
    while (OnOff == 1)
    {
      Conteggio();  // conteggia e visualizza minuti e secondi
      Pulsante();   // fino alla pressione del pulsante
      //--------------------------------------------------------------
      // modifica per conteggio rovescia ---------------------------
      if (TempoCont == TempoZero)// si controlla se si è raggiunto
                                 // il tempo Zero
      {
       OnOff = 0; // Questo ha la stessa funzione della pressione pulsante
      }
       //----------------- fine modifica --------------------------- 
    }
   //-----------------------------------------------------------// 
    // blocca il tempo di Stop
    TempoStop = millis();
    // visualizza il risultato fino alle pressione del tasto 
    while (OnOff == 0)
    {      
      VediStop();  // visualizza il risultato
      Pulsante();  // fino alle pressione del tasto
    }
  }
 // torna a loop  
//-------------------------------------------------------------//   
// End loop principale
//-------------------------------------------------------------//




//--------------------------------------------//
// FUNZIONI 
//-------------------------------------------//
//-----------------------------------------
// Procedura di partenza
// si visualizza la cifra 8 su tutti i display
// per controllo
//-----------------------------------------
void start()
{
  unsigned long n = 888888;
  for (int i = 0; i < 1000; i++)
  {
   visualizzaNumero(n);
   delay(1);
   }
}
 //-------------------------------------------------------
 // accende i segmenti centrali in attesa di start conteggio
void nonumero()
{
  for (int i = 0; i < 6; i++)
  {
   digitalWrite(tabSegmentiPin[6], HIGH);
   digitalWrite (i+8, HIGH);
   delayMicroseconds (10);
    digitalWrite (i+8, LOW);
   }
  spegniSegmenti();
  
}
  
//-----------------------------------------------
// Prepara quanto contento in TTS per mostrarlo
// in modo corretto con la funzione visualizzaNumero
// in TTS è contento il numero intero lungo dei millisecondi
// trascorsi dallo start al tempo attuale
// oppure al tempo di stop
//-------------------------------------------------------
void MostraTempo(unsigned long TTS) // in TTS è contenuto il tempo trascorso in millisecondi
{
   unsigned long millesimi = (TTS%1000); //contiene i millesimi trascorsi
   unsigned long sectr = (TTS /1000);   // contiene i secondi trascorsi
   unsigned long secondi = (sectr % 60); // contiene i secondi trascorsi in modulo 60
   unsigned long minuti = (sectr /60);   // contiene i minuti trascorsi
   unsigned long centesimi = (millesimi/10); // si prendono solo i centesimi
   
   // compone n da visualizzare
   unsigned long n = (TempoConteggio - ( centesimi + (secondi*100) + (minuti*10000)));
   
   TempoCont = n; // si utilizza per controllare se arrivati al tempo zero
                  // modifica aggiunta per conto alla rovescia
   
   visualizzaNumero(n);
   //-----------------------------------------------------------------------------
}

 //----------------------------------------
 // Conteggia e visualizza minuti e secondi
 // centesimi dal tempo di start  al tempo 
 // trascorso
 //----------------------------------------
 void Conteggio()
  unsigned long Tempo = millis() - TempoStart;
  MostraTempo(Tempo);
}

//-----------------------------------------------------
// conteggia e visualizza minuti, secondi e centesimi
// dal tempo di start al tempo di STOP
//----------------------------------------------------
void VediStop()
{
  unsigned long TTS = (TempoStop - TempoStart);
  MostraTempo(TTS);
}
//----------------------------------------------------- 

   
//----------------------------------------------------
// funzione che visualizza con il multiplexing il numero
// passato (unsigned long )
// visualizza unita, decine, centinaia ecc...
// utilizzando i sei display
// il numero viene prima scomposto in unità, decine centinaia ecc...
// quindi si accendono con le chiamate 
// alle singole subrutin le unità, decine, ecc...
//----------------------------------------------------
void visualizzaNumero(unsigned long numero)
{
 // scomposizione di numero
 // si scompone il numero che ogni display dovrà visualizzare.
 //----------------------------------------------------
  int u = numero % 10;
  int d = (numero / 10) % 10;
  int c = (numero / 100) % 10;
  int m = (numero / 1000) % 10;
  int dm = (numero / 10000) % 10;
  int cm = (numero / 100000) % 10;
  
  spegniCifre(); // si spengono tutte le cifre
  
  //-----------------------------------------------  
  // la serie di if accende le cifre necessarie
   if (numero > 99999)
   {
     accendiCenMill(cm);
     delayMicroseconds(MUXDELAY);
     digitalWrite (CenMill, LOW);
   }

   if (numero > 9999)
   {     
     accendiDecMill(dm);
     delayMicroseconds(MUXDELAY);
     digitalWrite (DecMill, LOW);
   }
  
   if (numero > 999)
   {
     accendiMigliaia(m);
     delayMicroseconds(MUXDELAY);
     digitalWrite (Mill, LOW);
   }
   
   if (numero > 99)
   {
     accendiCentinaia(c);
     delayMicroseconds(MUXDELAY);
     digitalWrite (Cent, LOW);     
   }

   if (numero > 9)
   {
      accendiDecine(d);
      delayMicroseconds(MUXDELAY);
      digitalWrite (Deci, LOW);     
   }
   
   accendiUnit(u); 
   delayMicroseconds(MUXDELAY);
   digitalWrite (Unit, LOW);        
}
  
//---------------------------------------------------------  
  
  
  //Funzione che spenge tutti i segmenti
void spegniSegmenti()
{
  digitalWrite (segA, LOW);
  digitalWrite (segB, LOW);
  digitalWrite (segC, LOW);
  digitalWrite (segD, LOW);
  digitalWrite (segE, LOW);
  digitalWrite (segF, LOW);
  digitalWrite (segG, LOW);
  
}
 // funzione che spegne tutte le cifre
void spegniCifre()
{
  digitalWrite (Unit, LOW);
  digitalWrite (Deci, LOW);
  digitalWrite (Cent, LOW);
  digitalWrite (Mill, LOW);
  digitalWrite (DecMill, LOW);
  digitalWrite (CenMill, LOW);
}

 // Funzione accendi tutti i segmenti
void accendiTuttiSegmenti()
{
  for (int i=0; i < 7; i++)
    digitalWrite (ottieniPin(i), HIGH);
}

//-----------------------------------------
// funzioni che accendono le cifre
//----------------------------------------
// Funzione Unità

void accendiUnit(int numUnita)
{
  spegniSegmenti();
  digitalWrite (Unit, HIGH);
  attivaSegmenti(numUnita); 
}
  
// Funzione Decine

void accendiDecine(int numDecine)
{
  spegniSegmenti();
  digitalWrite (Deci, HIGH);
  attivaSegmenti(numDecine);
}
  
   
// Funzione Centinaia

void accendiCentinaia(int numCentinaia)
{
  spegniSegmenti();
  digitalWrite (Cent, HIGH);
  attivaSegmenti(numCentinaia);

// Funzione Migliaia

void accendiMigliaia(int numMigliaia)
{
  spegniSegmenti();
  digitalWrite (Mill, HIGH);
  attivaSegmenti(numMigliaia);

  } 
  
  // funzione decine di migliaia
  void accendiDecMill(int numDecMill)
{
    spegniSegmenti();
  digitalWrite (DecMill, HIGH);
  attivaSegmenti(numDecMill);
  
  } 
  
  // funzione centinaia di migliaia
  
  void accendiCenMill(int numCenMill)
{
    spegniSegmenti();
  digitalWrite (CenMill, HIGH); 
  attivaSegmenti(numCenMill);
  
  } 
 //-------------------------------------------------- 
    
  
//ritorna il pin associato al segmento passato
int ottieniPin(int seg)
{
  return tabSegmentiPin[seg];
}

//Attiva i segmenti necessari a mostrare il numero n passato
void attivaSegmenti(int n)
{
  for (int i=0; i< 7; i++)
  {
    int segAttivo = tabNumeriSegmenti[n][i];
    
    if (segAttivo == 1)
    {
      digitalWrite(ottieniPin(i), HIGH); 
    }
  }
}
//------------------------------------------------------------
// funzione che gesisce il pulsante
// alla pressione del pulsante
// OnOff passa da 0 a 1 e viceversa
// ad una successiva pressione
//------------------------------------------------------------
 void Pulsante ()
 {
 // legge il valore restituito dal pin e lo memorizza in StatoButton_1
  StatoPulsante = digitalRead (Button); 

// controlla se lo stato attuale è cambiato
if ((StatoPulsante == HIGH) && (old_Stato == LOW))    
   {
     delay (10); // antirimbalzo
     OnOff = 1 - OnOff;  // cambia se premuto
   }
   // mettiamo in oldStatoButton_1 il valore attuale
   old_Stato = StatoPulsante;    
 }    
//-------------------------------------------------------------------------------------
Le foto il filmato sul post cubo Rubik
Un ringraziamento ad Adriano, Andrea, Gladio Rosso ed a tutti quanti hanno collaborato.

Al prossimo post.
Sergio

Nessun commento:

Posta un commento

Vi ringrazio per la lettura e vi invito al prossimo post.
Se il post vi è stato utile, vi è piaciuto oppure no, scrivete un commento.

Un saluto a tutti.
Sergio

Copyright - Condizioni d’uso - Disclaimer
http://avventurarduino.blogspot.it/2012/10/inizia-lavventura-arduino-12-settembre.html