A physical productivity controller that executes Windows shortcuts and web automation using an analog joystick. It bridges hardware inputs with OS commands using a background Python script.
The Challenge: The Arduino Uno (unlike the Leonardo/Micro) lacks native HID (Human Interface Device) capabilities, meaning it cannot be directly recognized as a USB keyboard or mouse by the computer to execute shortcuts.
The Solution: I created a Serial-to-Automation Bridge.
- Arduino: Reads raw analog values (X/Y axis) and digital states (button) and streams them via Serial Port.
- Python: Listens to the stream, interprets the coordinates, and uses
pyautoguito inject system-level keystrokes andwebbrowserfor navigation.
Result: A custom macro controller using entry-level hardware without needing complex firmware reflashing or HID-specific boards.
- Board: Arduino Uno.
- Input: Analog Joystick Module (KY-023 or similar).
- Languages: C++ (Arduino) and Python 3.x.
- Python Libraries:
pyserial,pyautogui.
Configuration based on the provided sketch:
| Joystick Pin | Arduino Pin | Description |
|---|---|---|
| VRx | A0 | X-Axis Analog Input |
| VRy | A1 | Y-Axis Analog Input |
| SW | D2 | Digital Switch (Button) |
| VCC | 5V | Power |
| GND | GND | Ground |
The Python script maps the physical movements to the following actions:
| Movement | Action | Function |
|---|---|---|
| Right (X > 723) | Alt + Tab |
Switch Windows / App Switcher |
| Left (X < 300) | Open URL | Opens YouTube |
| Up (Y > 723) | Ctrl + W |
Close current tab/window |
| Down (Y < 300) | Open URL | Opens Netflix |
| Click (Z == 0) | Win + D |
Minimize All / Show Desktop |
You can easily modify the code to trigger your own shortcuts or open different websites.
-
Change Websites: Open
joystick.pyand modify the URL variables at the top:URL_TO_OPEN_1 = "[https://www.stackoverflow.com](https://www.stackoverflow.com)" # Change this! URL_TO_OPEN_2 = "[https://www.spotify.com](https://www.spotify.com)"
-
Change Shortcuts: Look for the
pyautogui.hotkey()functions inside the loop and change the keys. For example, to make "UP" copy text instead of closing a tab:# Change 'ctrl', 'w' to 'ctrl', 'c' pyautogui.hotkey('ctrl', 'c')
Follow these steps strictly to avoid Serial Port conflicts.
- Open
analog_joystick.inoin Arduino IDE. - Connect your board via USB.
- Select the correct Board and Port.
- Click Upload.
Once uploaded, COMPLETELY CLOSE THE ARDUINO IDE.
If you leave the IDE (or Serial Monitor) open, Python won't be able to access the USB port, triggering an
Access Deniederror.
Open a terminal in the project folder and install dependencies:
pip install -r requirements.txtOpen joystick.py with a text editor (or VS Code) and verify the port line:
SERIAL_PORT = 'COM3' # <--- Make sure this matches your Arduino port- Keep your Arduino connected.
- In your terminal, run the script:
python joystick.py- Move the joystick! You should see your computer reacting to the commands.
Project developed by franlrs. Distributed under the MIT License.

