산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

아두이노 프로 미니로 적외선 안구 운동 추적 - LED 제어 데모

부품 및 소모품

부품 수량 비고
스파크펀 아두이노 프로 미니 328 - 5V/16MHz 1
아다프루트 리튬이온/리튬폴리머 백팩 애드온 (프로 트링킷/이치비츠이용) 1
네오픽셀 스트립 1
QTR-1A 반사율 센서 1
3.7V 리포 배터리 1

앱 및 온라인 서비스

프로젝트 소개

적외선 센서로 안구 운동을 감지해 LED를 제어합니다.

네오픽셀 LED 안구

네오픽셀 LED 테이프를 사용했습니다. LED는 68개입니다.

아두이노 프로 미니로 적외선 안구 운동 추적 - LED 제어 데모

LED는 양면 테이프로 볼에 고정하고 다음과 같은 순서로 배선했습니다.

아두이노 프로 미니로 적외선 안구 운동 추적 - LED 제어 데모

안구 운동 추적

회로도

아두이노 프로 미니로 적외선 안구 운동 추적 - LED 제어 데모

센서

눈 추적용으로 QTR-1A 센서 두 개를 사용했습니다. 두 센서는 눈 너비 정도의 간격으로 플라스틱 시트에 배치했습니다.

아두이노 프로 미니로 적외선 안구 운동 추적 - LED 제어 데모

센서 부분과 마이크로컨트롤러 부분은 각각 클립으로 안경에 고정했습니다.

아두이노 프로 미니로 적외선 안구 운동 추적 - LED 제어 데모
아두이노 프로 미니로 적외선 안구 운동 추적 - LED 제어 데모

아두이노 코드

홍채가 한 센서에 가까워지면 반사광이 감소하고 센서 값이 증가합니다. 반대로 홍채가 멀어지면 반사광이 증가하고 센서 값이 감소합니다.

LED 안구의 동공 좌우 움직임은 한 센서 값의 증감을 감지해 제어합니다.

깜빡일 때는 두 센서 값이 동시에 감소하므로, 두 센서 값이 동시에 감소하면 LED 안구의 눈꺼풀이 내려옵니다.

#include <QTRSensors.h>
#include <Adafruit_NeoPixel.h>

#define NUM_SENSORS 2
#define NUM_SAMPLES_PER_SENSOR 10
#define EMITTER_PIN QTR_NO_EMITTER_PIN

int iniSensorValL, sensorValL;
int iniSensorValR, sensorValR;

#define PIN A3
Adafruit_NeoPixel led = Adafruit_NeoPixel(68, PIN, NEO_GRB + NEO_KHZ800);

int blackNum = 24;
int pupilNum = 12;
uint32_t color;
int brightness = 40;
byte eyeColor;
int LR = 7;
boolean lid = false;
int cnt = 0;

// 검은 눈동자 좌우 애니메이션
int blackLED[15][24] = {
  {12,32,35,55,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
  {12,13,31,36,54,55,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
  {11,13,14,30,37,53,54,56,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
  {10,11,14,15,29,38,52,53,56,57,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
  { 9,10,11,12,15,16,28,33,34,39,51,52,55,56,57,58,68,68,68,68,68,68,68,68},
  { 0, 8, 9,10,11,12,13,16,17,27,32,35,40,50,51,54,55,56,57,58,59,67,68,68},
  { 0, 1, 7, 8, 9,10,13,14,17,18,26,31,36,41,49,50,53,54,57,58,59,60,66,67},
  { 1, 2, 6, 7, 8, 9,14,15,18,19,25,30,37,42,48,49,52,53,58,59,60,61,65,66},
  { 2, 3, 5, 6, 7, 8,15,16,19,20,24,29,38,43,47,48,51,52,59,60,61,62,64,65},
  { 3, 4, 5, 6, 7,16,17,20,21,23,28,39,44,46,47,50,51,60,61,62,63,64,68,68},
  { 4, 5, 6,17,18,21,22,27,40,45,46,49,50,61,62,63,68,68,68,68,68,68,68,68},
  { 4, 5,18,19,26,41,48,49,62,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
  { 4,19,20,25,42,47,48,63,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
  {20,21,24,43,46,47,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68},
  {21,23,44,46,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68}
};

// 동공 좌우 애니메이션
int pupilLED[15][12] = {
  {33,34,68,68,68,68,68,68,68,68,68,68},
  {32,33,34,35,68,68,68,68,68,68,68,68},
  {12,31,32,33,34,35,36,55,68,68,68,68},
  {12,13,30,31,32,33,34,35,36,37,54,55},
  {13,14,29,30,31,32,35,36,37,38,53,54},
  {14,15,28,29,30,31,36,37,38,39,52,53},
  {15,16,27,28,29,30,37,38,39,40,51,52},
  {16,17,26,27,28,29,38,39,40,41,50,51},
  {17,18,25,26,27,28,39,40,41,42,49,50},
  {18,19,24,25,26,27,40,41,42,43,48,49},
  {19,20,23,24,25,26,41,42,43,44,47,48},
  {20,21,22,23,24,25,42,43,44,45,46,47},
  {21,22,23,24,43,44,45,46,68,68,68,68},
  {22,23,44,45,68,68,68,68,68,68,68,68},
  {22,45,68,68,68,68,68,68,68,68,68,68}
};

// 깜빡임 애니메이션
int eyelid = 0;
int eyelidNum[8] = {0,4,8,16,24,34,44,56};
int eyelidLED[56] = {64,65,66,67,58,59,60,61,56,57,62,63,49,50,51,52,47,48,53,54,38,39,40,41,46,55,36,37,42,43,26,27,28,29,35,44,24,25,30,31,15,16,17,18,34,45,23,32,13,14,19,20,6,7,8,9};

QTRSensorsAnalog qtra((unsigned char[]) {0, 1}, NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS];

void blink(int eyelid, int LR) {
  if (eyelid != 8) {
    // 회색 배경
    for(uint16_t i=0; i<led.numPixels(); i++) {
      led.setPixelColor(i, led.Color(66, 66, 66));
    }
    // 검은 눈동자
    for(uint16_t i=0; i<blackNum; i++) {
      led.setPixelColor(blackLED[LR][i], color);
    }
    // 동공
    for(uint16_t i=0; i<pupilNum; i++) {
      led.setPixelColor(pupilLED[LR][i], led.Color(0, 0, 66));
    }
    // 눈꺼풀
    for(int i=0; i < eyelidNum[eyelid]; i++) {
      led.setPixelColor(eyelidLED[i], 0);
    }
  } else if (eyelid == 8) {
    led.clear();
  }
  led.show();
}

void setup() {
  Serial.begin(115200);
  led.begin();
  led.setBrightness(brightness);
  led.show();
  color = led.Color(0, 177, 55); // 동공 색상
  delay(100);
  qtra.read(sensorValues);
  iniSensorValL = sensorValues[0];
  iniSensorValR = sensorValues[1];
  blink(eyelid, LR);
}

void loop() {
  qtra.read(sensorValues);
  sensorValL = sensorValues[0];
  sensorValR = sensorValues[1];
  
  double rasioL = (double)sensorValL / iniSensorValL;
  double rasioR = (double)sensorValR / iniSensorValR;
  
  Serial.print(rasioL);
  Serial.print(" ");
  Serial.println(rasioR);
  
  if(rasioL > 0.985 && rasioR < 0.985) { // 오른쪽
    for(int i = LR; i < 12; i++) {
      blink(0, i);
      delay(40);
      LR = i;
    }
  } else if(rasioL < 0.985 && rasioR > 0.985) { // 왼쪽
    for(int i=LR; i>2; i--) {
      blink(0, i);
      delay(40);
      LR = i;
    }
  } else if(lid == false && rasioL < 0.96 && rasioR < 0.96) { // 깜빡임 감기
    for(int i = 1; i < 9; i++) {
      blink(i, LR);
      delay(40);
      lid = true;
    }
  } else if(lid == true && rasioL > 0.96 && rasioR > 0.96) { // 깜빡임 뜨기
    for(int i = 8; i > 0; i--) {
      blink(i, LR);
      delay(40);
      lid = false;
    }
  } else if(lid == false && rasioL > 0.96 && rasioR > 0.96) { // 정상
    if(LR <= 7) {
      for(int i=LR; i<=7; i++) {
        blink(0, i);
        delay(40);
        LR = i;
      }
    } else {
      for(int i=LR; i>=7; i--) {
        blink(0, i);
        delay(40);
        LR = i;
      }
    }
    Serial.println("정상");
  }
  
  // 초기값 갱신
  if (cnt > 10) {
    iniSensorValL = sensorValL;
    iniSensorValR = sensorValR;
    cnt = 0;
  }
}

작동

착용자의 안구 움직임에 따라 LED 안구의 동공이 좌우로 움직이고, 깜빡임 시 눈꺼풀이 닫히는 것을 확인할 수 있습니다.

제조공정

  1. 제품 디자인에서 천연 소재로 회귀하는 디자이너들
  2. 펄스 광 센서: LED 빛 펄스를 가청 소리로 증폭
  3. 라즈베리 파이와 TMP006 적외선 온도 센서: 파이썬 라이브러리 및 설정 가이드
  4. 라즈베리 파이와 파이썬으로 원격 온도 센서 만들기 – 단계별 가이드
  5. 라즈베리 파이와 KY-033 라인 트래킹 센서로 문 열림/선 감지하기
  6. 라즈베리 파이 Home Assistant로 안전한 홈 모니터링: 모션, 알람, 비디오 캡처
  7. 라즈베리 파이용 DIY 적외선 모션 센서 만들기 – 단계별 가이드
  8. 라즈베리 파이에서 PIR 모션 센서로 LED 제어하기
  9. 리프 모션 제어 레이저 탱크 만들기 – 아두이노, 라즈베리 파이, RGB LED
  10. 색상 민감 공정을 위한 정밀 적외선 온도 센싱