domenica 14 ottobre 2012

primi passi

Display a 7 segmenti

Contatore con display a 7 segmenti

21 Settembre 2012 

Programma che realizza il Multiplexing.

Invio bit alto dai pin arduino ai corrispondenti segmenti del display,  li accendo inviando bit alto alla base del transistor delle unità,  poi delle decine, centinaia e migliaia.

  Aggiornamento del 22 - Maggio - 2014

Ho aggiornato lo sketch ( in coda al post trovate l'aggiornamento)

In questo modo si accendono per pochi millisecondi alternativamente solo i segmenti del catodo chiuso verso massa. L'effetto impressione sulla retina dell'occhio fa sembrare accesi i numeri corrispondenti alle unità, decine, centinaia, migliaia.







Schema di un display a 7 segmenti ( di solito esiste un ottavo led per il punto)



Controllate sulla vostra documentazione la corrispondenza segmento piedino dei vostri display
Se volete utilizzare il codice qui sotto dovrete far corrispondere i segmenti ai pin arduino.

I segmenti dei display saranno collegati in parallelo, mentre il catodo a comune di ogni singlo display sarà collegato al collettore del relativo transistor.

qui sotto uno schema semplificato con due display che vi farà comprendere meglio il collegamento.






per questo progetto occorre il seguente materiale:

Arduino
4 Transistor ( BC547)
4 Resistenze da 1,2K
7 Resistenze da 560 ohm
4 Disply 7 segmenti con catodo comune.
1 breadboard
cavetti di collegamento vario colore.

ecco qui lo schema di collegamento:






Logicamente potrete realizzare moduli diversi a 2 - 3 - o più display, come vedrete dallo schema è tutto modulare. In tal caso occorrono fare le opportune modifiche di assegnazione dei pin sullo sketch.



Le resistenze da 560 ohm sono state calcolate su il display in mio possesso assorbimento 
circa 6 mA ( singolo led display) valore calcolato 530 ohm resistenza disponibile 560.

Voi controllate i valori del vostro display e calcolate queste resistenze affinchè non ci siano danni.

Il transistor è quello che avevo disponibile la corrente che potrà scorrere sarà data da quella del singolo led del display moltiplicato 8 numero massimo di led accesi per display.
Nel mio caso circa 50 mA. ATTENZIONE questa corrente NON passa da un singolo pin di arduino.

 
Con questo schema ho potuto sperimentare diversi sketch.

Sostanzialmente sono solo delle varianti ai numeri che verranno visualizzati.
qui sotto trovate il principale:


/* Prenleloup Sergio & Adriano
  21 Settembre 2012
 
  Quattro display a 7 segmenti a catodo comune
 
  versione 1.00
 
  prove per ARDUINO */


/* Programma che realizza il Multiplexing
invio bit alto ai piedini corrispondenti ai segmenti
Led e li attivo inviando bit alto alla base del transistor unità
poi delle decine, centinaia e migliaia.

Prova di un contatore */

// corrispondenza segmenti pin ARDUINO
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
};


// corrispondenza Unità, Decine, Centinaia, Migliaia
int Unit = 10;
int Deci = 11;
int Cent = 12;
int Mill = 13;

void setup()
{
  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);
  digitalWrite (Unit, LOW);
  digitalWrite (Deci, LOW);
  digitalWrite (Cent, LOW);
  digitalWrite (Mill, LOW);
}
 
 
// Main programma visualizza i numeri del contatore
void loop()
{
  for (int i = 0 ; i <= 9999 ; ++i) // Crea il contatore numeri da mostrare
  {
    for (int c = 0; c <= 3000 ; ++c) // Determina il tempo di visualizzazione
    {
       visualizzaNumero(i);
    }
   }
}
 
void visualizzaNumero(int numero)
{
  int u = numero % 10;
  int d = (numero / 10) % 10;
  int c = (numero / 100) % 10;
  int m = (numero / 1000) % 10;

  boolean cifraPrecedente = false;
 
   if (m > 0)
   {
     accendiMigliaia(m);
     cifraPrecedente = true;
   }
   else
   {
    digitalWrite (Mill, LOW);
    cifraPrecedente = false;
   }
  
   if (c > 0 || cifraPrecedente)
   {
     accendiCentinaia(c);
     cifraPrecedente = true;
   }
   else
   {
    digitalWrite (Cent, LOW);
    cifraPrecedente = false;
   }

   if (d > 0 || cifraPrecedente)
   {
      accendiDecine(d);
      cifraPrecedente = true;
   }
   else
   {
    digitalWrite (Deci, LOW);
    cifraPrecedente = false;
   }
  
     accendiUnit(u);
}
 
//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 accendi segmenti
void accendiTuttiSegmenti()
{
  for (int i=0; i < 7; i++)
    digitalWrite (ottieniPin(i), HIGH);
}

// Funzione Unità
void accendiUnit(int numUnita)
{
  spegniSegmenti();
  digitalWrite (Unit, HIGH);
  digitalWrite (Deci, LOW);
  digitalWrite (Cent, LOW);
  digitalWrite (Mill, LOW);
  spegniSegmenti();
  attivaSegmenti(numUnita);
}
 
// Funzione Decine
void accendiDecine(int numDecine)
{
  spegniSegmenti();
  digitalWrite (Unit, LOW);
  digitalWrite (Deci, HIGH);
  digitalWrite (Cent, LOW);
  digitalWrite (Mill, LOW);
  spegniSegmenti();
  attivaSegmenti(numDecine);
}
 
// Funzione Centinaia
void accendiCentinaia(int numCentinaia)
{
  spegniSegmenti();
  digitalWrite (Unit, LOW);
  digitalWrite (Deci, LOW);
  digitalWrite (Cent, HIGH);
  digitalWrite (Mill, LOW);
  spegniSegmenti();
  attivaSegmenti(numCentinaia);
}

// Funzione Migliaia
void accendiMigliaia(int numMigliaia)
{
  spegniSegmenti();
  digitalWrite (Unit, LOW);
  digitalWrite (Deci, LOW);
  digitalWrite (Cent, LOW);
  digitalWrite (Mill, HIGH);
  spegniSegmenti();
  attivaSegmenti(numMigliaia);
}
 
//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);
    }
  }
}

*********
Sketch - contatore quattro display



 qui puoi scaricare il Pdf dello schema.

schema quattro display




Qui il video della realizzazione


contattatemi pure per altri chiarimenti inerenti questo progetto

Aggiornamento del 22 Maggio 2014

Questo post è stato il primo che ho pubblicato, ed ha avuto molte visualizzazioni. (ad oggi 897).
Nel fare un progetto nuovo "Cronometro Rubik" (che trovate su questo blog), ho trovato dei piccoli errori ed infficienze nello sketch originale.
Adriano ha individuato gli errori e corretto lo sketch rendendo la funzione "visualizzaNumero" più efficiente e veloce.
Abbiamo anche esteso a 6 i display gestibili.
Vi riporto qui sotto il nuovo schema (è indicato anche un pulsante sul pin 7 per usi da implementare, vedi il post "Cronometro Rubik").


Qui sotto trovate lo sketch aggiornato.

//--------------------------------------------------------------------------------//
/*
//--------------------------------------------------------------------------//
//********************************
  Sergio  & Adiano Prenleloup
  
 ***contatore 6 display *********
 *********************************
 *** Versione 1.01 ***************
 ****** 20/05/2014 ***************
 *********************************

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

/* 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 un numero da 0 a 999999
//--------------------------------------------------------------------------//


*/
const int MUXDELAY = 100; // tempo in microsendi per multiplexing

// corrispondenza pin Unità, Decine, Centinaia, Migliaia


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

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

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



//--------------------------------------------------------------------------//
// gestione 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
//-----------------------------------------

 
 //------------------------------------------------------------//
// Main programma 

void loop()
{ 
  for (unsigned long i = 0 ; i <= 999999 ; ++i) // Crea il contatore numeri da mostrare
  {
    for (int c = 0; c <= 200 ; ++c) // Determina il tempo di visualizzazione
    {
       visualizzaNumero(i);
    }
   } 
}
  
 
//-------------------------------------------------------------//   
// 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);
   }
 
}
 
   
//----------------------------------------------------
// 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
  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 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); 
    }
  }
}

//-------------------------------------------------------------------------------------
 
Noterete un miglioramento nella visualizzazione dei numeri.


Vedi nel filmato il funzionamento.


grazie a tutti

 Sergio





3 commenti:

  1. e con solo due display?

    RispondiElimina
    Risposte
    1. Ciao!
      Lo schema è modulare, il numero dei display può essere da 1 a 6.
      Per due dovrai realizzare solo la parte di schema delle unità e decine.
      commentare le linee e le funzioni che non servono.
      Se non risolvi scrivi ancora.
      Grazie per il commento
      Sergio

      Elimina
    2. Questo commento è stato eliminato dall'autore.

      Elimina

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