Pico DV Demo Base USERSW BUTTON_A, ... BUTTON_C

I did not find any Circuitpython example for the Pico DV Demo BASE (PIM588) to read the state of the three USERSW buttons (board.BUTTON_A, board.BUTTON_B and board.BUTTON_C).

I tried the following script, however the values stay “False”

Script:

import board
import digitalio
import time

btn_a = digitalio.DigitalInOut(board.BUTTON_A)
btn_a.direction = digitalio.Direction.OUTPUT
btn_b = digitalio.DigitalInOut(board.BUTTON_B)
btn_b.direction = digitalio.Direction.OUTPUT
btn_c = digitalio.DigitalInOut(board.BUTTON_C)
btn_c.direction = digitalio.Direction.OUTPUT

  while True:
          #time.sleep(0.5)
          print(f"\nUser switch A: {btn_a.value}")
          print(f"User switch B: {btn_b.value}")
          print(f"User switch C: {btn_c.value}")
          time.sleep(2)

Something like this should work. You’ll have to edit the `Button(#) parts to match what pins are used on the Pico DV Base. I took a shoot at it, see if it works.
Switch A is pin 19 GP 14
Switch B is pin 20 GP 15
Switch C is pin 21 GP 16

from pimoroni import Button

button_a = Button(14)
button_b = Button(15)
button_c = Button(16)

while True:
    if button_a.read():                                   # if a button press is detected then...
        print(Button A pressed)
        timne.sleep(1)
    elif button_b.read():
        print (Button B pressed)
        time.sleep(1)
        clear()
    elif button_c.read():
        print(Button C pressed)
        time.sleep(1)
   else:
        print(Press any button!)
        
    time.sleep(0.1)  # this number is how frequently the Pico checks for button presses


Thank you.
However your example is like the example which is for micropython.
I am using Circuitpython…

I tried also:

btn_a = digitalio.DigitalInOut(board.GP14) # instead of (board.BUTTON_A)
btn_a.direction = digitalio.Direction.OUTPUT
btn_b = digitalio.DigitalInOut(board.GP15) # same
btn_b.direction = digitalio.Direction.OUTPUT
btn_c = digitalio.DigitalInOut(board.GP16) # same
btn_c.direction = digitalio.Direction.OUTPUT

with unfortunately no result

Ops, sorry about that. I somehow missed that you were using Circuit Python. My bad. =(
The only device I have running Circuit Python is my Pico RGB Keypad. The keypad buttons are connected via a TCA9555 IO expander. My code isn’t going to help you, and I have next to no Circuit Python skills.

OK. Measurements with a VOM and an oscilloscope revealed that there appear two bad electrical connections in the 20-pin header that ends with GP14 and GP15. I measure voltage at the solderpoints on the Base board but not at the pins of the Pico Lipo. If I create a shortcut between GP15 of the Pico Lipo and its solderpoint on the Base board, then the script reports that Button B is pressed (when I pressed it, that is).
If I create a shortcut between GP14 of the Pico Lipo and its solderpoint on the Base board and at the same time I press button A then the script reports that Button A is pressed.
If I create a shortcut between GP15 of the Pico Lipo and its solderpoint on the Base board and at the same time I press button B then the script reports that Button B is pressed.
Conclusion: script is now OK. It is a hardware problem.

The Pin definitions changed to:


btn_a = digitalio.DigitalInOut(board.BUTTON_A) # was: (GP14)
btn_a.direction = digitalio.Direction.INPUT
btn_a.pull = digitalio.Pull.DOWN

btn_b = digitalio.DigitalInOut(board.BUTTON_B) # GP15)
btn_b.direction = digitalio.Direction.INPUT
btn_b.pull = digitalio.Pull.DOWN

btn_c = digitalio.DigitalInOut(board.BUTTON_C) # GP16)
btn_c.direction = digitalio.Direction.INPUT
btn_c.pull = digitalio.Pull.DOWN

Bad on the DV Base or the Pico Lipo? From what you said it sounds like a defect on the DV Base?

How is the soldering on the Pico Lipo?

Yes, the problem is inside of the 10-pin header for GP14 of the Base. I created a hardware repair by: a) stacking two 10-pin headers with long pins; b) solder a wire between the solder point of the Base (GP14) and the 2nd pin of one of the stacked 10-pin headers. Result: the script reported USERSW A pressed.
I just finished writing a letter with images for Pimoroni support.

1 Like

I uploaded some images to Irmgur. Here is the link: images

Sorry, I didn’t answer one of your last questions. About the soldering on the Pico Lipo. I heated again GP14 and GP15. I measured for shortings: there were no shortings. The outcome after the modification, proved it.

1 Like

Btw:

  1. The test script:
"""
    Platform: Pimoroni Pico DV Demo Base with Pimoroni Pic Lipo (RP2040) board
    Update 2024-02-12.
    This script is to test the functionality of the 'board.BUTTON_A, BUTTON_B and BUTTON_C
    of the Pimoroni Pico DV Demo Base and stacked Pimoroni Pico Lipo 16MB.
    Modifications to the script to connect to the Pico Lipo, via I2C, an Adafruit Gamepad QT board
    and use its buttons X, Y, A and B.
    Firmware flashed into Pico Lipo 16MB:
    Adafruit CircuitPython 9.0.0-beta.0 on 2024-01-27; Pimoroni Pico dv Base with rp2040
"""
import board
import digitalio
import time
import sys
import busio
from micropython import const
from adafruit_seesaw.seesaw import Seesaw
import gc

my_debug = False

BUTTON_SELECT = const(0)
BUTTON_B = const(1)
BUTTON_Y = const(2)
BUTTON_A = const(5)
BUTTON_X = const(6)
BUTTON_START = const(16)

button_mask = const(
(  1 << BUTTON_X)      # = 1 <<  6 =     64 = 0x00040
| (1 << BUTTON_Y)      # = 1 <<  2 =      4 = 0x00004
| (1 << BUTTON_A)      # = 1 <<  5 =     32 = 0x00020
| (1 << BUTTON_B)      # = 1 <<  1 =      2 = 0x00002
| (1 << BUTTON_SELECT) # = 1 <<  0 =      1 = 0x00001
| (1 << BUTTON_START)  # = 1 << 16 =  65536 = 0x10000
)  # = 65639 dec or 0x10067

SCL = board.GP5
SDA = board.GP4

try:
    i2c = busio.I2C(SCL, SDA)
    seesaw = Seesaw(i2c, addr=0x50)
    seesaw.pin_mode_bulk(button_mask, seesaw.INPUT_PULLUP)
    qt_btns_present = True
    print(f"global: seesaw.chip_id= {hex(seesaw.chip_id)}")
    print("Press any of the buttons (A, B or C) on the Pico DV Demo Base")
    print("or press any of the buttons (X, Y, A or B) on the Gamepad QT\n")
except Exception as e:
    print(f"global(): Error while creating an instance seesaw class: {e}")
    qt_btns_present = False
    raise

"""
    +--------+--------+----------------------------+
    | BUTTON | VALUE  |  Value in CPY when pressed |
    +--------+--------+----------------------------+
    | SELECT |    1   |  65638                     |
    +--------+--------+----------------------------+
    | B      |    2   |  65637                     |
    +--------+--------+----------------------------+
    | Y      |    4   |  65635                     |
    +--------+--------+----------------------------+
    | ?      |    8   |  ?                         |
    +--------+--------+----------------------------+
    | ?      |   16   |  ?                         |
    +--------+--------+----------------------------+
    | A      |   32   |  65607                     |
    +--------+--------+----------------------------+
    | X      |   64   |  65637                     !
    +--------+--------+----------------------------+
    | START  | 65636  |  103                       |
    +--------+--------+----------------------------+

"""


btn_a = digitalio.DigitalInOut(board.BUTTON_A) # was: (GP14)
btn_a.direction = digitalio.Direction.INPUT
btn_a.pull = digitalio.Pull.DOWN

btn_b = digitalio.DigitalInOut(board.BUTTON_B) # GP15)
btn_b.direction = digitalio.Direction.INPUT
btn_b.pull = digitalio.Pull.DOWN

btn_c = digitalio.DigitalInOut(board.BUTTON_C) # GP16)
btn_c.direction = digitalio.Direction.INPUT
btn_c.pull = digitalio.Pull.DOWN

on_off_led = digitalio.DigitalInOut(board.GP23)
on_off_led.direction = digitalio.Direction.OUTPUT

led = digitalio.DigitalInOut(board.LED)  # LED = GPIO25 (see same file: pins.c)
led.direction = digitalio.Direction.OUTPUT
led_state = 0

#
#  blink_led
#
def blink_led(nr_times, bi_led=False, blink_slow=True):
    global led_state
    curr_state = led_state
    # print(f"blink_led(): nr_times: {nr_times}, bi_led= {bi_led}, blink_slow= {blink_slow}")
    if nr_times is None:
        nr_times = 1

    if blink_slow:
        delay = 0.5
    else:
        delay = 0.1

    if curr_state == 1:
        if bi_led:
            led.value = False  # first switch the led off
        on_off_led.value = False
        time.sleep(delay)

    for _ in range(nr_times):
        if bi_led:
            led.value = True
        on_off_led.value = False
        time.sleep(delay)
        if bi_led:
            led.value = False
        on_off_led.value = False
        time.sleep(delay)

    if curr_state == 1:  # if the led originally was on, switch it back on
        if bi_led:
            led.value = True
        on_off_led.value = False

# Check for button presses on the Gamepad QT
def ck_qt_btns():
    global led_state

    if not qt_btns_present:
        return

    TAG = "ck_qt_btns(): "
    s_btn = "Gamepad QT button "
    s_pre = " pressed"
    btns = ["X", "Y", "A", "B"]
    btn_names = ["BUTTON_X", "BUTTON_Y", "BUTTON_A", "BUTTON_B"]

    gc.collect()
    time.sleep(0.2)
    # Get the button presses, if any...
    buttons = seesaw.digital_read_bulk(button_mask)
    if my_debug:
        print("\n"+TAG+f"buttons = {buttons}")
    if buttons == 65639:
        if my_debug:
            print(TAG+f"Gamepad QT: no button pressed")
        return
    # time.sleep(0.5)

    res = -1

    for _ in range(len(btns)):
        if _ == 0:
            bz = 1 << BUTTON_X
            if not (buttons & bz):
                btnX = True
                res = _
            else:
                btnX = False
        elif _ == 1:
            bz = 1 << BUTTON_Y
            if not (buttons & bz):
                btnY = True
                res = _
            else:
                btnY = False
        elif _ == 2:
            bz = 1 << BUTTON_A
            if not (buttons & bz):
                btnA = True
                res = _
            else:
                btnA = False
        elif _ == 3:
            bz = 1 << BUTTON_B
            if not (buttons & bz):
                btnB = True
                res = _
            else:
                btnB = False
        else:
            btnX = btnY = btnA = btnB = False
            res = -1

    if res >= 0 and res <= 3:
        print(s_btn+btns[res]+s_pre)

        if btnX or btnA:
            blink_led(1, True) 
        if btnY or btnB:
            blink_led(2, True) 
        res = -1

        led.value = False
        led_state = 0

def main():
    TAG= "main(): "
    delay = 0.2
    a_val = b_val = c_val = False
    loopnr = 0
    while True:
        try:
            loopnr += 1
            ck_qt_btns()
            a_val = btn_a.value
            time.sleep(delay)
            b_val = btn_b.value
            time.sleep(delay)
            c_val = btn_c.value
            time.sleep(delay)
            print()
            if a_val:
                print(f"User switch A: {a_val}")
                blink_led(3, True, False)
            elif b_val:
                print(f"User switch B: {b_val}")
                blink_led(3, True, False)
            elif c_val:
                print(f"User switch C: {c_val}")
                blink_led(3, True, False)
            a_val = b_val = c_val = False
            time.sleep(delay)
        except KeyboardInterrupt:
            print(TAG+"KeyboardInterrrupt. Exiting...")
            break

        if loopnr >= 100:
            break

    sys.exit()

if __name__ == '__main__':
    main()

  1. The REPL output:
Thursday 2024-02-15 12h20

Boards: Pimoroni Pico DV Demo Base with on it: Pimoroni Pico Lipo 16MB

Adafruit CircuitPython 9.0.0-beta.0 on 2024-01-27; Pimoroni Pico dv Base with rp2040

IDE: mu 1.2.0

Project: test Pico DV Demo Base USERSW A, B and C 
         test X, Y, A and B of Adafruit Gamepad QT, connected to the Pico Lipo STEMMA/QT I2C connector


NOTE: Pico DV Demo Base USERSW A now working after soldering the red wire between the Base solderpoint of GP14
      and the 2nd pin of an added 10-pin header.

REPL output:

soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py output:
global: seesaw.chip_id= 0x87
Press any of the buttons (A, B or C) on the Pico DV Demo Base
or press any of the buttons (X, Y, A or B) on the Gamepad QT


User switch A: True

User switch B: True

User switch C: True


Gamepad QT button X pressed

Gamepad QT button Y pressed

Gamepad QT button A pressed

Gamepad QT button B pressed


main(): KeyboardInterrrupt. Exiting...

Code done running.

Press any key to enter the REPL. Use CTRL-D to reload.

Adafruit CircuitPython 9.0.0-beta.0 on 2024-01-27; Pimoroni Pico dv Base with rp2040
1 Like

Wow! In less than an hour I sent an e-mail with a letter containing information about the problem explained above, Pimoroni Support informed me that Pimoroni will send me a replacement for the faulty Pico DV Demo Base board. Immediately after I received an e-mail that the shipment is on the way. An excellent service! Thank you Pimoroni (Support)!

2 Likes

They are pretty darned good that way. I’ve had similar results any time I have had to go that route.

1 Like

Today, February 28, 2024, the replacement board was delivered. It works 100%. Pimoroni thank you again for a great service!
I modified the script a bit. I published it in a Github Gist:

code

2 Likes