Proximity Switch

by KT-AT in Circuits > Assistive Tech

891 Views, 11 Favorites, 0 Comments

Proximity Switch

vcnl4040 setup.JPG
PXL_20250227_144411420.jpg

Edited 5/1/2025 with improved housing designed by Christopher Archie (for the RP2040) and Robert Shirley (for the sensor). Thank you both so much!


Edited 5/13/2025 with improved cover photo


Edited 5/14/2025 with code for additional keypresses


Edited 6/17/2025 to remove multiple sets of code and add json file to modify code


Edited 6/20/2025 to add light-up function!


Proximity sensors are in many kinds of technology, like sinks, water fountains, paper towel dispensers, and automatic doors that activate without having to be touched. This same technology can help individuals with disabilities who struggle to use interfaces such as touchscreens, computers, keyboards, and traditional computer mice. These sensors can send a signal to a computer or tablet to activate an icon (enter keypress or left mouse click) or move to the next icon (tab keypress) when they detect that something is close to it.

In the past year, I have been on a journey with this technology that resulted in a $25, highly customizable proximity switch that gives access to computers and tablets without having to touch them using an access method called switch scanning. Commercially available proximity switches and adaptors that connect them to computers or tablets can cost hundreds of dollars and have limited customization options in terms of both appearance and function.

If you're anything like me, you might be thinking that you could never make something like that because you don't know how to code or solder or 3D print.

Do you know how to copy and paste?

Do you know how to left and right click on files and links?

Do you know how to get to your download folder?

Congratulations, you have the skills you need to make a proximity switch!

(The 3-D printing is optional. Making a case for the electronics can keep the wires in place better, protect them, and make them look nicer, but it's not required for them to work.)

Use a printed circuit board (PCB) and a proximity sensor to create a customizable proximity switch that can activate any keypress. No soldering is required or coding is required! You need to know how to download and unzip files, copy, and paste. That's it!


Issues that I know about:

  1. Sometimes there's a line between bullets that I copied and pasted from the PowerPoint and sometimes there isn't. I don't know why. I like the double-spacing better but I don't know how to tell it to that and formatting is a bear.
  2. Introduction: Needs a video of the switch in action controlling something


Please leave feedback telling me how to make this better!

Edited 2/28/2025 to add more information and materials about mounting, and add the STL for the mount.

Edited 3/20/2025 to describe more about what proximity sensors do.

Edited 5/1/2025 to add improved housing 3mf.

Edited 6/17/2025 to add json file.

Supplies

QT Py labled.jpg
vcnl4040 labeled.jpg
Stemma QT cable.jpg
USB A to C cable.jpg
vcnl in housing.jpg

Adafruit QT Py RP2040 printed circuit board

VCNL 4040 proximity sensor

STEMMA QT cable to connect the proximity sensor to the printed circuit board

USB A to USB C cable that transfers power AND data (can also be easily purchased from Amazon, just check the listing to make sure it specifies that the cable transfers power AND data)

OPTIONAL


Modular hose for mounting (the QT Py 2040 is small, but not small enough to thread through modular hose)

See attached file for a clamp with an opening that 1/4 inch modular hose can fit into. Recommended material is ABS.

Industrial twist ties (can loop around the outside of the modular hose to secure the wires and housing)


Plug Everything In

i am still plugged in.jpg

Connect the VCNL 4040 proximity sensor to the QT Py using the STEMMA cable (black cable with the four different colored wires exposed at the ends)

  1. Plug one end into the smaller connector on the QT Py (the word BOOT is written above it) and the other into either connector on the VCNL 4040 proximity sensor (both work the same).

Plug the QT Py into your computer using the metal USB-C cable (small oval end goes into the QT Py, the larger rectangular end goes into your computer).

For Mac users: You might need a USB adaptor, but this setup has been tested and works on Mac!


Put the QT Py Into Bootloader Mode

qt py boot and reset button.jpg
RPI-RP2 screenshot.jpg
  1. connect the QT-Py to your computer with the USB cable.
  2. press and hold the Boot button.
  3. press and release the Reset button.
  4. release the Boot button.

Make sure it worked!


•Look on the left where your list of drives are

•You should see a drive that says RP1-RP2 around where you’d see a USB drive pop up when you plug one of those in.

Downloads

Troubleshoot If Needed

USB A to C cable.jpg
  1. Make sure you are holding down the boot button WHILE you hold down AND release the reset button. Don't release the boot button until AFTER you've pressed and released the reset button.
  2. If you don't see the RPI-RP2 drive, make sure you have a USB cable that transfers power AND data. You can't tell just by looking! If you're not positive that your cable transfers both data AND power, try another cable.

Download Circuit Python

circuit python screenshot.jpg
  1. Go to https://circuitpython.org/board/adafruit_qtpy_rp2040/
  2. You need the most recent version, which was 9x at the time of making this tutorial
  3. Click, "Download .UF2 now"

Put CircuitPython on QT Py

•Open your downloads folder

•Find the file adafruit-circuitpython-adafruit_metro_rp2040-en_US-9.1.3.uf2 (it will probably be at the top for you)

•Click and drag that file down to RP1-RP2, or copy and paste

•You can also right click, go to “send to,” and select RP1-RP2

•The name of the drive will go away, it will beep, and the name of the drive will reappear as CIRCUITPY

Download File Libraries

circuit python libraries.jpg

•Download the Circuit Python libraries from https://circuitpython.org/libraries

  1. Scroll down a little to see the bundle

•Open your downloads file and find adafruit-circuitpython-bundle-9.x-mpy-20240910 (it will probably be at the top of the folder)

•If the number at the end of the file name is different, an updated version may have come out since this tutorial was made

•Unzip it!

Downloads

Put Files on QT Py

circuitpy drive screenshot.jpg

•Using the search function in Windows Explorer, search for the following file inside of the adafruit-circuitpython-bundle-9.x-mpy-20240910 folder :

  1. Adafruit_vcnl4040.mpy

•Drag that file to your CIRCUITPY drive and put it in the lib folder

  1. Make sure you put it inside the lib folder! The computer will be looking for it in that specific location
  2. You can also copy (ctrl + c) and paste (ctrl + v) the files and folders to the lib drive on CIRCUITPY

•Repeat that process for the following folders:

  1. adafruit_bus_device (a folder)
  2. adafruit_register (a folder)
  3. adafruit_hid (a folder)
  4. neopixel.mpy

NOTE: For some reason there are two files called neopixel.mpy. One is in another folder called seesaw and won't work. The other one is in the main adafruit-circuitpython-bundle-9x-mpy folder and does work, as of 6/20/2025. Hopefully they will change that in future versions, because it's easy to get the wrong one.

Put Code on QT Py

Select the code you want, highlight it, and copy it. Click on your CIRCUITPY drive and find the code.py document. Open it and paste your code into it.

Put JSON File on CIRCUITPY

Download config.json and drag it on to CIRCUITPY. Make sure it's in the main CIRCUITPY drive, NOT in lib like the files in step 7!

Downloads

Download Mu Editor to Troubleshoot and Customize

mu editor screenshot.jpg

•Get directions for how to download Mu Editor from https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor

•Get Mu Editor from https://codewith.mu

•Choose Circuit Python when prompted at start-up

If your switch is plugged it and set up, it should automatically open up the code. Click serial mode to see exactly what your switch is doing second by second!


When you plug in your switch, it will automatically turn on. The light on the QT Py RP2040 will flash green whenever it activates and the keypress will occur.

Customize the Code With the Json File

This switch is designed to be easily customizable, even if you’re new to coding! Instead of changing the main code.py file, you'll simply edit a special settings file called config.json.

Think of config.json as your switch's instruction manual. It tells the code.py how sensitive to be, which key to press, and how quickly it should react, and now even controls the built-in NeoPixel light!

How to Edit config.json

  1. Plug in your QT Py RP2040 to your computer. The CIRCUITPY drive should appear.
  2. Open config.json:Navigate to your CIRCUITPY drive in your file explorer.
  3. Find the file named config.json.
  4. Right-click on config.json and select "Open With...".
  5. Recommended: Choose Mu Editor. This is the easiest option, as it's what you use for code.py anyway!
  6. Alternatively (if Mu not installed/preferred):On Windows, choose Notepad.
  7. On Mac, choose TextEdit. (If using TextEdit, make sure it's in "Plain Text" mode: Format > Make Plain Text if it opens as rich text).
  8. Make Your Changes:Edit the values inside the config.json file. Be careful not to delete any commas, colons, or quotation marks unless you're changing the text itself.

Here's what each setting controls:


proximity_threshold

Number

This is how much the sensor reading needs to change for the switch to activate. A higher number means the sensor is less sensitive (requires more movement). A lower number means it's more sensitive (reacts to smaller movements).

Change the number.

5 (very sensitive), 10 (default), 20 (less sensitive)

triggered_key

Text

This determines which key on your keyboard the switch will simulate pressing. You need to use the specific Keycode name, surrounded by double quotes.

Change the text inside the double quotes.

"TAB", "SPACE", "ENTER", "UP_ARROW", "LEFT_ARROW", "Z", "F5" (see list below for more options)

key_press_duration_seconds

Number

This is how long, in seconds, the simulated key is held down. A very short duration (like 0.1) is usually fine. If you need it to act like a longer press, increase this value.

Change the number (can use decimals).

0.1 (default, very quick), 0.5 (half second), 1.0 (one second)

loop_delay_seconds

Number

This is how long, in seconds, the switch waits between checking the sensor. A smaller number means it checks more often (more responsive but uses a little more power). A larger number means it checks less often (less responsive but uses less power).

Change the number (can use decimals).

0.1 (very responsive), 0.25 (default), 0.5 (slower checks)

only_closer_trigger

Boolean

Controls when the switch activates:

• true: Activates ONLY when an object gets closer to the sensor.

• false: Activates when an object gets closer or farther by the proximity_threshold.

Change to true or false (all lowercase, no quotes).

true, false

enable_debug_prints

Boolean

Controls whether messages about current proximity readings are shown in the Mu Editor Serial Console.

• true: Shows real-time proximity values.

• false: Keeps the console clean (recommended for normal use).

Change to true or false (all lowercase, no quotes).

true, false

enable_neopixel_feedback

Boolean

Controls whether the QT Py's built-in NeoPixel lights up when the switch is activated.

• true: NeoPixel lights up.

• false: NeoPixel stays off.

Change to true or false (all lowercase, no quotes).

true, false

neopixel_color_rgb

Array of Numbers

The color of the NeoPixel when activated. This is a list of three numbers representing Red, Green, and Blue brightness, each from 0 (off) to 255 (full brightness). Example: [255, 0, 0] is red.

Change the numbers inside the [] brackets.

[255, 0, 0] (Red), [0, 255, 0] (Green), [0, 0, 255] (Blue), [255, 255, 0] (Yellow), [100, 0, 100] (Purple)

Example of Editing config.json

To change the key to SPACE, make the switch more sensitive (proximity_threshold of 5), disable debug prints, and make the NeoPixel light up in blue:

JSON


{
"proximity_threshold": 5,
"triggered_key": "SPACE",
"key_press_duration_seconds": 0.1,
"loop_delay_seconds": 0.25,
"only_closer_trigger": true,
"enable_debug_prints": false,
"enable_neopixel_feedback": true,
"neopixel_color_rgb": [0, 0, 255]
}

Common Keycode Names for triggered_key

Here are some common keys you might want to use for triggered_key. Remember to type them exactly as shown, in ALL CAPS and surrounded by "double quotes".

  1. "TAB"
  2. "SPACE"
  3. "ENTER" or "RETURN" (both work for the Enter key)
  4. "ESCAPE"
  5. "BACKSPACE"
  6. "DELETE"
  7. "UP_ARROW"
  8. "DOWN_ARROW"
  9. "LEFT_ARROW"
  10. "RIGHT_ARROW"
  11. "F1" through "F12" (e.g., "F5" for refresh)
  12. Letters: "A", "B", "C", etc. (for typing a single letter)
  13. Numbers: "ONE", "TWO", "THREE", etc. (for typing numbers, not on the keypad)
  14. Modifiers (use with caution, for advanced setups): "LEFT_CONTROL", "LEFT_SHIFT", "LEFT_ALT", "LEFT_GUI" (Windows/Command key)

Saving Your Changes

  1. Save the config.json file.
  2. After saving, your QT Py will automatically restart, and your switch will immediately begin using the new settings! You'll see the updated configuration printed in the Mu Editor's serial console (if enable_debug_prints is true).