A hardware mouse jiggler using the Waveshare RP2350-One (CircuitPython) that masks as an optical mouse to prevent sleep.
The device sends Bezier curve mouse movements — smooth, curved paths with natural acceleration that mimic human usage. Unlike simple pixel twitches or rigid straight lines, Bezier curves introduce random variation in angle, distance, and speed that makes it harder for endpoint detection software (EDR) to identify the repetitive patterns typical of automated movement.
When done correctly, it should make it harder to tell the difference between the Waveshare and a standard optical mouse because the device sends legitimate USB descriptor data with the correct VID/PID (0x093A:0x2510).
Software-based mouse jigglers are detectable by monitoring software that analyzes USB activity patterns. Hardware-based jigglers operate at the USB protocol level, the computer sees a physical mouse device, not a running process. Commercial hardware jigglers exist, but a programmable microcontroller like the RP2350-One provides the same functionality with full control over the USB identity.
Would we need to alter the code or do something special for the mouse jiggler to work cross-OS?
No. The code used here already works on the common operating systems like Windows, macOS, and Linux. This is due to the use of the USB HID standard. It is a universal protocol that has been built into the core of all modern operating systems for decades. The computer doesn't read the code on the Waveshare, it only reads the standardized USB signals.
- Prerequisites
- Setup Guide
- How It Works
- Why Waveshare RP2350-One
- Further Reading
- Attribution & Licensing
- Terms of Use
- Credits & Attribution
-
Waveshare RP2350-One (a Raspberry PI Pico/Pico W will suffice)
-
If going with a PI Pico/Pico W a micro-USB to USB-A cable (must support data transfer, not just charging).
-
A computer (to flash the initial code).
It is recommended to use CircuitPython instead of MicroPython. CircuitPython makes it straightforward to alter the USB descriptors (the "fingerprint" the computer sees).
-
CircuitPython Firmware: Flashed onto the device.
-
Adafruit HID Library: Contains the mouse control functions.
-
Hold the BOOTSEL button on the device (Waveshare or Pico).
-
Plug it into the computer.
-
Release the button; a drive named RPI-RP2 will appear.
-
Download the latest stable .uf2 file for Waveshare (or Pico) from: https://circuitpython.org/board/waveshare_rp2350_one/
-
Drag and drop the .uf2 file onto the RPI-RP2 drive. The device will reboot as a drive named CIRCUITPY.
-
Download the Adafruit CircuitPython Library Bundle from: https://circuitpython.org/libraries
-
Select the bundle matching your CircuitPython version. For version 10.2.1, download the file named: adafruit-circuitpython-bundle-10.x-mpy-YYYYMMDD.zip
-
Unzip the bundle on your computer.
-
Open the extracted folder and navigate to its lib directory.
-
Copy ONLY the following into the lib folder on your CIRCUITPY drive:
- The folder named adafruit_hid
- The file named neopixel.mpy
Do not copy the entire bundle. The RP2350-One has 4MB flash and the bundle contains hundreds of libraries that will not fit.
CircuitPython looks for specific filenames during its boot sequence. Your USB configuration file must be named exactly boot.py and placed in the root directory of the CIRCUITPY drive (the same level as boot_out.txt).
Why: USB identification code must run before the computer's operating system enumerates the USB device. CircuitPython explicitly looks for boot.py at startup for this purpose. This is where the VID/PID spoofing (0x093A:0x2510) and the storage/CDC/MIDI disabling are configured.
The mouse movement file must be named exactly code.py and placed in the root directory, replacing the original "Hello World" file.
Why: Once the device boots, CircuitPython automatically executes code.py as the main loop in an infinite cycle.
The code.py in this project uses cubic Bezier curves to generate smooth, natural mouse movements rather than rigid robotic lines (which corporate monitoring software flags).
The cursor wanders across the screen in curved arcs with natural acceleration — slow start, fast middle, slow end, mimicking how a human moves a mouse. Paths range from 30–200 pixels, sent every 5–15 seconds.
By default, the device (regardless of it being the Waveshare RP2350-One, a Raspberry Pi Pico or Pico W) acts as both a mouse and a flash drive (CIRCUITPY folder). An IT department looking closely at device logs will see a "Composite Device" (Mouse + Mass Storage). The storage.disable_usb_drive() call in boot.py hides the drive, making it look more like a mouse.
Note: If you disable the USB drive via boot.py, the CIRCUITPY drive will no longer appear when the device is plugged in. To regain access, see Recovery: Unlocking a Hidden Device.
You need to go into the boot.py code and uncomment the line
storage.disable_usb_drive()After you have done that you can unmount (be sure to not unmount to not risk any files being corrupted) the device and either press the BOOT button on the device or unplug and plug the device into the desired device.
Recovery: Unlocking a Hidden Device
If you disable the USB drive via boot.py, the CIRCUITPY drive will no longer appear when the device is plugged in. To regain access:
-
Press the BOOT button on the circuit board.
-
You will see a yellow blinking light. Press the RESET button once.
The device will now appear on the computer, but it will be named CIRCUITPY (not the device you choose to mask it as via the boot.py).
Now you can edit the files again.
A cubic Bezier curve is a smooth path defined by four points:
P0 (start) --- P1 (control) --- P2 (control) --- P3 (end)
The math:
B(t) = (1-t)^3*P0 + 3*(1-t)^2*t*P1 + 3*(1-t)*t^2*P2 + t^3*P3
Where t goes from 0.0 (at P0) to 1.0 (at P3). The control points P1 and P2 pull the curve toward them without the curve passing through them, creating natural arcs and S-curves.
Why it looks human:
- Curved paths — Humans rarely move in straight lines. Control points offset perpendicular to the travel direction create natural arcs.
- Variable speed — A smoothstep easing function (
t^2 * (3 - 2t)) makes the cursor accelerate out of the start and decelerate into the end, just like a real hand movement. - Random variation — Each path has a random angle, distance, curvature, and duration. No two movements are alike.
Why it mitigates detection: Endpoint detection software (EDR) flags straight lines at constant speed, identical movements repeating on a timer, and movements of exactly 1-2 pixels back and forth.
Bezier curves produce curved, irregular trajectories with variable speed and random path length and duration each time.
The built-in RGB LED on the RP2350-one indicates the device's current state:
| Color | Meaning | What's Happening |
|---|---|---|
| 🟢 Green | Idle | USB bus is silent — mimicking a human not using the mouse |
| 🟡 Yellow | Moving | HID reports being sent along a Bezier curve |
| 🔴 Red | Error | HID write failed |
Illustration of failure
When handling bare circuit boards like the RP2350-One, electrostatic discharge (ESD) can damage surface-mount components. Before touching the board:
-
Ground yourself by touching a grounded metal surface (such as a computer case plugged into a wall outlet).
-
Alternatively, wear an anti-static wrist strap connected to ground.
-
Store the board in an anti-static bag when not in use.
-
Avoid working on carpet or synthetic surfaces that generate static.
To further protect the board you could make use of a case either buy one or 3D print a case.
Community-designed cases for the RP2350-One are available at:
Search for "RP2350".
For this project the 3D printed RP2350-One clip on case by @jbp_1792760 at https://www.printables.com was used.
-
We don't need a cable because the USB connector is part of the circuit board, we just plug it into the USB port like a regular flash drive.
-
Small form factor makes it portable and could be complemented with a 3D-printed case to blend in and look like a regular flash drive.
-
Radio silence: It uses the RP2350A chip that doesn't have any Wi-Fi or Bluetooth.
-
More than enough disk space: With 4 MB flash memory we have more than enough space for CircuitPython and other scripts.
-
RGB light that can be used for notifying the end user of script execution.
- Security Analysis & Hardware Identification — EDR detection risks, OS-specific hardware verification commands
This repository is licensed under the Creative Commons Attribution 4.0 International (CC BY 4.0) license.
Any redistribution, mirroring, or derivative use of this project must credit the source repository:
-
Author Name:
HelixCipher -
Source Link: https://github.com/HelixCipher/mouse-jiggler
-
Change Log: Clearly state if modifications were made to the original code structure.
This research utilizes materials from the mouse-jiggler repository by
HelixCipher, licensed under CC BY 4.0. Source: https://github.com/HelixCipher/mouse-jiggler
For the complete legal framework, waiver of liability, and systemic compliance definitions, review the DISCLAIMER.md before cloning this repository.
This repository is for educational purposes. Use the tool responsibly and lawfully. Do not use to facilitate illegal activity.
The 3D printed case used in this project is based on the work of @jbp_1792760 at https://www.Printables.com, used under a Creative Commons (4.0 International License) Attribution—Noncommercial—No Derivatives license. You can find the case here.




