7

I am using Circuit Python on a Raspberry Pi Pico to give me hardware buttons for keyboard shortcuts. I am using Circuit Python as opposed to MicroPython because it has the USB_HID library.

I don't want the Pico to automatically mount as USB storage when being plugged in. I just want it to act as a HID device. I am aware that I can write a boot.py script in addition to a code.py but I can't find anywhere online what to put in this which would prevent it from mounting as a USB device. I also still want it to mount as USB sometimes (when a button is pressed/GPIO pin is connected) so there is a still a way for me to change the code on the device.

Is this possible? And, if so, what should the boot.py look like to only mount when a certain GPIO pin is connected?

jsaispasmoi
  • 71
  • 1
  • 2
  • I think you should identify your OS as the answer will differ. – Mark Setchell Feb 21 '21 at 18:56
  • 1
    The computer I am plugging the Pico into changes so I'd like it to apply to all OSes. My understanding of the boot.py script is that it runs before the USB volume is mounted so I want the Pico to prevent it from being mounted rather than the OS of the computer I'm plugging it into to prevent the mounting of the volume. I don't know what 'OS' in narrow terms the Raspberry Pi Pico runs beyond Circuit Python which had to be flashed to it. – jsaispasmoi Feb 21 '21 at 19:00
  • You might try on https://raspberrypi.stackexchange.com as it's pretty specific to the Raspberry Pi. – Mark Setchell Feb 23 '21 at 10:37

4 Answers4

2

I recently came across a need to do the same that you are looking for, and after a decent rabbit hole, have determined that it can't be done at this time.

https://github.com/adafruit/circuitpython/issues/1015

Looks like the request was opened a few years ago and is still listed as open.

I am not sure if running a pi zero in "gadget" mode can accomplish this or not, but may be worth a look

badbash27
  • 21
  • 2
  • As of March 2022, this feature is now implemented. As OP asked, see answer from Doug Harris which shows exact code – jdr5ca Mar 12 '22 at 08:40
1

The code below is what I use. Roughly, it checks to see if a button connected to one of the Pico's IO pins. If the button is pressed when the cable is plugged in, then it mounts as a USB drive. If the button is not pressed, it's not mounted:

import storage
import board, digitalio

# If not pressed, the key will be at +V (due to the pull-up).
# https://learn.adafruit.com/customizing-usb-devices-in-circuitpython/circuitpy-midi-serial#circuitpy-mass-storage-device-3096583-4
button = digitalio.DigitalInOut(board.GP2)
button.direction = digitalio.Direction.INPUT
button.pull = digitalio.Pull.UP

# Disable devices only if button is not pressed.
if button.value:
    print(f"boot: button not pressed, disabling drive")
    storage.disable_usb_drive()

This was adapted from examples on Adafruit's site

jdr5ca
  • 2,809
  • 14
  • 25
Doug Harris
  • 3,169
  • 5
  • 29
  • 31
0

Here's a good HID guide:

https://learn.adafruit.com/circuitpython-essentials/circuitpython-hid-keyboard-and-mouse

Here's the HID example:

import time

import board
import digitalio
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode

# A simple neat keyboard demo in CircuitPython

# The pins we'll use, each will have an internal pullup
keypress_pins = [board.A1, board.A2]
# Our array of key objects
key_pin_array = []
# The Keycode sent for each button, will be paired with a control key
keys_pressed = [Keycode.A, "Hello World!\n"]
control_key = Keycode.SHIFT

# The keyboard object!
time.sleep(1)  # Sleep for a bit to avoid a race condition on some systems
keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayoutUS(keyboard)  # We're in the US :)

# Make all pin objects inputs with pullups
for pin in keypress_pins:
    key_pin = digitalio.DigitalInOut(pin)
    key_pin.direction = digitalio.Direction.INPUT
    key_pin.pull = digitalio.Pull.UP
    key_pin_array.append(key_pin)

# For most CircuitPython boards:
led = digitalio.DigitalInOut(board.D13)
# For QT Py M0:
# led = digitalio.DigitalInOut(board.SCK)
led.direction = digitalio.Direction.OUTPUT

print("Waiting for key pin...")

while True:
    # Check each pin
    for key_pin in key_pin_array:
        if not key_pin.value:  # Is it grounded?
            i = key_pin_array.index(key_pin)
            print("Pin #%d is grounded." % i)

            # Turn on the red LED
            led.value = True

            while not key_pin.value:
                pass  # Wait for it to be ungrounded!
            # "Type" the Keycode or string
            key = keys_pressed[i]  # Get the corresponding Keycode or string
            if isinstance(key, str):  # If it's a string...
                keyboard_layout.write(key)  # ...Print the string
            else:  # If it's not a string...
                keyboard.press(control_key, key)  # "Press"...
                keyboard.release_all()  # ..."Release"!

            # Turn off the red LED
            led.value = False

    time.sleep(0.01) ```

The example only prints Hello World, so it's not very useful, but it's a good base to mod. 
g3holliday
  • 21
  • 9
0

You can view the this forum post: https://forums.raspberrypi.com/viewtopic.php?t=315263

In fact, you need to create a boot.py file and to put a storage.disable_usb_drive(), and you must know that this specific command can't work in code.py because the USB devices are already setup (see https://learn.adafruit.com/customizing-usb-devices-in-circuitpython/circuitpy-midi-serial)

Thornily
  • 533
  • 3
  • 15
Charlox29
  • 1
  • 1