Skip to content

keypad.ShiftRegisterKeys has wrong key_count #9718

Closed
@aseanwatson

Description

@aseanwatson

CircuitPython version

Adafruit CircuitPython 9.1.2 on 2024-08-22; Raspberry Pi Pico W with rp2040
Board ID:raspberry_pi_pico_w

Code/REPL

import board
import keypad

keys = keypad.ShiftRegisterKeys(
    data               = board.GP0,
    clock              = board.GP1,
    latch              = board.GP2,
    key_count          = 8,
    value_when_pressed = True,
    value_to_latch     = True,
    )

print(f"There are a total of {keys.key_count} keys.")

currentEvent = keypad.Event()

while True:
    # this if could be a while loop; that would let you handle every keypress
    # even if it means you don't call update as frequently
    while keys.events.get_into(currentEvent):
        if currentEvent.pressed:
            # TODO: handle key press
            print(f'key {currentEvent.key_number} was pressed')
        elif currentEvent.released:
            # TODO: handle key release
            print(f'key {currentEvent.key_number} was released')

Behavior

Actual:

code.py output:
There are a total of 17 keys.

It looks like
image

Expected:

code.py output:
There are a total of 8 keys.

Description

See the original Adafruit Forum Post.

Just trying different values, it seems like the effective value of the key_count parameter is key_count * 2 + 1 (so 8 => 17; 1 => 3)

Additional information

I don't have a good way to step through this in the debugger, but I looked at the source. I don't see an obvious bug.

keypad_shiftregisterkeys_make_new does this:

    mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);

to populate args and, specifically, args[ARG_key_count].

Then it does:

    if (mp_obj_is_int(args[ARG_key_count].u_obj)) {
        num_key_counts = 1;
    } 

And this:

    if (mp_obj_is_int(args[ARG_key_count].u_obj)) {
        const size_t key_count = (size_t)mp_arg_validate_int_min(args[ARG_key_count].u_int, 1, MP_QSTR_key_count);
        key_count_array[0] = key_count;
    } 

And finally this:

    common_hal_keypad_shiftregisterkeys_construct(
        self, clock, num_data_pins, data_pins_array, latch, value_to_latch, num_key_counts, key_count_array, value_when_pressed, interval, max_events, debounce_threshold);

common_hal_keypad_shiftregisterkeys_construct does this:

    self->key_counts = (mp_uint_t *)m_malloc(sizeof(mp_uint_t) * num_key_counts);
    self->num_key_counts = num_key_counts;

    // copy to an m_malloc() and on the fly record pin with largest Shift register
    mp_uint_t max = 0;

    for (mp_uint_t i = 0; i < self->num_key_counts; i++) {
        mp_uint_t cnt = key_counts[i];

        if (cnt > max) {
            max = cnt;
        }

        self->key_counts[i] = cnt;
    }

    self->max_key_count = max;

Taken together, I expect self->num_key_counts to be 1 and self->key_counts[0] to be 8 and self->max_key_count to be 8.

But the logic analyzer seems to indicate max_key_count is 17.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions