아두이노 WebJoystick 예제 가상 조이스틱 제어 튜토리얼
개요
WebJoystick 예제는 모든 웹 브라우저에서 접근 가능한 가상 조이스틱 인터페이스를 생성합니다.
아두이노 우노 R4 WiFi 및 DIYables STEM V4 IoT 교육 플랫폼에 맞춰 설계되었으며, 향상된 로봇 공학 기능과 내장 모터 제어 기능, 그리고 로봇 교육 모듈과의 원활한 통합을 제공합니다.
로봇, 차량 또는 2D 위치 입력이 필요한 모든 시스템 제어에 적합합니다.

특징
- 가상 조이스틱: 웹 인터페이스를 통한 인터랙티브 조이스틱 제어
- 실시간 좌표: 정밀 제어를 위한 -100에서 +100까지의 X/Y 값
- 터치 및 마우스 지원: 데스크톱, 태블릿 및 모바일 기기에서 작동
- 설정 가능한 자동 복귀: 손을 떼었을 때 중앙으로 돌아가도록 하는 옵션
- 감도 제어: 과도한 업데이트를 방지하기 위한 조정 가능한 감도
- 시각적 피드백: 실시간 위치 표시 및 좌표 값
- WebSocket 통신: 페이지 새로고침 없이 즉시 응답
- 중앙 위치: 중립 제어를 위한 명확한 중앙 위치 표시
- 플랫폼 확장성: 현재 Arduino Uno R4 WiFi용으로 구현되어 있지만, 다른 하드웨어 플랫폼으로 확장할 수 있습니다. 자세한 내용은 DIYables_WebApps_ESP32 참조
준비물
| 1 | × | 아두이노 우노 R4 와이파이 | 쿠팡 | 아마존 | |
| 1 | × | (또는) DIYables STEM V4 IoT | 쿠팡 | 아마존 | |
| 1 | × | USB 케이블 타입-A to 타입-C (USB-A PC용) | 쿠팡 | 아마존 | |
| 1 | × | USB 케이블 타입-C to 타입-C (USB-C PC용) | 아마존 | |
| 1 | × | (추천) 아두이노 우노 R4용 스크루 터미널 블록 쉴드 | 쿠팡 | 아마존 | |
| 1 | × | (추천) 아두이노 우노 R4용 브레드보드 쉴드 | 쿠팡 | 아마존 | |
| 1 | × | (추천) 아두이노 우노 R4용 케이스 | 쿠팡 | 아마존 | |
| 1 | × | (추천) 아두이노 우노 R4용 전원 분배기 | 쿠팡 | 아마존 | |
| 1 | × | (추천) 아두이노 우노용 프로토타이핑 베이스 플레이트 & 브레드보드 키트 | 아마존 |
공개: 이 포스팅 에 제공된 일부 링크는 아마존 제휴 링크입니다. 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
설정 지침
빠른 단계
다음 지침을 단계별로 따라가세요:
- 이 Arduino Uno R4 WiFi/DIYables STEM V4 IoT를 처음 사용하는 경우, Arduino IDE에서 Arduino Uno R4 WiFi/DIYables STEM V4 IoT를 위한 환경 설정 튜토리얼을 참조하십시오 아두이노 우노 R4 - 소프트웨어 설치.
- USB 케이블을 사용하여 컴퓨터에 Arduino Uno R4/DIYables STEM V4 IoT 보드를 연결합니다.
- 컴퓨터에서 Arduino IDE를 실행합니다.
- 적절한 Arduino Uno R4 보드(예: Arduino Uno R4 WiFi)와 COM 포트를 선택합니다.
- Arduino IDE의 왼쪽 바에 있는 Libraries 아이콘으로 이동합니다.
- "DIYables WebApps"를 검색한 뒤, DIYables에서 제공하는 DIYables WebApps 라이브러리를 찾으십시오.
- 라이브러리를 설치하려면 Install 버튼을 클릭합니다.

- 다른 라이브러리 의존성 설치를 요청받게 됩니다.
- 모든 라이브러리 의존성을 설치하려면 Install All 버튼을 클릭하세요.

- Arduino IDE에서 File 예제 DIYables WebApps WebJoystick 예제로 이동하거나, 위의 코드를 복사하여 Arduino IDE 편집기에 붙여넣으십시오.
/*
* DIYables WebApp Library - Web Joystick Example
*
* This example demonstrates the Web Joystick feature:
* - Interactive joystick control via web interface
* - Real-time X/Y coordinate values (-100 to +100)
* - Control pins based on joystick position
*
* Hardware: Arduino Uno R4 WiFi or DIYables STEM V4 IoT
*
* Setup:
* 1. Update WiFi credentials below
* 2. Upload the sketch to your Arduino
* 3. Open Serial Monitor to see the IP address
* 4. Navigate to http://[IP_ADDRESS]/webjoystick
*/
#include <DIYablesWebApps.h>
// WiFi credentials - UPDATE THESE WITH YOUR NETWORK
const char WIFI_SSID[] = "YOUR_WIFI_SSID";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
// Create WebApp server and page instances
// MEMORY SAFETY FIX: Use static factory to avoid stack object lifetime issues
static UnoR4ServerFactory serverFactory; // Static ensures lifetime matches program
DIYablesWebAppServer webAppsServer(serverFactory, 80, 81);
DIYablesHomePage homePage;
// Configure joystick with autoReturn=false and sensitivity=5 (minimum 5% change to trigger updates)
DIYablesWebJoystickPage webJoystickPage(false, 5);
// Variables to store current joystick values
int currentJoystickX = 0;
int currentJoystickY = 0;
void setup() {
Serial.begin(9600);
delay(1000);
// TODO: initialize your hardware pins here
Serial.println("DIYables WebApp - Web Joystick Example");
// Add home and web joystick pages
webAppsServer.addApp(&homePage);
webAppsServer.addApp(&webJoystickPage);
// Optional: Add 404 page for better user experience
webAppsServer.setNotFoundPage(DIYablesNotFoundPage());
// Start the WebApp server
if (!webAppsServer.begin(WIFI_SSID, WIFI_PASSWORD)) {
while (1) {
Serial.println("Failed to start WebApp server!");
delay(1000);
}
}
// Set up joystick callback for position changes
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
// Store the received values
currentJoystickX = x;
currentJoystickY = y;
// Print joystick position values (-100 to +100)
Serial.println("Joystick - X: " + String(x) + ", Y: " + String(y));
// TODO: Add your control logic here based on joystick position
// Examples:
// - Control motors: if (x > 50) { /* move right */ }
// - Control servos: servo.write(map(y, -100, 100, 0, 180));
// - Control LEDs: analogWrite(LED_PIN, map(abs(x), 0, 100, 0, 255));
// - Send commands to other devices via Serial, I2C, SPI, etc.
});
// Optional: Handle requests for current joystick values (when web page loads)
webJoystickPage.onJoystickValueToWeb([]() {
// Send the stored joystick values back to the web client
webJoystickPage.sendToWebJoystick(currentJoystickX, currentJoystickY);
Serial.println("Web client requested values - Sent to Web: X=" + String(currentJoystickX) + ", Y=" + String(currentJoystickY));
});
// You can change configuration at runtime:
// webJoystickPage.setAutoReturn(false); // Disable auto-return
// webJoystickPage.setSensitivity(10.0); // Only send updates when joystick moves >10% (less sensitive)
}
void loop() {
// Handle WebApp server communications
webAppsServer.loop();
// TODO: Add your main application code here
delay(10);
}
- 이 줄들을 업데이트하여 코드에서 WiFi 자격 증명을 구성하십시오:
const char WIFI_SSID[] = "YOUR_WIFI_NETWORK";
const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
- Arduino IDE에서 Upload 버튼을 클릭하여 Arduino UNO R4/DIYables STEM V4 IoT에 코드를 업로드합니다.
- 시리얼 모니터를 엽니다.
- 시리얼 모니터에서 결과를 확인하세요. 아래와 같습니다.
COM6
DIYables WebApp - Web Joystick Example
INFO: Added app /
INFO: Added app /web-joystick
DIYables WebApp Library
Platform: Arduino Uno R4 WiFi
Network connected!
IP address: 192.168.0.2
HTTP server started on port 80
Configuring WebSocket server callbacks...
WebSocket server started on port 81
WebSocket URL: ws://192.168.0.2:81
WebSocket server started on port 81
==========================================
DIYables WebApp Ready!
==========================================
📱 Web Interface: http://192.168.0.2
🔗 WebSocket: ws://192.168.0.2:81
📋 Available Applications:
🏠 Home Page: http://192.168.0.2/
🕹️ Web Joystick: http://192.168.0.2/web-joystick
==========================================
Autoscroll
Clear output
9600 baud
Newline
- 아무 것도 보이지 않으면 Arduino 보드를 재부팅하세요.
- 표시된 IP 주소를 메모해 두고, 이 주소를 스마트폰이나 PC의 웹 브라우저의 주소창에 입력하세요.
- 예시: http://192.168.0.2
- 아래 이미지와 같은 홈 페이지가 표시됩니다:

- Web Joystick 링크를 클릭하면 아래와 같은 Web Joystick 앱의 UI가 표시됩니다:

- 또는 IP 주소 뒤에 /web-joystick를 붙여 페이지에 직접 접속할 수도 있습니다. 예: http://192.168.0.2/web-joystick
- 조이스틱 영역을 클릭하고 드래그하여 가상 조이스틱을 제어한 뒤, 직렬 모니터에서 X/Y 좌표 값(-100에서 +100까지)을 확인해 보세요.
창의적인 맞춤화 - 코드를 프로젝트에 맞게 조정하기
2. 조이스틱 설정 구성하기
조이스틱은 다양한 매개변수로 구성될 수 있습니다:
기본 구성
// Create joystick with default settings (autoReturn=true, sensitivity=1)
DIYablesWebJoystickPage webJoystickPage;
고급 구성
// Create joystick with custom settings
// autoReturn=false: Joystick stays at last position when released
// sensitivity=5: Only send updates when movement > 5%
DIYablesWebJoystickPage webJoystickPage(false, 5);
조이스틱 사용 방법
웹 인터페이스 컨트롤
조이스틱 인터페이스는 제공합니다:
- 조이스틱 패드: 터치/마우스 입력용 원형 제어 영역
- 위치 표시기: 현재 조이스틱 위치를 표시합니다
- 좌표 표시: 실시간 X/Y 값(-100에서 +100까지)
- 중심점: 중립 위치를 위한 시각적 기준
조이스틱 조작
데스크탑 (마우스 제어)
- 클릭하고 드래그: 조이스틱을 클릭하고 드래그하여 이동
- 해제: 조이스틱이 중앙으로 돌아갑니다 (autoReturn=true인 경우)
- 클릭 위치: 조이스틱 위치를 직접 클릭으로 설정
모바일/태블릿(터치 컨트롤)
- 터치 및 드래그: 조이스틱을 터치하고 손가락을 드래그하여 이동
- 다중 터치: 정밀 제어를 위한 한 손가락 입력
- 해제: 활성화되면 중앙으로 자동 복귀
좌표계
조이스틱은 표준 직교 좌표계에서 좌표를 제공합니다:
- X축: -100 (왼쪽 끝)에서 +100 (오른쪽 끝)
- Y축: -100 (아래 끝)에서 +100 (위쪽 끝)
- 중심: X=0, Y=0 (중립 위치)
- 모서리: 대각 위치는 X와 Y 값을 함께 제공합니다
프로그래밍 예제
기본 조이스틱 핸들러
void setup() {
// Set up joystick callback for position changes
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
// Store the received values
currentJoystickX = x;
currentJoystickY = y;
// Print joystick position values
Serial.println("Joystick - X: " + String(x) + ", Y: " + String(y));
// Add your control logic here
});
}
모터 제어 예시
// Pin definitions for motor driver
const int MOTOR_LEFT_PIN1 = 2;
const int MOTOR_LEFT_PIN2 = 3;
const int MOTOR_RIGHT_PIN1 = 4;
const int MOTOR_RIGHT_PIN2 = 5;
const int MOTOR_LEFT_PWM = 9;
const int MOTOR_RIGHT_PWM = 10;
void setup() {
// Configure motor pins
pinMode(MOTOR_LEFT_PIN1, OUTPUT);
pinMode(MOTOR_LEFT_PIN2, OUTPUT);
pinMode(MOTOR_RIGHT_PIN1, OUTPUT);
pinMode(MOTOR_RIGHT_PIN2, OUTPUT);
pinMode(MOTOR_LEFT_PWM, OUTPUT);
pinMode(MOTOR_RIGHT_PWM, OUTPUT);
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
controlRobot(x, y);
});
}
void controlRobot(int x, int y) {
// Convert joystick coordinates to motor speeds
int leftSpeed = y + x; // Forward/backward + turn left/right
int rightSpeed = y - x; // Forward/backward - turn left/right
// Constrain speeds to valid range
leftSpeed = constrain(leftSpeed, -100, 100);
rightSpeed = constrain(rightSpeed, -100, 100);
// Control left motor
if (leftSpeed > 0) {
digitalWrite(MOTOR_LEFT_PIN1, HIGH);
digitalWrite(MOTOR_LEFT_PIN2, LOW);
analogWrite(MOTOR_LEFT_PWM, map(leftSpeed, 0, 100, 0, 255));
} else if (leftSpeed < 0) {
digitalWrite(MOTOR_LEFT_PIN1, LOW);
digitalWrite(MOTOR_LEFT_PIN2, HIGH);
analogWrite(MOTOR_LEFT_PWM, map(-leftSpeed, 0, 100, 0, 255));
} else {
digitalWrite(MOTOR_LEFT_PIN1, LOW);
digitalWrite(MOTOR_LEFT_PIN2, LOW);
analogWrite(MOTOR_LEFT_PWM, 0);
}
// Control right motor
if (rightSpeed > 0) {
digitalWrite(MOTOR_RIGHT_PIN1, HIGH);
digitalWrite(MOTOR_RIGHT_PIN2, LOW);
analogWrite(MOTOR_RIGHT_PWM, map(rightSpeed, 0, 100, 0, 255));
} else if (rightSpeed < 0) {
digitalWrite(MOTOR_RIGHT_PIN1, LOW);
digitalWrite(MOTOR_RIGHT_PIN2, HIGH);
analogWrite(MOTOR_RIGHT_PWM, map(-rightSpeed, 0, 100, 0, 255));
} else {
digitalWrite(MOTOR_RIGHT_PIN1, LOW);
digitalWrite(MOTOR_RIGHT_PIN2, LOW);
analogWrite(MOTOR_RIGHT_PWM, 0);
}
}
서보 제어 예제
#include <Servo.h>
Servo panServo; // X-axis control (left/right)
Servo tiltServo; // Y-axis control (up/down)
void setup() {
// Attach servos to pins
panServo.attach(9);
tiltServo.attach(10);
// Center servos initially
panServo.write(90);
tiltServo.write(90);
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
controlServos(x, y);
});
}
void controlServos(int x, int y) {
// Map joystick coordinates to servo angles
int panAngle = map(x, -100, 100, 0, 180); // X controls pan (0-180°)
int tiltAngle = map(y, -100, 100, 180, 0); // Y controls tilt (inverted)
// Move servos to calculated positions
panServo.write(panAngle);
tiltServo.write(tiltAngle);
Serial.println("Pan: " + String(panAngle) + "°, Tilt: " + String(tiltAngle) + "°");
}
LED 위치 표시등
// LED pins for position indication
const int LED_UP = 2;
const int LED_DOWN = 3;
const int LED_LEFT = 4;
const int LED_RIGHT = 5;
const int LED_CENTER = 13;
void setup() {
// Configure LED pins
pinMode(LED_UP, OUTPUT);
pinMode(LED_DOWN, OUTPUT);
pinMode(LED_LEFT, OUTPUT);
pinMode(LED_RIGHT, OUTPUT);
pinMode(LED_CENTER, OUTPUT);
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
updateLEDIndicators(x, y);
});
}
void updateLEDIndicators(int x, int y) {
// Turn off all LEDs first
digitalWrite(LED_UP, LOW);
digitalWrite(LED_DOWN, LOW);
digitalWrite(LED_LEFT, LOW);
digitalWrite(LED_RIGHT, LOW);
digitalWrite(LED_CENTER, LOW);
// Check if joystick is near center
if (abs(x) < 10 && abs(y) < 10) {
digitalWrite(LED_CENTER, HIGH);
return;
}
// Activate LEDs based on direction
if (y > 20) digitalWrite(LED_UP, HIGH);
if (y < -20) digitalWrite(LED_DOWN, HIGH);
if (x > 20) digitalWrite(LED_RIGHT, HIGH);
if (x < -20) digitalWrite(LED_LEFT, HIGH);
}
고급 구성
런타임 구성 변경
void setup() {
// Initial setup with default values
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
handleJoystickInput(x, y);
});
// Change settings at runtime
webJoystickPage.setAutoReturn(false); // Disable auto-return
webJoystickPage.setSensitivity(10.0); // Reduce sensitivity
}
void handleJoystickInput(int x, int y) {
// Handle different modes based on current settings
static bool precisionMode = false;
// Toggle precision mode with extreme positions
if (abs(x) > 95 && abs(y) > 95) {
precisionMode = !precisionMode;
if (precisionMode) {
webJoystickPage.setSensitivity(1.0); // High sensitivity
Serial.println("Precision mode ON");
} else {
webJoystickPage.setSensitivity(10.0); // Low sensitivity
Serial.println("Precision mode OFF");
}
}
}
데드 존 구현
void processJoystickWithDeadZone(int x, int y) {
const int DEAD_ZONE = 15; // 15% dead zone around center
// Apply dead zone filtering
int filteredX = (abs(x) < DEAD_ZONE) ? 0 : x;
int filteredY = (abs(y) < DEAD_ZONE) ? 0 : y;
// Scale values outside dead zone
if (filteredX != 0) {
filteredX = map(abs(filteredX), DEAD_ZONE, 100, 0, 100);
filteredX = (x < 0) ? -filteredX : filteredX;
}
if (filteredY != 0) {
filteredY = map(abs(filteredY), DEAD_ZONE, 100, 0, 100);
filteredY = (y < 0) ? -filteredY : filteredY;
}
// Use filtered values for control
controlDevice(filteredX, filteredY);
}
속도 램핑
class SpeedController {
private:
int targetX = 0, targetY = 0;
int currentX = 0, currentY = 0;
unsigned long lastUpdate = 0;
const int RAMP_RATE = 5; // Change per update cycle
public:
void setTarget(int x, int y) {
targetX = x;
targetY = y;
}
void update() {
if (millis() - lastUpdate > 20) { // Update every 20ms
// Ramp X value
if (currentX < targetX) {
currentX = min(currentX + RAMP_RATE, targetX);
} else if (currentX > targetX) {
currentX = max(currentX - RAMP_RATE, targetX);
}
// Ramp Y value
if (currentY < targetY) {
currentY = min(currentY + RAMP_RATE, targetY);
} else if (currentY > targetY) {
currentY = max(currentY - RAMP_RATE, targetY);
}
// Apply ramped values
applyControlValues(currentX, currentY);
lastUpdate = millis();
}
}
void applyControlValues(int x, int y) {
// Your control logic here with smooth ramped values
Serial.println("Ramped - X: " + String(x) + ", Y: " + String(y));
}
};
SpeedController speedController;
void setup() {
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
speedController.setTarget(x, y);
});
}
void loop() {
server.loop();
speedController.update(); // Apply speed ramping
}
하드웨어 통합 예시
로봇 자동차 제어
void setupRobotCar() {
// Motor driver pins
pinMode(2, OUTPUT); // Left motor direction 1
pinMode(3, OUTPUT); // Left motor direction 2
pinMode(4, OUTPUT); // Right motor direction 1
pinMode(5, OUTPUT); // Right motor direction 2
pinMode(9, OUTPUT); // Left motor PWM
pinMode(10, OUTPUT); // Right motor PWM
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
// Tank drive calculation
int leftMotor = y + (x / 2); // Forward/back + steering
int rightMotor = y - (x / 2); // Forward/back - steering
// Constrain to valid range
leftMotor = constrain(leftMotor, -100, 100);
rightMotor = constrain(rightMotor, -100, 100);
// Control motors
setMotorSpeed(9, 2, 3, leftMotor); // Left motor
setMotorSpeed(10, 4, 5, rightMotor); // Right motor
});
}
void setMotorSpeed(int pwmPin, int dir1Pin, int dir2Pin, int speed) {
if (speed > 0) {
digitalWrite(dir1Pin, HIGH);
digitalWrite(dir2Pin, LOW);
analogWrite(pwmPin, map(speed, 0, 100, 0, 255));
} else if (speed < 0) {
digitalWrite(dir1Pin, LOW);
digitalWrite(dir2Pin, HIGH);
analogWrite(pwmPin, map(-speed, 0, 100, 0, 255));
} else {
digitalWrite(dir1Pin, LOW);
digitalWrite(dir2Pin, LOW);
analogWrite(pwmPin, 0);
}
}
카메라 짐벌 제어
#include <Servo.h>
Servo panServo, tiltServo;
int panOffset = 90, tiltOffset = 90; // Center positions
void setupCameraGimbal() {
panServo.attach(9);
tiltServo.attach(10);
// Set initial center positions
panServo.write(panOffset);
tiltServo.write(tiltOffset);
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
// Calculate servo positions with offset
int panPos = panOffset + map(x, -100, 100, -45, 45); // ±45° range
int tiltPos = tiltOffset + map(y, -100, 100, -30, 30); // ±30° range
// Constrain to servo limits
panPos = constrain(panPos, 0, 180);
tiltPos = constrain(tiltPos, 0, 180);
// Move servos smoothly
panServo.write(panPos);
tiltServo.write(tiltPos);
});
}
RGB LED 색상 제어
const int RED_PIN = 9;
const int GREEN_PIN = 10;
const int BLUE_PIN = 11;
void setupRGBControl() {
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
// Convert joystick position to RGB values
int red = map(abs(x), 0, 100, 0, 255);
int green = map(abs(y), 0, 100, 0, 255);
int blue = map(abs(x + y), 0, 141, 0, 255); // Diagonal distance
// Apply quadrant-specific color mixing
if (x > 0 && y > 0) {
// Upper right: Red + Green = Yellow
blue = 0;
} else if (x < 0 && y > 0) {
// Upper left: Green + Blue = Cyan
red = 0;
} else if (x < 0 && y < 0) {
// Lower left: Blue + Red = Magenta
green = 0;
} else if (x > 0 && y < 0) {
// Lower right: Red only
green = blue = 0;
}
// Set RGB values
analogWrite(RED_PIN, red);
analogWrite(GREEN_PIN, green);
analogWrite(BLUE_PIN, blue);
});
}
문제 해결
일반적인 문제
- 조이스틱이 반응하지 않습니다
- 브라우저 콘솔에서 WebSocket 연결 상태를 확인
- 네트워크 연결 상태를 확인
- 브라우저 페이지를 새로고침
- 시리얼 모니터에서 오류를 확인
2. 거칠고 불규칙한 움직임
- 업데이트 빈도를 줄이려면 민감도 값을 높이십시오.
- 데드 존 필터링을 구현합니다.
- 부드러운 전환을 위한 속도 램핑을 추가합니다.
- 네트워크 지연 문제를 확인합니다.
- 자동 반환이 작동하지 않음
- AutoReturn 설정 확인: webJoystickPage.setAutoReturn(true)
- 브라우저 호환성 확인(일부 터치 기기는 다를 수 있습니다)
- 다양한 입력 방식으로 테스트하기(마우스 vs 터치)
- 전체 범위에 도달하지 못하는 값들
- 웹 인터페이스에서 조이스틱 보정 확인하기
- 콜백에서 좌표 계산을 검증하기
- 다양한 브라우저 및 기기 조합으로 테스트하기
디버깅 팁
포괄적인 디버깅 추가:
void debugJoystickState(int x, int y) {
Serial.println("=== Joystick Debug ===");
Serial.println("X: " + String(x) + " (" + String(map(x, -100, 100, 0, 100)) + "%)");
Serial.println("Y: " + String(y) + " (" + String(map(y, -100, 100, 0, 100)) + "%)");
Serial.println("Distance from center: " + String(sqrt(x*x + y*y)));
Serial.println("Angle: " + String(atan2(y, x) * 180 / PI) + "°");
Serial.println("=====================");
}
프로젝트 아이디어
로봇 공학 프로젝트
- 원격 제어 로봇 자동차
- 로봇 팔 제어
- 드론 비행 제어(기본 동작)
- 펫 로봇 내비게이션
가정 자동화
- 스마트 커튼 제어 (열기/닫기/위치)
- 카메라 팬/틸트 제어
- 조명 밝기 및 색상 제어
- 팬 속도 및 방향 제어
교육 프로젝트
- 좌표계 교육 도구
- 모터 제어 시연
- 서보 위치 제어 실험
- 게임 컨트롤러 인터페이스
예술 및 창의적 프로젝트
- LED 매트릭스 패턴 제어
- 음악 시각화 제어
- 드로잉 로봇 제어
- 인터랙티브 아트 설치
다른 예제와의 통합
WebSlider와 함께 사용
방향은 조이스틱으로, 속도/강도는 슬라이더로 조절하세요:
// Use joystick for direction, sliders for speed limits
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
int maxSpeed = getSliderValue(); // From WebSlider
int scaledX = map(x, -100, 100, -maxSpeed, maxSpeed);
int scaledY = map(y, -100, 100, -maxSpeed, maxSpeed);
controlRobot(scaledX, scaledY);
});
WebDigitalPins와 함께 사용하기
조이스틱 위치를 사용하여 디지털 핀의 상태를 트리거합니다:
webJoystickPage.onJoystickValueFromWeb([](int x, int y) {
// Activate pins based on joystick quadrants
webDigitalPinsPage.setPinState(2, x > 50); // Right quadrant
webDigitalPinsPage.setPinState(3, x < -50); // Left quadrant
webDigitalPinsPage.setPinState(4, y > 50); // Upper quadrant
webDigitalPinsPage.setPinState(5, y < -50); // Lower quadrant
});
다음 단계
WebJoystick 예제를 숙련한 후, 시도해 보세요:
- WebSlider - 추가적인 아날로그 제어를 위한
- WebDigitalPins - 이산형 온/오프 제어를 위한
- WebMonitor - 조이스틱 값을 디버깅하기 위한
- MultipleWebApps - 조이스틱과 다른 제어를 결합하기 위한
지원
추가 도움이 필요하신 경우:
- API 참조 문서를 확인하세요
- DIYables 튜토리얼 방문: https://newbiely.com/tutorials/arduino-uno-r4/arduino-uno-r4-diyables-webapps
- 아두이노 커뮤니티 포럼들