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.
// Conecões ao MAX7219
#define PIN_LOAD 6
#define PIN_DIN  5
#define PIN_CLK  4

#define LED      13

// Registradores do MAX7219
#define MAX7219_NOP   0x00
#define MAX7219_DIG0  0x01
#define MAX7219_DIG1  0x02
#define MAX7219_DIG2  0x03
#define MAX7219_DIG3  0x04
#define MAX7219_DIG4  0x05
#define MAX7219_DIG5  0x06
#define MAX7219_DIG6  0x07
#define MAX7219_DIG7  0x08
#define MAX7219_MODE  0x09
#define MAX7219_INT   0x0A
#define MAX7219_LIM   0x0B
#define MAX7219_SHUT  0x0C
#define MAX7219_TEST  0x0F

// CONEXOES DOS LEDS
#define DIG1   MAX7219_DIG0
#define DIG2   MAX7219_DIG1
#define DIG3   MAX7219_DIG2
#define DIG4   MAX7219_DIG3

uint8_t cont [4];

// Iniciação
void setup ()
{
  pinMode (LED, OUTPUT);
  pinMode (PIN_LOAD, OUTPUT);
  pinMode (PIN_DIN, OUTPUT);
  pinMode (PIN_CLK, OUTPUT);
  digitalWrite (PIN_LOAD, HIGH);
  digitalWrite (PIN_CLK, LOW);
  digitalWrite (PIN_DIN, LOW);
  
  write7219 (MAX7219_SHUT, 0x00);
  write7219 (MAX7219_TEST, 0x00);
  write7219 (MAX7219_MODE, 0x0F);
  write7219 (MAX7219_INT, 0x0F);
  write7219 (MAX7219_LIM, 0x03);
  write7219 (DIG1, 12);  // H
  write7219 (DIG2, 11);  // E
  write7219 (DIG3, 13);  // L
  write7219 (DIG4, 14);  // P
  write7219 (MAX7219_SHUT, 0x01);
  delay (2000);
  for (int i = 0; i < 4; i++)
    cont[i] = 0;
}

// Loop Principal
void loop ()
{
  // Mostra o contador atual
  write7219 (DIG1, cont[0]);
  write7219 (DIG2, cont[1]);
  write7219 (DIG3, cont[2]);
  write7219 (DIG4, cont[3]);

  // Soma 1 no contador
  for (int i = 3; i >= 0; i--)
  {
    if (cont[i] < 9)
    {
      cont[i]++;
      break;
    }
    cont[i] = 0;
  }
  delay (100);
}

// Escreve um dado no registrador addr do MAX7219
void write7219 (uint8_t addr, uint8_t data)
{
  digitalWrite (PIN_LOAD, LOW);
  shiftOut (PIN_DIN, PIN_CLK, MSBFIRST, addr);
  shiftOut (PIN_DIN, PIN_CLK, MSBFIRST, data);
  digitalWrite (PIN_LOAD, HIGH);
}
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.