#include <IRremote.h>  // IR리모콘을 사용하기 위한 헤더파일 호출
#define RECV_PIN A0  // 적외선 수신센서 모듈, 아두이노 우노 보드의 아날로그 A0 핀과 연결
IRrecv irrecv(RECV_PIN);  // IR읽어오는 핀 지정
decode_results results;  // IR리모콘 데이터 저장변수 객체 선언
#define EA 3  // 모터드라이버 EA 핀, 아두이노 디지털 3번 핀에 연결
#define EB 11  // 모터드라이버 EB 핀, 아두이노 디지털 11번 핀에 연결
#define M_IN1 4  // 모터드라이버 IN1 핀, 아두이노 디지털 4번 핀에 연결
#define M_IN2 5  // 모터드라이버 IN2 핀, 아두이노 디지털 5번 핀에 연결
#define M_IN3 13  // 모터드라이버 IN3 핀, 아두이노 디지털 13번 핀에 연결
#define M_IN4 12  // 모터드라이버 IN4 핀, 아두이노 디지털 12번 핀에 연결
int motorA_vector = 0;  // 모터의 회전방향이 반대일 시 0을 1로, 1을 0으로 바꿔주면 회전방향이 바뀜.
int motorB_vector = 1;  // 모터의 회전방향이 반대일 시 0을 1로, 1을 0으로 바꿔주면 회전방향이 바뀜.
// int motor_speed = 255;   모터 스피드 적외선 예제에선 고정
int readIR;  // 리모콘으로 부터 들어오는 값을 저장하는 변수
void setup()  // 초기화
{ 
  Serial.begin(9600);
  pinMode(EA, OUTPUT);
  pinMode(EB, OUTPUT);
  pinMode(M_IN1, OUTPUT);
  pinMode(M_IN2, OUTPUT);
  pinMode(M_IN3, OUTPUT);
  pinMode(M_IN4, OUTPUT);

  irrecv.enableIRIn();
}

void loop()
{
  if (irrecv.decode(&results)) {
    Serial.println(readIR);
    Serial.println(results.value, HEX);

    switch (results.value) { //읽어온 IR값과 비교
      case 0x3D9AE3F7: // Key 2, 전진
      case 0x00FF18E7: 
        motor_con(1,1); //전진
        readIR = 2;
        break;
      case 0x8C22657B: // Key 4, 좌회전
      case 0x00FF10EF: 
        motor_con(1, 0); //좌회전
        readIR = 4;
        break;
      case 0x488F3CBB: // Key 5, 정지
      case 0x00FF38C7: 
        motor_con(0, 0); //정지
        readIR = 5;
        break;
      case 0x449E79F: // Key 6, 우회전
      case 0x0FF5AA5:
        motor_con(0, 1); //우회전
        readIR = 6;
        break;
      case 0x1BC0157B: // Key 8, 후진
      case 0x00FF4AB5: 
        motor_con(-1, -1); //후진
        readIR = 8;
        break;
      default:
        break;
    }
    irrecv.resume();
  }
}

void motor_con(int M1, int M2) //모터 함수
{ 
  if (M1 > 0) //모터A 정회전
  {   
    digitalWrite(EA, HIGH);
    digitalWrite(M_IN1, motorA_vector);
    digitalWrite(M_IN2, !motorA_vector);
  }
  else if (M1 < 0) //모터A 역회전
  {   
    digitalWrite(EA, HIGH);
    digitalWrite(M_IN1, !motorA_vector);
    digitalWrite(M_IN2, motorA_vector);
  }
  else //모터 A 정지
  {   
    digitalWrite(EA, LOW);
    digitalWrite(M_IN1, LOW);
    digitalWrite(M_IN2, LOW);
  }
  if (M2 > 0) //모터B 정회전
  {   
    digitalWrite(EB, HIGH);
    digitalWrite(M_IN3, motorB_vector);
    digitalWrite(M_IN4, !motorB_vector);
  }
  else if (M2 < 0) //모터B 역회전
  {   
    digitalWrite(EB, HIGH);
    digitalWrite(M_IN3, !motorB_vector);
    digitalWrite(M_IN4, motorB_vector);
  }
  else //모터 B 정지
  {   
    digitalWrite(EB, LOW);
    digitalWrite(M_IN3, LOW);
    digitalWrite(M_IN4, LOW);
  }
}