Proyecto Puerto serial a Led Display

Hola a todos, espero que estén bien :)

Les comento... Ya me he dado vuelta casi toda internet buscando la solución a mi problema, pero por mis verdes conocimientos en electrónica, puesto que soy programador y no electrónico, me es muy difícil encontrar la solución :cry:

Les cuento mi problema...
necesito enviar mediante un programa de pc (echo por mi), la hora actual hacia un led display. ( por ejemplo: "07:17"), siendo lo mas sencillo:

he pensado utilizar el puerto paralelo o el puerto serie (rs232) con un max232, sin embargo no tengo los conocimientos, de como seguir el esquema para conectarlo hacia un led display.


si alguien me pudiera dar un empujoncito, se lo agradecería enormemente...:alabanza:
 
mmm programador

soy ing electronico :/ bueno

yo haria lo siguiente :

por puerto paralelo es posible si tu envias 1 nible que valla de 0 a 9 y del lado del puerto paralelo enviar a un 74ls47 y de ahi al display de 7 segmentos.

y con una funcion de rotar a la izq o hacer el barrido para ir seleccionando en el tiempo los displays

asi mas o menos en borland C o turbo C que tenias acceso al puertp

void funcion de reloj()
{
//tu codigo
reloj
}

//mas codigo
rotar=rotar<<inc;
inc++;
if(inc>=4)
{
inc=0;
}

outportb(0x378,rotado|reloj());


facil no?


ahora con un display LCD

es bien sabido que por puerto paralelo puedes manejar un display LCD 16x2

solo necesitas 4 lineas de datos y 3 lineas de control
en el puerto paralelo nos sobraria 1 bit perfectamente

debes leer la hoja de datos del LCD y tratar de enviar esos bits por puerto paralelo
exactamente igual como lo haria uno con 1 microcontrolador

o la mas facil de todas

usando un microcontrolador en lenguaje C o basic no se que tan ducho seas en programacion
 
Hola, Amigo, bueno lo veo muy complejo resolver el tema por lógica, ya que se requiere convertir los datos provenientes de la interface RS232 a paralelo, luego discriminar los bits de control con los bits de datos para garantizar el "orden" del tráfico y luego gestionar un barrido para mostrar en display.
Lo más práctico, es implementar un PIC como comenta el compañero, ya que sabes programar, una rutina en c para PIC puedes realizarla sencillamente, sólo que debes adquirir éste microcontrolador con hardware serial incorporado, por ejem. el 16F628.
 
bueno programar en C es facil

pero en C de CCS esta de super risa programar


solo jalas el lcd.h
y para el serie
#use rs232(bla bla bla)

lcd_init();
printf(put_lcd,"bla bla bla");

asi le haces para rapido y sin gastar cerebro ;)
 
Muchas gracias amigos por toda la información entregada hasta por el post que fue borrado, no he respondido en brevedad, ya que luego de sus respuestas comencé a informarme acerca de éstas, desde luego vuelvo a dar gracias por el apoyo.

En fin, tratare de resumir todo lo que he aprendido con mis palabras:

1.- El Led Display que usare (http://www.olimex.cl/pdf/YSD-439AY2B-35.pdf) se controla a través de 7 entradas para cada posición de la Led que forma el numero(8) en un solo digito excluyendo el punto, mediante las otras 4 entradas se controla la posición del digito a encender (en este caso son 4), esto significa que es un areglo o matris, la función de este, va encendiendo y apagando digito a digito, de manera tan rápida que el ojo humano es incapaz de ver si alguno se encuentra apagado. (88:88)

2.- Por lo visto el PIC 16F628, puede controlar las 7 entradas y cambiar entre los 4 dígitos...
jamás he programado un PIC, pero si he programado en C y C++, por lo menos tengo un programador universal y acepta ese PIC, este programador solo lo he utilizado para grabar EPROM

La idea de este pic, es que sea capaz de recibir los datos a través del RX, reconocer los números enviados (ej: 07:13) y transformarlos a las salidas correspondientes para formar el numero en el LED display

Por otro lado, busque mas información acerca de CCS y es un lenguaje estándar en C para la programación de PIC, me parece de lo mas COOL

Me imagino que el programa dentro del PIC, debería ser algo asi:

Código:
 #use rs232(baud=9600, xmit=pin_b2, rcv=pin_b1, bits=8)
int dato;

#int_rda
rda_isr()
{
dato=getc();
}
 
 void main()
 {
       while(1)
       {
              Transformar_y_Encender(dato);
       }
 }
  
 void Transformar_y_Encender(int dato)
 {
       1.- transformar el numero recibido
       2.- encender los led del primer digito
       3.- encender los led del segundo digito
       4.- encender los led del tercer digito
       5.- encender los led del cuarto digito
       6.- encender los led de los dos puntos
 }
Aquí es donde me surge la siguiente duda:

he visto diagramas con max232 para enviar al RX del PIC16F628
otros que envían directamente desde el puerto serie al PIC16F628,
¿cual es el correcto de los dos anteriores?


por otro lado vi algunos diseños desde el puerto USB hacia el PIC18F4550, ¿se podrá realizar lo mismo mediante ese PIC ?


Saludos a todos y nuevamente dar gracias por su ayuda
 
Última edición:
Hola, no puedes enviar directamente datos de un puerto serial al PIC, sin antes interceder por la interfaz que justamente hace eso. Ya que las señales del sistema RS232 poseen niveles lógicos mayores/menores que los 5V. requeridos para una entrada digital de PIC.
 
Última edición:
pues si
aveces uno trabaja en una laptop y el puerto serie no es disponible del todo para eso se usa un cable serie a usb o en su defecto un modulito como estos
BK_USB.jpg


y ya no es nesesario usar el max232 , asi ya se conecta directo

puedes optar por ambos caminos

ahora con los pic 18fX550 que tienen el puerto USB
pues no es tan facil la cosa para leer el puerto USB en modo CDC para hacer un puerto serie virtual

requiere tiempo y saber como trabaja el protocolo

lo mas facil por ahora es el puerto serie

ahora para no desperdiciar todo un puerto de 8 bits para un micro tan pequeño puedes usar un 74ls47 para decodificar un numero en BCD y los 4 bits restantes para hacer el barrido en los displays

yo usaria la funcion de rotar a la izq con una OR envio mi codigo BCD es decir roto un 1 el numero de veces que es 0 a 4 sumado con el BCD
quedaria mas o menos asi:
outputB(1<<display | BCD);

suerte
 
Hola amigos

por fin pude terminar el código del PIC, agregue y quite algunas cosas a mi proyecto, puesto que pude realizar toda la programación dentro del PIC, ya no es necesario utilizar el computador. :D

sin embargo necesito de su ayuda, nuevamente... :confused:

Este es el esquema de mi circuito

BotonTimer.jpg

Pero no se, que elemento de electrónica, hay que utilizar para crear la negación (NOT U4-U9) de una salida, por lo que estuve leyendo al parecer es un NPN

por otro lado, pienso que deben faltar resistencias o algo, lo veo muy simple


Muchas gracias de ante mano

Saludos

PD: Codigo del PIC
Código:
 //Creado por SkarStoker
 #include <16F628A.h>
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NOBROWNOUT, NOMCLR, NOLVP, NOCPD
#use delay(clock=4000000)

 //prototipo de las funciones
void ShowNumber(int num, int pos);
void ActTime();
  
 //variables globales
int32 time = 0;
short start = 0;
  
 //interrupcion B0
#int_EXT
void  EXT_isr(void) 
{
      output_high(pin_b7);
      time += 901;
      start = 1;
}
  
 void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
  
    while(1)
   {
      ActTime();
      if(start)
      {
         time -= 1;
         if (time == 0)
         {
            start = 0;
            output_low(pin_b7);
            output_high(pin_a4);
         }
      }
   }
}
 void ActTime()
{
   int8 dig1 = 0;
   int8 dig2 = 0;
   int8 dig3 = 0;
   int8 dig4 = 0;
   int8 dig5 = 0;
   int8 dig6 = 0;
   
   int8 cont = 0;
   int8 hor = 0;
   int8 min = 0;
   int8 seg = 0;
   
   hor=time/3600;  
   min=(time-(3600*hor))/60;  
   seg=time-((hor*3600)+(min*60)); 
   
   dig2 = hor%10;
   dig1 = (hor-dig2)/10;
   
   dig4 = min%10;
   dig3 = (min-dig4)/10;
   
   dig6 = seg%10;
   dig5 = (seg-dig6)/10;
   
   for(cont=0; cont < 25; cont++)
   {
      ShowNumber(dig1,1);
      delay_ms(6);
      ShowNumber(dig2,2);
      delay_ms(6);
      ShowNumber(dig3,3);
      delay_ms(6);
      ShowNumber(dig4,4);
      delay_ms(6);
      ShowNumber(dig5,5);
      delay_ms(6);
      ShowNumber(dig6,6);
      delay_ms(6);
      if(cont < 15)
      {
         ShowNumber(0,7);
      }
      delay_ms(4);
   }
}
 void ShowNumber(int num, int pos)
{
   switch(pos)
   {
      case 1: //000
      output_low(pin_b1);
      output_low(pin_b2);
      output_low(pin_b3);
      //output_low(pin_b4);
      //output_low(pin_b5);
      //output_low(pin_b6);
      break;
      case 2: //001
      output_high(pin_b1);
      output_low(pin_b2);
      output_low(pin_b3);
      //output_low(pin_b4);
      //output_low(pin_b5);
      //output_low(pin_b6);
      break;
      case 3: //010
      output_low(pin_b1);
      output_high(pin_b2);
      output_low(pin_b3);
      //output_low(pin_b4);
      //output_low(pin_b5);
      //output_low(pin_b6);
      break;
      case 4: //011
      output_high(pin_b1);
      output_high(pin_b2);
      output_low(pin_b3);
      //output_high(pin_b4);
      //output_low(pin_b5);
      //output_low(pin_b6);
      break;
      case 5: //100
      output_low(pin_b1);
      output_low(pin_b2);
      output_high(pin_b3);
      //output_low(pin_b4);
      //output_high(pin_b5);
      //output_low(pin_b6);
      break;
      case 6: //101
      output_high(pin_b1);
      output_low(pin_b2);
      output_high(pin_b3);
      //output_low(pin_b4);
      //output_low(pin_b5);
      //output_high(pin_b6);
      break;
      case 7: //110
      output_low(pin_b1);
      output_high(pin_b2);
      output_high(pin_b3);
      return;
      break;
      case 8: //111
      output_high(pin_b1);
      output_high(pin_b2);
      output_high(pin_b3);
   }
   
   switch(num)
   {
      case 0:
      output_low(pin_a0);
      output_low(pin_a1);
      output_low(pin_a2);
      output_low(pin_a3);
      break;
      
      case 1:
      output_high(pin_a0);
      output_low(pin_a1);
      output_low(pin_a2);
      output_low(pin_a3);
      break;
      
      case 2:
      output_low(pin_a0);
      output_high(pin_a1);
      output_low(pin_a2);
      output_low(pin_a3);
      break;
      
      case 3:
      output_high(pin_a0);
      output_high(pin_a1);
      output_low(pin_a2);
      output_low(pin_a3);
      break;
      
      case 4:
      output_low(pin_a0);
      output_low(pin_a1);
      output_high(pin_a2);
      output_low(pin_a3);
      break;
      
      case 5:
      output_high(pin_a0);
      output_low(pin_a1);
      output_high(pin_a2);
      output_low(pin_a3);
      break;
      
      case 6:
      output_low(pin_a0);
      output_high(pin_a1);
      output_high(pin_a2);
      output_low(pin_a3);
      break;
      
      case 7:
      output_high(pin_a0);
      output_high(pin_a1);
      output_high(pin_a2);
      output_low(pin_a3);
      break;
      
      case 8:
      output_low(pin_a0);
      output_low(pin_a1);
      output_low(pin_a2);
      output_high(pin_a3);
      break;
      
      case 9:
      output_high(pin_a0);
      output_low(pin_a1);
      output_low(pin_a2);
      output_high(pin_a3);
      break;
   }
}
 
Mi duda, es que no se cual elemento electrónico, reemplaza una compuerta lógica de negación, o existe ese elemento en electrónica...?

Creo que la pregunta es que elemento de electrónica, convierte un 0 lógico a un 1 lógico,...un NPN?
 
Última edición:
pues un transistor en si
recuerda que las compuertas logicas estan hechas de transistores.

otra cosa si ya tienes el microcontrolador puedes cambiar su logica para evitar usar compuertas
digo si multiplexas con 1 por que no multiplexas con 0.

eso podria ayudarte a reducir aun mas el circuito.
es decir invierte lo que sacas para multiplexar y si puedes manejar los displays con el ULN2003
para evitar poner muchos transistores y asi reducir espacio en el protoboard o en la PCB
en si los ULN2003 son transistores medianamente galletudos en un encapsulado tipo DIP :LOL:

suerte
 
Siguiendo tu consejo, intento invertir el esquema, pero no me enciende, quizás es problema de proteus o mio?

Inverso.png

Para reducir el esquema, tengo pensado cambiar el pic por otro, que realice lo mismo que el 16F628A pero éste debe contener mas salidas para manejar mediante código un buzzer además del led display, cual me recomendarían?...

La idea es utilizar:
1.-El PIC y un 74ls47 para manejar las entradas de la A a la G del led display
2.-El PIC para manejar las entradas directas de cada pin 1 y 2 del led display (sin el 74ls138)
3.-Manejar un buzzer.
 
Última edición:
Muchas gracias TRILO-BYTE y Darkbytes, busque lo que me indicaban y claro está, se da vuelta la polaridad (por palabras mías, de como lo entiendo), voy a modificar el circuito a ver que tal.. en breve subo avances


http://img190.imageshack.us/img190/3722/dibujo4y.jpg


En fin, les presento mi versión 2.0 :D

BotonTimerV2.jpg

Cambie el 74LS47 por un 74LS48, para enviar un 1 lógico a los pines A-G en vez de un 0 lógico, asi eliminando las compuertas lógicas (not) del circuito anterior

me quedan solo dos dudas:

1º PREGUNTA
En el caso de que si al Led Display, se le enviará un 1 lógico a los pines A,B,C,D,E,F, y además se le enviará un 1 lógico al pin 1, se echaría a perder el led display? (pienso que no, porque el led del display funciona como diodo, no estoy seguro :unsure:)

Pienso que una foto lo explica mejor...

abcdefg.png

Pregunto esto, debido que a veces sucede en mi esquema actual


2º PREGUNTA
El PIC es el encargado de actualizar el Led Display cada segundo, realizado a través de la función delay_ms(1000);

que tan exacta es esa función?

me refiero si yo utilizo por ejemplo
delay_ms(1000); //crea una espera de 1 segundo
realmente el PIC espera un segundo antes de continuar con las siguientes líneas?
que tan exacto es?

Saludos
 
Última edición por un moderador:
usar delay y por mucho tiempo como para todo 1 segundo no es buena idea por que trabas tu micro todo un segundo.

exacto pues mas o menos depende de que tantas instrucciones maneje es lo puedes revisar en un osciloscopio

respecto al display

lo pudiste dejar como estaba con el 74ls47 solo que ahi debiste jugar con el byte, por que 1 byte lo podemos ver asi en HEX
0xAB donde A son 4 bits y B son los otros cuatro bits
y veras que en HEX 0X00 a 0XFF se pueden manejar los 4 bits casi de forma independiente


entonces pudiste usar los primeros 4 bits para manejar el display con el 74ls47 ;)
y los otros 4 bits los podias invertir con una funcion NOT y enviarlos :LOL:

suena simple pero nos deja pensar un rato
 
Atrás
Arriba