아두이노 나노로 물방울 고속 촬영하기 – DIY 하이스피드 포토그래피
부품 및 소모품
| 부품 | 수량 |
| Arduino Nano R3 | 1 |
| 레이저 모듈 KY-008 | 1 |
| LM393 기반 조도 센서 모듈 | 1 |
| 범용 NPN 트랜지스터 | 3 |
| 로터리 포텐셔미터 | 1 |
| C&K PTS 645 시리즈 스위치 (버튼) | 1 |
앱 및 온라인 서비스
프로젝트 소개
고속 촬영 사진에 도전하고 싶어 이 프로젝트를 시작했습니다. 아래는 아두이노 기반으로 물방울 튀는 순간을 포착하는 간단한 세팅입니다.
준비물
- 수동 설정 가능한 카메라 + 외장 플래시 (둘 다 원격 제어 지원 필요)
- 사용 장비: Sony DSC-HX300 (그림 1), GODOX SY8000 플래시 + 동기 케이블 (그림 2)


그림 2에서 아두이노 와이어 2가 동기 케이블의 PC 커넥터에 절연 처리돼 연결된 것을 볼 수 있습니다.
릴리즈 리모컨 개조
리모컨에 3핀 헤더를 추가했습니다 (그림 3).

내부에는 스프링 금속 스트립 3개가 있습니다 (그림 4): 1번 셔터 '+', 2번 GND, 3번 AF '+'. 버튼을 누르면 2-3(AF), 1-2(셔터) 순으로 쇼트됩니다.

이제 아두이노로 버튼 누름을 프로그래밍 방식으로 에뮬레이트할 수 있습니다. 동기 케이블도 PC 커넥터 접점을 쇼트시키면 플래시가 터지는 같은 원리입니다.
물방울 감지 원리
목표: 물방울이 수면에 떨어져 튀는 순간 포착.
약병 스포이트 부품을 조립해 물방울 장치 제작 (그림 5).

레이저 모듈 KY-008과 LM393 조도 센서로 물방울 낙하 감지 (그림 6).

레이저 빔이 떨어지는 물방울에 의해 차단되면 센서가 감지합니다. 센서 모듈의 가변저항으로 레이저 파워에 맞춰 감도 조절 가능. 모듈 간 거리를 멀리 둘 수도 있습니다.
촬영 방식
암실에서 장노출(수 초)로 촬영하므로, 짧은 플래시 빛만 사진에 기록됩니다.
회로도

작동 순서
- 관찰할 물방울이 떨어지기 전 버튼 누름
- 아두이노가 리모컨 접점을 순차 쇼트: AF 트리거 → 셔터 트리거 → 셔터 개방 (수 초간)
- 동시에 플래시 발사 허용 상태 진입
- 물방울이 레이저 빔 차단 → 조도 센서 감지 → 설정된 지연 시간 후 플래시 트리거 쇼트 → 플래시 발광
- 지연 시간은 포텐셔미터로 1~500ms 범위 조절 가능 (코드에서 변경 가능). 이로써 물방울 충돌의 다양한 순간 포착 가능
- 이후 물방울은 플래시 발사 안 함. 다시 촬영하려면 버튼 재누름
조립 완성

참고: 고전압 플래시 회로와 저전압 로직 분리를 위해 옵토커플러 추가 권장.
코드 주요 파라미터 (그림 9)

DBG_MODE 플래그: 카메라/플래시 없이 레이저/센서 정렬 테스트용. 내장 LED로 동작 표시 (버튼 누르면 ON, 물방울 감지 시 OFF)
- 설정 완료 후 플래그 주석 처리하고 다시 업로드
- 주요 상수: 핀 할당, AF/셔터/플래시 쇼트 지속 시간, 포텐셔미터 지연 시간 범위
촬영 결과 예시



코드
//#define DBG_MODE
const byte BUTTON_PIN = 2;
const byte FOCUS_PIN = 3;
const byte SHUTTER_PIN = 4;
const byte FLASH_PIN = 5;
const byte SENSOR_PIN = 6;
const byte RESISTOR_PIN = A5;
const unsigned int FOCUS_DELAY = 100;
const unsigned int SHUTTER_DELAY = 100;
const unsigned int FLASH_DELAY = 10;
const unsigned int FIRE_DELAY_MIN = 1;
const unsigned int FIRE_DELAY_MAX = 500;
boolean prevButton, currButton;
boolean prevSensor, currSensor;
boolean allowFlash;
unsigned long fireDelay;
void openShutter() {
#ifndef DBG_MODE
digitalWrite(FOCUS_PIN, HIGH); delay(FOCUS_DELAY);
digitalWrite(SHUTTER_PIN, HIGH); delay(SHUTTER_DELAY);
digitalWrite(SHUTTER_PIN, LOW); delay(FOCUS_DELAY);
digitalWrite(FOCUS_PIN, LOW);
#else
digitalWrite(LED_BUILTIN, HIGH);
#endif
}
void fireFlash() {
#ifndef DBG_MODE
digitalWrite(FLASH_PIN, HIGH); delay(FLASH_DELAY);
digitalWrite(FLASH_PIN, LOW);
#else
digitalWrite(LED_BUILTIN, LOW);
#endif
}
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(FOCUS_PIN, OUTPUT); pinMode(SHUTTER_PIN, OUTPUT);
pinMode(FLASH_PIN, OUTPUT); pinMode(SENSOR_PIN, INPUT);
#ifdef DBG_MODE pinMode(LED_BUILTIN, OUTPUT); #endif
digitalWrite(FOCUS_PIN, LOW); digitalWrite(SHUTTER_PIN, LOW); digitalWrite(FLASH_PIN, LOW);
prevButton = digitalRead(BUTTON_PIN);
prevSensor = digitalRead(SENSOR_PIN);
allowFlash = false;
}
void loop() {
currButton = digitalRead(BUTTON_PIN);
if (prevButton != currButton) {
prevButton = currButton;
if (currButton == LOW) {
allowFlash = true; prevSensor = HIGH;
fireDelay = map(analogRead(RESISTOR_PIN), 0, 1023, FIRE_DELAY_MIN, FIRE_DELAY_MAX);
openShutter();
} else { delay(50); }
}
currSensor = digitalRead(SENSOR_PIN);
if (prevSensor != currSensor) {
prevSensor = currSensor;
if (currSensor == HIGH && allowFlash) {
allowFlash = false; delay(fireDelay); fireFlash();
}
}
}
회로도
