프로젝트들/메타버스게임

20221007 메타버스 4. Arduino IR Sender

Choi Jaekuk 2022. 10. 7. 22:51

Github : https://github.com/cjk09083/meta

 

GitHub - cjk09083/meta: 메타버스 게임 [Flutter(iOS), Arduino]

메타버스 게임 [Flutter(iOS), Arduino]. Contribute to cjk09083/meta development by creating an account on GitHub.

github.com

 

지난 포스트에 이어 

 

이번엔 리모콘 역할을 하는 적외선 송신기를 제작하였다.

 

완성된 회로는 아래와 같다.

 

리모콘 회로도

위 회로도에서 각 부품은 다음과 같다.

1 왼쪽위: IR 송신을 위한 KY-005 모듈

2 하단 : Arduino Nano 

3 상단 : 스위치 매트릭스 (4방향 화살표, 확인, 전체메뉴(Home) 키)

 

여기서 스위치 매트릭스는 하나의 아날로그 입력당 3개의 스위치를 사용할 수 있도록 아래 그림을 참고하여 구성하였다.

(출처: https://worklab.tistory.com/m/7)

스위치 매트릭스

 

Arduino 에서 스위치가 동시에 여러개 눌리더라도 이를 처리하기 위해 다음과 같은 방법을 사용했다.

void getVolt(int num){
  int adc = adcRef + num;
  digitalWrite(num, HIGH); 
  delay(10);
  val[num] = analogRead(adc);
  digitalWrite(num, LOW);
  Serial.print("A");
  Serial.print(num-3);
  Serial.print(":");
  Serial.print(val[num]);
  chkValue(num-3,val[num]);
  Serial.print(" ");
}

250ms 마다 getVolt 함수에서  각 Analog Input핀의 전압 입력값을 체크한다.

 

void chkValue(int num, int val){
  int setArr[] = {100,100,100};
  if(val < 10) return;
  else if(val < 200) setArr[0] = 0;
  else if(val < 250) setArr[0] = 1;
  else if(val < 290) setArr[0] = 2;
  else if(val < 320) setArr[0] = 0, setArr[1] = 1;
  else if(val < 350) setArr[0] = 0, setArr[1] = 2;
  else if(val < 390) setArr[0] = 1, setArr[1] = 2;
  else setArr[0] = 0, setArr[1] = 1, setArr[2] = 2;
  Serial.print(" {");
  for (int i=0; i <= 2; i++ ){
    int set = setArr[i];
    if(set > 10 ) break;
    sendMsg(num,set);
    Serial.print(",");
    delay(10);
  }
  Serial.print("} ");
}

가져온 전압값이 10 이하라면 무시하고 그보다 크다면 미리 측정해둔 스위치 별 분배 전압값에 따라 어떤 스위치가 눌렸는지 판단한다. 현재 저항 3종류 x 아날로그 입력 2개 = 6개의 스위치를 동시에 입력 가능하다. 

 

void sendMsg(int num, int set){
  uint16_t sAddress = 0xC0DA;
  uint8_t sCommand = cmdHex[num][set];
  uint8_t sRepeats = 0;
  Serial.print(sCommand,HEX);
  IrSender.sendNEC(sAddress, sCommand, sRepeats);
}

스위치가 눌린것으로 판단되면 이에 해당하는 HEX 코드를 적외선으로 송신한다. 

 

프로젝트에서는 최소 20개의 스위치가 필요하므로 아날로그 입력 7개(A0 ~ A6)를 사용할 예정이다.

 

 

LG U+ TV를 제어하는 모습

 

최종 Arduino 코드는 아래와 같다.

 

더보기

#include <IRremote.h>

int val[10];
int adcRef = 14 - 3;
String cmdStr[][3] = {
                    {"home","up","left"},
                    {"enter","right","down"}
                  };

int cmdHex[][3] = {
                    {0x45,0x40,0x42},
                    {0x44,0x43,0x41}
                  };

void setPin(int num);
void getVolt(int num);
void sendMsg(int num, int val);
void chkValue(int num, int val);

void setup() {
  Serial.begin(115200);
  IrSender.begin(2);
  setPin(3);
  setPin(4);
}

void loop() {
  getVolt(3);
  getVolt(4);
  
  Serial.println();
  delay(250);
}

void setPin(int num){
  int adc = adcRef + num;
  pinMode(adc, INPUT);
  pinMode(num, OUTPUT);
  digitalWrite(num, LOW); 
}

void getVolt(int num){
  int adc = adcRef + num;
  digitalWrite(num, HIGH); 
  delay(10);
  val[num] = analogRead(adc);
  digitalWrite(num, LOW);
  Serial.print("A");
  Serial.print(num-3);
  Serial.print(":");
  Serial.print(val[num]);
  chkValue(num-3,val[num]);
  Serial.print(" ");
}

void chkValue(int num, int val){
  int setArr[] = {100,100,100};
  if(val < 10) return;
  else if(val < 200) setArr[0] = 0;
  else if(val < 250) setArr[0] = 1;
  else if(val < 290) setArr[0] = 2;
  else if(val < 320) setArr[0] = 0, setArr[1] = 1;
  else if(val < 350) setArr[0] = 0, setArr[1] = 2;
  else if(val < 390) setArr[0] = 1, setArr[1] = 2;
  else setArr[0] = 0, setArr[1] = 1, setArr[2] = 2;
  Serial.print(" {");
  for (int i=0; i <= 2; i++ ){
    int set = setArr[i];
    if(set > 10 ) break;
    sendMsg(num,set);
    Serial.print(",");
    delay(10);
  }
  Serial.print("} ");
}

void sendMsg(int num, int set){
  uint16_t sAddress = 0xC0DA;
  uint8_t sCommand = cmdHex[num][set];
  uint8_t sRepeats = 0;
  Serial.print(sCommand,HEX);
  IrSender.sendNEC(sAddress, sCommand, sRepeats);
}