Autor Tema: Multiplexado con 74HC595  (Leído 198 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2760
Multiplexado con 74HC595
« en: 13 de Septiembre de 2017, 16:41:59 »

Tengo algunas dudas sobre el multiplexado de leds y displays BCD, usando el 74HC595.

En mi diseño de ruleta, tengo 61 dígitos BCD en displays de dos dígitos cada uno, más 38 leds. En principio no iba a usar el multiplexado para facilitar la programación, pero cuando ya había pedido los displays me dí cuenta de que estaban multiplexados, y al final tuve que cambiar el diseño para al menos multiplexar con un barrido en dos bloques.

Ahora pienso que podría cambiar el diseño, y poner un multiplexado a 4 bloques y así me ahorro la mitad de los 74HC595. Mi duda es si el barrido será lo suficientemente rápido para que no parpadeen los displays ni los led. Uso un STM32F405 a 168 Mhz, he conectado los 74HC595 al STM32 por SPI.

Y otra duda que tengo, he visto por Google que en algunos esquemas, en vez de poner resistencias limitadoras para cada uno de los segmentos del display BCD (7 resistencias, más una si se usa el punto), ponen solo una resistencia en el común. ¿ Que diferencia hay entre poner resistencias a todos los segmentos o solo una en el común ?.

Este es el circuito que he puesto en mi ruleta, para los displays y los led.






Y este el esquema que me encuentro por Google, con una sola resistencia limitadora en el común del display.




« Última modificación: 13 de Septiembre de 2017, 16:49:48 por planeta9999 »

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3116
    • Automation Media Lab
Re:Multiplexado con 74HC595
« Respuesta #1 en: 13 de Septiembre de 2017, 17:36:32 »
Si pones una resistencia como común para los LEDs el brillo es diferente si tienes 1,2, o todos los LEDs encendidos.

Pare evitar que se vea el parpadeo de los LEDs siempre intento llevar a 40-50 Hz el refresco de los LEDs.
Al aumentar los elementos a multiplexar lo que se hace es diminuir Ton(tiempo de encendido)para cumplir con los Hz y compensar disminuyendo la resistencia limitadora para que el brillo sea mayor.
Ejemplo , si el LED tiene una Vf de 2.4v y una Inom de 20mA y puede recibir maximo 50mA por X tiempo, solo te aseguras de no superar ese X tiempo e Imax para excitarlo al máximo con la multiplexion.


Saludos!
« Última modificación: 13 de Septiembre de 2017, 17:39:14 por AKENAFAB »

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2760
Re:Multiplexado con 74HC595
« Respuesta #2 en: 13 de Septiembre de 2017, 17:41:39 »
Si pones una resistencia como común para los LEDs el brillo es diferente si tienes 1,2, o todos los LEDs encendidos.


Es lo que sospecho, con una sola resistencia limitadora, el total de la corriente se reparte entre todos los segmentos, y estos lucirán más o menos dependiendo de cuantos estén encendidos. Creo que eso quedará fatal, porque unos dígitos lucirán más y otros menos, según cuantos segmentos tengan encendidos.

Creo que lo dejaré como está, lo que si me planteo es pasar el multiplexado de 2 a 4 barridos, así me ahorro la mitad de 595 y  de arrays de resistencias.
« Última modificación: 13 de Septiembre de 2017, 17:44:12 por planeta9999 »

Desconectado tsk

  • PIC16
  • ***
  • Mensajes: 161
Re:Multiplexado con 74HC595
« Respuesta #3 en: 13 de Septiembre de 2017, 18:57:18 »
Y si usas un expansor de puertos como el mcp23017, este es por i2c, y tiene 16 salidas. Podrías manejar 4 dígitos.

14 pines para los segmentos más otros 2 para controlar el multiplexado de ambos displays. Soporta hasta 1.7Mhz

Hay de más salidas:
PCA9698DGG  (40 líneas)
CY8C9560A-24AXI (60 líneas)

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2760
Re:Multiplexado con 74HC595
« Respuesta #4 en: 13 de Septiembre de 2017, 19:53:39 »
El MCP23017 es bastante caro en comparación con los 74HC595 (como diez veces más caro), y el multiplexado quedaría igual.  Me voy a quedar con los 74HC595 y veré si paso el multiplexado de 2 a 4, para quitarme de encima la mitad de chips y arrays de resistencias.

Estoy diseñando y voy a montar un prototipo en miniatura de la ruleta, con todo en una placa para las tareas de programación y pruebas, pero el diseño final para el cliente, son varias placas con displays más grades, conectadas con cables planos. A él le interesa que el coste del producto por unidad sea lo más bajo posible porque lo va a fabricar en cantidad, al final el funcionamiento sería igual, pero más barato con los 595.

Esos otros chips gordos, se ven bien, pero no se si me vale la pena complicarme ahora cambiando todo el diseño.
« Última modificación: 13 de Septiembre de 2017, 20:00:16 por planeta9999 »

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3143
Re:Multiplexado con 74HC595
« Respuesta #5 en: 14 de Septiembre de 2017, 03:09:36 »
Algo que quizás te interese valorar es que el hc595 puede entregar muy poca corriente, lo que podría provocar que la intensidad de los dígitos 1 y 8, por ejemplo, fuera diferente.
Existen versiones específicas del HC595, como el TPIC6B595, pero son bastante más caras.

Si puedes, haz algunas pruebas para valorar cómo se comporta el hc595 a la velocidad de refresco que le estás pidiendo.

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3143
Re:Multiplexado con 74HC595
« Respuesta #6 en: 14 de Septiembre de 2017, 03:26:48 »
Un detalle: Yo tengo montado un hc595 normal que alimenta 8 columnas de una matriz de leds 8x8 (sin resistencias limitadoras), multiplexadas a tierra a través de un uln2803 (dirigido por un CD4017; aprovecho el ST latch del hc595 para avanzar el contador del cd4017) y va bastante bien.

Desconectado tsk

  • PIC16
  • ***
  • Mensajes: 161
Re:Multiplexado con 74HC595
« Respuesta #7 en: 14 de Septiembre de 2017, 05:01:32 »
Tan sólo estoy divagando pero, sólo por curiosidad, no has pensado en usar un FPGA para realizar el controlador de los displays, tienes FPGAs desde 3 USD (o menos según la cantidad) con 78 I/O en TQFP-100 y 256 LUTs (LAMXO256C-3TN100E) u otro con 1280 LUTs a 6.28 USD (iCE40HX1K-VQ100 72 I/O) en mouser. Tan sólo actualizarías los valores de registros en el FPGA correspondientes a cada dígito.

Con el primero podrías controlar (tentativamente) 20 dígitos (70 líneas) + 2 para el multiplexeo + la comunicación, que podría ser por SPI o I2C. En internet puedes encontrar implementaciones ya hechas.

Requerirías 3 de estos para controlar 60 dígitos.

Realmente no tienes que adquirir absolutamente nada para darte una idea de lo que podrías hacer, ya que por medio de simulaciones puedes determinar si es viable. Tan sólo creas un sólo bloque que controle dos dígitos, realizas las simulaciones, y después solamente realizas instancias del mismo bloque hasta que el FPGA te diga basta, ya sea por LUTs o por I/Os

El programa puede residir en el Microcontrolador y cargarlo al iniciar el sistema.

Aquí te dejo un ejemplo totalmente burdo y a las carreras pero funcional.

register7.vhd

Código: VHDL
  1. LIBRARY ieee;
  2. USE ieee.std_logic_1164.ALL;
  3.  
  4. entity register7 is
  5. port(
  6.     d_in : in std_logic_vector(6 downto 0);
  7.     load : in std_logic;
  8.     clear: in std_logic;
  9.     clk  : in std_logic;
  10.     d_out: out std_logic_vector(6 downto 0)
  11. );
  12. end register7;
  13.  
  14. architecture behave of register7 is
  15. begin
  16.     process(clk, clear)
  17.     begin
  18.         if clear = '1' then
  19.             d_out <= "0000000";
  20.         elsif rising_edge(clk) then
  21.             if load = '1' then
  22.                 d_out <= d_in;
  23.             end if;
  24.         end if;
  25.     end process;
  26. end behave;
  27.  
tb_register7.vhd
Código: VHDL
  1. LIBRARY ieee;
  2. USE ieee.std_logic_1164.ALL;
  3.  
  4. entity tb_register7 is
  5. end tb_register7;
  6.  
  7. architecture behave of tb_register7 is
  8.  
  9. component register7 is
  10. port(
  11.     d_in : in std_logic_vector(6 downto 0);
  12.     load : in std_logic;
  13.     clear: in std_logic;
  14.     clk  : in std_logic;
  15.     d_out: out std_logic_vector(6 downto 0)
  16. );
  17. end component;
  18.  
  19. signal d_in: std_logic_vector(6 downto 0);
  20. signal d_out: std_logic_vector(6 downto 0);
  21. signal load: std_logic:='0';
  22. signal clear: std_logic:='0';
  23. signal clk: std_logic:='1';
  24. signal PERIOD: time:= 100 ns;
  25.  
  26. begin
  27.  
  28.     gen_clk: process(clk)
  29.     begin
  30.         clk <= not clk after PERIOD/2;
  31.     end process gen_clk;
  32.  
  33.     U0: register7
  34.     port map(
  35.     d_in => d_in,
  36.     load => load,
  37.     clear => clear,
  38.     clk => clk,
  39.     d_out => d_out
  40.     );
  41.  
  42.     stim: process
  43.     begin
  44.         wait for 1 ms;
  45.         d_in <= "1111111";
  46.         wait for 1 ms;
  47.         load <= '1';
  48.         wait for 1 ms;
  49.         load <= '0';
  50.         wait for 1 ms;
  51.         d_in <= "1110001";
  52.         wait for 1 ms;
  53.         load <= '1';
  54.         wait for 1 ms;
  55.         load <= '0';
  56.         wait for 1 ms;
  57.         clear <= '1';
  58.         wait for 1 ms;
  59.         clear <= '0';
  60.         wait;
  61.     end process;
  62. end behave;
  63.  



display_controller.vhd  (Faltaría agregar el divisor de frecuencia para ajustar la velocidad del multiplexor)

Código: VHDL
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3.  
  4. entity display_controller is
  5. port(
  6.     d_in: in std_logic_vector(6 downto 0);
  7.     d_out: out std_logic_vector(6 downto 0);
  8.     clk : in std_logic;
  9.     address: in std_logic;
  10.     load: in std_logic;
  11.     clear: in std_logic;
  12.     reset: in std_logic;
  13.     mux_out: out std_logic_vector(1 downto 0)
  14. );
  15. end display_controller;
  16.  
  17. architecture behave of display_controller is
  18. component register7 is
  19. port(
  20.     d_in : in std_logic_vector(6 downto 0);
  21.     load : in std_logic;
  22.     clear: in std_logic;
  23.     clk  : in std_logic;
  24.     d_out: out std_logic_vector(6 downto 0)
  25. );
  26. end component;
  27.  
  28. type state_type is (dig_0,dig_1);
  29. signal State: state_type;
  30.  
  31. signal d_out_0: std_logic_vector(6 downto 0);
  32. signal d_out_1: std_logic_vector(6 downto 0);
  33. signal load_0: std_logic;
  34. signal load_1: std_logic;
  35. signal clear_0: std_logic;
  36. signal clear_1: std_logic;
  37.  
  38. begin
  39.     U0: register7
  40.     port map(
  41.     d_in => d_in,
  42.     load => load_0,
  43.     clear => clear_0,
  44.     clk => clk,
  45.     d_out => d_out_0
  46.     );
  47.  
  48.     U1: register7
  49.     port map(
  50.     d_in => d_in,
  51.     load => load_1,
  52.     clear => clear_1,
  53.     clk => clk,
  54.     d_out => d_out_1
  55.     );
  56.  
  57.     load_in: process(load, address)
  58.     begin
  59.         case address is
  60.             when '0' => load_0 <= load; load_1 <= '0';
  61.             when '1' => load_0 <= '0'; load_1 <= load;
  62.             when others => load_0 <= load; load_1 <= '0';
  63.         end case;
  64.     end process;
  65.  
  66.     clear_in: process(clear, address)
  67.     begin
  68.         case address is
  69.             when '0' => clear_0 <= clear; clear_1<= '0';
  70.             when '1' => clear_0 <= '0'; clear_1 <= clear;
  71.             when others => clear_0 <= clear; clear_1<= '0';
  72.         end case;
  73.     end process;
  74.  
  75.     dout_state: process(d_out_0, d_out_1, reset, clk)
  76.     begin
  77.         if(reset='1') then
  78.             State <= dig_0;
  79.         elsif rising_edge(clk) then
  80.             case State is
  81.                 when dig_0 => d_out <= d_out_0; mux_out <= "01"; State <= dig_1;
  82.                 when dig_1 => d_out <= d_out_1; mux_out <= "10"; State <= dig_0;
  83.                 when others => d_out <= d_out_0; mux_out <= "01"; State <= dig_1;
  84.             end case;
  85.         end if;
  86.     end process;
  87.  
  88.  
  89. end behave;
  90.  

tb_display_c.vhd
Código: VHDL
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3.  
  4. entity tb_display_c is
  5. end tb_display_c;
  6.  
  7. architecture behave of tb_display_c is
  8. component display_controller is
  9. port(
  10.     d_in: in std_logic_vector(6 downto 0);
  11.     d_out: out std_logic_vector(6 downto 0);
  12.     clk : in std_logic;
  13.     address: in std_logic;
  14.     load: in std_logic;
  15.     clear: in std_logic;
  16.     reset: in std_logic;
  17.     mux_out: out std_logic_vector(1 downto 0)
  18. );
  19. end component;
  20.  
  21. signal d_in: std_logic_vector(6 downto 0);
  22. signal d_out: std_logic_vector(6 downto 0);
  23. signal address: std_logic:='0';
  24. signal load: std_logic:='0';
  25. signal clear: std_logic:='0';
  26. signal reset: std_logic:='0';
  27. signal mux_out: std_logic_vector(1 downto 0);
  28. signal clk: std_logic:='1';
  29. signal PERIOD: time:= 100 ns;
  30.  
  31. begin
  32.     gen_clk: process(clk)
  33.     begin
  34.         clk <= not clk after PERIOD/2;
  35.     end process gen_clk;
  36.  
  37.     U0: display_controller
  38.     port map(
  39.     d_in => d_in,
  40.     d_out => d_out,
  41.     clk => clk,
  42.     address => address,
  43.     load => load,
  44.     clear => clear,
  45.     reset => reset,
  46.     mux_out => mux_out
  47.     );
  48.    
  49.     stim: process
  50.     begin
  51.         reset <= '1';
  52.         wait for 1 ms;
  53.         reset <= '0';
  54.         d_in <= "1111111";
  55.         address <= '0';
  56.         load <= '1';
  57.         wait for 200 ns;
  58.         load <= '0';
  59.         wait for 200 ns;
  60.         d_in <= "1110001";
  61.         address <= '1';
  62.         load <='1';
  63.         wait for 200 ns;
  64.         load <='0';
  65.         wait for 10 ms;
  66.         wait;
  67.     end process;
  68.    
  69. end behave;
  70.  



El micro sólo se encargaría de cargar el valor en el registro correspondiente y el FPGA se encargaría de lo demás.

PD: Digo tentativamente, porque no conozco los FPGA de Lattice, y en este momento no tengo instalada ninguna herramienta para que me diga cuantos LUTs usa el código de arriba.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2760
Re:Multiplexado con 74HC595
« Respuesta #8 en: 14 de Septiembre de 2017, 05:34:08 »
No me puedo meter en fregados de FPGA, es algo que apenas conozco y el proyecto lo tengo que sacar ya. Ahora mismo el prototipo con los HC595 ya lo tengo acabado, y listo para enviar a fábrica.

En principio el prototipo es una versión en miniatura de la ruleta, que concentra en una sola placa toda la circuitería, con displays pequeños y leds SMD 3528.  El resto de la circuitería es idéntica a la que tendré el diseño final, un STM32F405 para controlarlo todo, un Kinetis MK20 para reproducir sonidos WAV almacenados en tarjeta SD y un TPA3111 de Texas como amplificador. También lleva un 4050 como buffer para leer los pulsos del monedero y la tolva, y un transistor para activar el motor de la tolva (conectado a un fototriac MOC3020 en la fuente original de la máquina). En el diseño final es posible que meta optoacopladores para aislar los 20 pulsadores del frontal y los lea con un registro de desplazamiento paralelo-serie 74HC166 o algo parecido.

Si el prototipo, cuando lo pruebe da poca intensidad en los displays, ya veré de cambiarlo por otro chip que soporte más corriente, como el mencionado TPIC6B595, o algún otro.

No he usado antes los HC595, porque no tuve que controlar displays BCD, pero por lo que veo por Youtube y Google, se usan mucho con la típica circuitería multiplexada, y parece que dan sufiente corriente para que los displays luzcan bien. Al final voy a dejar el multiplexado a 2 barridos y reduciré las resistencias limitadoras a unos 100 ohm, en principio las compré de 470 ohm.

Ahora casí me preocupa más la programación de los premios que el hardware necesario para controlar los displays.
« Última modificación: 14 de Septiembre de 2017, 05:41:43 por planeta9999 »

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2760
Re:Multiplexado con 74HC595
« Respuesta #9 en: 14 de Septiembre de 2017, 05:42:55 »
Un detalle: Yo tengo montado un hc595 normal que alimenta 8 columnas de una matriz de leds 8x8 (sin resistencias limitadoras), multiplexadas a tierra a través de un uln2803 (dirigido por un CD4017; aprovecho el ST latch del hc595 para avanzar el contador del cd4017) y va bastante bien.

Eso es interesante, eliminar las resistencias limitadoras al usar el multiplexado. Lo probaré en el prototipo, cortocircuitando alguno de los arrays de resistencias a ver como se comporta el display.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2760
Re:Multiplexado con 74HC595
« Respuesta #10 en: 14 de Septiembre de 2017, 05:45:25 »

A todo esto lo que tengo muchas ganas de probar son las librerías de audio de Teensy. Tengo muchos proyectos que las podrían usar, las prestaciones de esas librerías son increíbles, hacen de todo y totalmente configurables por el usuario.

He aprovechado que este proyecto necesita reproducir ficheros de audio, para meter un Kinetis con esas librerías, en principio solo para reproducir sonidos, pero hay muchas más opciones, como filtros, ecualizadores, efectos de eco, flanger, mezclador, sintetizador, control de volumen digital, control de tonos, detector de nivel y mucho más.

No parece que en el foro haya cuajado el uso de estas librerias, y eso que es todo gratuito, o será que poca gente usa los Kinetis.
« Última modificación: 14 de Septiembre de 2017, 05:49:35 por planeta9999 »