728x90
반응형

처음으로 본격적으로 사람들과 무엇을 만들지 고민하고 만들어본 경험이었던 것 같다.

비슷한 경험이 이미 있긴 했지만 이때가 스케일이 훨씬 컸던 것 같다.

팀 구성부터 시작해서 작품 계획, 구현, 마지막 부스 발표까지 많은 깨달음이 있었던 것 같다.

단순히 작품을 만드는 것보다 무엇을 왜 만드는지, 어떻게 만들지 와 같은 계획이 훨씬 더 중요하다는 것을 알았다...

그리고 부스 발표는 상당히 좋은 경험이었던 것 같다.

교수님들이 단체로 지나가시는 것을 보고 처음에는 상당히 겁이 났었는데,

처음만 그랬고 그 후에는 발표하는 게 재미있었다. 

이번 연도도 나가고 싶었지만 전체적으로 그럴 상황이 나오지 않아서 못 나갔다.

졸업하기 전에 더 큰 상을 받아 보고 싶었는데, 조금 아쉽다ㅜ  

판넬
동상
동상

 

728x90
반응형
728x90
반응형

에어 마우스: https://jinho-study.tistory.com/247

 

아두이노 에어 마우스(자이로센서)

2019년 창의적 종합설계 경진대회 때 만들었던 에어 마우스이다. 하루면 만들 수 있는 작품인데, 알 수 없는 통신에러 때문에 몇 주일을 날렸었다. 알고 보니 핀 문제였는데 각 핀마다 어느 정도 �

jinho-study.tistory.com

에어 마우스에서 필요 없는 기능만(민감도 조절) 빼면 바로 완성이다. 

그렇기 때문에 새로운 코드는 없다.

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

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

#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;

void setup()
{
  // 설정인데 안 건드는게 좋음. 잘 되있음.
  Serial.begin(9600);

  Serial.println("start");
  Serial.print(MPU6050_INT); Serial.print(" on pin "); Serial.print(MPU6050_INT_PIN);
  
  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(10, INPUT); // 좌클릭 버튼
  pinMode(11, INPUT); // 우클릭 버튼
  Mouse.begin();
  pinMode(MPU6050_INT, INPUT);
  //attachInterrupt(MPU6050_INT, dmpDataReady, RISdlfhgk62ING);
}

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)
  // 여기 위까지는 코드 건들지 않는 걸 추천. 여기 아래부터 수정 ㄱㄱ

  int lb = digitalRead(10); // 1이면 누른 상태, 0이면 안 누른 상태임.
  int rb = digitalRead(11); // 위와 마찬가지
  
  float gyroY, gyroZ;
  int sens = 1100;
  gyroZ = GyZ / sens;
  gyroY = -GyY / sens;

if(lb == 1) // Left button이 1이라는건 좌클릭을 하고 있다는 상태이므로 
  {                                       // 마우스를 누른 상태로 유지시켜주는 Mouse.press()를 사용함.
    Mouse.press(); // 좌클릭 한 상태 유지
  }
  if (rb == 1) // 우클릭
  {
    Mouse.press(MOUSE_RIGHT);
  } 
  if (lb == 0) 
  {
    Mouse.release(); //클릭 상태 해제
  }
   if (rb == 0) 
  {
    Mouse.release(MOUSE_RIGHT); //클릭 상태 해제
  }

  Sprint1(gyroY, gyroZ, lb, rb);
  Mouse.move(gyroZ, gyroY); // 마우스를 움직이는 함수
}

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(lb);
  Serial.print(" // 우 클릭: ");
  Serial.println(rb);
}

필요한 재료는 다이소에서 파는 2000원? 짜리 장난감 총, 인두기, 접착제 정도이다. 

1. 장난감 총을 완전히 분해한다.

2. 방아쇠 부분과 손잡이 옆쪽 부분을 인두기로 뚫고 그 구멍 사이에 각각 버튼이 삐죽 튀어나도록 붙인다.

3. 손잡이 아래부분에 구멍을 뚫고, 점퍼선들을 잘 정리해서 그 구멍에서 빼냄.

4. 다시 조립하면 완성!

탕탕탕
728x90
반응형

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

아두이노 에어 마우스(자이로센서)  (0) 2020.06.20
아두이노 조이스틱 마우스  (0) 2020.06.19
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
728x90
반응형

에어 마우스를 만들기 전에 만들었던 조이스틱 마우스이다.  

/* 버튼 코드 참조: https://kikiai.tistory.com/29
   마우스 코드 참조: https://www.arduino.cc/reference/ko/language/functions/usb/mouse/mousemove/
   위의 링크에 마우스 관련 함수 다 설명되있음. 
   조이스틱 코드 참조: http://blog.naver.com/PostView.nhn?blogId=boilmint7&logNo=220927175653
   조이스틱에도 버튼이 있지만 사용하기 힘들어서 안썼음.

   버튼: 핀 4개 있는데 2개 버리고 2개중 하나에 +5V, 하나는 그라운드랑 Pin2에 박으면 됨.
   
   조이스틱: 그라운드랑 +5V는 말 그대로 그라운드랑 +5V에 연결 
   VRX, VRY 는 각각 A0, A1에 연결함. 나는 조이스틱핀이 아래를 보는 방향으로 구현해서 x, y축이 바뀜.
   그래서 아래 코드 보면 A0, A1 순서가 다름. 
*/


#include <Mouse.h> // 마우스 헤더(레오나르도가 아니면 라이브러리 깔아도 오류 뜸!, 무조건 레오나르도로 ㄱㄱ)

void setup() {
  pinMode(2, INPUT); // 좌클릭 버튼
  pinMode(4, INPUT); // 우클릭 버튼
  Mouse.begin(); // 마우스 제어 시작
  Serial.begin(9600); //시리얼 통신을 시작
}

void loop() {/* 다 다르겠지만 나는 조이스틱 초기 값이 x: 517, y: 506 정도였음. 이게 의미하는건 
                중심 좌표가 (512, 512) 쯤이라는건데, 사용하기 불편하므로 중심을 (0, 0)로 만들었다. 
                200을 나눈건 마우스가 너무 큰 범위로 움직이게 되기 때문에 크기를 줄여줬다.*/
  int x = (analogRead(A1) - 517) / 260; /* 나누는 값은 맘대로 바꿔도 된다. 다만 500이 넘어가면 마우스가 움직이지 않게 된다.
                                         왜냐하면 (analogRead(A1) - 517)의 최대값이 500정도 되는데, 거기에 500을 나눠버리면 0이 되기 때문*/
  int y = - (analogRead(A0) - 506) / 260; /* 조이스틱을 위로 올리면 같이 +가 되야 되는데,
                                             -가 되길래 그냥 -곱해줬다.*/
  int Left_button = digitalRead(2); // 1이면 누른 상태, 0이면 안 누른 상태임.
  int Right_button = digitalRead(4); // 위와 마찬가지
  Sprint(x, y, Left_button, Right_button); // 시리얼 프린트
  
  if (Left_button == 1) // Left button이 1이라는건 좌클릭을 하고 있다는 상태이므로 마우스를 누른 상태로 유지시켜주는 Mouse.press()를 사용함
  {
    Mouse.press(MOUSE_LEFT); // 좌클릭 한 상태 유지
  }
  else if (Left_button == 0 && Right_button == 0) 
  {
    Mouse.release(); //클릭 상태 해제
  }
  else if (Right_button == 1) // 우클릭
  {
    Mouse.click(MOUSE_RIGHT);
  } 
  Mouse.move(x, y); // 마우스를 움직이는 함수
}

// 루프안에 여러줄 있는거 꼴보기 싫어서 함수로 만듬. 별 의미 없음.
void Sprint(int x, int y, int lb, int rb) 
{
  Serial.print("X: ");
  Serial.print(x);
  Serial.print(' ');
  Serial.print("Y: ");
  Serial.print(-y); // 시리얼프린트에 -로 출력되길래 부호 바꿔줌.
  Serial.print(' ');
  Serial.print("Left_button: ");
  Serial.print(lb);
  Serial.print(' ');
  Serial.print("Rigft_button: ");
  Serial.println(rb);
}

 

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

아두이노 우노로는 마우스를 제어할 수가 없다. 무조건 레오나르도여야 한다.

github: https://github.com/kimjinho1/Air_Mouse/blob/master/Joystick_Mouse.ino

 

kimjinho1/Air_Mouse

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

github.com

728x90
반응형
728x90
반응형

아두이노 LED 색깔 조절하기: https://jinho-study.tistory.com/241

 

아두이노 LED 색깔 조절하기(NeoPixel)

NeoPixel을 사용해서 빨간색, 초록색, 파란색, 노란색, 흰색을 켜보았다. (아두이노 extension board와 NeoPixel이 필요하고, Adafruit_NeoPixel 라이브러리를 설치해야 한다) #include //..

jinho-study.tistory.com

저번에는 NeoPixel로 빨강, 초록, 파랑, 노랑, 흰색을 켰었는데 똑같은 코드를 5번이나 넣는 식으로 구현을 했었다.

개인적으로 이런 코드는 비효율적이라고 생각하기에, 배열을 사용해서 코드를 짧게 구현해 보려고 한다.

그리고 버튼을 누르고 있어야 NeoPixel이 켜지는 기능과 색을 조금 더 추가하려고 한다.

우선 단순하게 코드를 짜면 아래와 같다. 

#include <Adafruit_NeoPixel.h>
#define LED 11 // LED Pin
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(1, LED, NEO_GRB + NEO_KHZ800);

const int SW = 10; // Button Pin
int led = 0; // LED의 상태를 저장해주는 변수

void setup() {
  pixels.begin();
  pixels.show();
  pinMode(SW, INPUT);
}

void loop() {  
  // 버튼을 누르고 있을 때 Led를 켬
  if (digitalRead(SW) == LOW) {
    if (led == 0) {
      pixels.setPixelColor(0, 100, 0, 0); // 빨강
      pixels.show(); 
      delay(1000);
    }    
    if (led == 1) {
      pixels.setPixelColor(0, 0, 100, 0); // 파랑
      pixels.show(); 
      delay(1000);
    }
    if (led == 2) {
      pixels.setPixelColor(0, 0, 0, 100); // 초록
      pixels.show(); 
      delay(50);
    }
    if (led == 3) {
      pixels.setPixelColor(0, 100, 100, 0); // 노랑
      pixels.show(); 
      delay(1000);
    }
    if (led == 4) {
      pixels.setPixelColor(0, 100, 0, 100); //  보라
      pixels.show(); 
      delay(1000);
    }
    if (led == 5) {
      pixels.setPixelColor(0, 0, 100, 100); // 하늘
      pixels.show(); 
      delay(1000);
    }
    if (led == 6) {
      pixels.setPixelColor(0, 100, 100, 100); // 하양
      pixels.show(); 
      delay(1000);
      led = -1;
    }
    led += 1;
  }
  // 버튼을 누르지 않았을 때는 정전 상태
  else {
    pixels.setPixelColor(0, 0, 0, 0);
    pixels.show();     
  }
}

버튼을 누르고 있을 때는 LED가 켜지면서 색깔이 계속 바뀌고, 누르지 않았을 때는 정전 상태이다.

구현이 되긴 했지만 코드가 쓸데없이 길다. 1차원 배열과 %(나머지 연산)을 사용하면 아래와 같이 짧게 구현할 수 있다.

#include <Adafruit_NeoPixel.h>
#define LED 11 // LED Pin
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(1, LED, NEO_GRB + NEO_KHZ800);

const int SW = 10; // Button Pin
int led = 0; // LED의 상태를 저장해주는 변수

int R[7] = {100, 0, 0, 100, 100, 0, 100}; // 빨간색 
int G[7] = {0, 100, 0, 100, 0, 100, 100}; // 초록색
int B[7] = {0, 0, 100, 0, 100, 100, 100}; // 파란색

void setup() {
  pixels.begin();
  pixels.show();
  pinMode(SW, INPUT);
}

void loop() {  
  // 버튼을 누르고 있을 때 Led를 켬
  if (digitalRead(SW) == LOW) {
    // 배열을 사용함으로써 코드를 엄청 짧게 만들수 있음
    pixels.setPixelColor(0, R[led%7], G[led%7], B[led%7]); 
    pixels.show(); 
    delay(1000); // 1초 주기
    led += 1;
  }
  // 버튼을 누르지 않았을 때는 정전 상태
  pixels.setPixelColor(0, 0, 0, 0); 
  pixels.show();     
}

위에 코드를 보면 R, G, B 3개의 배열에 빨강, 초록, 파랑, 노랑, 보라, 하늘, 하양의 RGB 값들이 순서대로 저장되어 있다.

(100, 0, 0) 같은 방식으로 여러 번 반복할 필요 없기 때문에 훨씬 코드가 짧아지게 된다. 

R[led%7], G[...], B[...]의 의미 -> 지금 led 변수는 led의 색깔(순서)을 가리키는데 예를 들면

led = 3 -> R[3%7] = R[3] = 100, 

led = 10 -> R[10%7] = R[3] = 100과 같은 방식이다.

%(나머지 연산)을 사용하지 않는다면 중간에 아래와 같이 조건문을 추가해야 되는데 위의 방법보다는 좋지 않은 방법 같다.

if (led == 6) { 
  led = -1; 
}

마지막으로 2차원 배열을 사용해보자.

#include <Adafruit_NeoPixel.h>
#define LED 11 // LED Pin
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(1, LED, NEO_GRB + NEO_KHZ800);

const int SW = 10; // Button Pin
int led = 0; // LED의 상태를 저장해주는 변수

// RGB 값이 저장되어 있는 2차원 배열(빨강, 파랑, 초록, 노랑, 보라, 하늘, 하양)
int RGB[7][3] = {{100,0,0}, {0,100,0}, {0,0,100}, {100,100,0}, {100,0,100}, {0,100,100}, {100,100,100}};

void setup() {
  pixels.begin();
  pixels.show();
  pinMode(SW, INPUT);
}

void loop() {  
  // 버튼을 누르고 있을 때 Led를 켬
  if (digitalRead(SW) == LOW) {
    // 배열을 사용함으로써 코드를 엄청 짧게 만들수 있음
    pixels.setPixelColor(0, RGB[led%7][0], RGB[led%7][1], RGB[led%7][2]); 
    pixels.show(); 
    delay(1000); // 1초 주기
    led += 1;
  }
  // 버튼을 누르지 않았을 때는 정전 상태
  pixels.setPixelColor(0, 0, 0, 0); 
  pixels.show();     
}

맨 위에 있는 한눈에 다 안 보이던 코드가 이제는 한눈에 다 보인다.

RGB[7][3]은 7행 3열인 행렬이라고 생각하면 될 것 같다.

첫 번째 행에는 빨간색의 RGB 값, 두 번째 행에는 초록색의 RGB 값이 들어있는 식이다. 

아래와 같이 잘 작동된다.

쉬운 예제더라도 다양한 방식으로 코드를 짜보는 게 처음 공부할 때는 도움이 되는 것 같다.

남이 짠 코드를 사용하더라도 그걸 그냥 사용하기만 하는 게 아니라, 자신의 것으로 만들고 사용하도록 하자. 그렇지 않으면 남는 게 정말 하나도 없다.  

728x90
반응형
728x90
반응형

저번엔 NeoPixel 가지고 빨강, 초록, 파랑, 노랑색을 켜보았다.

이번엔 빨강 Blink, 초록 Fade in, 파랑 Fade out을 구현해보았다.

#include <Adafruit_NeoPixel.h>

int led = 11; // 11번 Pin을 +로 사용

Adafruit_NeoPixel pixels(1, led, NEO_GRB + NEO_KHZ800);

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

void loop() {
  // 빨간색 Blink(2초)
  for(int i = 0; i <= 20; i += 1)  {
    pixels.setPixelColor(0, 250, 0, 0);
    pixels.show(); 
    delay(50);  
    pixels.setPixelColor(0, 0, 0, 0);
    pixels.show(); 
    delay(50);  
  }  
  // 초록색 Fade in(2초)
  for(int brightness = 0; brightness <= 250; brightness += 5) {
    pixels.setPixelColor(0, 0, brightness, 0);
    pixels.show(); 
    delay(40);  
  }
  // 파란색 Fade out(2초)
  for(int brightness = 250; brightness >= 0; brightness -= 5) {  
    pixels.setPixelColor(0, 0, 0, brightness);
    pixels.show(); 
    delay(40);  
  }
}

빨강색 blink는 2초동안 총 20번 껐다 켜지도록 했다.

2초 동안 초록색이 천천히 켜지고, 2초 동안 파란색이 천천히 꺼진다. 

 

잘 됨

 

728x90
반응형
728x90
반응형

NeoPixel을 사용해서 빨간색, 초록색, 파란색, 노란색, 흰색을 켜보았다.

(아두이노 extension board와 NeoPixel이 필요하고, Adafruit_NeoPixel 라이브러리를 설치해야 한다)

#include <Adafruit_NeoPixel.h> // 사용하기 전 라이브러리 설치 필수

int led = 11; // 11번 Pin을 +로 사용           

// 첫 번째 led 사용, 11번 pin 사용
Adafruit_NeoPixel pixels(1, led, NEO_GRB + NEO_KHZ800); 

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

void loop() {
  pixels.setPixelColor(0, 255, 0, 0);     // 빨간색
  pixels.show(); 
  delay(1000);                            // 1초간 딜레이
  pixels.setPixelColor(0, 0, 255, 0);     // 초록색
  pixels.show(); 
  delay(1000);                            // 1초간 딜레이
  pixels.setPixelColor(0, 0, 0, 255);     // 파란색
  pixels.show(); 
  delay(1000);                            // 1초간 딜레이
  pixels.setPixelColor(0, 255, 255, 0);   // 노란색
  pixels.show(); 
  delay(1000);                            // 1초간 딜레이
  pixels.setPixelColor(0, 255, 255, 255); // 흰색
  pixels.show(); 
  delay(1000);                            // 1초간 딜레이
}

 

회로는 아래와 같이 생겼다.

회로도

실행시키면 색이 예쁘게 잘 나오는 것을 확인할 수 있다.

그냥 보면 눈이 아픈 수준이라 밝기를 255에서 100으로 줄여야 될 것 같다. 

github: https://github.com/kimjinho1/Arduino

 

kimjinho1/Arduino

Contribute to kimjinho1/Arduino development by creating an account on GitHub.

github.com

728x90
반응형
728x90
반응형

이번엔 LED 2개를 동시에 blink 해봤다. 

LED1은 1초 주기로 깜빡이고, LED2는 2초 주기로 깜빡이도록 구현해봤다. 

int LED1 = 11; // 11번 Pin을 +로 사용
int LED2 = 10; // 10번 Pin을 +로 사용

void setup() {
  // LED는 입력을 받는게 아니라 그저 출력할 뿐이므로 OUTPUT으로 설정
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT); 
}

void loop() {
  digitalWrite(LED1, HIGH); // LED1 킴
  digitalWrite(LED2, HIGH); // LED2 킴
  delay(1000);             // 1초간 딜레이
  digitalWrite(LED1, LOW);  // LED1 끔
  delay(1000);             // 1초간 딜레이
  digitalWrite(LED1, HIGH); // LED1 킴
  digitalWrite(LED2, LOW);  // LED2 끔
  delay(1000);             // 1초간 딜레이
  digitalWrite(LED1, LOW); // LED1 킴
  delay(1000);             // 1초간 딜레이
}

 

회로는 아래와 같은 느낌이다.

회로도

github: https://github.com/kimjinho1/Arduino

 

kimjinho1/Arduino

Contribute to kimjinho1/Arduino development by creating an account on GitHub.

github.com

728x90
반응형
728x90
반응형

LED가 1초 동안 켜지고 1초 동안 꺼지도록 구현해보았다(blink).

int LED = 11; // 11번 Pin을 +로 사용

void setup() {
  // LED는 입력을 받는게 아니라 그저 출력할 뿐이므로 OUTPUT으로 설정
  pinMode(LED, OUTPUT); 
}

void loop() {
  digitalWrite(LED, HIGH); // LED를 킴
  delay(1000);             // 1초간 딜레이
  digitalWrite(LED, LOW);  // LED를 끔
  delay(1000);             // 1초간 딜레이
}

 

회로는 아래와 같은 느낌이다. 

저항이 꼭 필요한 것은 아니라서, 저항 빼버리고 11번 Pin 선을 LED에 직접 박아도 잘 실행된다. 

회로도

github: https://github.com/kimjinho1/Arduino

 

kimjinho1/Arduino

Contribute to kimjinho1/Arduino development by creating an account on GitHub.

github.com

728x90
반응형

+ Recent posts