LedDriver MAX7221

MAX7221: Serially Interfaced, 8-Digit, LED Display Drivers

Este circuito integrado da Maxim pode controlar até 64 led's ou 8 dígitos de displays de 7 segmentos. Controlado por SPI utilizamos apenas 3 fios do Arduino.

Este MAX7221 normalmente é usado em:

A maior parte dos esquemas que se encontram na web utilizam o MAX7221 para controlar uma matriz de 8x8. No entanto existe um esquema que explica as ligações a uma simples Ledbar e encontra-se no site instructables pelo user 'bratan'.

Neste projecto a biblioteca usada é a LedControl 1.0.4

Pinout:

Existem 8 pinos 'Digit' (0-7) e 8 pinos "Segment" (SegA-SegF e SegDP), podemos controlar 64 LEDs vendo os pinos Digit como linhas, que podem ter até 8 LEDs, e os pinos Segment como LEDs individuais, que controlam as linhas de LEDs a acender. 8x8=64 LEDs (matriz 8x8). Desta forma é muito útil para matrizes de Leds (8x8) e Display de 7 segmentos.

Acendendo apenas 10 LEDs, utilizando uma Ledbar, podemos utilizar o seguinte esquema:

 A resistência ligada no ISET é calculada tendo em conta as propriedades dos LEDs usados, pois vai limitar a corrente que irá passar por cada um.

A Ledbar usada é a seguinte:

 

Podemos ligar a cada pino DIG 8 LEDs, como a Ledbar tem 10 LEDs, podemos ligar os Cátodos (-) dos LEDs 1 ao 8 todos juntos ao DIG0 (pino 2). Os restantes 2 Cátodos (2 LEDs finais) vamos ligá-los também entre si e ao DIG1 (pino 11).   

Os pinos Ânodo da Ledbar vamos ligá-los aos pinos SEG do Maxim da seguinte forma:

Como também só existem 8 pinos SEG vamos usar o SegDP e o SegA para controlar o LED1\LED9 e LED2\LED10 respetivamente.

 

Resumo de ligações do MAX7221 e da Ledbar:

Dependendo do DIG ativo (DIG0 e DIG1) e SEG os LEDs vão acender.

NOTA: Podemos colocar um condensador de 10uF e um condensador de cerâmica 0.1uF (code 104) na linha de alimentação e o mais perto possível do MAX7221.

Código de teste:

// V4 2014-01-21 (Improved logic of bit shifting for last 2 LEDs)

// Notes: 33K Rset reisistor must! Also decoupling 10uF polarized and .1uf ceramic capacitors needed on VCC line

// (c) 2014 LensDigital.com

#include "LedControl.h"

#define MAX_LED 10 // Number of LEDs in bar graph array

#define MAX_BRIGHTNESS 15 // 0-15 LED brightness

#define pauseLED 250

#define BLINK_SPEED 250 // Speed of blinking

#define LED_TIMEOUT 20000 // Time out after which LED bar turns off

boolean isOn=true;

boolean isSleeping=false;

boolean okBlink=false; // Triggers blinking

unsigned long lastBlink = 0; // Last time LEDs blinked

unsigned long lastOn = 0; // Last time LED Bar was turned off

byte blinkCount=0; // Counts blinks/flashes

byte Bars=10; // Temp. number of barts to light up

/*

 pin 9 is connected to the DataIn 

 pin 8 is connected to the CLK 

 pin 7 is connected to LOAD 

 We have only a single MAX72XX.

 */

LedControl lc=LedControl(9,8,7,1);

void setup() {

  Serial.begin(115200);

  lc.shutdown(0,false);

  /* Set the brightness to a medium values */

  lc.setIntensity(0,MAX_BRIGHTNESS);

  /* and clear the display */

  lc.clearDisplay(0);

 LEDBarDisplay (Bars);

okBlink=true;

 delay (1000);

  Serial.println ("ready");

}

void loop() { 

//ADICIONAL PARA TESTE: 

//okBlink=true;

//LEDBarBlink(5);  

chaseLED();

}

// =============================================================================

// --- Main Function. Light up "mark" number of sequential LEDs in Bar Graph

// =============================================================================

void LEDBarDisplay(int mark) {

  if (mark < 0 || mark > MAX_LED) return; // Sanity check, cannot be more than max or less than 0 LEDs

  byte LEDBit=B11111111;

 if (mark <=8) { // First row (first 8 LEDs)

    LEDBit=LEDBit << (8-mark); // Shift bits to the left

    lc.setRow(0,0,LEDBit);  //Light up LEDs

    lc.setRow(0,1,B00000000); // Blank out second row

  }

  else { // Second row (LED 9-10)

   LEDBit=LEDBit << (16-mark); // Shift bits to the left. 16 is 8*row

   lc.setRow(0,0,B11111111);  //Light first 8 LEDs

   lc.setRow(0,1,LEDBit); 

  }

    //Serial.print ("Mark is: "); Serial.print (mark); Serial.print (". In Binary: ");

  //  Serial.println (LEDBit,BIN);

  lastOn=millis();

  isSleeping=false;

}

// ===================================================================================================

// --- Blinks LED Bar Graph for specified number of times. Must be permitted with okBlink global var

// ===================================================================================================

void LEDBarBlink (int blinkTimes) {

 if (!okBlink) return;

 if (millis()-lastBlink > BLINK_SPEED) { 

   if (isOn) { // Turn LEDs off

     isOn=false;

     LEDBarDisplay(0);

   }

   else { // Turn LEDs on

    isOn=true;

    LEDBarDisplay(Bars);

    blinkCount++;

    if (blinkCount > blinkTimes-1) {

    blinkCount=0;

    okBlink=false; 

    }

   }

   lastBlink=millis();

   

   }

}

// ====================================================================

// --- Sleep mode. Clears display after timeout period

// ====================================================================

void sleepLEDBar() {

  if (isSleeping) return; // Already off

  if (millis()-lastOn > LED_TIMEOUT) { 

       lc.clearDisplay(0);

       isSleeping=true;

  }

}

// ====================================================================

// --- Back and forth pattern chase

// ====================================================================

void chaseLED() {

  for (int i=0;i<10;i++) {

    LEDBarDisplay(i);

    delay (pauseLED);

  }

  for (int i=10;i>=0;i--) {

    LEDBarDisplay(i);

    delay (pauseLED);

  }

      

}

// ====================================================================

// --- Back and forth pattern chase

// ====================================================================

void chaseLED_old() {

  for (int i=0;i<10;i++) {

    if (i<8) lc.setLed(0,0,i,true);

    else  lc.setLed(0,1,i-8,true);

    delay (pauseLED);

  }

  for (int i=10;i>=0;i--) {

    if (i<8) lc.setLed(0,0,i,false);

    else  lc.setLed(0,1,i-8,false);

    delay (pauseLED);

  }

      

}

Agora vamos fazer o teste com um display de 7 segmentos, para o efeito temos de usar sempre um de Cátodo comum (-), pois podemos ver os pinos do MAX7221 da seguinte forma:

 DIGs\Linhas

 SEGs\Colunas

 NEGATIVOS

 POSITIVOS 

O display usado é o seguinte: 

NOTA: Os segmentos são identificados com as seguintes letras:

As ligações são muito simples, apenas temos de ver a datasheet do display a usar, para saber quais os pinos que correspondem a cada letra\segmento e os pinos comuns.

Neste caso temos a seguinte combinação:

 

A resistência ISET usada foi também de 30k, de acordo com a tabela vamos limitar em ~20mA.

Para o código basta usar o exemplo de 7 segmentos da biblioteca:

//We always have to include the library

#include "LedControl.h"

/*

 Now we need a LedControl to work with.

 ***** These pin numbers will probably not work with your hardware *****

 pin 12 is connected to the DataIn 

 pin 11 is connected to the CLK 

 pin 10 is connected to LOAD 

 We have only a single MAX72XX.

 */

LedControl lc=LedControl(12,11,10,1);

/* we always wait a bit between updates of the display */

unsigned long delaytime=350;

void setup() {

  /*

   The MAX72XX is in power-saving mode on startup,

   we have to do a wakeup call

   */

  lc.shutdown(0,false);

  /* Set the brightness to a medium values */

  lc.setIntensity(0,8);

  /* and clear the display */

  lc.clearDisplay(0);

}

/*

 This method will display the characters for the

 word "Arduino" one after the other on digit 0. 

 */

void writeArduinoOn7Segment() {

  lc.setChar(0,0,'a',false);

  delay(delaytime);

  lc.setRow(0,0,0x05);

  delay(delaytime);

  lc.setChar(0,0,'d',false);

  delay(delaytime);

  lc.setRow(0,0,0x1c);

  delay(delaytime);

  lc.setRow(0,0,B00010000);

  delay(delaytime);

  lc.setRow(0,0,0x15);

  delay(delaytime);

  lc.setRow(0,0,0x1D);

  delay(delaytime);

  lc.clearDisplay(0);

  delay(delaytime);

/*

  This method will scroll all the hexa-decimal

 numbers and letters on the display. You will need at least

 four 7-Segment digits. otherwise it won't really look that good.

 */

void scrollDigits() {

  for(int i=0;i<13;i++) {

    lc.setDigit(0,3,i,false);

    lc.setDigit(0,2,i+1,false);

    lc.setDigit(0,1,i+2,false);

    lc.setDigit(0,0,i+3,false);

    delay(delaytime);

  }

  lc.clearDisplay(0);

  delay(delaytime);

}

void loop() { 

  writeArduinoOn7Segment();

  scrollDigits();

  

  for(int i=0;i<10;i++) {

    lc.setDigit(0,3,i,false);

    lc.setDigit(0,2,i,false);

    lc.setDigit(0,1,i,false);

    lc.setDigit(0,0,i,false);

    delay(2000);

  }

  lc.clearDisplay(0);

  delay(delaytime); 

  

}