이런거 저런거 그런거

Matrix LED를 좀 쉽게 컨트롤하는 방법(MAX7219) 본문

이것저것 해보기/아두이노 가지고 놀기

Matrix LED를 좀 쉽게 컨트롤하는 방법(MAX7219)

빵진 2019. 9. 21. 20:15

부품을 하나 샀다.

그것은 바로 MAX7219가 달린 "SZH-EK063" !!

 

 

이 부품(MAX7219)를 사용 함으로서 VCC, GND, DIN, CS(ChipSelect), CLK(Clock) 5개 핀만으로

아두이노에서 64개 led를 컨트롤 할 수 있다.

아두이노에서는 위 5개 핀을 이용해 MAX7219에 필요한 설정을 하고 MAX7219는 설정된 Led를 켜 주는 것이다.

 

Led On/Off 제어를 MAX7219에게 외주(?)를 준 덕분에 아래와 같은 장점을 얻을 수 있다.

- 연결 Line (pin)을 줄일 수 있다. (16개 -> 5개)

- Loop마다 Line을 돌아가며 led on/off 해주는 번거스러움 없어짐

- Loop가 지연됨으로 인해 도트 매트릭스에 그림(또는 문자)가 이상하게 보여지는 부분 방지

- 확장 가능

 

이제 데이터 시트를 살펴보자

(참고 사이트 : https://pdf1.alldatasheet.co.kr/datasheet-pdf/view/227793/MAXIM/MAX7219.html)

연결해줘야 하는 핀은 총 5개

SPI 인터페이스 방식으로 통신 하며

설정 할 땐 CS핀을 Low로 컨트롤 후 설정한다.

데이터 포맷의 크기는16bit(2byte)이며 D15부터 보내면 되겠다(MSB)

 

여기서 CS(ChipSelect)를 간단히 설명하자면 multi slave를 지원하는 방법으로서 

여러개의 slave를 지원하는 방법으로 CS(Chip Select)를 이용하는 방법, Daisy-Chain 방법이 있다.

 

CS를 이용하는 경우 활성화 할 Slave의 CS핀을 Low로 컨트롤 함으로서 CLK, DataIn, DataOut 핀을 공유함에도 특정 slave하고 통신 할 수 있는 것이다.

반면 Daisy-Chain 방법의 경우 각 Slave의 DataOut이 다음 Slave의 DataIn에 연결되어 자신의 차례가 아닌 Slave가 데이터를 받을 경우 다음 Slave로 데이터를 전달 해 줘야 한다. 따라서 차례를 알려주기 위해 마스터가 좀 더 귀찮은 작업을 해 줘야 한다. (No-Op가 이때 쓰인다.) 참고로 지금 사용 할 "SZH-EK063"가 이  방법으로 여러개를 이어 붙일 수 있다.

 

출처 : https://www.analog.com/en/analog-dialogue/articles/introduction-to-spi-interface.html

 

이처럼 Line과 핀을 줄이려는 것은 Line과 Pin이 곧 돈이기 때문에....

SPI에 대해서는 아래 site에 잘 설명되어있어 참고하면 좋다.

https://www.analog.com/en/analog-dialogue/articles/introduction-to-spi-interface.html

 

Introduction to SPI Interface | Analog Devices

Introduction to SPI Interface by Piyu Dhaker Download PDF Serial peripheral interface (SPI) is one of the most widely used interfaces between microcontroller and peripheral ICs such as sensors, ADCs, DACs, shift registers, SRAM, and others. This article pr

www.analog.com

 

 

설정 할 수 있는 Address 중에 살펴 봐야 하는게

Decode Mode

  • 0x00 : No decode 모드로서 D0~7에 설정된 값 그대로 이용하여 컨트롤 함
    내가 사용하는 자재는 도트 매트릭스이므로 No decode(0x00)으로 설정한다.
  • 0x01, 0x0F, 0xFF : D0~7을 필요한 만큼 decode하여 미리 설정 내용 대로 컨트롤 함

Intensity

  • 밝기 조정 (0x00(어두움) ~ 0x0F(밝음))
    최대 밝기로 하면 눈 아픔...... 

Scan Limit

  • 얼마나 많은 digit을 사용할지 (8자로 보이는 led에서는...)
    도트 매트릭스에선 이 값을 줄이면 줄인 수만큼 lin이 안그려지게 된다. (1개 라인 8개 led 컨트롤이 한 글자)

No-Op의 경우 여러개 연결 시 필요한 내용이다.

 

대충 어떤 방식으로 데이터를 보내고 어떤 값을 전달해야하는지 알아봤으니 실제로 컨트롤해보았다.

SPI 방식으로 보내는 방법은

  • 직접 GPIO를 High/Low 컨트롤 하여 보내는 방법 (SW적인 방법)
  • HW SPI 를 사용하여 보내는 방법 (HW적인 방법으로 특정 핀만 사용 가능)

SW적인 방법을 사용하여 테스트 해 보기로 했다.

참고로 SW적인 방법을 사용 할 때 특별히 지연이 되어도 문제 없는 이유는 읽어야 하는 타이밍을 알려주는 CLK신호도 같이 전달하기 때문이다.

 

핀 연결은 VCC, GND는 아두이노의 각 VCC(5v) , GND에 연결해 두고

나머지 CLK, CS, DIN은 각각 11, 10, 12번 핀에 연결하였다.

 

매트릭스에 켜질 패턴은 이 사이트를 이용하여 만듬~!

http://dotmatrixtool.com/#

 

#define MAX7219_CLK (11)
#define MAX7219_CS  (10)
#define MAX7219_DIN (12)

#define DECODE_MODE_ADDR  (0x09)
#define DECODE_MODE_VAL   (0x00)
#define INTENSITY_ADDR    (0x0A) //Bright Setting (0x00 ~ 0x0F)
#define INTENSITY_VAL     (0x01)
#define SCAN_LIMIT_ADDR   (0x0B) //How many use digit led (line count in matrix led device)
#define SCAN_LIMIT_VAL    (0x07)
#define POWER_DOWN_MODE_ADDR  (0x0C)
#define POWER_DOWN_MODE_VAR   (0x01)
#define TEST_DISPLAY_ADDR (0x0F)
#define TEST_DISPLAY_VAL  (0x00)


void write_to_max7219(uint8_t addr, uint8_t value)
{
  digitalWrite(MAX7219_CS, LOW);  //ChipSelect to LOW
  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, addr);
  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, value);
  digitalWrite(MAX7219_CS, HIGH); //ChipSelect to HIGH
}

void init_max7219(void)
{
  pinMode(MAX7219_CLK, OUTPUT);
  pinMode(MAX7219_CS, OUTPUT);
  pinMode(MAX7219_DIN, OUTPUT);

  //settings
  write_to_max7219(DECODE_MODE_ADDR, DECODE_MODE_VAL);
  write_to_max7219(INTENSITY_ADDR, INTENSITY_VAL);
  write_to_max7219(SCAN_LIMIT_ADDR, SCAN_LIMIT_VAL);
  write_to_max7219(POWER_DOWN_MODE_ADDR, POWER_DOWN_MODE_VAR);
  write_to_max7219(TEST_DISPLAY_ADDR, TEST_DISPLAY_VAL);
}

void setup()
{
  Serial.begin(115200);
  
  init_max7219();
}

void loop()
{
  static unsigned int pattern = 0;
  unsigned int i;
  unsigned char display_data[2][8] = {
    {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
    {0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa},
  };
  for (i = 0; i < 8; i++) {
    write_to_max7219(i+1, display_data[pattern][i]);
  }

  pattern = !pattern;
  delay(500);
}

 

위 코드에서 shiftOut() 함수에 대한 설명 (즉 데이터 1byte를 bit 단위로 pin 2개를 컨트롤 & 토글 해 준다)

https://www.arduino.cc/reference/ko/language/functions/advanced-io/shiftout/

 

아두이노 참조

설명 한번에 한 비트씩의 바이트를 옮긴다. 최고(가장 왼쪽) 또는 최저(가장 오른쪽) 비트부터 시작한다. 각 비트에, 클락 핀은 하이로 풀 되고, 다음 비트는 데이터 라인에서 읽히고, 클락 핀은 로우 된다. 각 비트는 차례로 데이터 핀에 써지며, 각 클락 핀이 펄스되어(high 되면, low) 비트가 사용가능함을 가리킨다. 주의 - 올라가는 에지에 의해 클락되는 장치와 인터페이스하면, shiftOut() 이 불리기 전에 클락 핀이 로우되는, 예를 들어 d

www.arduino.cc

 

 

이로서 MAX7219를 통해 좀 더 쉽고 효율적으로 도트 매트릭스를 컨트롤 할 수 있게 되었다.

다음엔 무엇을 해 볼까나.......

 

 

 

Comments