1. 시리얼 통신으로 피코 제어
from machine import Pin, PWM
from time import sleep
import sys
# 내장 LED 설정
led = Pin("LED", Pin.OUT)
# 서보모터 설정
servo1 = PWM(Pin(15))
servo2 = PWM(Pin(17))
servo1.freq(50)
servo2.freq(50)
# 초기 각도
angle1 = 90
angle2 = 90
# 듀티 범위
MIN_DUTY = 1638
MAX_DUTY = 8100
STEP = 15
running = True
def angle_to_duty(angle):
return int(MIN_DUTY + (angle / 180) * (MAX_DUTY - MIN_DUTY))
def update_servos():
servo1.duty_u16(angle_to_duty(angle1))
servo2.duty_u16(angle_to_duty(angle2))
update_servos()
print("시리얼 명령 대기 중...")
try:
while True:
command = sys.stdin.readline().strip()
if command == '1':
led.value(1)
print("LED 켜짐")
elif command == '2':
led.value(0)
print("LED 꺼짐")
elif command == '3':
print("LED 깜빡이기 시작")
for _ in range(5):
led.toggle()
sleep(0.3)
led.value(0)
print("LED 깜빡이기 완료")
elif command == '4':
if running:
angle1 = (angle1 + STEP) % 180
update_servos()
print(f"서보모터 1 각도: {angle1}도")
elif command == '5':
if running:
angle2 = (angle2 + STEP) % 180
update_servos()
print(f"서보모터 2 각도: {angle2}도")
elif command == '6':
if running:
angle1 = (angle1 + STEP) % 180
angle2 = (angle2 + STEP) % 180
update_servos()
print(f"서보모터 1: {angle1}도, 서보모터 2: {angle2}도")
elif command == '7':
# 서보모터 완전 정지
servo1.deinit()
servo2.deinit()
running = False
print("서보모터 완전 정지됨")
elif command == "8":
angle1 = 90
angle2 = 90
servo1 = PWM(Pin(16))
servo2 = PWM(Pin(17))
servo1.freq(50)
servo2.freq(50)
update_servos()
print("서보모터 초기화 (90도)")
else:
print("알 수 없는 명령입니다. 1~8 중 입력하세요.")
except KeyboardInterrupt:
servo1.deinit()
servo2.deinit()
print("프로그램 종료")
Python
복사
실습 1. 내부 led 코드 제어 코드
2. 미디어파이프로 피코 제어
•
웹켐 버튼 제어 코드
import cv2
import mediapipe as mp
# Mediapipe 손 추적 설정
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils
hands = mp_hands.Hands(
max_num_hands=1,
min_detection_confidence=0.7,
min_tracking_confidence=0.7
)
# 버튼 클래스 정의
class Button:
def __init__(self, x, y, w, h, label):
self.x, self.y, self.w, self.h = x, y, w, h
self.label = label
self.clicked = False
def draw(self, img):
color = (0, 255, 0) if self.clicked else (200, 200, 200)
cv2.rectangle(img, (self.x, self.y), (self.x+self.w, self.y+self.h), color, -1)
cv2.putText(img, self.label, (self.x+30, self.y+50), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 0), 3)
def check_click(self, px, py):
if self.x < px < self.x + self.w and self.y < py < self.y + self.h:
self.clicked = True
else:
self.clicked = False
# 버튼 배열 생성
buttons = []
for i in range(9):
x = 100 + (i % 3) * 150
y = 100 + (i // 3) * 150
buttons.append(Button(x, y, 120, 100, str(i + 1)))
# 웹캠 열기
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("❌ 웹캠을 열 수 없습니다.")
exit()
while True:
ret, frame = cap.read()
if not ret:
print("❌ 프레임을 읽을 수 없습니다.")
break
frame = cv2.flip(frame, 1) # 좌우 반전
h, w, _ = frame.shape
# Mediapipe용 RGB 변환
img_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = hands.process(img_rgb)
index_x, index_y = None, None
# 손 검출되었을 때
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
# 랜드마크 그리기
mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
# 검지 손가락 끝 좌표 (랜드마크 8번)
index_tip = hand_landmarks.landmark[8]
index_x = int(index_tip.x * w)
index_y = int(index_tip.y * h)
# 손끝 시각화
cv2.circle(frame, (index_x, index_y), 10, (255, 0, 255), -1)
# 버튼 클릭 체크
for button in buttons:
button.check_click(index_x, index_y)
# 버튼 그리기
for button in buttons:
button.draw(frame)
# 화면 출력
cv2.imshow("Hand Button Interface", frame)
# 종료 조건
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 종료 처리
cap.release()
cv2.destroyAllWindows()
hands.close()
Python
복사
[과제명][학교][이름] 바꿔주세요, 과제태그를 선생님 설명 듣고 넣어주세요.