The Pimoroni QwSTPad is an I2C mini gamepad with 10 buttons and 4 status LEDs. The buttons are arranged as two four-way directional pads with two independent buttons in the middle.
To start using QwSTPad in your project, you will first need to import the QwSTPad
class and one of its four addresses:
from machine import I2C
from qwstpad import QwSTPad
from qwstpad import DEFAULT_ADDRESS as ADDRESS
ℹ️ Up to four QwSTPads can be used at once for multiplayer fun. Change the address of a QwSTPad on its rear using the two cuttable traces.
Next, create an I2C object on the correct bus and pins for your QwST port:
i2c = I2C(id=0, scl=4, sda=3) # Typical pins used by our products
This is what we will use to communicate to the QwSTPad.
Finally, create a QwSTPad
object and pass it the I2C
instance and the ADDRESS
. It can be helpful to wrap this in a try except
block in case communication with the QwSTPad fails due to an incorrect address or bad connection.
try:
pad = QwSTPad(i2c, ADDRESS)
except OSError:
print("QwSTPad: Not Connected ... Exiting")
raise SystemExit
print("QwSTPad: Connected ... Starting")
By default, any connected QwSTPad will turn on an LED that corresponds with its I2C address, making it easy to identify controllers if multiple are connected at once (for a 4 player mini-game perhaps). This function can be disabled by adding , show_address=False
when creating the QwSTPad
object.
To read the buttons on QwSTPad, simply call .read_buttons()
on the QwSTPad
object:
buttons = pad.read_buttons()
This will return an ordered dictionary of all the button states at a single moment in time. To then get a button's state, address the dictionary with the character of the button:
if buttons['U']:
# Up pressed
else:
# Up unpressed
Supported characters are A
, B
, X
, Y
, U
, D
, L
, R
, +
, and -
.
It is also possible to print out all the button states, using the following for loop:
for key, value in buttons.items():
print(f"{key} = {value:n}", end=", ")
print()
The four status LEDs on QwSTPad can be set in one of two ways. The first is by calling .set_led()
on the QwSTPad
object, passing it the number of the LED (from 1
to 4
) along with either True
to turn the LED on or False
to turn the LED off. E.g.
pad.set_led(1, True)
pad.set_led(2, False)
pad.set_led(3, False)
pad.set_led(4, True)
The second way is to set all four LEDs at once using the .set_leds()
function. This takes in an integer from 0
to 15
. These correspond to the binary representations 0b0000
and 0b1111
. Here is how a wave effect could be played on the LEDs using this function:
while True:
pad.set_leds(0b1000)
time.sleep(0.2)
pad.set_leds(0b0100)
time.sleep(0.2)
pad.set_leds(0b0010)
time.sleep(0.2)
pad.set_leds(0b0001)
time.sleep(0.2)
Related to this, there is the .address_code()
function. This returns an integer representing the I2C address of the connected QwSTPad, that can be passed directly into .set_leds()
.
pad.set_leds(pad.address_code())
This happens by default when first creating the QwSTPad
object, but can be useful to call again, in case you have changed the LEDs at any point. For example to flash when a player takes damage.
The final LED function is .clear_leds()
, which turns all the LEDs off. This is a shorthand for .set_leds(0)
and can be handy for calling at the end of your program.
NUM_LED = 4
NUM_BUTTONS = 10
DEFAULT_ADDRESS = 0x21
ALT_ADDRESS_1 = 0x23
ALT_ADDRESS_2 = 0x25
ALT_ADDRESS_3 = 0x27
ADDRESSES = (DEFAULT_ADDRESS, ALT_ADDRESS_1, ALT_ADDRESS_2, ALT_ADDRESS_3)
# Registers
INPUT_PORT0 = 0x00
INPUT_PORT1 = 0x01
OUTPUT_PORT0 = 0x02
OUTPUT_PORT1 = 0x03
POLARITY_PORT0 = 0x04
POLARITY_PORT1 = 0x05
CONFIGURATION_PORT0 = 0x06
CONFIGURATION_PORT1 = 0x07
# Mappings
BUTTON_MAPPING = OrderedDict({'A': 0xE, 'B': 0xC, 'X': 0xF, 'Y': 0xD,
'U': 0x1, 'D': 0x4, 'L': 0x2, 'R': 0x3,
'+': 0xB, '-': 0x5
})
LED_MAPPING = (0x6, 0x7, 0x9, 0xA)
# Initialisation
QwSTPad(i2c: I2C | PimoroniI2C,
address: int=DEFAULT_ADDRESS,
show_address: bool=True)
# Special
address_code() -> int
# Buttons
read_buttons() -> OrderedDict()
# LEDs
set_leds(states: int) -> None
set_led(led: int, state: bool | int) -> None
clear_leds() -> None