How To Make a DIY Mouse Jiggler with Raspberry Pi Pico
If you need a PC, especially a company laptop, and need to make sure you’re active even when you’re away, Mouse Jiggler is the way to go. Most company-issued computers don’t allow you to install software or spy on running apps. So using a device that moves the pointer automatically and appears to the OS as a mouse solves the problem. You can also go to Amazon and purchase USB devices ranging from $7 to $40. $4 Raspberry Pi Pico.
In this how-to we build a DIY mouse jiggler using a Raspberry Pi Pico and CircuitPython. This $4 project saves you a lot of time and money because you don’t need anything else, not even a screwdriver. I used Pico, but please note that these instructions will work for any microcontroller (almost any) with an RP2040 that supports CircuitPython.board like Adafruit Trinky QT2040Another $8 RP2040-powered microcontroller is even better than the Pico because it has USB Type-A built in, so you don’t even need a wire to connect it to your PC.
Configure CircuitPython for Mouse Jiggler
1. Go to the official CircuitPython page for Raspberry Pi Pico and download the latest released UF2 firmware image. At the time of writing this was CircuitPython 8 Beta 6. If you’re using another RP2040-powered board, find it. UF2 page on Circuitpython.org.
2. While holding down the BOOTSEL button, connect the Raspberry Pi Pico to your computer. New drive, RPI-RP2 is coming
3. Copy the downloaded CircuitPython UF2 file to the RPI-RP2. This will write CircuitPython to the Pico’s internal flash storage. A new drive, CIRCUITPY, will appear.
Before we continue, we need a number of CircuitPython libraries. These libraries of pre-built code add extra functionality to your project.
1. download Library bundle For the same version of CircuitPython that is installed on Pico. I installed CircuitPython 8, so I downloaded the version 8.x bundle.
2. Unzip the bundle to your desktop When then open the lib folder contained within.
3. Copy the adafruit_hid folder. From this lib folder navigate to the lib folder on your CIRCUITPY drive.
Writing CircuitPython Code for Mouse Jigler
1. Download and install Thonny if you don’t already have it. Thonny is a Python editor covering Python 3, MicroPython and CircuitPython.
2. Open Thonny and[ツール]>>[オプション]Go to.
3. Select Interpreter, set Interpreter to CircuitPython, Port to Auto, and click OK.Thonny connects to Pico W running CircuitPython.
4. Click File >> Open and open code.py on your CircuitPython device (Raspberry Pi Pico).
Five. Remove any code that is already in the file.
6. Import the USB_HID library, Next is Adafruit’s mouse support library.
import usb_hid
from adafruit_hid.mouse import Mouse
7. Import the sleep function from the time library. Use this to add a short delay between each move.
from time import sleep
8. Create an object m. Control the virtual mouse.
m = Mouse(usb_hid.devices)
9. Create a loop that runs code continuously. For testing purposes, you can replace this loop with a for loop. Otherwise the code will lock you up and you won’t be able to work.
while True:
Alternate tests for loops
for i in range(2):
Ten. Use Move to move the cursor 100 pixels to the left.
m.move(-100, 0, 0)
11. Print a message to the Python shell and pause for 0.5 seconds. Printing is useful for debugging code.
print("I am working")
12. Now move the mouse 100 pixels to the right, print another message, and pause for another half second.
m.move(100, 0, 0)
print("I am so busy")
sleep(0.5)
13. Move the mouse down 100 pixels, print a message, then pause again.
m.move(0, -100, 0)
print("So much to do")
sleep(0.5)
14. Move the mouse up 10 pixels, print the message, then pause again.
m.move(0, 100, 0)
print("I need a vacation")
sleep(0.5)
15. Save the code as code.py on your Raspberry Pi Pico (CircuitPython device). CircuitPython automatically runs code.py when Pico is connected to your computer (MicroPython can also run this in main.py and boot.py). The OS knows this is “just a mouse”, so the project can be used on any OS.
complete code listing
import usb_hid
from adafruit_hid.mouse import Mouse
from time import sleep
m = Mouse(usb_hid.devices)
while True:
m.move(-100, 0, 0)
print("I am working")
sleep(0.5)
m.move(100, 0, 0)
print("I am so busy")
sleep(0.5)
m.move(0, -100, 0)
print("So much to do")
sleep(0.5)
m.move(0, 100, 0)
print("I need a vacation")
sleep(0.5)
Add buttons to your DIY jiggler
A plug-and-play mouse jiggler is convenient, but a jiggler that can be activated at the push of a button is more convenient. Here I modified the code to include a push button on GPIO12 that toggles the jiggler on and off.
What you need for this project
- pico on raspberry pi
- half size breadboard
- I press the button
- 2 x male to male wires
The circuit is very simple, just connect the pushbutton to GPIO 12 and GND. GPIO 12 is set to pull up, connecting the pin to GND when the button is pressed. This will change the state of the pin to Low and we will use this as a toggle for our Ziggler code. This project builds on previous versions of the code.
1. Add two imports: board and digitalio. These two libraries provide access to the GPIO and allow setting the state of the GPIO pins.
import usb_hid
from adafruit_hid.mouse import Mouse
from time import sleep
import board
from digitalio import DigitalInOut, Direction, Pull
2. Create an object, Button, and set it to GPIO12.
m = Mouse(usb_hid.devices)
button = DigitalInOut(board.GP12)
3. Configure GPIO 12 as an input and pull the pin high. Some GPIO pins have internal resistors that can be pulled to 3.3V or pulled to GND.
button.direction = Direction.INPUT
button.pull = Pull.UP
Four. Create two variables, active and button_press, and store 0 in each. These two variables store 0 or 1 and identify if the jiggler is active and the button is pressed. Both are set to inactive using 0 at the beginning of the code.
active = 0
button_press = 0
Five. Add a while True loop to run the code.
while True:
6. Create a conditional statement that checks the state of the button and the value stored in the active. Pressing the button changes the state of GPIO 12 from high (True) to low (False). When pressed, the conditional statement actively checks the stored value. The default value is 0, which means Ziggler is not active.
if button.value == False and active == 0:
7. Update the variable to 1, then print a message to the Python shell.
active = 1
button_press = 1
print("Turning on")
8. Add a 5 second pause to this condition. This gives you time to press the button and the code registers the press and provides enough debounce time to prevent multiple button presses.
sleep(5)
9. Use an else if condition to check that the button is not currently pressed and that the value stored in active and button_press is 1. This means you have to press a button to run some mouse jiggler code.
elif button.value == True and active == 1 and button_press == 1:
Ten. Reuse mouse jiggler code to move the mouse around the screen.
m.move(-100, 0, 0)
print("I am working")
sleep(0.5)
m.move(100, 0, 0)
print("I am so busy")
sleep(0.5)
m.move(0, -100, 0)
print("So much to do")
sleep(0.5)
m.move(0, 100, 0)
print("I need a vacation")
sleep(0.5)
11. Create another conditional statement to check that the button was pressed and that active and button_press contain the value 1. This means the user wants to turn off the Ziggler code.
elif button.value == False and active == 1 and button_press == 1:
12. Print a message to the user, reset the value stored in the variable, and then pause for 5 seconds.
print("Turning off")
active = 0
button_press = 0
sleep(5)
13. Save the project as code.py on your Raspberry Pi Pico. The board will reset and your code will run. Press the button to toggle the jiggler code on and off.
complete code listing
import usb_hid
from adafruit_hid.mouse import Mouse
from time import sleep
import board
from digitalio import DigitalInOut, Direction, Pull
m = Mouse(usb_hid.devices)
button = DigitalInOut(board.BUTTON)
button.direction = Direction.INPUT
button.pull = Pull.UP
active = 0
button_press = 0
while True:
if button.value == False and active == 0:
active = 1
button_press = 1
print("Turning on")
sleep(5)
elif button.value == True and active == 1 and button_press == 1:
m.move(-100, 0, 0)
print("I am working")
sleep(0.5)
m.move(100, 0, 0)
print("I am so busy")
sleep(0.5)
m.move(0, -100, 0)
print("So much to do")
sleep(0.5)
m.move(0, 100, 0)
print("I need a vacation")
sleep(0.5)
elif button.value == False and active == 1 and button_press == 1:
print("Turning off")
active = 0
button_press = 0
sleep(5)
Special Adafruit Trinket QT2040 Version
Adafruit Trinky QT2040 It is a USB dongle type board equipped with RP2040 of Raspberry Pi. It doesn’t have traditional GPIO per se, but uses a StemmaQT connector for use with compatible breakout boards.
This special version of the Button Toggle Code uses a board built into the User Button (BOOT) to toggle the code on/off and uses a NeoPixel to indicate if the Ziggler is active. This code is almost identical to the previous button toggle code, modified to use a button reference (a CircuitPython abstraction) and set up NeoPixels.
1. download Library bundle For the same version of CircuitPython that is installed on Pico. I installed CircuitPython 8, so I downloaded the version 8.x bundle.
2. Unzip the bundle to your desktop When then open the lib folder contained within.
3. Copy the following files/folders from this lib folder to the lib folder of your CIRCUITPY drive.
adafruit_hid
adafruit_pixelbuf.mpy
neopixel.mpy
Four. Open a new file in Thonny and copy the code from the previous example.
Five. Add a line to your imports to import the NeoPixel library.
import neopixel
6. After setting up the button, add a new line to create a connection to a single NeoPixel on the Trinkey QT2040.
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
7. Scroll down to the else if condition that turns on Ziggler. Press the button here. The active and button_press variables are set to 1. Add a line that sets the pixel to red at 1/4 brightness.
pixel.fill((32, 0, 0))
8. Scroll down to where the Ziggler code is off. This is where the button was pressed and the active and button_press variables are set to 1. Change the color of the NeoPixel to a quarter-brighter green.
pixel.fill((0, 32, 0))
9. Save the code as code.py on the Adafruit Trinkey QT2040. The board will reset and the code will start. Press the button to switch the code.
complete code listing
import usb_hid
from adafruit_hid.mouse import Mouse
from time import sleep
import board
from digitalio import DigitalInOut, Direction, Pull
import neopixel
m = Mouse(usb_hid.devices)
button = DigitalInOut(board.BUTTON)
button.direction = Direction.INPUT
button.pull = Pull.UP
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
active = 0
button_press = 0
while True:
if button.value == False and active == 0:
active = 1
button_press = 1
print("Turning on")
sleep(5)
elif button.value == True and active == 1 and button_press == 1:
pixel.fill((32, 0, 0))
m.move(-100, 0, 0)
print("I am working")
sleep(0.5)
m.move(100, 0, 0)
print("I am so busy")
sleep(0.5)
m.move(0, -100, 0)
print("So much to do")
sleep(0.5)
m.move(0, 100, 0)
print("I need a vacation")
sleep(0.5)
elif button.value == False and active == 1 and button_press == 1:
pixel.fill((0, 32, 0))
print("Turning off")
active = 0
button_press = 0
sleep(5)