The WebJoystick example creates a virtual joystick interface accessible from any web browser. Designed for Arduino Uno R4 WiFi and DIYables STEM V4 IoT educational platform with enhanced robotics capabilities, built-in motor control features, and seamless integration with robotics educational modules. Perfect for controlling robots, vehicles, or any system requiring 2D position input.
Features
Virtual Joystick: Interactive joystick control via web interface
Real-time Coordinates: X/Y values from -100 to +100 for precise control
Touch & Mouse Support: Works on desktop, tablet, and mobile devices
Configurable Auto-Return: Option for joystick to return to center when released
Sensitivity Control: Adjustable sensitivity to prevent excessive updates
Visual Feedback: Real-time position display and coordinate values
WebSocket Communication: Instant response without page refresh
Center Position: Clear center position indicator for neutral control
Platform Extensible: Currently implemented for Arduino Uno R4 WiFi, but can be extended for other hardware platforms. See DIYables_WebApps_ESP32
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you. Additionally, some of these links are for products from our own brand, DIYables .
Connect the Arduino Uno R4/DIYables STEM V4 IoT board to your computer using a USB cable.
Launch the Arduino IDE on your computer.
Select the appropriate Arduino Uno R4 board (e.g., Arduino Uno R4 WiFi) and COM port.
Navigate to the Libraries icon on the left bar of the Arduino IDE.
Search "DIYables WebApps", then find the DIYables WebApps library by DIYables
Click Install button to install the library.
You will be asked for installing some other library dependencies
Click Install All button to install all library dependencies.
On Arduino IDE, Go to File Examples DIYables WebApps WebJoystick example, or copy the above code and paste it to the editor of 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 NETWORKconstchar WIFI_SSID[] = "YOUR_WIFI_SSID";constchar WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";// Create WebApp server and page instances// MEMORY SAFETY FIX: Use static factory to avoid stack object lifetime issuesstatic UnoR4ServerFactory serverFactory; // Static ensures lifetime matches programDIYablesWebAppServerwebAppsServer(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 valuesint currentJoystickX = 0;int currentJoystickY = 0;voidsetup() {Serial.begin(9600);delay(1000);// TODO: initialize your hardware pins hereSerial.println("DIYables WebApp - Web Joystick Example");// Add home and web joystick pageswebAppsServer.addApp(&homePage);webAppsServer.addApp(&webJoystickPage);// Optional: Add 404 page for better user experiencewebAppsServer.setNotFoundPage(DIYablesNotFoundPage());// Start the WebApp serverif (!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)}voidloop() {// Handle WebApp server communicationswebAppsServer.loop();// TODO: Add your main application code heredelay(10);}
Configure WiFi credentials in the code by updating these lines:
Click Upload button on Arduino IDE to upload code to Arduino UNO R4/DIYables STEM V4 IoT
Open the Serial Monitor
Check out the result on Serial Monitor. It looks like the below
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno R4 WiFi
Newbiely.ino
···
8Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno R4 WiFi' on 'COM15')
New Line
9600 baud
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
==========================================
Ln 11, Col 1
Arduino Uno R4 WiFi on COM15
2
If you do not see anything, reboot Arduino board.
Take note of the IP address displayed, and enter this address into the address bar of a web browser on your smartphone or PC.
Example: http://192.168.0.2
You will see the home page like below image:
Click to the Web Joystick link, you will see the Web Joystick app's UI like the below:
Or you can also access the page directly by IP address followed by /web-joystick. For example: http://192.168.0.2/web-joystick
Try controlling the virtual joystick by clicking and dragging on the joystick area and observe the X/Y coordinate values (-100 to +100) in the Serial Monitor.
Creative Customization - Adapt the Code to Your Project
2. Configure Joystick Settings
The joystick can be configured with different parameters:
Basic Configuration
// Create joystick with default settings (autoReturn=true, sensitivity=1)DIYablesWebJoystickPage webJoystickPage;
Advanced Configuration
// 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);
How to Use the Joystick
Web Interface Controls
The joystick interface provides:
Joystick Pad: Circular control area for touch/mouse input
Position Indicator: Shows current joystick position
Coordinate Display: Real-time X/Y values (-100 to +100)
Center Point: Visual reference for neutral position
Operating the Joystick
Desktop (Mouse Control)
Click and Drag: Click on joystick and drag to move
Release: Joystick returns to center (if autoReturn=true)
Click Position: Direct click to set joystick position
Mobile/Tablet (Touch Control)
Touch and Drag: Touch joystick and drag finger to move
Multi-touch: Single finger for precise control
Release: Automatic return to center (if enabled)
Coordinate System
The joystick provides coordinates in a standard Cartesian system:
X-axis: -100 (full left) to +100 (full right)
Y-axis: -100 (full down) to +100 (full up)
Center: X=0, Y=0 (neutral position)
Corners: Diagonal positions provide combined X/Y values
Programming Examples
Basic Joystick Handler
voidsetup() {// Set up joystick callback for position changes webJoystickPage.onJoystickValueFromWeb([](int x, int y) {// Store the received values currentJoystickX = x; currentJoystickY = y;// Print joystick position valuesSerial.println("Joystick - X: " + String(x) + ", Y: " + String(y));// Add your control logic here });}
void setupRobotCar() {// Motor driver pinspinMode(2, OUTPUT); // Left motor direction 1pinMode(3, OUTPUT); // Left motor direction 2pinMode(4, OUTPUT); // Right motor direction 1pinMode(5, OUTPUT); // Right motor direction 2pinMode(9, OUTPUT); // Left motor PWMpinMode(10, OUTPUT); // Right motor PWM webJoystickPage.onJoystickValueFromWeb([](int x, int y) {// Tank drive calculationint leftMotor = y + (x / 2); // Forward/back + steeringint 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, intspeed) {if (speed > 0) {digitalWrite(dir1Pin, HIGH);digitalWrite(dir2Pin, LOW);analogWrite(pwmPin, map(speed, 0, 100, 0, 255)); } elseif (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); }}
Use joystick for direction and sliders for speed/intensity:
// Use joystick for direction, sliders for speed limitswebJoystickPage.onJoystickValueFromWeb([](int x, int y) {intmaxSpeed = getSliderValue(); // From WebSliderint scaledX = map(x, -100, 100, -maxSpeed, maxSpeed);int scaledY = map(y, -100, 100, -maxSpeed, maxSpeed); controlRobot(scaledX, scaledY);});
Combine with WebDigitalPins
Use joystick positions to trigger digital pin states:
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});
Next Steps
After mastering the WebJoystick example, try:
WebSlider - For additional analog control
WebDigitalPins - For discrete on/off control
WebMonitor - For debugging joystick values
MultipleWebApps - Combining joystick with other controls
Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!