Hermit Under the Cliff

[Arduino] 아두이노 코딩봇 만들기 (13) - 8x8 LED Dot Matrix 장착 본문

Personal Projects/아두이노 코딩봇

[Arduino] 아두이노 코딩봇 만들기 (13) - 8x8 LED Dot Matrix 장착

AnonymousDeveloper 2022. 3. 18. 14:57

코딩봇을 자작해 나가면서

점점 이 프로젝트의 목적이 따님을 위한 코딩봇 제작이 아니라

저의 재미를 위한 프로젝트가 되어가고 있습니다.

초심을 되찾고자, 따님의 관심을 끌 만한 것을 추가하기로 합니다.

 

mBlock의 블록 중에는 아래와 같이 NxN Dot Matrix의 모양을 설정해 주는 기능이 있습니다.

컴퓨터에서 찍은 도트로 된 그림들이 로봇에 표시가 되면

따님이 좋아할 것 같으니 한번 장착을 해보도록 합니다.

그런데 문제가 있습니다. 아래와 같이 8x8 짜리 Dot Led 모듈에는

핀도 행/열의 수와 같이 8개씩 총 16개의 핀이 있습니다.

 

아두이노에 바로 연결하기에는 핀이 모자랍니다.

이런 비슷한 경험을 대학교때 뭔가 배웠던 것 같은데

졸업한지 오래되어 기억이 나지 않아 검색을 해 봅니다.

 

쉬프트 레지스터(Shift Register)를 통해서 병렬의 신호를 직렬로 바꾸면 되는군요.

(배운지 오래되서 잘 기억나지는 않지만)

간단하게 설명하면 한번에 16개의 핀에 신호를 주어서 LED를 켜고 끄는 것이 아니라

행 별로 (혹은 열별로) 빠르게 신호를 줌으로써

사람의 눈에는 계속해서 켜져 있는 것으로 느끼게 해주는 것입니다.

쉬프트 레지스터는 클럭에 따라서 핀의 출력을 순차적으로 내 보낼 수 있는 역할을 합니다.

16개의 핀을 한번에 컨트롤 하기 위해서 MAX7129라는 칩을 사용하면 됩니다.

 

MAX7219 Datasheet의 Timing Diagram

오랜만에 데이터시트를 보니 머리가 아파옵니다.

저 핀들을 다 결선할 생각만해도 골치가 아프구요. 

그래서 아래 모듈을 주문했습니다.

쇼핑몰 링크 : https://www.ic114.com/WebSite/site/sc/00V0.aspx?id_p=P0080187 

 

MAX7219와 8x8 Dot Matrix가 합쳐져있고 그냥 사용만 하면 되는 모듈이죠.

그리고 이를 제어하기 위한 라이브러리가 아두이노에는 이미 존재합니다.

LedControl이라는 라이브러리를 추가해 준뒤 아래와 같이 테스트 코드를 짜 봅니다.

 

#include "LedControl.h"
LedControl dot = LedControl(11,13,12,1); //DIN CLK CS ADDR
void setup() {
  // put your setup code here, to run once:
  dot.shutdown(0, false);
  dot.setIntensity(0,8);
  dot.clearDisplay(0);
  
}

void loop() {
  
  
  // put your main code here, to run repeatedly:
for (int row=0; row<8; row++)
  {
    for (int col=0; col<8; col++)
    {
      dot.setLed(0,col,row,true);      // LED가 켜지면서 밑에서부터 올라갑니다.
      delay(25);                      // 25만큼 지연
    }
  }
  

  for (int row=0; row<8; row++)
  {
    for (int col=0; col<8; col++)
    {
      dot.setLed(0,col,row,false);       // LED가 꺼지면서 밑에서부터 올라갑니다
      delay(25);                        //25만큼 지연
    }
  }
  
}

동작원리를 대충만 알아도 되는게

이런 식으로 이미 있는 것들이 많아 그냥 가져다 쓰면 되는 충분히 편한 세상입니다.

프로그래밍으로 밥 벌어먹고 사는 엔지니어에가 필수적으로 갖추어야 할 능력이죠!

어찌됬건 이 모듈과 위 코드를 통해 3+2 개(신호핀 3개, Vcc, GND)로 8x8 Dot Matrix를 제어할 수 있습니다.

그것도 아주 쉽게요.

 

이제 이 모듈을 코딩봇에 붙이기 위해서

우선 어떤식으로 엠블록에서 데이터가 전송되는지를 알아보아야 합니다.

그전에 먼저 해 줄 것은 기본틀을 만들어야 합니다.

 

mBlock Extenstion Builder에서 Pannel Setting에 들아가시면 Matrix의 템플릿 작성이 가능합니다.

아래와 같이 8x8로 설정을 해 두고 몇가지 모양들도 등록해 봅니다.

 

 

그런다음 블록을 하나 생성하여 인자 중에 LED panel을 선택을 하면 아래와 같이

윗 단계에서 지정해 놓은 panel을 선택할 수 있습니다.

우선은 데이터가 어떻게 표시되는지 확인을 해야하기 때문에

간단하게 블록을 만들고 "This block comes with a checkbox for reading value" 를 체크해 줍니다.

그런 다음 이 Extension을 mBlock에서 열고 블록 옆에있는 체크박스를 체크하면

아래와 같이 우리가 찍은 도트의 값이 0과 1의 조합으로 나오는 것을 확인할 수 있습니다.

 

안타깝게도 저 글자가 복사가 되지 않아 일일히 눈이 빠져가며 

열심히 옮겨 적은 뒤 8개 단위로 잘라보았습니다.

그럼 아래와 같이 나오게 됩니다.

(나중에 알게된건데 조금의 작업을 해서 upload 모드 코드 생성에서 가져와도 되더군요)

00111000
01111100
11111110
00111111
00111111
11111110
01111100
00111000

 

자세히 살펴보니 하트 모양이 90도 돌아가 있네요.

이를 똑바로 나타내 주게 할 코드를 아래와 같이 작성 합니다.

 

/// Dot-Matrix Display
void displayAtDotMatrix(String data)
{
  int index = 63;
  for(int col = 0; col <8; col++)
  {
    for(int row = 7; row >= 0; row--)
    {
      int ledState = data.charAt(index) - '0';
      dot.setLed(0,col,row,ledState);
      index--;
    }
  }
}
/// End of Dot-Matrix Display

사실 계산을 하고 이래저래 짜봤는데 여전히 누워있거나 돌아가 있거나 해서

머리를 별로 쓰지 않고

for 문의 col/row의 조건들을 0->7과 7->0으로 몇번 바꿔가면서 돌려서 얻은 코드입니다.

역시나 몸이 나쁘면 머리가 고생하는 법이죠.

 

이제 라이브모드를 위해서 이 데이터를 시리얼로 전송받아 처리해야 하는 부분을 만들어야 하는데

데이터의 길이가 64글자라서 기존에 정의해 놓았던 컨트롤 프로토콜이랑 맞지 않습니다.

기존의 컨트롤 프로토콜에서 Length 부분을 1글자에서 2글자로 변경을 해주고

 
    char target = recv_data.charAt(1);
    int data_len = recv_data.substring(2,4).toInt();
    //int data_len = recv_data.charAt(2) - '0';
    String data = recv_data.substring(4, 4 + data_len);

위와 같이 이를 처리해 주는 부분을 교체해 줍니다.

추가로 mBlock Extenstion에서도 Serial Command를 다 바꿔줍니다. (M2MF-> M02MF 등으로)

그 이후 swith 문에 아래 조건을 추가하여 dot matrix를 켜주게 합니다.

case 'D': //Dot Matrix
        displayAtDotMatrix(data);
        break;

이제 시리얼로 @D64[DATA]# 을 써 줌으로써 Dot Matrix에 그림을 그릴 수 있게 됩니다.

 

아래와 같이 블록을 하나 추가하고

업로드 코드와 라이브 코드를 작성해 줍니다.

아래와 같이 간단하게 작성하면 됩니다.

 

<Upload transcode>

// CODE: 부분에 아래 내용 삽입
displayAtDotMatrix("/*{{this.shape}}*/");

<Live mode handler>

(args, app, device, block) => {
    // JavaScript code
    var command = "@D64" + block.arguments.shape +"#";

    const _sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
    device.writeText(command);
}

물론 Transcode setting 메뉴와 기본 이벤트 블록에서 추가된 내용들을 넣는 것이 필요합니다.

LEDControl 라이브러리도 추가하는 것을 잊으면 안됩니다.

모든 작업이 끝나면 아래와 같이 블록코딩으로 만든 하트 모양이

코딩봇에 부착된 LED에 나타나는 것을 볼 수 있습니다.

 

역시나 모든 소스코드들은 아래 Github에서 확인 가능합니다.

https://github.com/reitn/OlbinBot

 

GitHub - reitn/OlbinBot: Olbin Coding bot based on Arduino and Mblock

Olbin Coding bot based on Arduino and Mblock. Contribute to reitn/OlbinBot development by creating an account on GitHub.

github.com

 

다음 포스트는 코딩봇의 머리를 만들어 주고

이 머리를 서보모터를 이용하여 회전을 해 주는 것을 알아보겠습니다.

Comments