INU ESE : 창의설계입문 2nd

박건민·2023년 10월 11일
0

자.. <이제 2번째다>

▶ LED Matrix Animation을 제작하는 과정을 '상세히'
  코드 설명과 함께 블로그에 작성하여 링크를 댓글로 제시하세요.

  1. 코드에 대한 설명이 있어야 합니다.
  2. 코드를 작성하는 과정이 있어야 합니다.
  3. 작동하는 영상이 포함되어야 합니다.

  • 네이버 블로그, T스토리, 개인 웹사이트,
    Github md file, Notion등 모든 블로그 형식의 사이트 링크

    제출기한 : 10월 11일 수요일 오후 16시 30분까지
    점수 : 제출 +20점 + 정성평가 최대 10점

  • 내용이 부실할 경우 기본점보다 낮은 점수가 부여될 수 있음 (!!)

우선 Matrix를 봤을 때 떠올랐던 건 DOT, 즉 Pixel이였다.
하지만, 생각보다 Matrix 크기도 작고, 색깔 표현도 못하기에
생각났던 게임이나 캐릭터들을 '제대로' 구현하기엔 어려움이 있었다;;

ex) 마리오, 소닉, 카트라이더 등등..


그래서 PING-PONG 시대 수준으로 구현해보기로 했다..

(이게 최선인 듯;;)

이때, 갑자기 머릿속을 스쳐지나간 첫 마리오 카트가 생각나면서
(도트 그래픽의 캐릭터, 카트가 바닥의 트랙을 달림)
이를 카트라이더로 만들어보고 싶다는 생각이 들었다!

하지만, 카트바디, 캐릭터는 물론이고 트랙마저 그리기 어려운 상황;;
그럼에도 불구하고, 우선 부딪혀보자는 생각으로 시작해봤다...

난 섭종하지 않아ㅠㅠㅜ!!


1. 트랙과 카트, 속도 구현

  • 전체 트랙을 먼저 보여주고
  • 카트(DOT)가 이동하면서 트랙을 그려간다.
  • 또한 속도는 실습 시간에서 썼던 가변 저항 값을 활용한다!

           빌리지 고가의 질주


            빌리지 손가락

#include "Arduino_LED_Matrix.h"
#include "Count.h"				// 3, 2, 1!
#include "Village_Overpass.h"	// Circuit 1
#include "Village_Fingers.h"	// Circuit 2



ArduinoLEDMatrix matrix;
int c1 = 0;	// Circuit 1 Count
int k1 = 0;	// Circuit 1 Kart
int c2 = 0;	// Circuit 2 Count
int k2 = 0;	// Circuit 2 Kart

// 전체 Circuit 모습
const uint32_t Circuit1[] = {
   0x38e2ea23,
   0xa6038016,
   0x13031fe
};
const uint32_t Circuit2[] = {
	0x7fc43ce3,
	0xfe3fe3c4,
	0x3c5bf7ff
};


void setup(){
	matrix.begin();
}

void loop(){
	
   // delay가 가변 저항 값(0~1023)에 따라 변함
   int d = analogRead(A1);
   
   if(k1 <= 38){
   	   
		// Circuit 보여주기
		if(c1 == 0){
			matrix.loadFrame(Circuit1);
			delay(5000);
		}
       // Count
		if(c1 < 3){
			matrix.loadFrame(Count[c1%3]);
			c1++;
			delay(1000);
		}
		else{
     		// 카트가 트랙 그리기
     		matrix.loadFrame(Village_Overpass[k1%38]);
     		k1++;
     		delay(d);	// 여기
		}
   }
   else if(k2 <= 55){
   
		if(c2 == 0){
			matrix.loadFrame(Circuit2);
			delay(5000);
		}
		if(c2 < 3){
     		matrix.loadFrame(Count[c2%3]);
     		c2++;
     		delay(1000);
		}
		else{
			matrix.loadFrame(Village_Fingers[k2%55]);
			k2++;
			delay(d);	// 얘도
		}
   }
   else{
		// 무한 반복
		c1 = 0;
		c2 = 0;
		k1 = 0;
		k2 = 0;
   }
}

            노가다도 노가다지만.. 글자를 보여주고 싶다!!


2. LCD에 글자 출력

마침 LCD 강의도 올라와 있다!!

뭔가 게임적인 면을 돋보이게?! 기존 회로에 LCD 추가!!!
로고라도 그려보려고 했는데 쉽지 않았다..


아래는 LCD를 사용하기 전에 꼭 실행시켜야 하는 부분!

출처 : https://kocoafab.cc/tutorial/view/727

// I2C LCD의 I2C 주소 확인
#include <Wire.h>

void setup()
{
  Wire.begin();

  Serial.begin(9600);
  while (!Serial);           
  Serial.println("\nI2C Scanner");
}

void loop()
{
  byte error, address;
  int nDevices;
  Serial.println("Scanning...");
  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknow error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }

  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
  delay(5000);
}

여기서 나온 값이 내 LCD의 I2C 주소임!!

여기서 I2C란?

  • 2개의 선(SDA, SCL)을 이용하는 직렬 통신
  • 하나의 마스터와 여러 개의 슬레이브 기기가 물려 통신이 가능

  이제 LCD에 글자를 출력시켜볼까!!

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);	// 0x27 or 0x3F

void Kart(){
  lcd.setCursor(0,0);
  lcd.print("R.I.P KARTRIDER.");
  lcd.setCursor(0,1);	
  lcd.print("2004-2023.03.31.");
  delay(5000);
  lcd.clear();
}

void Circuits_List(){
  lcd.setCursor(0,0);
  lcd.print("1.VillageOverpas");
  lcd.setCursor(0,1);
  lcd.print("2.VillageFingers");
  delay(5000);
  lcd.clear();
}


void setup() {
	// 초기화
	lcd.init();
	// LCD 백라이트 ON
	lcd.backlight();
  Kart();
  Circuits_List();
}

void loop(){
	if(k1 <= 38){
    	lcd.setCursor(0,0);
    	lcd.print("Dot KART DEMOver");
    	lcd.setCursor(0,1);	
    	lcd.print("VillageOverpass!");
        ...
    }
    else if(k2 <= 55){
    	lcd.setCursor(0,0);
    	lcd.print("Dot KART DEMOver");
    	lcd.setCursor(0,1);	
    	lcd.print("VillageFingers!!");
    }
}

     최종 코드 및 구현 영상

#include <LiquidCrystal_I2C.h>
#include "Arduino_LED_Matrix.h"
#include "Count.h"
#include "Village_Overpass.h"
#include "Village_Fingers.h"

LiquidCrystal_I2C lcd(0x27, 16, 2);
ArduinoLEDMatrix matrix;
int c1 = 0;
int k1 = 0;
int c2 = 0;
int k2 = 0;

void Kart(){
  lcd.setCursor(0,0);
  lcd.print("R.I.P KARTRIDER.");
  lcd.setCursor(0,1);	
  lcd.print("2004-2023.03.31.");
  delay(5000);
  lcd.clear();
}

void Circuits_List(){
  lcd.setCursor(0,0);
  lcd.print("1.VillageOverpas");
  lcd.setCursor(0,1);
  lcd.print("2.VillageFingers");
  delay(5000);
  lcd.clear();
}


void setup() {
	lcd.init();
	lcd.backlight();
  Kart();
  Circuits_List();
  matrix.begin();
}

void loop() {

  int d = analogRead(A1);

  const uint32_t Circuit1[] = {
    0x38e2ea23,
    0xa6038016,
    0x13031fe
  };

  if(k1 <= 38){
  
    lcd.setCursor(0,0);
    lcd.print("Dot KART DEMOver");
    lcd.setCursor(0,1);	
    lcd.print("VillageOverpass!");
    
    if(c1 == 0){
      matrix.loadFrame(Circuit1);
      delay(5000);
    }
    if(c1 < 3){
      matrix.loadFrame(Count[c1%3]);
      c1++;
      delay(1000);
    }
    else{
      matrix.loadFrame(Vil_Over[k1%38]);
      k1++;
      delay(d);
    }
  }
  else if(k2 <= 55){
  
    const uint32_t Circuit2[] = {
	  	0x7fc43ce3,
	  	0xfe3fe3c4,
	  	0x3c5bf7ff
    };

    lcd.setCursor(0,0);
    lcd.print("Dot KART DEMOver");
    lcd.setCursor(0,1);	
    lcd.print("VillageFingers!!");
    
    if(c2 == 0){
      matrix.loadFrame(Circuit2);
      delay(5000);
    }
    if(c2 < 3){
      matrix.loadFrame(Count[c2%3]);
      c2++;
      delay(1000);
    }
    else{
      matrix.loadFrame(Vil_Finger[k2%55]);
      k2++;
      delay(d);
     }
  }
  else{
    c1 = 0;
    c2 = 0;
    k1 = 0;
    k2 = 0;
  }
}

    ▲ 위 이미지를 클릭하세요!


p . s . 이건 아이디어를 생각해내는 게 제일 힘들었다;;
    또 구현된 맵을 Matrix에 맞게 변환하는 거랑
    loop 안에서 1개의 함수가 끝까지 실행된 후, 다른 함수 실행시키는 것
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...

  총평 : ㆍㆍㆍ ─ ─ ─ ㆍㆍㆍ

0개의 댓글