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

초음파 눈: 8x8 LED 매트릭스 거리 센서 인터랙티브 아트

부품 및 소모품

부품 수량 비고
초음파 센서 HC-SR04 2 좌/우 눈 거리 측정용
아두이노 나노 R3 1 소형, USB 전원/프로그래밍, 충분한 GPIO
포토 레지스터 (LDR) 1 주변 밝기 감지 → LED 밝기 자동 조절
MAX7219 8x8 LED 매트릭스 모듈 2 데이지 체인 연결 가능 (SPI)
하프 사이즈 브레드보드 1 납땜 없이 프로토타이핑
점퍼 와이어 다수 빨강/검정은 전원/그라운드용 권장
저항 330 옴 1 LDR 분압용

앱 및 온라인 서비스

프로젝트 소개

초음파 센서와 8x8 LED 매트릭스로 움직이는 "눈"을 만들었습니다. 거실이나 사무실 책상에 두면 지나가는 사람을 따라 눈을 움직이고, 깜빡이기도 하며, 주변 밝기에 따라 LED 밝기가 자동 조절됩니다. 재미있고 약간 으스스한 인터랙티브 아트 작품입니다.

필요한 것들

중요: 제공 코드는 하드웨어 SPI 사용 (SCK=D13, MOSI=D11). 나노 외 보드 사용 시 해당 보드의 하드웨어 SPI 핀 확인 필수!

배선 가이드

전원 및 그라운드

  1. 나노 GND → 브레드보드 GND 레일 (검정)
  2. 나노 3.3V (또는 5V) → 브레드보드 VCC 레일 (빨강)
  3. 양쪽 레일 간 GND-GND, VCC-VCC 점퍼로 연결
  4. ※ 일부 매트릭스 모듈은 5V 필요할 수 있음. 불안정하면 5V 핀 사용

초음파 센서 2개

8x8 LED 매트릭스 2개 (데이지 체인)

LDR 밝기 센서

초음파 눈: 8x8 LED 매트릭스 거리 센서 인터랙티브 아트

코드 업로드 및 테스트

  1. USB 연결 후 아두이노 IDE에서 UltrasonicEyes 스케치 업로드
  2. 센서 앞을 지나가거나 손 흔들며 눈 움직임 확인

영구 제작 및 3D 케이스

전체 소스 코드

#include   // LED 매트릭스 제어 라이브러리 (라이브러리 매니저에서 설치)
#include       // 초음파 센서 라이브러리 (라이브러리 매니저에서 설치)

// LED 매트릭스 핀 (하드웨어 SPI 사용)
// #define CLK_PIN 13  // 하드웨어 SPI SCK - 나노에서 D13
// #define DATA_PIN 11 // 하드웨어 SPI MOSI - 나노에서 D11
#define CS_PIN 10        // Chip Select
#define MAX_DEVICES 2    // 2개 매트릭스 (양쪽 눈)
#define LIGHT A5         // LDR 아날로그 핀

MD_MAX72XX mx = MD_MAX72XX(CS_PIN, MAX_DEVICES);

// 초음파 센서 핀
#define t1 2  // 왼쪽 눈 TRIG
#define e1 3  // 왼쪽 눈 ECHO
#define t2 4  // 오른쪽 눈 TRIG
#define e2 5  // 오른쪽 눈 ECHO
#define maxDist 400 // 최대 감지 거리 (cm)

NewPing eyeR(t2, e2, maxDist); // 오른쪽 눈
NewPing eyeL(t1, e1, maxDist); // 왼쪽 눈

// 눈 상태: 0=정면, 1=오른쪽, 2=왼쪽
int currentState = -1;
long duration1, duration2;
int distance1, distance2;
float nextBlink = 0;
float lightAmount = 0;

// 눈 패턴 비트맵 (8x8, 열 단위)
uint8_t eye_forward[8] = {
  0b00111100, 0b01000010, 0b01011010, 0b10101101,
  0b10111101, 0b10011001, 0b01000010, 0b00111100
};
uint8_t eye_right[8] = {
  0b00111100, 0b01000010, 0b01110010, 0b11011001,
  0b11111001, 0b10110001, 0b01000010, 0b00111100
};
uint8_t eye_left[8] = {
  0b00111100, 0b01000010, 0b01001110, 0b10010111,
  0b10011111, 0b10001101, 0b01000010, 0b00111100
};
uint8_t eye_blink[8] = {
  0b00000000, 0b00111100, 0b01111110, 0b11111111,
  0b10111101, 0b11000011, 0b01111110, 0b00111100
};

void setup() {
  mx.begin();
  pinMode(t1, OUTPUT); pinMode(e1, INPUT);
  pinMode(t2, OUTPUT); pinMode(e2, INPUT);
  digitalWrite(t1, LOW); digitalWrite(t2, LOW);
  pinMode(LIGHT, INPUT);
  ShowEye_Forward();
  currentState = 0;
  nextBlink = millis() + 1000;
}

void loop() {
  // 주변 밝기 읽기 (0-1023 → 0-MAX_INTENSITY 매핑)
  lightAmount = analogRead(LIGHT);
  lightAmount = (lightAmount / 255.0) * MAX_INTENSITY;
  mx.control(MD_MAX72XX::INTENSITY, lightAmount);

  // 왼쪽 눈 핑 (중앙값 필터 5회)
  distance1 = eyeL.ping_median(5);
  delay(500); // 간섭 방지 대기
  // 오른쪽 눈 핑
  distance2 = eyeR.ping_median(5);

  // 랜덤 깜빡임 체크
  if (nextBlink < millis()) {
    nextBlink = millis() + random(2000, 10000); // 2-10초 후 다음 깜빡임
    // 1-13 중 6 이하면 더블 깜빡임
    if (random(1, 13) <= 6) ShowEye_Blink_Dbl();
    else ShowEye_Blink();
    delay(250);
    return; // 이번 루프 종료
  }

  // 두 눈 거리 차이로 시선 방향 결정
  float diff = distance2 - distance1;
  if (abs(diff) < 250 || (distance1 == 0 && distance2 == 0)) {
    // 차이가 250cm 미만이거나 둘 다 감지 안 됨 → 정면
    ShowEye_Forward(); currentState = 0;
  } else if (distance2 < distance1 && distance1 > 0) {
    // 오른쪽 눈이 더 가까움 → 오른쪽 응시
    ShowEye_Right(); currentState = 1;
  } else if (distance1 < distance2 && distance2 > 0) {
    // 왼쪽 눈이 더 가까움 → 왼쪽 응시
    ShowEye_Left(); currentState = 2;
  }
  delay(250);
}

// 눈 패턴 표시 함수들
void ShowEye_Right() {
  mx.clear();
  mx.control(MD_MAX72XX::INTENSITY, lightAmount);
  for (uint8_t row = 0; row < 8; row++) {
    mx.setColumn(row, eye_right[row]);       // 왼쪽 눈 (디바이스 0)
    mx.setColumn(row + 8, eye_right[row]);   // 오른쪽 눈 (디바이스 1)
  }
}

void ShowEye_Left() {
  mx.clear();
  mx.control(MD_MAX72XX::INTENSITY, lightAmount);
  for (uint8_t row = 0; row < 8; row++) {
    mx.setColumn(row, eye_left[row]);
    mx.setColumn(row + 8, eye_left[row]);
  }
}

void ShowEye_Forward() {
  mx.clear();
  mx.control(MD_MAX72XX::INTENSITY, lightAmount);
  for (uint8_t row = 0; row < 8; row++) {
    mx.setColumn(row, eye_forward[row]);
    mx.setColumn(row + 8, eye_forward[row]);
  }
}

void ShowEye_Blink() {
  mx.clear();
  mx.control(MD_MAX72XX::INTENSITY, lightAmount);
  for (uint8_t row = 0; row < 8; row++) {
    mx.setColumn(row, eye_blink[row]);
    mx.setColumn(row + 8, eye_blink[row]);
  }
  delay(150); // 깜빡임 유지
  // 이전 상태로 복구
  if (currentState == 0) ShowEye_Forward();
  else if (currentState == 1) ShowEye_Right();
  else if (currentState == 2) ShowEye_Left();
}

void ShowEye_Blink_Dbl() {
  mx.clear();
  mx.control(MD_MAX72XX::INTENSITY, lightAmount);
  for (uint8_t row = 0; row < 8; row++) {
    mx.setColumn(row, eye_blink[row]);
    mx.setColumn(row + 8, eye_blink[row]);
  }
  delay(75);
  // 잠깐 이전 상태 표시
  if (currentState == 0) ShowEye_Forward();
  else if (currentState == 1) ShowEye_Right();
  else if (currentState == 2) ShowEye_Left();
  delay(75);
  // 다시 깜빡임
  ShowEye_Blink();
}

3D 프린트 케이스

어떤 3D 프린터로도 출력 가능, 특별 설정 불필요. 프로젝트 페이지에서 STL 파일 다운로드.

회로도

초음파 눈: 8x8 LED 매트릭스 거리 센서 인터랙티브 아트

Fritzing 파일: ultrasoniceyes_final_Th84xpUyB2.fzz

제조공정

  1. 아두이노 우노 & MAX7219로 만드는 UFO 어택 게임 – 직접 만드는 레트로 아케이드
  2. 스마트 블라인드: 아두이노와 태양광으로 자동 조명 제어
  3. 3D RGB 아두클락(Arduclock) - 블루투스 제어 LED 타임피스 with RTC
  4. 강 건강 모니터: 아두이노 기반 수질 측정 시스템
  5. 아두이노 아이언맨 제작: 부품, 센서, 단계별 가이드
  6. 아두이노로 간단한 장애물 센서 만들기 - IR LED & 포토다이오드 튜토리얼
  7. 아두이노 조이스틱 인터랙티브 게임 - LED 피드백으로 방향 감지
  8. 아두이노와 블루투스로 만드는 스마트 물건 찾기 'Find Me'
  9. 아두이노 릴레이 제어 가습기 자동화 – 고전압 안전 설계
  10. 아두이노로 만드는 소형 자율 주행 로버