728x90
반응형

2019년 창의적 종합설계 경진대회 때 만들었던 에어 마우스이다. 

하루면 만들 수 있는 작품인데, 알 수 없는 통신에러 때문에 몇 주일을 날렸었다. 

알고 보니 핀 문제였는데 각 핀마다 어느 정도 정해진 역할 같은 것이 있는 건 알고 있었지만 

이런 식으로 통신에서 오류가 날줄은 몰랐다. 덕분에 큰 깨달음을 얻었다.. ㅜㅜ

 

시연 영상

시연 영상이다. 

사실 단순하게 자이로 센서와 버튼 센서만 있으면 되는 작품이지만 뭔가 내용이 너무 모자란 것 같아 민감도 설정 기능을 추가했다.

그리고 발표날에 사람들이 우리 작품 많이 보고 갔으면 좋겠다는 생각에 다이소 2000원짜리 장난감 총과

에어 마우스를 합체시킨 에어 건? 을 만들었고 이걸로 발표날 아침부터 부스에서 배틀그라운드를 했다.

학생들에게는 반응은 매우 좋았지만, 교수님들에게는 작품이 좀 애매한 것 같다?라는 평을 많이 들었다. 

몸으로는 그 말이 이해가 됐는데 지금 말로 설명하려니 좀 어려운 것 같다.

그래도 다행히 동상이라도 받았기에, 좋은 경험이었던 것 같다. 

#include<Wire.h> // 통신 때문에 필요
#include<Mouse.h> // 마우스 움직여야지!

/*
 SDA 2번 Pin, SCL 3번 Pin, Int 7번 Pin
 Int 무조건 박아야됨. 
*/
 
#define MPU6050_INT_PIN 7 // 레오나르도에서는 무조건 7번 Pin에 박아주자
#define MPU6050_INT digitalPinToInterrupt(MPU6050_INT_PIN)

const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

//민감도 조절 변수
int timer1 = 0;
int sens = 1100; // sens_num = 3
int sens_num = 3; // sens = 1100;

int Led1 = 9;
int Led2 = 10;
int Led3 = 11;
int Led4 = 12;
int Led5 = 13;

void setup()
{
  // 설정인데 안 건드는게 좋음. 잘 되있음.
  Serial.begin(9600);
  Serial.println("start");
  Serial.print(MPU6050_INT); Serial.print(" on pin "); Serial.print(MPU6050_INT_PIN);
  
  Mouse.begin();

  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  
  pinMode(4, INPUT); // 좌클릭 버튼
  pinMode(8, INPUT); // 우클릭 버튼
  pinMode(MPU6050_INT, INPUT);
  
  //attachInterrupt(MPU6050_INT, dmpDataReady, RISdlfhgk62ING);
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  pinMode(Led3, OUTPUT);
  pinMode(Led4, OUTPUT);
  pinMode(Led5, OUTPUT);
}

void loop()
{
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  // 여기 위까지는 코드 건들지 않는 걸 추천. 여기 아래부터 수정 ㄱㄱ

  // 버튼의 센서값을 읽음 -> 누르면 1, 안 누르면 0
  int lb = digitalRead(4); // 좌클릭, 1이면 누른 상태, 0이면 안 누른 상태임.
  int rb = digitalRead(8); // 우클릭, 위와 마찬가지
  
  float gyroY, gyroZ;
  
  // 좌우클릭을 동시에 함 
  if (lb == 1 && rb == 1) {
    ++timer1;
    delay(20);
    // 1초 동안 동시에 좌우클릭 -> 민감도 설정 모드
    if (timer1 > 50) {
      Serial.println("민감도 설정 모드\n");
      delay(500); // 이거 없으면 민감도 설정 모드 바로 탈출하게 됨. 꼭 필요함.
      Serial.print("민감도:  ");
      Serial.println(sens_num);
      
      while(1) { 
        lb = digitalRead(4); // 좌클릭 
        rb = digitalRead(8); // 우클릭

        // 민감도 설정 모드 안에서 한번 더 좌우 클릭을 동시에 한 경우 
        if(lb == 1 && rb == 1) { 
          break; // 민감도 설정 모드 탈출 
        }        
        
        else if(lb == 0 && rb == 1) { 
          if(sens_num > 1) { 
            --sens_num; //분모가 커지니까 gyro값 작아짐 >> 민감도 작아짐  
            Serial.print("민감도:  ");
            Serial.println(sens_num);
            delay(500);
          }
        }
        
        else if(lb == 1 && rb == 0) {
          if(sens_num < 5) { 
            ++sens_num; //분모가 작아지니까 gyro값 커짐 >> 민감도 커짐
            Serial.print("민감도:  ");
            Serial.println(sens_num);
            delay(500);
          }    
        }
        
        switch(sens_num) {
           case 5: sens = 820; Sens_Led_On(sens_num); break;
           case 4: sens = 850; Sens_Led_On(sens_num); break;
           case 3: sens = 1100; Sens_Led_On(sens_num); break;
           case 2: sens = 1220; Sens_Led_On(sens_num); break;
           case 1: sens = 1380; Sens_Led_On(sens_num); break;
           default: break;
        }
        //Sprint2(timer1, sens, sens_num);
      }
      timer1 = 0;
      Serial.println("\n민감도 설정 완료!");
      Serial.print("현재 민감도: ");
      Serial.println(sens_num);     
      delay(500);
    }
  }
  // 좌우클릭을 1초 동안 하지 않은 경우
  else { 
    timer1 = 0; // timer1 변수 값 0으로 초기화
  }
  
  gyroZ = GyZ / sens;  // X축
  gyroY = -GyY / sens; // Y축
  
  // lb 가 1 -> 좌클릭을 한 경우
  if(lb == 1)  {
    // 마우스를 누른 상태로 유지시켜주는 Mouse.press()를 사용함.           
    Mouse.press(); // 좌클릭 한 상태 유지
  }

  // rb 가 1 -> 우클릭을 한 경우
  else if (rb == 1) {
    Mouse.click(MOUSE_RIGHT); // 우클릭
    delay(200);
  } 

  // 좌우클릭 둘 다 안했으므로 클릭 상태 해제
  else if (lb == 0 && rb == 0) {
    Mouse.release(); //클릭 상태 해제
  }

  Sprint1(gyroY, gyroZ, lb, rb); // 센서 값을 출력해줌
  //digitalWrite(8 + sens_num, HIGH); // 민감도에 대응되는 LED를 킴
  Mouse.move(gyroZ, gyroY); // 마우스를 움직여주는 함수
}

// 민감도에 따른 LED On/Off 함수
void Sens_Led_On(int sens_num) 
{
  // 우선 다 끄고 시작함
  digitalWrite(Led1, LOW);
  digitalWrite(Led2, LOW);
  digitalWrite(Led3, LOW);
  digitalWrite(Led4, LOW);
  digitalWrite(Led5, LOW);
  
  /*
  민감도에 대응되는 LED 하나만 켜야 됨.  
  8 + sens_num --> Led1,2,3,4,5 에 대응되는 9, 10, 11, 12, 13번 핀을 의미
  Example) Sens_num이 3일 때 8 + sens_num은 11 즉 Led3을 키게 된다. 
  다른 4가지 경우도 똑같이 작동함. 
  */
  digitalWrite(8 + sens_num, HIGH); // Led On
}

// 센서 값을 출력해줌는 함수(자이로, 버튼)
void Sprint1(int gyroY, int gyroZ, int lb, int rb)
{
  Serial.print("X축: "); 
  Serial.print(gyroZ);
  Serial.print(" // Y축: "); 
  Serial.print(-gyroY);
  Serial.print(" // 좌 클릭: ");
  Serial.print(rb);
  Serial.print(" // 우 클릭: ");
  Serial.println(lb);
}

 

대략적인 설명은 코드 안에 주석을 달아놓은 것 같다. 

조이스틱 마우스와 마찬가지로 에어 마우스도 아두이노 우노에서는 동작하지 않는다. 

무조건 레오나르도여야 된다. 

Loop 시작부터 GyZ=Wire.read()<<8 부분까지는 건들지 않는 게 좋을 것 같고

그 아래부터는 원하는 본인이 원하는 대로 바꿔서 사용하면 될 것 같다.  

github: https://github.com/kimjinho1/Air_Mouse/blob/master/Air_Mouse_V2_%2B.ino

 

kimjinho1/Air_Mouse

2019 Incheon University(INU) Capstone Design. Contribute to kimjinho1/Air_Mouse development by creating an account on GitHub.

github.com

조이스틱 마우스: https://jinho-study.tistory.com/246

 

아두이노 조이스틱 마우스

에어 마우스를 만들기 전에 만들었던 조이스틱 마우스이다.  /* 버튼 코드 참조: https://kikiai.tistory.com/29 마우스 코드 참조: https://www.arduino.cc/reference/ko/language/functions/usb/mouse/mousemov..

jinho-study.tistory.com

728x90
반응형

'Projects > 에어 마우스' 카테고리의 다른 글

아두이노 에어 마우스로 총게임 하기  (6) 2020.06.20
아두이노 조이스틱 마우스  (0) 2020.06.19

+ Recent posts