하드웨어 표준 포트 설계 표준안
실습 중 포트 충돌과 오배선을 줄이기 위해 사용하는 로보그램 교육용 표준 하드웨어 연결 규격입니다.
| 하드웨어 컴포넌트 | 아두이노 우노 지정 디지털 핀 | 제어 명령 | 사용 값 |
|---|---|---|---|
| LED 모듈 | 디지털 11번 포트 (Digital 11) | "value" |
"HIGH" (5V 점등) / "LOW" (0V 소등) |
| 피에조 부저 (Buzzer) | 디지털 5번 포트 (Digital 5) | "tone" |
주파수 값 (단위: Hz) |
| 서보 모터 (Servo) | 디지털 9번 포트 (Digital 9) | "servo" |
"181" (시동) / "182" (보호), 각도 신호(0~180) |
실습 전 꼭 확인하기
코드 복사: 노트북 웹페이지에서 코드 복사 버튼을 누른 다음,
라즈베리파이의 지니 코딩창을 클릭하고
Ctrl + V로 붙여넣습니다.
최신 Clipboard API가 동작하지 않는 환경에서도 사용할 수 있도록 호환 복사 기능을 함께 적용했습니다.
이 교재의 표준 포트:
LED는
11번, 부저는 5번, 서보 모터는 9번을 사용합니다.
뒤의 모든 예제도 같은 포트 번호로 통일했습니다.
중요: 라즈베리파이마다 아두이노 장치명이
/dev/ttyUSB0가 아닐 수 있습니다.
연결이 되지 않으면 터미널에서 ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null로 실제 포트를 확인하세요.
[PART 1] LED 디지털 출력 및 타이밍 응용 제어
예제 1. LED.py
LED.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 11, "output")
print("LED 켜는 중...")
myArduino.write("value", 11, "HIGH")
sleep(3)
print("LED 끄는 중...")
myArduino.write("value", 11, "LOW")
예제 2. LED SOS 구조신호.py
LED_SOS_구조신호.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 11, "output")
print("🆘 LED SOS 구조 신호를 시작합니다.")
def blink(on_time, off_time):
myArduino.write("value", 11, "HIGH")
sleep(on_time)
myArduino.write("value", 11, "LOW")
sleep(off_time)
try:
# S : 짧게 3번
for i in range(3):
blink(0.2, 0.2)
sleep(0.4)
# O : 길게 3번
for i in range(3):
blink(0.7, 0.2)
sleep(0.4)
# S : 짧게 3번
for i in range(3):
blink(0.2, 0.2)
print("SOS 신호 전송 완료!")
finally:
myArduino.write("value", 11, "LOW")
예제 3. 깜빡이등.py
깜빡이등.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 11, "output")
print("딱 5번만 깜빡이고 자동으로 꺼지는 경고등")
# range(5)를 넣으면 0부터 4까지 딱 5번만 반복하고 끝납니다!
for i in range(5):
print(f"{i+1}번째 깜빡!")
myArduino.write("value", 11, "HIGH")
sleep(0.5)
myArduino.write("value", 11, "LOW")
sleep(0.5)
print("정해진 횟수를 다 채워서 안전하게 종료합니다.")
예제 4. 미니 불꽃놀이.py
미니 불꽃놀이.py
from robomy_arduino import Arduino
from time import sleep
import random # 랜덤한 느낌을 주기 위해 추가!
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 11, "output")
print("✨ 미니 불꽃놀이 시작!")
try:
while True:
# 1단계: 불꽃이 피어오르듯 파르르 떨리며 켜지는 효과 (15번 빠르게 반짝임)
for i in range(15):
myArduino.write("value", 11, "HIGH")
sleep(0.02)
myArduino.write("value", 11, "LOW")
sleep(0.05)
# 2단계: 불꽃이 팡! 터져서 유지되는 순간
myArduino.write("value", 11, "HIGH")
sleep(1.5) # 1.5초 동안 환하게 유지!
# 3단계: 불꽃이 꺼지고 다음 불꽃이 터질 때까지 대기
myArduino.write("value", 11, "LOW")
# 1초에서 3초 사이의 랜덤한 시간 동안 암전 (진짜 불꽃놀이처럼!)
wait_time = random.uniform(1.0, 3.0)
sleep(wait_time)
except KeyboardInterrupt:
print("\n불꽃놀이를 종료합니다.")
myArduino.write("value", 11, "LOW")
추가 예제 A. 로켓 발사 카운트다운 LED.py
로켓_발사_카운트다운_LED.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 11, "output")
print("🚀 로켓 발사 준비!")
for count in range(5, 0, -1):
print(count)
# 숫자가 줄어들수록 더 빠르게 반짝입니다.
blink_time = 0.12 + count * 0.08
myArduino.write("value", 11, "HIGH")
sleep(blink_time)
myArduino.write("value", 11, "LOW")
sleep(blink_time)
print("🚀 발사!")
for i in range(12):
myArduino.write("value", 11, "HIGH")
sleep(0.04)
myArduino.write("value", 11, "LOW")
sleep(0.04)
myArduino.write("value", 11, "LOW")
추가 예제 B. 심장 박동 LED.py
심장_박동_LED.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 11, "output")
print("❤️ 심장 박동 LED - Ctrl + C로 종료")
try:
while True:
# 두 번 빠르게 뛰고 잠시 쉬는 박동 패턴
for beat in range(2):
myArduino.write("value", 11, "HIGH")
sleep(0.12)
myArduino.write("value", 11, "LOW")
sleep(0.12)
sleep(0.7)
except KeyboardInterrupt:
print("\n심장 박동 LED를 종료합니다.")
finally:
myArduino.write("value", 11, "LOW")
[PART 2] 피에조 부저 음계·효과음 및 경보음 제어
예제 5. 버저음.py
버저음.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital",5,"output")
print(" 도...")
myArduino.write("tone",5,"262")
sleep(1)
print(" 레...")
myArduino.write("tone",5,"294")
sleep(1)
print(" 미...")
myArduino.write("tone",5,"330")
sleep(1)
print(" 파...")
myArduino.write("tone",5,"349")
sleep(1)
print(" 솔...")
myArduino.write("tone",5,"392")
sleep(1)
print(" 라 ...")
myArduino.write("tone",5,"440")
sleep(1)
print(" 시 ...")
myArduino.write("tone",5,"494")
sleep(1)
print(" 정지 ...")
myArduino.write("tone",5,"0")
예제 6. 긴급 사이렌 효과.py
긴급 사이렌 효과.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 5, "output")
print("🚨 사이렌 패턴을 실행합니다. (종료하려면 Ctrl + C)")
try:
while True:
# 고음
myArduino.write("tone", 5, "880")
sleep(0.3)
# 저음
myArduino.write("tone", 5, "659")
sleep(0.3)
except KeyboardInterrupt:
print("\n사이렌을 종료합니다.")
myArduino.write("tone", 5, "0")
예제 7. 슈퍼마리오 점프음.py
슈퍼마리오 점프음.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 5, "output")
print("🎮 게임 효과음 예제를 시작합니다. (3회 반복)")
try:
for jump in range(3):
print(f"{jump+1}번째 점프")
# 주파수를 300부터 1200까지 40씩 빠르게 올립니다.
for freq in range(300, 1200, 40):
myArduino.write("tone", 5, str(freq))
sleep(0.01) # 0.01초마다 음이 변함
# 점프 후 잠시 쉬기
myArduino.write("tone", 5, "0")
sleep(1)
print("효과음 재생을 마쳤습니다.")
except KeyboardInterrupt:
myArduino.write("tone", 5, "0")
추가 예제 A. 게임 아이템 획득음.py
게임_아이템_획득음.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 5, "output")
notes = [523, 659, 784, 1047]
print("✨ 아이템 획득!")
for freq in notes:
myArduino.write("tone", 5, str(freq))
sleep(0.12)
myArduino.write("tone", 5, "0")
추가 예제 B. 폭탄 타이머 효과음.py
폭탄_타이머_효과음.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 5, "output")
print("⏱️ 5초 타이머 시작!")
for remain in range(5, 0, -1):
print(remain)
myArduino.write("tone", 5, "880")
sleep(0.08)
myArduino.write("tone", 5, "0")
sleep(0.18 + remain * 0.10)
print("💥 시간 종료!")
myArduino.write("tone", 5, "1200")
sleep(0.35)
myArduino.write("tone", 5, "0")
[PART 2-1] LED + 부저 복합 제어
두 개의 출력 장치를 함께 제어하면 시각 신호와 청각 신호를 동시에 설계할 수 있습니다. 이 예제에서는 LED 11번 핀과 부저 5번 핀을 함께 사용합니다.
예제 8. 비상 경고등 + 경고음.py
비상_경고등_경고음.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 11, "output") # LED
myArduino.setPort("digital", 5, "output") # 부저
print("🚨 비상 경고 신호를 5회 출력합니다.")
try:
for i in range(5):
print(f"{i + 1}번째 경고")
myArduino.write("value", 11, "HIGH")
myArduino.write("tone", 5, "880")
sleep(0.3)
myArduino.write("value", 11, "LOW")
myArduino.write("tone", 5, "659")
sleep(0.3)
finally:
myArduino.write("value", 11, "LOW")
myArduino.write("tone", 5, "0")
print("경고 신호 출력이 끝났습니다.")
예제 9. 퀴즈 정답 알림 장치.py
퀴즈_정답_알림장치.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 11, "output") # LED
myArduino.setPort("digital", 5, "output") # 부저
answer = input("문제: 7 × 8 = ? : ").strip()
try:
if answer == "56":
print("✅ 정답입니다.")
myArduino.write("value", 11, "HIGH")
for freq in [523, 659, 784]:
myArduino.write("tone", 5, str(freq))
sleep(0.18)
myArduino.write("tone", 5, "0")
sleep(1)
else:
print("❌ 다시 확인해 보세요.")
for i in range(3):
myArduino.write("value", 11, "HIGH")
myArduino.write("tone", 5, "220")
sleep(0.2)
myArduino.write("value", 11, "LOW")
myArduino.write("tone", 5, "0")
sleep(0.2)
finally:
myArduino.write("value", 11, "LOW")
myArduino.write("tone", 5, "0")
확장 활동: 정답 문자열, LED 점멸 횟수, 부저 주파수를 바꾸어 자신만의 알림 장치를 설계해 보세요.
[PART 3] 서보 모터 각도 제어 및 동작 시나리오
예제 10. 모터제어9번포트.py
모터제어9번포트.py
from robomy_arduino import Arduino
from time import sleep
# 1. 아두이노 보드 연결
myArduino = Arduino("/dev/ttyUSB0")
# 2. 9번 핀을 모터 출력 모드로 설정
myArduino.setPort("digital", 9, "output")
# 3. 모터 제어 신호 켜기 (초기화)
print("motor 키는중...")
myArduino.write("servo", 9, "181")
sleep(2) # ⭐ 중요: 모터가 켜지고 준비할 시간을 2초 동안 줍니다!
# 4. 90도로 회전
print("motor 회전 ...")
myArduino.write("servo", 9, "90")
sleep(3) # 90도까지 완전히 회전할 수 있도록 3초 대기
# 5. 0도로 회전
print("motor 회전 ...")
myArduino.write("servo", 9, "0")
sleep(3) # 0도까지 완전히 돌아올 수 있도록 3초 대기
# 6. 모터 제어 신호 끄기 (안전 종료)
print("motor 정지 및 보호...")
myArduino.write("servo", 9, "182") # ⭐ 모터의 힘을 풀어 과열을 방지합니다.
예제 11. 자동차 와이퍼 모드.py
자동차 와이퍼 모드.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 9, "output")
print("🚗 와이퍼 시스템 가동! (종료하려면 Ctrl + C)")
# 1. 모터 신호 켜고 대기
myArduino.write("servo", 9, "181")
sleep(2)
try:
while True:
print("오른쪽으로 쓱~")
myArduino.write("servo", 9, "180")
sleep(1.5) # 끝까지 회전할 수 있도록 여유 있게 대기
print("왼쪽으로 싹~")
myArduino.write("servo", 9, "0")
sleep(1.5)
except KeyboardInterrupt:
print("\n와이퍼를 안전하게 정지합니다.")
# 안전하게 0도로 복귀시킨 후 모터 전원 끄기
myArduino.write("servo", 9, "0")
sleep(1)
myArduino.write("servo", 9, "182")
예제 12. 낚시꾼 모드.py
낚시꾼 모드.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 9, "output")
print("🎣 🎣 서보 모터 낚시 시뮬레이션을 시작합니다.")
# 1. 모터 신호 켜고 준비 단계
myArduino.write("servo", 9, "181")
sleep(2)
try:
# 0도(기본 위치)에서 대기
myArduino.write("servo", 9, "0")
sleep(2)
# 2. 입질 단계: 물고기가 툭툭 건드림 (80도와 90도 사이를 아주 빠르게 3번 왕복)
print("어? 입질이 옵니다...! 툭. 툭.")
for i in range(3):
myArduino.write("servo", 9, "80")
sleep(0.15)
myArduino.write("servo", 9, "90")
sleep(0.15)
sleep(1) # 잠시 정적...
# 3. 챔질 단계: 물고기가 미끼를 물었을 때 확 낚아챔! (180도로 빠르게 회전)
print("입질 감지! 낚싯대를 빠르게 들어 올립니다. 🌊")
myArduino.write("servo", 9, "180")
sleep(3) # 낚아챈 상태로 3초간 힘겨루기 유지
# 4. 마무리: 원래 자리로 돌아와서 모터 쉬게 하기
print("상황 종료! 물고기를 바구니에 담고 다음 낚시 준비...")
myArduino.write("servo", 9, "0")
sleep(2)
except KeyboardInterrupt:
print("\n낚시대를 접습니다.")
myArduino.write("servo", 9, "0")
sleep(1)
myArduino.write("servo", 9, "182")
추가 예제 A. 레이더 스캐너 모터.py
레이더_스캐너_모터.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 9, "output")
myArduino.write("servo", 9, "181")
sleep(1)
print("📡 레이더 스캔 시작!")
try:
for scan in range(3):
print(f"{scan + 1}회 스캔")
for angle in range(20, 161, 20):
myArduino.write("servo", 9, str(angle))
sleep(0.18)
for angle in range(160, 19, -20):
myArduino.write("servo", 9, str(angle))
sleep(0.18)
finally:
myArduino.write("servo", 9, "90")
sleep(0.5)
myArduino.write("servo", 9, "182")
print("레이더 스캔 종료")
추가 예제 B. 주차장 차단기.py
주차장_차단기.py
from robomy_arduino import Arduino
from time import sleep
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 9, "output")
myArduino.write("servo", 9, "181")
sleep(1)
myArduino.write("servo", 9, "0")
sleep(1)
print("🚗 차량 접근! 차단기를 엽니다.")
myArduino.write("servo", 9, "90")
sleep(3)
print("🚧 차량 통과 완료! 차단기를 닫습니다.")
myArduino.write("servo", 9, "0")
sleep(1)
myArduino.write("servo", 9, "182")
[PART 4] 인공지능 컴퓨터 비전 사물 인식 엔진 연동
후반부 예제 보강: LED·부저·모터 포트를 11·5·9번으로 통일했고, 실시간 인식 예제는 같은 사물이 화면에 계속 보일 때 매 프레임 하드웨어가 반복 동작하지 않도록 상태값을 추가했습니다.
예제 13. 사물인식.py
사물인식.py
import robomy_cv as rcv
rcv.create_object_h5('obj_data',90,6)
예제 14. 사물인식1(보정).py
사물인식1(보정).py
import robomy_cv as rcv
import cv2
# [주의] rcv.create_object_h5('obj_data', 90, 3) 명령어는 이미 사진 수집과
# AI 모델 학습을 끝마쳤으므로 다시 실행하여 데이터가 덮어써지지 않도록 주석(##) 처리합니다.
## rcv.create_object_h5('obj_data', 90, 3)
# 1. 프로그램에서 사용할 변수들을 초기화합니다.
keyVal = None # 키보드 입력 값을 저장할 변수
camera = None # 카메라 장치 객체를 담을 변수
# 2. 라즈베리파이에 연결된 0번(기본) 카메라의 전원을 켜고 영상 스트리밍을 준비합니다.
camera = rcv.get_camera(0)
print("🔍 [실시간 사물 인식 가동] 카메라 화면이 열립니다.")
print("👉 가방, 스마트폰, 키보드, 볼펜 등을 카메라에 보여주세요.")
print("👉 종료하려면 카메라 영상 창을 선택한 상태에서 키보드 'ESC' 키를 누르세요.")
# 3. 사용자가 ESC 키(아스크코드 27번)를 누르기 전까지 영상 처리를 무한 반복합니다.
while not keyVal == 27:
# [단계 A] 카메라 렌즈로부터 현재 순간의 정지 영상 화면(Frame)을 1장 캡처해 가져옵니다.
frame = rcv.get_frame(camera)
# [단계 B] 캡처한 화면(frame)을 우리가 미리 학습시켜 둔 인공지능 모델('obj_data')에 입력하여
# 사물이 어디에 있고 이름이 무엇인지 판단(Prediction)합니다.
# 인식 결과 사물 이름 문자열(예: 'keyboard', 'mouse')이 pred 변수에 담깁니다.
frame, pred = rcv.find_object_from_frame(frame, 'obj_data')
# [단계 C] 인공지능이 분석한 결과 상자와 이름표가 합성된 화면을 컴퓨터 모니터 창('로보그램 실시간 인식')에 출력합니다.
cv2.imshow('로보그램 실시간 인식', frame)
# [단계 D] 키보드 입력이 들어오는지 0.01초(10ms) 동안 대기하며 입력값을 keyVal 변수에 업데이트합니다.
keyVal = cv2.waitKey(10)
print("\n🛑 사물 인식 프로그램을 안전하게 종료합니다.")
cv2.destroyAllWindows()
예제 15. 오픈CV 버그 우회! 터미널 출력 + 아두이노 LED 연동.py
오픈CV_버그_우회_연동.py
import robomy_cv as rcv
from robomy_arduino import Arduino
import cv2
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 11, "output")
keyVal = None
camera = rcv.get_camera(0)
print("🔥 사물이 인식되면 이름을 출력하고 LED가 켜집니다. ESC로 종료합니다.")
try:
while keyVal != 27:
frame = rcv.get_frame(camera)
frame, pred = rcv.find_object_from_frame(frame, 'obj_data')
if pred and len(pred) > 0:
detected_item = str(pred).strip().lower()
myArduino.write("value", 11, "HIGH")
if 'keyboard' in detected_item:
print("🎯 키보드 감지")
elif 'mouse' in detected_item:
print("🎯 마우스 감지")
elif 'smartphone' in detected_item:
print("🎯 스마트폰 감지")
elif 'bag' in detected_item:
print("🎯 가방 감지")
elif 'ball point pen' in detected_item:
print("🎯 볼펜 감지")
elif 'slippers' in detected_item:
print("🎯 슬리퍼 감지")
else:
print(f"🎯 {detected_item} 감지")
else:
myArduino.write("value", 11, "LOW")
cv2.imshow('로보그램 실시간 인식', frame)
keyVal = cv2.waitKey(10)
finally:
print("\n프로그램을 종료합니다.")
myArduino.write("value", 11, "LOW")
cv2.destroyAllWindows()
예제 16. 사물별 하드웨어 매칭 및 사용자 선택 제어 코드.py
사물별_하드웨어_매칭_시스템.py
import robomy_cv as rcv
from robomy_arduino import Arduino
import cv2
import time
myArduino = Arduino("/dev/ttyUSB0")
myArduino.setPort("digital", 11, "output") # LED
myArduino.setPort("digital", 5, "output") # 부저
myArduino.setPort("digital", 9, "output") # 서보 모터
myArduino.write("servo", 9, "181")
time.sleep(0.5)
myArduino.write("servo", 9, "0")
time.sleep(0.5)
def normalize_choice(value, default):
value = value.strip().lower()
if value in ("led", "buzzer", "motor"):
return value
if value:
print(f"⚠️ '{value}'는 사용할 수 없어 기본값 {default}를 사용합니다.")
return default
def control_hardware(target):
myArduino.write("value", 11, "LOW")
myArduino.write("tone", 5, "0")
if target == "led":
myArduino.write("value", 11, "HIGH")
print("💡 LED가 켜졌습니다!")
elif target == "buzzer":
myArduino.write("tone", 5, "523")
print("🔊 부저가 울립니다!")
elif target == "motor":
myArduino.write("servo", 9, "90")
print("🚪 서보 모터가 90도로 회전합니다.")
time.sleep(1.5)
myArduino.write("servo", 9, "0")
print("🤖 사물별 동작을 led / buzzer / motor 중에서 선택하세요.")
set_bag = normalize_choice(input("🎒 가방 [기본 led]: "), "led")
set_phone = normalize_choice(input("📱 스마트폰 [기본 buzzer]: "), "buzzer")
set_key = normalize_choice(input("⌨️ 키보드 [기본 motor]: "), "motor")
set_mon = normalize_choice(input("🖥️ 모니터 [기본 led]: "), "led")
set_ms = normalize_choice(input("🖱️ 마우스 [기본 buzzer]: "), "buzzer")
set_sl = normalize_choice(input("🩴 슬리퍼 [기본 led]: "), "led")
set_pen = normalize_choice(input("✏️ 볼펜 [기본 motor]: "), "motor")
mapping = {
"bag": set_bag,
"smartphone": set_phone,
"keyboard": set_key,
"monitor": set_mon,
"mouse": set_ms,
"slippers": set_sl,
"ball point pen": set_pen,
}
keyVal = None
camera = rcv.get_camera(0)
last_item = None
print("\n🚀 AI 사물-하드웨어 매칭 시스템을 시작합니다. ESC로 종료합니다.")
try:
while keyVal != 27:
frame = rcv.get_frame(camera)
frame, pred = rcv.find_object_from_frame(frame, 'obj_data')
detected_item = str(pred).strip().lower() if pred else ""
matched_name = None
for object_name in mapping:
if object_name in detected_item:
matched_name = object_name
break
# 같은 사물이 계속 보이는 동안에는 매 프레임 다시 작동하지 않습니다.
if matched_name and matched_name != last_item:
print(f"🎯 감지된 사물: {matched_name}")
control_hardware(mapping[matched_name])
last_item = matched_name
elif not matched_name:
myArduino.write("value", 11, "LOW")
myArduino.write("tone", 5, "0")
last_item = None
cv2.imshow('AI IoT 사물 인식', frame)
keyVal = cv2.waitKey(10)
finally:
print("\n🛑 시스템을 종료하고 하드웨어를 초기화합니다.")
myArduino.write("value", 11, "LOW")
myArduino.write("tone", 5, "0")
myArduino.write("servo", 9, "0")
time.sleep(0.5)
myArduino.write("servo", 9, "182")
cv2.destroyAllWindows()
[PART 5] OpenCV 얼굴 인식 및 종합 연동
수업 팁: 얼굴 데이터는 본인 또는 촬영에 동의한 사람의 사진만 사용하고, 수업이 끝난 뒤
faces 폴더를 삭제하는 방식으로 운영하는 것이 좋습니다.예제 17. 얼굴인식.py
얼굴인식.py
import robomy_cv as rcv
from time import sleep
from cv2 import waitKey # 오타 수정 (waitkey -> waitKey)
# ===================================================
# [1단계] 카메라 설정 및 데이터(얼굴 사진 50장) 수집
# ===================================================
camera = None
camera = rcv.get_camera(0) # 0번(기본) 카메라 활성화
print("📸 얼굴 등록을 시작합니다. 카메라를 정면으로 바라봐 주세요!")
sleep(2) # 카메라 준비 시간 잠시 대기
# 0부터 49까지 총 50장의 얼굴 사진을 'faces' 폴더에 저장합니다.
for i in range(0, 50):
rcv.save_face(camera, 'faces', i)
print(f"사진 촬영 중... ({i+1}/50)")
sleep(0.05) # 너무 빨리 찍히지 않게 미세한 간격 추가
# ===================================================
# [2단계] 수집된 사진으로 AI 얼굴 모델 학습(공부)
# ===================================================
print("\n🤖 인공지능이 얼굴 특징을 학습하는 중입니다. 잠시만 기다려주세요...")
faceModel = None
faceModel = rcv.train_face('faces')
print("✅ 학습 완료! 실시간 보안 모드를 시작합니다.")
# ===================================================
# [3단계] 실시간 얼굴 인식 매칭 (ESC 누르면 종료)
# ===================================================
keyVal = None
print("\n🔒 [보안 실행 중] 등록된 사용자 확인 중... (종료하려면 ESC 키를 누르세요)")
while not keyVal == 27:
# 실시간으로 카메라에서 얼굴 영역만 추출하여 가져옵니다.
camera_face = rcv.face_extractor(camera)
# 추출한 얼굴과 미리 학습된 AI 모델(faceModel)의 특징점 데이터를 대조 분석합니다.
if rcv.compare_face(camera_face, faceModel):
print("🟢 Recognized : 등록된 사용자(등록 사용자)가 확인되었습니다. 문을 엽니다.")
else:
print("🔴 Unknown : 등록되지 않은 얼굴입니다. 접근을 제한합니다.")
keyVal = waitKey(1)
print("\n👋 얼굴 인식 보안 시스템이 안전하게 종료되었습니다.")
예제 18. 얼굴인식응용.py
얼굴인식응용.py
import robomy_cv as rcv
from robomy_arduino import Arduino
from time import sleep
from cv2 import waitKey
import cv2
# ===================================================
# [준비 단계] 아두이노 하드웨어 및 카메라 초기 설정
# ===================================================
# 1. 아두이노 및 카메라 연결
myArduino = Arduino("/dev/ttyUSB0")
camera = rcv.get_camera(0)
# 2. 하드웨어 핀 모드 설정
myArduino.setPort("digital", 11, "output") # LED (11번)
myArduino.setPort("digital", 5, "output") # 버저 (5번)
myArduino.setPort("digital", 9, "output") # 서보 모터 (9번)
# 3. 서보 모터(도어락) 초기화 (전원 켜고 문 잠금 상태로 시작)
myArduino.write("servo", 9, "181")
sleep(1)
myArduino.write("servo", 9, "0") # 0도: 문이 잠긴 상태
sleep(1)
# ===================================================
# [1단계] 얼굴 등록 및 AI 모델 학습
# ===================================================
print("📸 [얼굴 등록] 카메라를 정면으로 바라봐 주세요!")
sleep(1)
for i in range(0, 50):
rcv.save_face(camera, 'faces', i)
sleep(0.05)
print("\n🤖 인공지능이 얼굴을 학습하고 있습니다...")
faceModel = rcv.train_face('faces')
print("✅ 시스템 준비 완료! 실시간 감시를 시작합니다.")
# ===================================================
# [2단계] 실시간 보안 도어락 제어 (무한 반복)
# ===================================================
keyVal = None
door_open = False # 문이 현재 열려있는지 체크하는 변수
try:
while not keyVal == 27: # ESC 누르면 종료
camera_face = rcv.face_extractor(camera)
# 👤 [경우 1] 얼굴 인식 성공 (등록 사용자 등장!)
if rcv.compare_face(camera_face, faceModel):
print('🟢 Recognized : 등록 사용자 확인! 문을 엽니다.')
myArduino.write("value", 11, "HIGH") # 1) LED 불 켜기
myArduino.write("servo", 9, "90") # 2) 도어락 열기 (90도 회전)
myArduino.write("tone", 5, "0") # 혹시 울리던 경고음이 있다면 끄기
sleep(5) # ⏰ 문이 열린 채로 5초 동안 대기합니다 (사람이 들어가는 시간)
print('🔒 다시 문을 잠급니다.')
myArduino.write("value", 11, "LOW") # 3) LED 불 끄기
myArduino.write("servo", 9, "0") # 4) 도어락 다시 잠금 (0도 복귀)
sleep(1)
# 👤 [경우 2] 얼굴 인식 실패 또는 모르는 사람 (경고 상황!)
else:
print('🔴 Unknown! : 등록되지 않은 얼굴입니다. 경고음을 출력합니다.')
# 경찰차 사이렌처럼 고음과 저음을 빠르게 반복해서 강력한 경고음을 냅니다.
myArduino.write("tone", 5, "988") # 높은 시 음
sleep(0.15)
myArduino.write("tone", 5, "784") # 높은 솔 음
sleep(0.15)
keyVal = waitKey(1)
except KeyboardInterrupt:
print("\n시스템을 안전하게 종료합니다.")
finally:
# 종료할 때 모든 하드웨어를 안전하게 정지시킵니다.
myArduino.write("value", 11, "LOW") # LED 끄기
myArduino.write("tone", 5, "0") # 버저 끄기
myArduino.write("servo", 9, "0") # 모터 원위치
sleep(1)
myArduino.write("servo", 9, "182") # 모터 보호 모드
cv2.destroyAllWindows()