물체 운동 속도 측정기
포토 인터럽터 2개를 일정 거리로 놓고 물체가 첫 번째와 두 번째 빛길을 가리는 시간을 재서 평균 속도를 계산합니다.
- 사용 센서
- 포토 인터럽터 2개, 부저 또는 2색 LED
- 측정값
- 통과 시간, 평균 속도, 반복 실험 편차
센서로 세상을 느끼고, 모터로 움직이는 나만의 스마트 로봇을 만들어보세요. 기초부터 탄탄하게 시작하는 메이커 교육 가이드입니다.
시작하기Wi-Fi와 블루투스가 내장된 30핀 메인 두뇌와 선 연결을 쉽게 해주는 확장보드
온도, 소리, 빛 등 다양한 환경을 감지하는 센서 세트와 암-암 케이블
360도 서보모터 또는 DC 기어드 모터, 그리고 이를 제어할 L298N 등의 드라이버
18650 배터리(2홀더), 전압강하 모듈, 골판지, 볼캐스터, 글루건 등
주의: ESP32의 신호핀은 3.3V에서 동작합니다. (5V 센서 연결 시 데이터핀 레벨에 주의하세요)
ESP32 30핀 보드를 확장보드(쉴드)에 꽂으면 왼쪽 포트 라인은 S(신호), V(전원), G(그라운드) 순서이고, 오른쪽 포트 라인은 G(그라운드), V(전원), S(신호) 순서입니다. 좌우 방향이 다르므로 꽂기 전에 줄 이름을 먼저 확인하세요!
확장보드 한눈에 보기
SCL과 SDA는 I2C 통신에 쓰이는 두 신호선입니다. SCL은 장치들이 박자를 맞추는 시계선(Clock), SDA는 실제 데이터를 주고받는 데이터선(Data)입니다. OLED, PCA9685, 일부 센서처럼 I2C 장치는 보통 같은 SCL/SDA 선을 함께 나눠 쓰고, 장치마다 주소가 달라 ESP32가 구분합니다.
I2C 모듈 대부분은 풀업 저항이 포함되어 있지만, 긴 배선이나 여러 모듈을 연결할 때는 신호 안정성을 확인하세요.
USB 포트를 위쪽으로 두고 보드를 정면에서 봤을 때의 일반적인 ESP32 DevKit V1 30핀 배열입니다. 제조사마다 실크 인쇄가 조금 다를 수 있으므로 실제 보드에 적힌 핀 이름을 최우선으로 확인하세요.
크롬(Chrome)이나 엣지(Edge) 브라우저를 사용하면 복잡한 프로그램 설치 없이 웹에서 바로 ESP32에 MicroPython 펌웨어를 올릴 수 있습니다.
0x1000으로 설정한 뒤
Program 버튼을 클릭하여 설치를 완료합니다.플러그인의 잦은 연결 오류가 싫고 가벼운 툴을 원한다면,
마이크로파이썬 공식 CLI 툴인 mpremote와
자동 완성용 스텁(Stub) 파일을 함께 쓰는 방법입니다. 확장 프로그램의 동작과 관계없이 ESP32 전용 내부 함수(machine, network 등)의 자동 완성을 지원합니다.
mpremote run main.py # 보드에서 즉시 실행mpremote cp main.py :main.py # 보드로 파일 복사micropython-stubber를
통해 빨간 줄(에러 표시)을 줄이고 자동 완성을 사용해 보세요.모터를 사용하는 피지컬 컴퓨팅의 핵심은 '전력(전압과 전류)'의 올바른 분배입니다. 안정적인 회로 구성을 위한 필수 지식을 알아봅니다.
이 확장보드는 DC 6.5~16V 배럴잭 입력이 있으므로 18650 배터리 2구 홀더(2S)를 배럴잭 플러그에 연결해 전원을 넣으면 됩니다. 2구 직렬 18650은 평소 약 7.4V, 완충 시 약 8.4V라 보드 입력 범위에 맞습니다.
배럴잭으로 들어온 7.4V 배터리 전원은 확장보드에서 5V/3.3V로 변환해 G/V/S의 V열에 공급할 수 있습니다. 이 점퍼는 G/V/S 전체 V열 전압을 한 번에 바꾸므로, 서보와 센서를 동시에 쓸 때는 어떤 부품이 V열을 함께 쓰는지 먼저 정해야 합니다.
이 수업 구성에서는 18650 2구 배터리를 DC 배럴잭에 연결하고, 확장보드 점퍼로 G/V/S의 V열 전압을 선택합니다. G/V/S의 G열은 보드 안에서 이미 GND로 연결되어 있으므로, 서보와 센서는 각 핀 줄의 G, V, S 방향만 맞춰 꽂으면 됩니다.
# 배럴잭 전원 입력
18650 2구(7.4V) -> DC 배럴잭(6.5~16V)
점퍼 5V 선택 -> G/V/S의 V열 -> 360도 서보
점퍼 3.3V 선택 -> G/V/S의 V열 -> 3.3V 센서
ESP32를 활용하여 서보모터, DC 모터를 포함한 다양한 센서와 부품을 제어하는 방법을 알아봅니다. (클릭하여 확인)
센서 입력과 모터 출력을 함께 사용해 작은 조종 시스템을 만들어 봅니다.
응용 구성: 조이스틱 아날로그 입력 + 360도 무한회전 서보 2개 PWM 제어
360도 무한회전 서보는 각도를 정하는 모터가 아니라 속도와 방향을 정하는 모터입니다. 조이스틱이 가운데에 있으면 두 서보가 멈추고, 레버를 앞으로/뒤로 밀면 회전 방향이 바뀌며, 많이 기울일수록 더 빠르게 회전합니다. X축은 좌우 회전, Y축은 전진/후진 속도로 섞어 작은 2바퀴 로봇처럼 움직입니다.
from machine import ADC, Pin, PWM
import time
# 360도 무한회전 서보 2개
left_servo = PWM(Pin(13), freq=50) # D13 S핀
right_servo = PWM(Pin(14), freq=50) # D14 S핀
# 조이스틱: VCC는 5V, VRx/VRy는 저항 분압 후 ESP32 ADC로 입력
joy_x = ADC(Pin(34)) # VRx
joy_y = ADC(Pin(35)) # VRy
joy_sw = Pin(32, Pin.IN, Pin.PULL_UP)
for adc in (joy_x, joy_y):
adc.atten(ADC.ATTN_11DB)
adc.width(ADC.WIDTH_12BIT)
# 서보마다 정지값이 조금 다릅니다. 중립에서 움직이면 75~78 사이에서 조정하세요.
LEFT_STOP = 77
RIGHT_STOP = 77
MIN_DUTY = 40
MAX_DUTY = 115
# 조이스틱 중립 근처 흔들림을 무시하는 범위입니다.
RAW_DEAD_ZONE = 180
CENTER_SAMPLES = 30
def clamp(value, low=-100, high=100):
return max(low, min(high, value))
def read_center(adc, samples=CENTER_SAMPLES):
total = 0
for _ in range(samples):
total += adc.read()
time.sleep_ms(10)
return total // samples
def axis_to_speed(raw, center):
"""
조이스틱 ADC 값을 -100~100 속도값으로 변환합니다.
중립이면 0, 한쪽으로 밀면 양수, 반대쪽으로 밀면 음수가 됩니다.
"""
delta = raw - center
if abs(delta) < RAW_DEAD_ZONE:
return 0
if delta > 0:
span = max(1, 4095 - center)
else:
span = max(1, center)
speed = int(delta / span * 100)
return clamp(speed)
def set_servo(servo, speed, stop_duty):
"""
speed: -100(역방향 최대) ~ 0(정지) ~ 100(정방향 최대)
"""
speed = clamp(speed)
if speed == 0:
duty = stop_duty
elif speed > 0:
duty = int(stop_duty + (MAX_DUTY - stop_duty) * speed / 100)
else:
duty = int(stop_duty - (stop_duty - MIN_DUTY) * abs(speed) / 100)
servo.duty(duty)
def stop_all():
set_servo(left_servo, 0, LEFT_STOP)
set_servo(right_servo, 0, RIGHT_STOP)
print("조이스틱을 가운데에 놓고 기다리세요.")
center_x = read_center(joy_x)
center_y = read_center(joy_y)
print("중립값:", "x =", center_x, "y =", center_y)
stop_all()
time.sleep(1)
try:
while True:
turn = axis_to_speed(joy_x.read(), center_x)
drive = -axis_to_speed(joy_y.read(), center_y) # 방향이 반대면 -를 제거하세요.
# 버튼을 누르면 즉시 정지
if joy_sw.value() == 0:
stop_all()
time.sleep(0.1)
continue
# 중립이면 drive=0, turn=0이 되어 두 서보가 멈춥니다.
# 레버를 많이 기울일수록 speed 절댓값이 커져 더 빠르게 회전합니다.
left_speed = clamp(drive + turn)
right_speed = clamp(drive - turn)
# 오른쪽 서보가 왼쪽과 마주 보는 방향으로 붙어 있으면 부호를 반대로 줍니다.
set_servo(left_servo, left_speed, LEFT_STOP)
set_servo(right_servo, -right_speed, RIGHT_STOP)
print("turn:", turn, "drive:", drive, "left:", left_speed, "right:", right_speed)
time.sleep(0.05)
except KeyboardInterrupt:
pass
finally:
stop_all()
left_servo.deinit()
right_servo.deinit()
현재 센서 목록만으로 만들 수 있는 간단한 측정 장치 예시입니다. 값은 CSV로 저장하거나 시리얼 플로터로 관찰하면 탐구 보고서 자료로 바로 쓸 수 있습니다.
포토 인터럽터 2개를 일정 거리로 놓고 물체가 첫 번째와 두 번째 빛길을 가리는 시간을 재서 평균 속도를 계산합니다.
진자가 중앙을 지날 때 포토 인터럽터가 신호를 만들도록 설치하고, 연속 통과 시간 차이로 주기를 구합니다.
LED 또는 레이저를 용액 뒤에서 비추고 조도 센서로 통과한 빛을 읽어 탁도 변화나 색 변화 속도를 비교합니다.
반응 전후 온도 변화를 일정 간격으로 기록해 냉각 곡선이나 반응열 차이를 비교합니다.
빛의 세기와 온습도를 함께 기록하고, LED 색이나 조도 조건을 바꿔 식물 실험 환경을 비교합니다.
발효 용기 주변 온습도를 기록하고, 투명 튜브를 지나는 기포를 포토 인터럽터로 세어 발효 속도를 비교합니다.
LED가 켜진 순간부터 터치 센서나 버튼을 누르기까지의 시간을 재서 시각 자극 반응 시간을 비교합니다.
온습도와 조도를 기록하면서 팬이나 조명 조건을 바꿔 물의 증발 또는 표본 건조 속도 차이를 비교합니다.
지금까지 배운 센서와 모터를 결합하여 현실의 문제를 해결하는 AI 피지컬 컴퓨팅 시스템을 구축합니다.
데이터 수집 및 자동화 환경 제어 시스템. 예: '스마트 온실' 또는 '미니 기상 관측소'
DHT11(온습도), 조도 센서, 아날로그 토양수분 센서, 릴레이 모듈, 워터 펌프, 쿨링팬
1. 센서가 온도와 흙의 수분량을 주기적으로 측정.
2. 수분량이 기준치 이하로 떨어지면 ESP32가 릴레이를 통해 워터 펌프를 작동시켜 물을 공급.
3. 온도가 높으면 팬을 돌려 온도를 낮추고, 수집된 데이터를 웹이나 스마트폰으로 전송.
환경을 인지하고 스스로 주행 경로를 결정하는 모빌리티. 예: '장애물 회피 라인트레이서'
DC 기어드 모터 2개, 모터 드라이버(L298N), 트래킹(적외선) 센서 2개, 초음파 거리 센서
1. 트래킹 센서가 바닥의 검은색 라인을 감지하여 모터의 좌/우 PWM 속도를 조절해 선을 따라감.
2. 전방 초음파 센서로 물체와의 거리를 계속 측정.
3. 거리가 15cm 이내로 가까워지면 즉시 후진 후 우회전하여 장애물을 회피한 뒤 라인 복귀.