#include <Servo.h>
#include <ezButton.h>
/* ========================================
핀 연결 배선도
========================================
아두이노 R4 WiFi 보드 핀 배치:
버튼 1 (오른쪽 회전) -> 2번 핀 (디지털 입력, 내부 풀업 저항 사용)
버튼 2 (왼쪽 회전) -> 3번 핀 (디지털 입력, 내부 풀업 저항 사용)
서보모터 -> 9번 핀 (PWM 출력)
서보모터 접선:
- 빨강: 5V
- 검정: GND
- 노랑: 9번 핀
버튼 접선 (내부 풀업 저항 사용):
- VCC: 아두이노 5V (필요 없음, 내부 풀업 사용)
- 한쪽: 2번 핀 또는 3번 핀
- 다른쪽: GND
버튼 동작: 누르면 LOW, 놓으면 HIGH (풀업 저항)
======================================== */
// 핀 정의
const int BUTTON_RIGHT_PIN = 2; // 버튼 1 (오른쪽, 내부 풀업)
const int BUTTON_LEFT_PIN = 3; // 버튼 2 (왼쪽, 내부 풀업)
const int SERVO_PIN = 9; // 서보모터
// 서보모터 각도 범위
const int SERVO_CENTER_ANGLE = 90; // 중앙 위치
// 서보 이동 방향 상수
const int DIRECTION_RIGHT = 1; // 오른쪽
const int DIRECTION_LEFT = -1; // 왼쪽
const int DIRECTION_STOP = 0; // 정지
// 타이밍 제어 상수
const unsigned long SERVO_MOVE_DURATION = 50; // 서보 이동 시간(ms) - 50ms마다 1도씩
const unsigned long BUTTON_DEBOUNCE_TIME = 50; // 버튼 디바운싱(ms)
const int SERVO_SPEED = 1; // 연속 이동시 매 루프마다 증감 각도(도)
const int SERVO_MIN_ANGLE = 0; // 서보 최소 각도
const int SERVO_MAX_ANGLE = 180; // 서보 최대 각도
// ezButton 객체 생성 (내부 풀업 저항 사용)
ezButton button_right(BUTTON_RIGHT_PIN);
ezButton button_left(BUTTON_LEFT_PIN);
// 서보모터 객체
Servo servo_motor;
// 상태 변수
unsigned long last_update_time = 0; // 마지막 업데이트 시간
int current_servo_angle = 90; // 현재 서보 각도 (초기값: 90도)
int servo_direction = 0; // 서보 이동 방향 (1: 오른쪽, -1: 왼쪽, 0: 정지)
void setup()
{
// 직렬 통신 초기화 (디버깅용)
Serial.begin(9600);
// ezButton 초기화 (내부 풀업 저항 사용)
button_right.setDebounceTime(BUTTON_DEBOUNCE_TIME);
button_left.setDebounceTime(BUTTON_DEBOUNCE_TIME);
// 서보모터 초기화
servo_motor.attach(SERVO_PIN);
servo_motor.write(SERVO_CENTER_ANGLE);
Serial.println("Setup complete!");
Serial.println("Button - Servo Motor Control with ezButton Library");
Serial.println("Right Button (Pin 2): Move Right");
Serial.println("Left Button (Pin 3): Move Left");
}
void loop()
{
// ezButton 상태 업데이트 (반드시 호출)
button_right.loop();
button_left.loop();
// 버튼 상태에 따라 방향 결정
if (isButtonRightPressed())
{
servo_direction = DIRECTION_RIGHT;
}
else if (isButtonLeftPressed())
{
servo_direction = DIRECTION_LEFT;
}
else
{
servo_direction = DIRECTION_STOP;
}
// 서보 각도 업데이트
updateServoAngle();
}
// 오른쪽 버튼 누름 확인
boolean isButtonRightPressed()
{
return (button_right.getState() == LOW);
}
// 왼쪽 버튼 누름 확인
boolean isButtonLeftPressed()
{
return (button_left.getState() == LOW);
}
// 서보 각도 업데이트 (연속 이동)
void updateServoAngle()
{
unsigned long current_time = millis();
unsigned long time_diff = current_time - last_update_time;
// 매 50ms마다 업데이트 (1도씩 이동)
if (time_diff < SERVO_MOVE_DURATION)
{
return;
}
last_update_time = current_time;
// 방향에 따라 각도 증감
if (servo_direction == DIRECTION_RIGHT)
{
if (current_servo_angle < SERVO_MAX_ANGLE)
{
current_servo_angle += SERVO_SPEED;
Serial.print("Moving RIGHT -> Current angle: ");
Serial.println(current_servo_angle);
}
else
{
current_servo_angle = SERVO_MAX_ANGLE;
}
}
else if (servo_direction == DIRECTION_LEFT)
{
if (current_servo_angle > SERVO_MIN_ANGLE)
{
current_servo_angle -= SERVO_SPEED;
Serial.print("Moving LEFT -> Current angle: ");
Serial.println(current_servo_angle);
}
else
{
current_servo_angle = SERVO_MIN_ANGLE;
}
}
// 서보 위치 업데이트
servo_motor.write(current_servo_angle);
}