Salve a tutti,
vorrei imparare ad utilizzare i display a 7 segmenti a doppia cifra, conosco le basi e il loro funzionamento.
Avevo imparato ad utilizzare un 74hc595 shift register per pilotare un 7 segmenti con pochi pin ma ora ho la necessità di utilizzare un display a doppia cifra e non credo che questo metodo sia più adatto.
La mia domanda riguarda il modo in cui potrei pilotarli con arduino utilizzando il minimo numero di pin.
Ho trovato un chip chiamato max7221 che mi permette di pilotarne fino a 8 ma questo è un chip sovradimensionato per le mie esigenze ed occupa molto spazio essendo a 24 pin.
Vorrei chiedervi se esiste un driver per display 7 segmenti più compatto con il quale posso pilotare un display a due cifre e se esiste qualche guida dove imparare ad usarlo.
Ringrazio chiunque voglia aiutarmi.
scusa e utilizzare 2 shift register ? ![]()
Si hai perfettamente ragione infatti è il metodo che sto adottando, ma ho visto che quel chip ha un ingresso spi e ha bisogno di soli 3 pin per 8 display e mi chiedevo se esistesse un chip piu compatto
multiplexxa tutto!!
ovvero è come se pilotassi una sola cifra sul display, ma con dei bit di selezione, selezioni quela degli n display deve illuminarsi e li ci scrivi un numero, poi passi al secondo, poi al terzo e cosi via.
quindi ti servono i bit normali de 7 segmenti (piu punto) + 1,2,3 bit aggiuntivi per selzionare il display.
Ho acquistato dei display 7 segmenti con 10 pin sul retro 8 per i segmenti 2 per la selezione della cifra.
Quello che volevo fare era utilizzare lo shift register per selezionare il simbolo da visualizzare e altri 2 pin per selezionare il display da attivare. Non avendo ancora a disposizione i display mi era venuto il dubbio che questo metodo (tipo multiplexing) non è adatto perche' nel momento in cui vado a commutare dall'uno all'altro display potrei perdere la visualizzazione. Per questo motivo stavo penando al max7221 perchè credo gestisca lui il multiplexing.
Secondo voi usare il 74hc595 con la commutazione tramite arduino dei due display è sufficiente?
in realtà se non impalli il micro a fargli calcolare cose abnormi come il seno del seno del coseno del seno, con una routine che visualizza e multiplexa sempre i display non dovresti vedere che si spengono o blinkano ![]()
Poi aspetta la parola di quelli che ne sanno di più ma se stai sopra ai 100Hz di refresh non dovresti aver problemi anzi ![]()
Il multiplex sui display a led ha senso se fai uno switch molto veloce da una cifra all'altra e contemporaneamente tieni la cifra accesa per un lasso di tempo superiore alla capacità dell'occhio di percepire il cambio d'immagine (mediamente l'occhio umano non distingue più le singole immagini dopo circa 25/30 immagini al secondo).
Per evitare di avere problemi, potresti usare un timer per la visualizzazione che ad intervalli regolari scrive la cifra da visualizzare sul display giusto e si occupa anche di cambiare il display stesso.
L'alternativa è appunto usare un driver apposito.
Rebel_88:
Salve a tutti,
vorrei imparare ad utilizzare i display a 7 segmenti a doppia cifra, conosco le basi e il loro funzionamento.
Avevo imparato ad utilizzare un 74hc595 shift register per pilotare un 7 segmenti con pochi pin ma ora ho la necessità di utilizzare un display a doppia cifra e non credo che questo metodo sia più adatto.
La mia domanda riguarda il modo in cui potrei pilotarli con arduino utilizzando il minimo numero di pin.
Ho trovato un chip chiamato max7221 che mi permette di pilotarne fino a 8 ma questo è un chip sovradimensionato per le mie esigenze ed occupa molto spazio essendo a 24 pin.
Vorrei chiedervi se esiste un driver per display 7 segmenti più compatto con il quale posso pilotare un display a due cifre e se esiste qualche guida dove imparare ad usarlo.
Ringrazio chiunque voglia aiutarmi.
nonostante che arduino sia in grado di pilotare display 7 seg in multiplex è sempre una PESSIMA idea,
MOLTO meglio usare il 7219-7221 sono chip dedicati e puoi cambiare la luminosità a piacere da software
con arduino se devi fare anche qualcos'altro che supera i 10 ms la visualizzazione diventa "cattiva"
se usi interrupt è ancora peggio
con il solo arduino devi aggiungere 7 transistor e 7 resistenze per vedere i numeri con luminosità costante
altrimenti luno lo vedi molto piu luminoso dell'8
Grazie a tutti per i chiarimenti.
Quello che farò è acquistare il max7221 per piltare il mio display .
Visto che ho molti pin in più pensavo di collegarci anche 5 led di segnalazione che farei pilotare direttamente dal max7221, dovrebbero accendersi uno alla volta in funzione di un parametro fornito da arduino. Secondo voi è fattibile l'aggiunta di questi led? oppure sarò costretto ad inviare solo numeri e lettere e quindi la combinazione di pin attivi sarà tale da non poter accendere uno alla volta i miei led?
elrospo:
nonostante che arduino sia in grado di pilotare display 7 seg in multiplex è sempre una PESSIMA idea,
Perché? Spiegalo.
MOLTO meglio usare il 7219-7221 sono chip dedicati e puoi cambiare la luminosità a piacere da software
Perché?
con arduino se devi fare anche qualcos'altro che supera i 10 ms la visualizzazione diventa "cattiva"
La visualizzazione in multiplexing è cattiva per via dell'occhio umano, non per via dell'Arduino.
se usi interrupt è ancora peggio
Su che basi dici questo? Io ho fatto una serratura con codice a tastiera e piloto il display con un interrupt mosso da un timer.
Posso capire "è difficile", non puoi dire "è ancora peggio".
con il solo arduino devi aggiungere 7 transistor e 7 resistenze per vedere i numeri con luminosità costante
altrimenti luno lo vedi molto piu luminoso dell'8
Questo perché strutturi male il circuito e usi 1 resistenza per cifra, in questo modo la corrente si distribuisce fra i led accesi ma così rischi di bruciarli.
Devi usare una resistenza per LED e poi un transistor per ogni anodo (se il display è a anodo comune) o per ogni catodo (se il display è a catodo comune).
Il display che hai comprato é uno coi catodi o coi anodi comuni?
Il MAX7219 sa pilotare in modalitá cifre ( visualizza numeri da 0 a 9 e -, E, H, L, P, blank ) solo display con catodo comune.
Inoltre é possibile con un trucchetto anche usare quelli ad anodo comune usando il MAX7219 in modalitá matrice (pilotaggio di 64 LED 8x8 dove ogni bit dei dati trasmessi corrisponde a un LED acceso o spento)
Il codice sottostante é per il pilotaggio di un display ad anodi comuni. C'ha a scelta due set di caratteri da visualizzare, quello originale del MAX7219 e l' altro con 0-9, a-f per visualizzare numeri esadecimali.
Ciao Uwe
/*
Library to drive 8 digit 7 segment LED display with common anode with the MAX7219 in Matrix mode.
by Uwe Federer
*/
int dataIn = 2;
int load = 3;
int clock = 4;
int maxInUse = 4; //change this variable to set how many MAX7219's you'll use
int e = 0;
byte digit[8]; // Numbers to display LSB at Right position.
byte matrix[8]; // valute to send to the MAX7219 order LSB right, SEG: R->L: A B C D E F G dp
// define max7219 registers
byte max7219_reg_noop = 0x00;
byte max7219_reg_digit0 = 0x01;
byte max7219_reg_digit1 = 0x02;
byte max7219_reg_digit2 = 0x03;
byte max7219_reg_digit3 = 0x04;
byte max7219_reg_digit4 = 0x05;
byte max7219_reg_digit5 = 0x06;
byte max7219_reg_digit6 = 0x07;
byte max7219_reg_digit7 = 0x08;
byte max7219_reg_decodeMode = 0x09;
byte max7219_reg_intensity = 0x0a;
byte max7219_reg_scanLimit = 0x0b;
byte max7219_reg_shutdown = 0x0c;
byte max7219_reg_displayTest = 0x0f;
/*
byte dots[] ={ // original MAX7219 code, order: DIG: dp, g, f, e, d, c, b, a
B00111111, // 0
B00000110, // 1
B01011011, // 2
B01001111, // 3
B01100110, // 4
B01101101, // 5
B01111101, // 6
B00000111, // 7
B01111111, // 8
B01101111, // 9
B01000000, // -
B01111001, // E
B01110110, // H
B00111000, // L
B01110011, // P
B00000000 // blank
};
*/
byte dots[] ={ // alternative hexadecimal code, order : DIG: dp, g, f, e, d, c, b, a
B00111111, // 0
B00000110, // 1
B01011011, // 2
B01001111, // 3
B01100110, // 4
B01101101, // 5
B01111101, // 6
B00000111, // 7
B01111111, // 8
B01101111, // 9
B01110111, // A
B01111100, // b
B01011000, // c
B01011110, // d
B01111001, // E
B01110001 // F
};
void MAXsetnumber(byte data, byte stelle)
{
for (byte n=0; n <=7; n++)
{
Serial.print (bitRead(dots[data],n),HEX);
bitWrite(matrix[n], stelle, bitRead(dots[data],n));
}
Serial.println(" ");
}
void MAXupdate()
{
for (byte k=0; k <=7; k++)
{
maxSingle(k+1, matrix[k]);
}
}
void putByte(byte data) {
byte i = 8;
byte mask;
while(i > 0) {
mask = 0x01 << (i - 1); // get bitmask
digitalWrite( clock, LOW); // tick
if (data & mask){ // choose bit
digitalWrite(dataIn, HIGH);// send 1
}else{
digitalWrite(dataIn, LOW); // send 0
}
digitalWrite(clock, HIGH); // tock
--i; // move to lesser bit
}
}
void maxSingle( byte reg, byte col) {
//maxSingle is the "easy" function to use for a //single max7219
digitalWrite(load, LOW); // begin
putByte(reg); // specify register
putByte(col); //((data & 0x01) * 256) + data >> 1); // put data
digitalWrite(load, LOW); // and load da shit
digitalWrite(load,HIGH);
}
void maxAll (byte reg, byte col) { // initialize all MAX7219's in the system
int c = 0;
digitalWrite(load, LOW); // begin
for ( c =1; c<= maxInUse; c++) {
putByte(reg); // specify register
putByte(col);//((data & 0x01) * 256) + data >> 1); // put data
}
digitalWrite(load, LOW);
digitalWrite(load,HIGH);
}
void setup () {
pinMode(dataIn, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(load, OUTPUT);
Serial.begin(9600);
digitalWrite(13, HIGH);
//initiation of the max 7219
maxAll(max7219_reg_scanLimit, 0x07); //scan all Digits
maxAll(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits)
maxAll(max7219_reg_shutdown, 0x01); // not in shutdown mode
maxAll(max7219_reg_displayTest, 0x00); // no display test
for (e=1; e<=8; e++) { // empty registers, turn all LEDs off
maxAll(e,0);
}
maxAll(max7219_reg_intensity, 0x0f & 0x0f); // the first 0x0f is the value you can set
// range: 0x00 to 0x0f
}
void loop () {
for (int m = 0; m<=15; m++)
{
MAXsetnumber( m,0); //MAXsetnumber(byte data, byte stelle)
MAXsetnumber( m,1);
MAXsetnumber( m,2);
MAXsetnumber( m,3);
MAXsetnumber( m,4);
MAXsetnumber( m,5);
MAXsetnumber( m,6);
MAXsetnumber( m,7);
MAXupdate();
Serial.println(m);
delay(500);
}}