quinta-feira, abril 10, 2014

MAX7219 Display Driver - Controlando um Display de 7 Segmentos com o Arduino

Como primeiro exercício prático com o MAX7219, vou ligá-lo a um display de 7 segmentos com quatro dígitos e a um Arduino.



Hardware

O display de quatro dígitos simplifica as ligações entre os módulos, já que os segmentos estão interligados internamente. O Arduino utilizado é um Nano, que pode ser colocado diretamente na protoboard. Embora seja possível (e até preferível do ponto de vista de desempenho) usar a interface SPI do ATmega, nesta montagem liguei o MAX7219 a três saídas digitais quaisquer e gerei "na mão" os sinais de comunicação (com uma pequena ajuda da biblioteca do Arduino).



O circuito possui somente três componentes discretos: o resistor que define a corrente nos segmentos e dois capacitores. A finalidade destes capacitores é filtrar as interferências geradas na alimentação pelo liga/desliga dos LEDs.

Software

O software é bastante simples mas ilustra o básico do uso do MAX7219 no comando de displays de 7 segmentos.
  1. // Conecões ao MAX7219  
  2. #define PIN_LOAD 6  
  3. #define PIN_DIN  5  
  4. #define PIN_CLK  4  
  5.   
  6. #define LED      13  
  7.   
  8. // Registradores do MAX7219  
  9. #define MAX7219_NOP   0x00  
  10. #define MAX7219_DIG0  0x01  
  11. #define MAX7219_DIG1  0x02  
  12. #define MAX7219_DIG2  0x03  
  13. #define MAX7219_DIG3  0x04  
  14. #define MAX7219_DIG4  0x05  
  15. #define MAX7219_DIG5  0x06  
  16. #define MAX7219_DIG6  0x07  
  17. #define MAX7219_DIG7  0x08  
  18. #define MAX7219_MODE  0x09  
  19. #define MAX7219_INT   0x0A  
  20. #define MAX7219_LIM   0x0B  
  21. #define MAX7219_SHUT  0x0C  
  22. #define MAX7219_TEST  0x0F  
  23.   
  24. // CONEXOES DOS LEDS  
  25. #define DIG1   MAX7219_DIG0  
  26. #define DIG2   MAX7219_DIG1  
  27. #define DIG3   MAX7219_DIG2  
  28. #define DIG4   MAX7219_DIG3  
  29.   
  30. uint8_t cont [4];  
  31.   
  32. // Iniciação  
  33. void setup ()  
  34. {  
  35.   pinMode (LED, OUTPUT);  
  36.   pinMode (PIN_LOAD, OUTPUT);  
  37.   pinMode (PIN_DIN, OUTPUT);  
  38.   pinMode (PIN_CLK, OUTPUT);  
  39.   digitalWrite (PIN_LOAD, HIGH);  
  40.   digitalWrite (PIN_CLK, LOW);  
  41.   digitalWrite (PIN_DIN, LOW);  
  42.     
  43.   write7219 (MAX7219_SHUT, 0x00);  
  44.   write7219 (MAX7219_TEST, 0x00);  
  45.   write7219 (MAX7219_MODE, 0x0F);  
  46.   write7219 (MAX7219_INT, 0x0F);  
  47.   write7219 (MAX7219_LIM, 0x03);  
  48.   write7219 (DIG1, 12);  // H  
  49.   write7219 (DIG2, 11);  // E  
  50.   write7219 (DIG3, 13);  // L  
  51.   write7219 (DIG4, 14);  // P  
  52.   write7219 (MAX7219_SHUT, 0x01);  
  53.   delay (2000);  
  54.   for (int i = 0; i < 4; i++)  
  55.     cont[i] = 0;  
  56. }  
  57.   
  58. // Loop Principal  
  59. void loop ()  
  60. {  
  61.   // Mostra o contador atual  
  62.   write7219 (DIG1, cont[0]);  
  63.   write7219 (DIG2, cont[1]);  
  64.   write7219 (DIG3, cont[2]);  
  65.   write7219 (DIG4, cont[3]);  
  66.   
  67.   // Soma 1 no contador  
  68.   for (int i = 3; i >= 0; i--)  
  69.   {  
  70.     if (cont[i] < 9)  
  71.     {  
  72.       cont[i]++;  
  73.       break;  
  74.     }  
  75.     cont[i] = 0;  
  76.   }  
  77.   delay (100);  
  78. }  
  79.   
  80. // Escreve um dado no registrador addr do MAX7219  
  81. void write7219 (uint8_t addr, uint8_t data)  
  82. {  
  83.   digitalWrite (PIN_LOAD, LOW);  
  84.   shiftOut (PIN_DIN, PIN_CLK, MSBFIRST, addr);  
  85.   shiftOut (PIN_DIN, PIN_CLK, MSBFIRST, data);  
  86.   digitalWrite (PIN_LOAD, HIGH);  
  87. }  
Resultado

O vídeo abaixo mostra a montagem funcionando.




12 comentários:

DJ Maggioni disse...

DEMAIS! E se eu quisesse que aparecesse o valor de uma leitura de um pino analógica (A0) como eu colocaria no código?

DJ Maggioni disse...

Outra coisa que não aparece no código é a biblioteca, sabe me informar qual é?

Daniel Quadros disse...

A biblioteca é a que está automaticamente disponível para os programas do Arduino (no caso pinMode, digitalWrite, delay e shiftOut). Para mostrar a leitura do A0 você precisaria substituir o código em loop(). Primeiro você faz a leitura e depois coloca cada dígito no seu lugar:

void loop()
{
int x = analogRead(A0);
write7219 (DIG1, x/1000);
write7219 (DIG2, (x / 100) % 10);
write7219 (DIG3, (x / 10) % 10);
write7219 (DIG4, x % 10);
delay(100);
}

Obs: não testei o código acima!

DJ Maggioni disse...

Obrigado =D

Fica bem mais simplificado que ligar diretamente no arduino o display sem o driver!

Unknown disse...

Ola.
Sera que vc pode me ajudar, meu display provavelmente tem a disposição dos pinos diferente do seu. Quando executo o codigo, os numeros aparecem todos 'embaralhados' e nao consigo fazer uma combinação que funcione corretamente. Meu display nao tem identificação e por isso nao sei exatamente qual eh o seu datasheet. Provavelmente é esse: http://html.alldatasheet.com/html-pdf/683804/FORYARD/FYQ-2841BX-20/912/3/FYQ-2841BX-20.html
O 2841B.
Como altero a combinação dos pinos entre o MAX7219 e o display para que funcione exibindo os digitos corretamente ? Nao consigo entender como é feita essa combinação.
Valeu

Daniel Quadros disse...

Luiz, a combinação dos pinos é feita pelos fios interligando os dois. Dê uma olhada na primeira parte desta série (http://dqsoft.blogspot.com.br/2014/04/max7219-display-driver-introducao.html). O MAX7219, no modo 7 segmentos, requer um display do tipo catodo comum. O 2841B é anodo comum, neste caso não dá para usar o modo 7 segmentos. Dá para usar como se fossem LEDs discretos, mas é mais complicado. O jeito mais fácil de conferir a pinagem do display é fazer testes ligando os pinos a 5V através de um resistor de 1K (isto é fácil de fazer na protoboard).

Anônimo disse...

Alguem um projeto de um Placar Simples de dois times? Com acréscimo e decréscimo de pontos?

Unknown disse...

se eu quizer colocar um botão pra fazer a contagem e outro pra zerar, como eu faria?

Daniel Quadros disse...

Basta ligar os botões a entradas digitais, usar digitalRead para testar se um dos botões está apertado e tratar adequadamente.

Unknown disse...

Obrigado "Daniel Quadros" Testei aqui e Deu Certo!

SuB disse...

copiei o projeto exatamente igual e não funcionou, o display ficou maluco.

Daniel Quadros disse...

SuB, provavelmente o seu display tem uma pinagem diferente do que eu usei. O display precisa ser do tipo catodo comum, veja na parte 1 qual pino do 7219 corresponde a qual dígito e qual segmento. Por exemplo, o pino 2 do 7219 precisa ser ligado ao catodo comum do primeiro dígito do display e o pino 14 do 7219 ao segmento A dos displays.