Arduino : 32x8 LED Matrix Scrolling
아두이노 우노 보드로 LED Matrix에 문자를 스크롤하는 원리와 코드를 소개
합니다.문자열 스크롤 기본 원리
LED Matrix에 문자열을 스크롤 하기 위한 방법 용도에 따라 다양한 방법으로 구현 가능합니다. 이 포스트에서 소개한 방법은 많은 방법 중 하나임을 참고해주세요.
디스플레이 버퍼
LED Matrix, LCD 와 같은 디스플레이 장치는 대부분 디스플레이 버퍼를 사용합니다. 디스플레이 버퍼는 화면에 표시할 데이터를 저장하는 데이터 배열입니다. 아래와 같이 32x8 픽셀의 LED Matrix와 320 x 240 LCD 가 있는 경우 아래와 같은 데이터 사이즈 버퍼를 사용합니다. 용도에 따라 다른 다양한 방식으로 사용 가능합니다.
디스플레이 버퍼 예시
- 32 x 8 LED Matrix : char[4][8]
- 320 x 240 LED Matrix : int[320][240]
위의 디스플레이 버퍼를 사용하면 디스플레이 장치를 아래 그림과 같은 방법으로 동작 가능합니다. 일단 컨트롤러 내부의 사정과 관련 없이 Display Buffer에서 디스플레이 장치로 주기적으로 데이터를 전송하는 기능을 만듭니다. 표시할 화면이 변경되는 경우 컨트롤러 내부에서 Display Buffer의 데이터만 변경합니다. 크게 이런 원리로 디지털 디스플레이 장치를 제어 가능합니다.
LED Matrix의 스크롤
32X8 LED Matrix에서 문자열을 스크롤하기 위해 2개의 데이터 버퍼를 사용하였습니다. 제가 작명에는 소질이 없어서 적절한지 모르겠지만, 출력할 텍스트가 모두 저장되는 stringBuff와 표시할 화면의 데이터를 저장하는 displayBuff 두 개를 만들었습니다.
8x8 Font를 사용하는 경우 32x8 LED Matrix에는 4글자만 표현이 가능합니다. "Hello World!"와 같은 12 문자를 표시하기 위해 12글자와 문자열 앞뒤 여백을 stringBuff에 저장합니다. 이후에 스크롤 속도에 따라 displayBuff에 저장될 데이터를 변경합니다. 아래 그림은 이해를 돕기 위한 그림입니다. 붉은색은 stringBuff이고 빨간색은 displayBuff입니다.
LED 매트릭스 스크롤 하기
준비물
본 예제에 사용된 부품은 아래와 같습니다.
- Arduino Uno x 1EA
- MAX7219 32x8 LED 매트릭스 x 1EA
- 점퍼 와이어
하드웨어 연결
Arduino Uno와 LED Matrix는 아래의 회로도와 같이 연결하였습니다. Arduino Uno 보드의 13, 11, 10번 핀을 각각 LED 매트릭스 모듈의 SCK, DIN, CS 핀에 연결하였습니다.
코드 작성
아래 코드를 실행시키기 위한 옵션은 아래와 같습니다.
#define TEXTBUFFERLENGTH 40: stringBuff의 크기 설정#define MODULESIZE 4: MAX7219 LED Matrix 모듈 개수#define SCROLLSPEED 70: 스크롤 스피드 조정하는 숫자(오차는 있지만 ms 단위로 생각)- 60 이하로 설정 시 잔상효과 있을 수 있음
#define STRING "Hello World!": LED 매트릭스에 표시할 문자열- 문자열 4자리 이하 : 경우 고정된 문자 출력
- 문자열 4자리 초과 : 문자열 스크롤
#define SCK 13
#define DIN 11
#define LATCH 10
#define TEXTBUFFERLENGTH 40
#define MODULESIZE 4 /* Module Number */
#define SCROLLSPEED 70
#define STRING "Test"
String string = STRING; /* Input String to Display */
int stringLength; /* string 의 문자열 길이를 저장하는 변수 */
uint8_t stringBuff[TEXTBUFFERLENGTH][8]; /* String Dot Data Buffer*/
uint8_t displayBuff[MODULESIZE][8]; /* Display Data Buffer */
boolean scrollFlag = false; /* string 변수가 5글자 이상일 경우 인지 판단하는 flag */
int scrollTIme = SCROLLSPEED; /* 스크롤 속도 조정 */
/* Reference : https://github.com/dhepper/font8x8/blob/master/font8x8_basic.h */
const uint8_t font[128][8] PROGMEM = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space)
{ 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!)
{ 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (")
{ 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#)
{ 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($)
{ 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%)
{ 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&)
{ 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (')
{ 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (()
{ 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ())
{ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*)
{ 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,)
{ 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.)
{ 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/)
{ 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0)
{ 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1)
{ 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2)
{ 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3)
{ 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4)
{ 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5)
{ 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6)
{ 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7)
{ 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8)
{ 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9)
{ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:)
{ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (//)
{ 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<)
{ 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=)
{ 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>)
{ 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?)
{ 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@)
{ 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A)
{ 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B)
{ 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C)
{ 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D)
{ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E)
{ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F)
{ 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G)
{ 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H)
{ 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I)
{ 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J)
{ 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K)
{ 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L)
{ 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M)
{ 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N)
{ 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O)
{ 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P)
{ 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q)
{ 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R)
{ 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S)
{ 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T)
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U)
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V)
{ 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W)
{ 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X)
{ 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y)
{ 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z)
{ 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([)
{ 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\)
{ 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (])
{ 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_)
{ 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`)
{ 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a)
{ 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b)
{ 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c)
{ 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d)
{ 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e)
{ 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f)
{ 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g)
{ 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h)
{ 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i)
{ 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j)
{ 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k)
{ 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l)
{ 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m)
{ 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n)
{ 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o)
{ 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p)
{ 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q)
{ 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r)
{ 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s)
{ 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t)
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u)
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v)
{ 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w)
{ 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x)
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y)
{ 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z)
{ 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({)
{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|)
{ 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (})
{ 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F
};
void setup(){
pinMode(SCK, OUTPUT);
pinMode(DIN, OUTPUT);
pinMode(LATCH, OUTPUT);
write_Max7219(0x09, 0x00); // Decode Mode - No decode for digits
write_Max7219(0x0a, 0x01); // Intensity - 1/32
write_Max7219(0x0b, 0x07); // Scan Limit - All Output Port Enable
write_Max7219(0x0c, 0x01); // Shutdown - Normal Operation
write_Max7219(0x0f, 0x00); // Display Test
delay(50);
reset_StringBuff(); // string에 저장된 문자열을 stringBuff에 저장
}
void loop(){
unsigned long now = millis();
static unsigned long pastTime;
if(now-pastTime >= scrollTIme){ // 설정된 스크롤 간격으로 동작하는 if문
if(scrollFlag){
pastTime = now;
static int index;
static int shiftCount;
for(int i = 0 ; i < MODULESIZE ; i++){
for(int j = 0 ; j < 8 ; j++){
displayBuff[i][j] = (stringBuff[index+i][j] >> shiftCount) | stringBuff[index+i+1][j] << 8 - shiftCount;
}
}
shiftCount++;
if(shiftCount == 8){
shiftCount = 0;
index++;
}
if(index > stringLength + 5){
index = 0;
}
display_Max7219();
}
}
}
void write_Max7219(uint8_t address, uint8_t data){
digitalWrite(LATCH,LOW);
for(int i = 0 ; i < MODULESIZE ; i++){
shiftOut(DIN, SCK, MSBFIRST, address);
shiftOut(DIN, SCK, MSBFIRST, data);
}
digitalWrite(LATCH,HIGH);
}
void display_Max7219(){
for( int rowNumber = 1 ; rowNumber < 9 ; rowNumber++){
digitalWrite(LATCH,LOW);
for( int columnData = 0 ; columnData < MODULESIZE ; columnData++){
shiftOut(DIN, SCK, MSBFIRST, rowNumber);
shiftOut(DIN, SCK, LSBFIRST, displayBuff[columnData][rowNumber - 1]);
}
digitalWrite(LATCH,HIGH);
}
}
void reset_StringBuff(){ // stringBuff에 데이터 세팅하는 함수
stringLength = string.length();
for(int i = 0 ; i < TEXTBUFFERLENGTH ; i++){
for(int j = 0 ; j < 8 ; j++){
stringBuff[i][j] = 0b00;
}
}
if(stringLength > 4){
scrollFlag = true;
for(int i = 5 ; i < stringLength + 5 ; i++){
for(int j = 0 ; j < 8 ; j++){
stringBuff[i][j] = pgm_read_byte(&(font[string.charAt(i-5)][j]));
}
}
}
else{
scrollFlag = false;
for(int i = 0 ; i < stringLength ; i++){
for(int j = 0 ; j < 8 ; j++){
displayBuff[i][j] = pgm_read_byte(&(font[string.charAt(i)][j]));
}
}
display_Max7219();
}
}
주요 코드 설명
void loop() 내의 아래 if문 코드는 선언문에서 #define으로 정의된 SCROLLSPEED 속도에 따라 displayBuff의 데이터를 설정하는 코드입니다.
if(now-pastTime >= scrollTIme){ // 설정된 스크롤 간격으로 동작하는 if문
if(scrollFlag){
pastTime = now;
static int index;
static int shiftCount;
for(int i = 0 ; i < MODULESIZE ; i++){
for(int j = 0 ; j < 8 ; j++){
displayBuff[i][j] = (stringBuff[index+i][j] >> shiftCount) | stringBuff[index+i+1][j] << 8 - shiftCount;
}
}
shiftCount++;
if(shiftCount == 8){
shiftCount = 0;
index++;
}
if(index > stringLength + 5){
index = 0;
}
display_Max7219();
}
}
void reset_StringBuff() 함수는 string 변수에 저장된 문자열의 길이가 4를 초과하는지 판단하여 4를 초과하는 경우 stringBuff에 문자열 도트 데이터를 저장하고, 4이하면 displayBuff에 문자열 도트데이터를 바로 저장 후 MAX7219에 데이터를 송신합니다.
void reset_StringBuff(){ // stringBuff에 데이터 세팅하는 함수
stringLength = string.length();
for(int i = 0 ; i < TEXTBUFFERLENGTH ; i++){
for(int j = 0 ; j < 8 ; j++){
stringBuff[i][j] = 0b00;
}
}
if(stringLength > 4){
scrollFlag = true;
for(int i = 5 ; i < stringLength + 5 ; i++){
for(int j = 0 ; j < 8 ; j++){
stringBuff[i][j] = pgm_read_byte(&(font[string.charAt(i-5)][j]));
}
}
}
else{
scrollFlag = false;
for(int i = 0 ; i < stringLength ; i++){
for(int j = 0 ; j < 8 ; j++){
displayBuff[i][j] = pgm_read_byte(&(font[string.charAt(i)][j]));
}
}
display_Max7219();
}
}
실행 결과
위 코드에서 선언문 #define STRING "TEST" 4글자를 입력한 경우 아래 그림과 같은 정지 화면이 정상적으로 출력됩니다.
위 코드에서 #define STRING "Hello World!" 와 같이 4 글자를 초과하는 문자열을 입력하면 아래 영상과 같이 스크롤이 되는 것을 확인할 수 있습니다.
마무리
이번 포스트에서는 LED Matrix를 사용하여 텍스트 스크롤하는 원리와 동작 코드 예시를 소개하였습니다. 코드에서 사용한 폰트는 8x8 사이즈인데, 5x7의 텍스트를 사용해서 촘촘하게 데이터를 만들면 한결 보기 좋고, 부드러운 문자열을 출력할 수 있을 것이라 예상합니다.
'Embedded > Arduino' 카테고리의 다른 글
아두이노 #56 2.4inch TFT LCD 초기화 설정 및 시작하기 (0) | 2020.12.15 |
---|---|
아두이노 #55-1 32x8 LED Matrix 시리얼 통신으로 텍스트 스크롤하기 - 라이브러리 없이 (6) | 2020.12.04 |
아두이노 #54 32x8 LED Matrix Font 데이터 참조로 문자 표시 및 메모리 문제 해결 (0) | 2020.12.02 |
아두이노 #53 MAX7219 32x8 LED Matrix 문자 표시하기 기초 - 라이브러리 없이 코드 작성 (0) | 2020.12.02 |
아두이노 #52 MAX7219 LED Matrix 모듈 기초 사용법 - 라이브러리 없이 동작 (0) | 2020.12.01 |