Problema reloj con LED display de 4 dígitos 7 segmentos[SOLUCIONADO]

Buenas ante todo me presento ya que soy novato tanto en el mundo de la programación en c como en Arduino que me parece un invento genial y con el que se puede realizar casi cualquier proyecto que se te venga a la cabeza.

Bueno os propongo mi problema y es que tengo conectado el display a la placa arduino y consigo usar cada dígito por separado pero no se como puedo hacer para usarlos conjuntamente (creo que se llama multiplexado y que a pesar de que encuentro cosas por internet nada resuelve mi duda).

En principio el proyecto seria hacer un simple reloj con minutos y segundos --> mm : ss

Aqui os dejo un video de lo que consigo hacer de momento:

El circuito montado es el siguiente:

To build the circuit, attach the LED display’s (through a 220-ohm resistor) Pin 11, 7, 4, 2, 1, 10, 5, 3 to your Arduino board’s digital Pin 12, 11, 10, 9, 8, 7, 6, 5 .
Attach the LED display’s 12, 9, 8, 6 to the Ardiuno board’s digital Pin 4, 3, 2, 1 .

Y el código usado en el video:

int a = 12;
int b = 11;
int c = 10;
int d = 9;
int e = 8;
int f = 7;
int g = 6;
int dp = 5;
int ls1 = 1;
int ls2 = 2;
int ls3 = 3;
int ls4 = 4;



void digital_0(void)
{
  unsigned char j;
  digitalWrite(dp,LOW);
  digitalWrite(g,LOW);
  for(j=7;j<=12;j++)
    digitalWrite(j,HIGH);
}

void digital_1(void)
{
  unsigned char j;
  digitalWrite(a,LOW);
  for(j=5;j<=9;j++)
    digitalWrite(j,LOW);
  digitalWrite(b,HIGH);
  digitalWrite(c,HIGH);
}

void digital_2(void)
{
  unsigned char j;
  digitalWrite(c,LOW);
  digitalWrite(f,LOW);
  digitalWrite(dp,LOW);
  for(j=11;j<=12;j++)
    digitalWrite(j,HIGH);
  for(j=8;j<=9;j++)
    digitalWrite(j,HIGH);
  digitalWrite(g,HIGH);
}

void digital_3(void)
{
  unsigned char j;
  digitalWrite(e,LOW);
  digitalWrite(f,LOW);
  digitalWrite(dp,LOW);
  for(j=9;j<=13;j++)
    digitalWrite(j,HIGH);
  digitalWrite(g,HIGH);
}

void digital_4(void)
{
  digitalWrite(a,LOW);
  digitalWrite(d,LOW);
  digitalWrite(e,LOW);
  digitalWrite(dp,LOW);
  digitalWrite(b,HIGH);
  digitalWrite(c,HIGH);
  digitalWrite(f,HIGH);
  digitalWrite(g,HIGH);   
}

void digital_5(void)
{
  unsigned char j;
  digitalWrite(b,LOW);
  digitalWrite(e,LOW);
  digitalWrite(dp,LOW);
  
  digitalWrite(a,HIGH);
  for(j=6;j<=7;j++)
    digitalWrite(j,HIGH);
  for(j=9;j<=10;j++)
    digitalWrite(j,HIGH);
}

void digital_6(void)
{
  unsigned char j;
  digitalWrite(b,LOW);
  digitalWrite(dp,LOW);
  
  digitalWrite(a,HIGH);
  for(j=6;j<=10;j++)
    digitalWrite(j,HIGH); 
}

void digital_7(void)
{
  unsigned char j;
  for(j=5;j<=9;j++)
    digitalWrite(j,LOW);
  for(j=10;j<=12;j++)
    digitalWrite(j,HIGH);
}
void digital_8(void)
{
  unsigned char j;
  digitalWrite(dp,LOW);
  for(j=6;j<=12;j++)
    digitalWrite(j,HIGH);
}

void digital_9(void)
{
  unsigned char j;
  digitalWrite(e,LOW);
  digitalWrite(dp,LOW);
  
  for(j=9;j<=12;j++)
    digitalWrite(j,HIGH);
  for(j=6;j<=7;j++)
    digitalWrite(j,HIGH);
}


void Display(unsigned char mun)
{
  switch (mun) {
    case 0:
      digital_0();
      break;
    case 1:
      digital_1();
      break;
    case 2:
      digital_2();
      break;
    case 3:
      digital_3();
      break;
    case 4:
      digital_4();
      break;
    case 5:
      digital_5();
      break;
    case 6:
      digital_6();
      break;
    case 7:
      digital_7();
      break;
   case 8:
      digital_8();
      break;
   case 9:
      digital_9();
      break;  
    default: return;
     
  }
}

void setup()
{
  int i;//????
  
  for(i=1;i<=12;i++)
    pinMode(i,OUTPUT);
}
void loop()
{ 
   int k;
  digitalWrite(ls3, LOW);
  digitalWrite(ls4,HIGH);
  digitalWrite(ls2,HIGH);
  digitalWrite(ls1,HIGH);
  for(k=0;k<10;k++){
   Display(k);
  
  delay(1000);
   
  
  
  }
  k=9;
  digitalWrite(ls4, LOW);
  digitalWrite(ls3,HIGH);
  digitalWrite(ls2,HIGH);
  digitalWrite(ls1,HIGH);
  for(k=0;k<10;k++){
   Display(k);
  delay(500);
  }

te cuento como va.

yo hice un polimetro pero con 2 integrados que hacen lo mismo. Si no recuerdo mar el cd3061 y cd3062 ( hablo de memoria )

hay 2 tipos de displays, los de anodo común ( positivo comun) y los de cátodo común ( negativo común ) dependiendo de cuales tngas tendras que dar una salida u otra, en definitiva es trabajar con logica positiva o negativa.

si tienes 4 displays debes poner en paralelo todos los segmentos y con una resistencia para cada linea, y el elemento comun ( anodo comun o catodo comun) gobernarlo a traves de un transistor que cuando ataquemos la base del mismo conduzca y se encienda el display.

arduino necesita entonces 7 lineas para los segmentos y 4 lineas para gobernar los transistores.
puedes reducir patillaje de los segmentos de 7 a solo 4 si pones un convertidor de BCD a 7 segmentos..

el ojo humano a una frecuencia mayor de 25 hercios no nota el parpadeo y con ello jugamos.

se trata de que arduino ponga el numero que tiene que salir en el display 1 enla salida de los 7 segmentos y active el display 1 solo para que se vea el numero, luego apaga display 1, pone numero del display 2 y lo activa, desactiva 2 pone numero del display 3 y lo actica, y así sucesivamente

si tienes que representar por ejemplo las 12:30
sacas por 7segmentos el 1, activas el display 1
apagas display 1, sacas por 7segmentos el 2, activas el display 2
apagas display 2, sacas por 7segmentos el 3, activas el display 3
apagas display 3, sacas por 7segmentos el 0, activas el display 4

y asi continuamente a una velocidad superior a 100 hercios ( 4 x 25 hercios )

este es un esquema de 3, le agregas un display mas con otro TR y listo

un saludo

Bienvenido al mundo de Arduino socramone.

Un consejo, comenta el código como si se lo tuvieras que hacer comprensible a un niño de 5 años, nos ayudará a los demás ahora y a ti dentro de 6 meses.

Has definido unas funciones que sirven para formar un carácter numérico, bien.

Supongo que tu problema es hacer que aparezcan varios números a la vez y lo estás intentando de una forma equivocada. Por ejemplo al principio del void() seleccionas el display con la variable ls3 y luego muestras los digitos del 0 al 9 con un retardo de 1000 milisegundos entre uno y otro. El comando delay() paraliza la actividad del procesador durante ese tiempo, por lo que no puede hacer nada más hasta que no transcurren esos 1000 milisegundos.

Debes aprovechar la recursividad del loop() y la velocidad del procesador, durante un único ciclo activa cada dígito del display y muestra en el un número, del ls1 al ls4, hazlo muchas veces y luego cambia la secuencia de números que se muestran. No se si me explico, escribes los números en el display uno a uno, la placa los encenderá y apagará tan rápido que tus ojos los verá como si estubiesen encencidos varios números a la vez.

En otras palabras, tienes que mantener los segmentos del display encendidos sin usar el comando delay(). Si a cada vuelta que da el loop() unos segmentos se encienden y se apagan y otros permanecen siempre apagados, el ciclo se repetirá miles de veces por segundo así que los que parpadeen lo harán tan rápido que parecerá que están siempre encendidos.

Espero haberte sido de utilidad, pero no se expresarlo mejor.

Ups, mientras escribía esto SrDonGato lo ha explicado divinamente.

Lo único que estás haciendo en tu código es activar una salida mientras las otras están apagadas. Enciendes el ls4 y el ls3 pero las demás no. Por ejemplo si quieres mostrar el número 1234 multiplexado tienes que encender el display1 mostrar el 4 con el resto apagados. Luego enciendes el display2 muestras el 3 y todos los demás apagados. Luego enciendes el display3 muestras el 2 con todos los demás apagados etc... Esto lo metes en una función por ejemplo para que te quede más modular. Y si quieres un control de tiempos más preciso deberás usar el RTI y no delays.

Bueno lo primero agradeceros la ayuda que me habéis dado que me ha servido de mucho y aquí os traigo el resultado final después de unos días de programación y la ayuda de un amigo (ManEspGav)

Aquí esta después de 10 minutos funcionando perfectamente. El reloj solo marca minutos y segundos y cuando finaliza la hora comienza de cero sin contador de horas.

El código terminado es el siguiente:

int a = 12;
int b = 11;
int c = 10;
int d = 9;
int e = 8;
int f = 7;
int g = 6;
int dp = 5;
int ls1 = 1;
int ls2 = 2;
int ls3 = 3;
int ls4 = 4;
 
int uno=0;
int t=0;
int dos=0;
int tres=0;
int cuatro=0;
int currentMillis = 0;
 
//Estas funcionen estan para mostrar los numeros del 0 al 9 con sus segmentos correspondientes


void digital_0(void)
{
  unsigned char j;
  digitalWrite(dp,LOW);
  digitalWrite(g,LOW);
  for(j=7;j<=12;j++)
    digitalWrite(j,HIGH);
}

void digital_1(void)
{
  unsigned char j;
  digitalWrite(a,LOW);
  for(j=5;j<=9;j++)
    digitalWrite(j,LOW);
  digitalWrite(b,HIGH);
  digitalWrite(c,HIGH);
}

void digital_2(void)
{
  unsigned char j;
  digitalWrite(c,LOW);
  digitalWrite(f,LOW);
  digitalWrite(dp,LOW);
  for(j=11;j<=12;j++)
    digitalWrite(j,HIGH);
  for(j=8;j<=9;j++)
    digitalWrite(j,HIGH);
  digitalWrite(g,HIGH);
}

void digital_3(void)
{
  unsigned char j;
  digitalWrite(e,LOW);
  digitalWrite(f,LOW);
  digitalWrite(dp,LOW);
  for(j=9;j<=13;j++)
    digitalWrite(j,HIGH);
  digitalWrite(g,HIGH);
}

void digital_4(void)
{
  digitalWrite(a,LOW);
  digitalWrite(d,LOW);
  digitalWrite(e,LOW);
  digitalWrite(dp,LOW);
  digitalWrite(b,HIGH);
  digitalWrite(c,HIGH);
  digitalWrite(f,HIGH);
  digitalWrite(g,HIGH);   
}

void digital_5(void)
{
  unsigned char j;
  digitalWrite(b,LOW);
  digitalWrite(e,LOW);
  digitalWrite(dp,LOW);
 
  digitalWrite(a,HIGH);
  for(j=6;j<=7;j++)
    digitalWrite(j,HIGH);
  for(j=9;j<=10;j++)
    digitalWrite(j,HIGH);
}

void digital_6(void)
{
  unsigned char j;
  digitalWrite(b,LOW);
  digitalWrite(dp,LOW);
 
  digitalWrite(a,HIGH);
  for(j=6;j<=10;j++)
    digitalWrite(j,HIGH); 
}

void digital_7(void)
{
  unsigned char j;
  for(j=5;j<=9;j++)
    digitalWrite(j,LOW);
  for(j=10;j<=12;j++)
    digitalWrite(j,HIGH);
}

void digital_8(void)
{
  unsigned char j;
  digitalWrite(dp,LOW);
  for(j=6;j<=12;j++)
    digitalWrite(j,HIGH);
}

void digital_9(void)
{
  unsigned char j;
  digitalWrite(e,LOW);
  digitalWrite(dp,LOW);
 
  for(j=9;j<=12;j++)
    digitalWrite(j,HIGH);
  for(j=6;j<=7;j++)
    digitalWrite(j,HIGH);
}
 

void Display(unsigned char mun)
{
  switch (mun) {
    case 0:
      digital_0();
      break;
    case 1:
      digital_1();
      break;
    case 2:
      digital_2();
      break;
    case 3:
      digital_3();
      break;
    case 4:
      digital_4();
      break;
    case 5:
      digital_5();
      break;
    case 6:
      digital_6();
      break;
    case 7:
      digital_7();
      break;
   case 8:
      digital_8();
      break;
   case 9:
      digital_9();
      break;  
    default: return;
     
  }
}
 
void setup()
{
 
  int i;
 
  for(i=1;i<=12;i++)
    pinMode(i,OUTPUT);
    
}
void loop(){ 
   
  if( currentMillis >= 10000)
   {
    currentMillis = 0;
    dos++;
    	if(dos>=6)
    	{
	    	dos=0;
	    	tres++;
	    		if(tres>=10)
	    		{
		    		tres=0;
		    		cuatro++;
		    		if (cuatro>=6)
		    		{
		    			uno=0;
		    			dos=0;
		    			tres=0;
		    			cuatro=0;
		    		}
		    	}
	    }
 }
 
   uno=(currentMillis)/1000;
 
        digitalWrite(ls4,HIGH);
        digitalWrite(ls3,HIGH);
        digitalWrite(ls2,HIGH);
        digitalWrite(ls1,LOW );
 
  Display(uno); 
 
  delay(5);
 digitalWrite(ls4,HIGH);
        digitalWrite(ls3,HIGH);
        digitalWrite(ls1,HIGH);
        digitalWrite(ls2,LOW);
 
  Display(dos);
 
   delay(5);
   digitalWrite(ls4,HIGH);
        digitalWrite(ls2,HIGH);
        digitalWrite(ls1,HIGH);
        digitalWrite(ls3,LOW);
 
   Display(tres);
   delay(5);
        digitalWrite(ls3,HIGH);
        digitalWrite(ls2,HIGH);
        digitalWrite(ls1,HIGH);
        digitalWrite(ls4,LOW);
  Display(cuatro);
 
  delay(5);
 
 
  currentMillis=currentMillis+20; //esto lo pongo por los 20 ms acumulados en los delays

}

Espero que a alguien le pueda servir de utilidad. Un saludo

gracias por el código.

subelo al playground para que otros usuarios lo vean fácilmente.

un saludo ¡

Buenas,

Buen trabajo!!! Yo también estoy empezando... La parte de programación la llevo bastante bien, pero la parte de electrónica pppppppff... me tengo que poner a estudiar cosillas. Una duda que tengo y que necesito para mi primer proyecto, es:

Tengo un display 7 segmentos de dos dígitos de ánodo común... ¿Se puede manejar los dos dígitos sin necesidad de Decodificador o transistor y sin usar 14 patillas digitales? Según tu video, parece que se puede, pero no sé como conectarlo ... :frowning:

Muchas gracias!

miraté el esquema de SrDonGato,
que és para 3, el tuyo se simplifica un poco, si tuvieses 2, los puedes poner, así visualmente te quedará más chulo.
Puedes quitar los transistores. Realmente lo que tienes que hacer es: encender un dígito, apagarlo, y encender el siguiente, apagarlo....
el efecto óptico si se hace muy rápido es que están todos los dígitos encendidos a la vez.

Hola,

Gracias por la rápida contestación. Y como se gestionan los dígitos para encenderlo y apagarlos, ¿con el nodo común? ¿Cuántas salidas digitales necesitaré? Perdona mi confusión pero de electrónica no tengo mucha idea. Lo que quiero hacer es un termométro digital basicamente. La entrada del sensor ya la tengo, ahora la quiero plasmar en el display de 7 segmentos de dos digitos

Gracias
Saludos

si has visto mi video, es un termómetro, reloj.
lo primero, te olvidas de arduino.
coges el display, una pila, un poco de cable y una resistencia. 4,5v y 330 ohms o superior.
ahora juega a encender los leds, y lo apuntas en un papel o donde quieras.
Una vez identificados los + y los -, ya tienes casi todo.
Ahora si que podemos coger el arduino, donde ponías +, harás un HIGH, y donde ponías -, harás un LOW. No conectes todos de golpe, poco a poco y con buena letra.

Hola, por favor podrias monstrar tu diagrama; tengo una práctica similar y me serviría mucho.
O por lo menos decir en que pin del arduino va cada sector del Display de 7 segmentos.
Y si usaste transistores para el barrido igual indicarme los pines por favor. Me urge un poco. Gracias.

Ese código es una un poco caótico.

Lo que deberías hacer es usar un decodificador 74HC595 para el display y con una variable usar los bits que quieres encender o apagar. Así solo utilizarás 3 pines del Arduino

Hola, ya veo que se ha solucionado el problema que tenías.

De todas formas, esta es una solución diferente y además está documentada y con ejemplos varios, deberías echarle un vistazo al siguiente enlace:

http://www.hispavila.com/3ds/atmega/display_multiple.html

Igual te aclara alguna duda que te quedara.

Saludos.

Hola que tal,

Como podrán ver soy nuevo en estos temas de arduino... Mi proyecto consiste en mostrar la temperatura con un LM35, ya he logrado hacer el multiplexeo, mi problema mas bien radica en que los segmentos de un display de anodo comun de 3 digitos no encienden con la intensidad adecuada, la verdad es que no se q mas hacer pues ya revise las conexiones y los comunes estan a tierra. Espero me puedan ayudar.

Hola amigo Diego.

Revisa la frecuencia de escaneo, en ocasiones, esto es motivo de una baja iluminación, y otra cosa, reduce al mínimo los delay que hayas usado.

Espero que te sirva.

Saludos a todos.

hola yo estoy queriendo aser lo mismo pero con displey separados los cuales tienen un parpadeo para esplicarme mas no queda n ensendidos alguen me podria ayudar con esto

hola, quien me puede ayudar hacer un reloj que muestre horas y minutos y que se pueda modificar la hora?