adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.01k stars 1.19k forks source link

M1 macOS Monterey USB enumeration issue #5658

Open savt22 opened 2 years ago

savt22 commented 2 years ago

CircuitPython version

Adafruit 7.0.0; issue present both on Pimoroni Keybow 2040 and Raspberry Pi Pico (with Pimoroni RGB Keypad).

Code/REPL

import time
from keybow2040 import Keybow2040
#from keybow_hardware.pim56x import PIM56X as Hardware # for Keybow 2040
from keybow_hardware.pim551 import PIM551 as Hardware # for Pico RGB Keypad Base

import usb_midi
import adafruit_midi
from adafruit_midi.note_off import NoteOff
from adafruit_midi.note_on import NoteOn

keybow = Keybow2040(Hardware())
keys = keybow.keys

midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0)
rgb = (0, 0, 0)

#sets keyboard layout, creates slight flicker when holding down button. White and black notes on piano different colours 
while True:
    keybow.update()

    for key in keys:
        if key.pressed:
            key.set_led(*rgb)
        else:
            keybow.set_led(0, 100, 100, 100)
            keybow.set_led(1, 50, 100, 10)
            keybow.set_led(2, 100, 100, 100)
            keybow.set_led(3, 50, 100, 10)
            keybow.set_led(4, 100, 100, 100)
            keybow.set_led(5, 100, 100, 100)
            keybow.set_led(6, 50, 100, 10)
            keybow.set_led(7, 100, 100, 100)
            keybow.set_led(8, 50, 100, 10)
            keybow.set_led(9, 100, 100, 100)
            keybow.set_led(10, 50, 100, 10)
            keybow.set_led(11, 100, 100, 100)
            keybow.set_led(12, 200, 100, 100)
            keybow.set_led(13, 100, 200, 100)
            keybow.set_led(14, 100, 100, 200)
            keybow.set_led(15, 100, 50, 100)

#stops hanging notes 

    if keys[15].pressed:
        M = keys[15]
        @keybow.on_release(M)
        def release_handler(M):

            midi.send([NoteOff(60, 0),
                       NoteOff(61, 0),
                       NoteOff(62, 0),
                       NoteOff(63, 0),
                       NoteOff(64, 0),
                       NoteOff(65, 0),
                       NoteOff(66, 0),
                       NoteOff(67, 0),
                       NoteOff(68, 0),
                       NoteOff(69, 0),
                       NoteOff(70, 0),
                       NoteOff(71, 0),
                       NoteOff(72, 0),
                       NoteOff(73, 0),
                       NoteOff(74, 0),
                       NoteOff(75, 0),
                       NoteOff(76, 0),
                       NoteOff(77, 0),
                       NoteOff(78, 0),
                       NoteOff(79, 0),
                       NoteOff(81, 0),
                       NoteOff(82, 0),
                       NoteOff(83, 0),
                       NoteOff(84, 0),
                       NoteOff(85, 0),
                       NoteOff(86, 0)])

    if keys[14].pressed:
        O = keys[14]
        @keybow.on_release(O)
        def release_handler(O):

            midi.send([NoteOff(60, 0),
                       NoteOff(61, 0),
                       NoteOff(62, 0),
                       NoteOff(63, 0),
                       NoteOff(64, 0),
                       NoteOff(65, 0),
                       NoteOff(66, 0),
                       NoteOff(67, 0),
                       NoteOff(68, 0),
                       NoteOff(69, 0),
                       NoteOff(70, 0),
                       NoteOff(71, 0),
                       NoteOff(72, 0),
                       NoteOff(73, 0),
                       NoteOff(74, 0),
                       NoteOff(75, 0),
                       NoteOff(76, 0),
                       NoteOff(77, 0),
                       NoteOff(78, 0),
                       NoteOff(79, 0),
                       NoteOff(81, 0),
                       NoteOff(82, 0),
                       NoteOff(83, 0),
                       NoteOff(84, 0),
                       NoteOff(85, 0),
                       NoteOff(86, 0)])

    if keys[13].pressed:
        D = keys[13]
        @keybow.on_release(D)
        def release_handler(D):

            midi.send([NoteOff(60, 0),
                       NoteOff(61, 0),
                       NoteOff(62, 0),
                       NoteOff(63, 0),
                       NoteOff(64, 0),
                       NoteOff(65, 0),
                       NoteOff(66, 0),
                       NoteOff(67, 0),
                       NoteOff(68, 0),
                       NoteOff(69, 0),
                       NoteOff(70, 0),
                       NoteOff(71, 0),
                       NoteOff(72, 0),
                       NoteOff(73, 0),
                       NoteOff(74, 0),
                       NoteOff(75, 0),
                       NoteOff(76, 0),
                       NoteOff(77, 0),
                       NoteOff(78, 0),
                       NoteOff(79, 0),
                       NoteOff(81, 0),
                       NoteOff(82, 0),
                       NoteOff(83, 0),
                       NoteOff(84, 0),
                       NoteOff(85, 0),
                       NoteOff(86, 0)])

    if keys[12].pressed:
        S = keys[12]
        @keybow.on_release(S)
        def release_handler(S):

            midi.send([NoteOff(60, 0),
                       NoteOff(61, 0),
                       NoteOff(62, 0),
                       NoteOff(63, 0),
                       NoteOff(64, 0),
                       NoteOff(65, 0),
                       NoteOff(66, 0),
                       NoteOff(67, 0),
                       NoteOff(68, 0),
                       NoteOff(69, 0),
                       NoteOff(70, 0),
                       NoteOff(71, 0),
                       NoteOff(72, 0),
                       NoteOff(73, 0),
                       NoteOff(74, 0),
                       NoteOff(75, 0),
                       NoteOff(76, 0),
                       NoteOff(77, 0),
                       NoteOff(78, 0),
                       NoteOff(79, 0),
                       NoteOff(81, 0),
                       NoteOff(82, 0),
                       NoteOff(83, 0),
                       NoteOff(84, 0),
                       NoteOff(85, 0),
                       NoteOff(86, 0)])

                      #Single note
    if not keys[15].pressed and not keys[14].pressed \
    and not keys[13].pressed and not keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):

            midi.send(NoteOn(60, 127))

        @keybow.on_release(C)
        def release_handler(C):

            midi.send(NoteOff(60, 0))

        Db = keys[1]
        @keybow.on_press(Db)
        def press_handler(Db):

            midi.send(NoteOn(61, 127))

        @keybow.on_release(Db)
        def release_handler(Db):

            midi.send(NoteOff(61, 0))

        D = keys[2]
        @keybow.on_press(D)
        def press_handler(D):

            midi.send(NoteOn(62, 127))

        @keybow.on_release(D)
        def release_handler(D):

            midi.send(NoteOff(62, 0))

        Eb = keys[3]
        @keybow.on_press(Eb)
        def press_handler(Eb):

            midi.send(NoteOn(63, 127))

        @keybow.on_release(Eb)
        def release_handler(Eb):

            midi.send(NoteOff(63, 0))

        E = keys[4]
        @keybow.on_press(E)
        def press_handler(E):

            midi.send(NoteOn(64, 127))

        @keybow.on_release(E)
        def release_handler(E):

            midi.send(NoteOff(64, 0))

        F = keys[5]
        @keybow.on_press(F)
        def press_handler(F):

            midi.send(NoteOn(65, 127))

        @keybow.on_release(F)
        def release_handler(F):

            midi.send(NoteOff(65, 0))

        Gb = keys[6]
        @keybow.on_press(Gb)
        def press_handler(Gb):

            midi.send(NoteOn(66, 127))

        @keybow.on_release(Gb)
        def release_handler(Gb):

            midi.send(NoteOff(66, 0))

        G = keys[7]
        @keybow.on_press(G)
        def press_handler(G):

            midi.send(NoteOn(67, 127))

        @keybow.on_release(G)
        def release_handler(G):

            midi.send(NoteOff(67, 0))

        Ab = keys[8]
        @keybow.on_press(Ab)
        def press_handler(Ab):

            midi.send(NoteOn(68, 127))

        @keybow.on_release(Ab)
        def release_handler(Ab):

            midi.send(NoteOff(68, 0))

        A = keys[9]
        @keybow.on_press(A)
        def press_handler(A):

            midi.send(NoteOn(69, 127))

        @keybow.on_release(A)
        def release_handler(A):

            midi.send(NoteOff(69, 0))

        Bb = keys[10]
        @keybow.on_press(Bb)
        def press_handler(Bb):

            midi.send(NoteOn(70, 127))

        @keybow.on_release(Bb)
        def release_handler(Bb):

            midi.send(NoteOff(70, 0))

        B = keys[11]
        @keybow.on_press(B)
        def press_handler(B):

            midi.send(NoteOn(71, 127))

        @keybow.on_release(B)
        def release_handler(B):

            midi.send(NoteOff(71, 0))

                     #Major chord
    if keys[15].pressed and not keys[14].pressed \
    and not keys[13].pressed and not keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):

            midi.send([NoteOn(60, 127),
                       NoteOn(64, 127),
                       NoteOn(67, 127)])

        @keybow.on_release(C)
        def release_handler(C):

            midi.send([NoteOff(60, 127),
                       NoteOff(64, 127),
                       NoteOff(67, 127)])

        Db = keys[1]
        @keybow.on_press(Db)
        def press_handler(Db):

            midi.send([NoteOn(61, 127),
                       NoteOn(65, 127),
                       NoteOn(68, 127)])

        @keybow.on_release(Db)
        def release_handler(Db):

            midi.send([NoteOff(61, 127),
                       NoteOff(65, 127),
                       NoteOff(68, 127)])

        D = keys[2]
        @keybow.on_press(D)
        def press_handler(D):

            midi.send([NoteOn(62, 127),
                       NoteOn(66, 127),
                       NoteOn(69, 127)])

        @keybow.on_release(D)
        def release_handler(D):

            midi.send([NoteOff(62, 127),
                       NoteOff(66, 127),
                       NoteOff(69, 127)])

        Eb = keys[3]
        @keybow.on_press(Eb)
        def press_handler(Eb):

            midi.send([NoteOn(63, 127),
                       NoteOn(67, 127),
                       NoteOn(70, 127)])

        @keybow.on_release(Eb)
        def release_handler(Eb):

            midi.send([NoteOff(63, 127),
                       NoteOff(67, 127),
                       NoteOff(70, 127)])

        E = keys[4]
        @keybow.on_press(E)
        def press_handler(E):

            midi.send([NoteOn(64, 127),
                       NoteOn(68, 127),
                       NoteOn(71, 127)])

        @keybow.on_release(E)
        def release_handler(E):

            midi.send([NoteOff(64, 127),
                       NoteOff(68, 127),
                       NoteOff(71, 127)])

        F = keys[5]
        @keybow.on_press(F)
        def press_handler(F):

            midi.send([NoteOn(65, 127),
                       NoteOn(69, 127),
                       NoteOn(72, 127)])

        @keybow.on_release(F)
        def release_handler(F):

            midi.send([NoteOff(65, 127),
                       NoteOff(69, 127),
                       NoteOff(72, 127)])

        Gb = keys[6]
        @keybow.on_press(Gb)
        def press_handler(Gb):

            midi.send([NoteOn(66, 127),
                       NoteOn(70, 127),
                       NoteOn(73, 127)])

        @keybow.on_release(Gb)
        def release_handler(Gb):

            midi.send([NoteOff(66, 127),
                       NoteOff(70, 127),
                       NoteOff(73, 127)])

        G = keys[7]
        @keybow.on_press(G)
        def press_handler(G):

            midi.send([NoteOn(67, 127),
                       NoteOn(71, 127),
                       NoteOn(74, 127)])

        @keybow.on_release(G)
        def release_handler(G):

            midi.send([NoteOff(67, 127),
                       NoteOff(71, 127),
                       NoteOff(74, 127)])

        Ab = keys[8]
        @keybow.on_press(Ab)
        def press_handler(Ab):

            midi.send([NoteOn(68, 127),
                       NoteOn(72, 127),
                       NoteOn(75, 127)])

        @keybow.on_release(Ab)
        def release_handler(Ab):

            midi.send([NoteOff(68, 127),
                       NoteOff(72, 127),
                       NoteOff(75, 127)])

        A = keys[9]
        @keybow.on_press(A)
        def press_handler(A):

            midi.send([NoteOn(69, 127),
                       NoteOn(73, 127),
                       NoteOn(76, 127)])

        @keybow.on_release(A)
        def release_handler(A):

            midi.send([NoteOff(69, 127),
                       NoteOff(73, 127),
                       NoteOff(76, 127)])

        Bb = keys[10]
        @keybow.on_press(Bb)
        def press_handler(Bb):

            midi.send([NoteOn(70, 127),
                       NoteOn(74, 127),
                       NoteOn(77, 127)])

        @keybow.on_release(Bb)
        def release_handler(Bb):

            midi.send([NoteOff(70, 127),
                       NoteOff(74, 127),
                       NoteOff(77, 127)])

        B = keys[11]
        @keybow.on_press(B)
        def press_handler(B):

            midi.send([NoteOn(71, 127),
                       NoteOn(75, 127),
                       NoteOn(78, 127)])

        @keybow.on_release(B)
        def release_handler(B):

            midi.send([NoteOff(71, 127),
                       NoteOff(75, 127),
                       NoteOff(78, 127)])

                      #Minor chord
    if not keys[15].pressed and keys[14].pressed \
    and not keys[13].pressed and not keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):

            midi.send([NoteOn(60, 127),
                       NoteOn(63, 127),
                       NoteOn(67, 127)])

        @keybow.on_release(C)
        def release_handler(C):

            midi.send([NoteOff(60, 127),
                       NoteOff(63, 127),
                       NoteOff(67, 127)])

        Db = keys[1]
        @keybow.on_press(Db)
        def press_handler(Db):

            midi.send([NoteOn(61, 127),
                       NoteOn(64, 127),
                       NoteOn(68, 127)])

        @keybow.on_release(Db)
        def release_handler(Db):

            midi.send([NoteOff(61, 127),
                       NoteOff(64, 127),
                       NoteOff(68, 127)])
        D = keys[2]
        @keybow.on_press(D)
        def press_handler(D):

            midi.send([NoteOn(62, 127),
                       NoteOn(65, 127),
                       NoteOn(69, 127)])

        @keybow.on_release(D)
        def release_handler(D):

            midi.send([NoteOff(62, 127),
                       NoteOff(65, 127),
                       NoteOff(69, 127)])

        Eb = keys[3]
        @keybow.on_press(Eb)
        def press_handler(Eb):

            midi.send([NoteOn(63, 127),
                       NoteOn(66, 127),
                       NoteOn(70, 127)])

        @keybow.on_release(Eb)
        def release_handler(Eb):

            midi.send([NoteOff(63, 127),
                       NoteOff(66, 127),
                       NoteOff(70, 127)])

        E = keys[4]
        @keybow.on_press(E)
        def press_handler(E):

            midi.send([NoteOn(64, 127),
                       NoteOn(67, 127),
                       NoteOn(71, 127)])

        @keybow.on_release(E)
        def release_handler(E):

            midi.send([NoteOff(64, 127),
                       NoteOff(67, 127),
                       NoteOff(71, 127)])

        F = keys[5]
        @keybow.on_press(F)
        def press_handler(F):

            midi.send([NoteOn(65, 127),
                       NoteOn(68, 127),
                       NoteOn(72, 127)])

        @keybow.on_release(F)
        def release_handler(F):

            midi.send([NoteOff(65, 127),
                       NoteOff(68, 127),
                       NoteOff(72, 127)])

        Gb = keys[6]
        @keybow.on_press(Gb)
        def press_handler(Gb):

            midi.send([NoteOn(66, 127),
                       NoteOn(69, 127),
                       NoteOn(73, 127)])

        @keybow.on_release(Gb)
        def release_handler(Gb):

            midi.send([NoteOff(66, 127),
                       NoteOff(69, 127),
                       NoteOff(73, 127)])

        G = keys[7]
        @keybow.on_press(G)
        def press_handler(G):

            midi.send([NoteOn(67, 127),
                       NoteOn(70, 127),
                       NoteOn(74, 127)])

        @keybow.on_release(G)
        def release_handler(G):

            midi.send([NoteOff(67, 127),
                       NoteOff(70, 127),
                       NoteOff(74, 127)])

        Ab = keys[8]
        @keybow.on_press(Ab)
        def press_handler(Ab):

            midi.send([NoteOn(68, 127),
                       NoteOn(71, 127),
                       NoteOn(75, 127)])

        @keybow.on_release(Ab)
        def release_handler(Ab):

            midi.send([NoteOff(68, 127),
                       NoteOff(71, 127),
                       NoteOff(75, 127)])

        A = keys[9]
        @keybow.on_press(A)
        def press_handler(A):

            midi.send([NoteOn(69, 127),
                       NoteOn(72, 127),
                       NoteOn(76, 127)])

        @keybow.on_release(A)
        def release_handler(A):

            midi.send([NoteOff(69, 127),
                       NoteOff(72, 127),
                       NoteOff(76, 127)])

        Bb = keys[10]
        @keybow.on_press(Bb)
        def press_handler(Bb):

            midi.send([NoteOn(70, 127),
                       NoteOn(73, 127),
                       NoteOn(77, 127)])

        @keybow.on_release(Bb)
        def release_handler(Bb):

            midi.send([NoteOff(70, 127),
                       NoteOff(73, 127),
                       NoteOff(77, 127)])

        B = keys[11]
        @keybow.on_press(B)
        def press_handler(B):

            midi.send([NoteOn(71, 127),
                       NoteOn(74, 127),
                       NoteOn(78, 127)])

        @keybow.on_release(B)
        def release_handler(B):

            midi.send([NoteOff(71, 127),
                       NoteOff(74, 127),
                       NoteOff(78, 127)])

                      #Maj7 chord
    if not keys[15].pressed and not keys[14].pressed \
    and keys[13].pressed and not keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):

            midi.send([NoteOn(60, 127),
                       NoteOn(64, 127),
                       NoteOn(71, 127)])

        @keybow.on_release(C)
        def release_handler(C):

            midi.send([NoteOff(60, 127),
                       NoteOff(64, 127),
                       NoteOff(71, 127)])

        Db = keys[1]
        @keybow.on_press(Db)
        def press_handler(Db):

            midi.send([NoteOn(61, 127),
                       NoteOn(65, 127),
                       NoteOn(72, 127)])

        @keybow.on_release(Db)
        def release_handler(Db):

            midi.send([NoteOff(61, 127),
                       NoteOff(65, 127),
                       NoteOff(72, 127)])

        D = keys[2]
        @keybow.on_press(D)
        def press_handler(D):

            midi.send([NoteOn(62, 127),
                       NoteOn(66, 127),
                       NoteOn(73, 127)])

        @keybow.on_release(D)
        def release_handler(D):

            midi.send([NoteOff(62, 127),
                       NoteOff(66, 127),
                       NoteOff(73, 127)])

        Eb = keys[3]
        @keybow.on_press(Eb)
        def press_handler(Eb):

            midi.send([NoteOn(63, 127),
                       NoteOn(67, 127),
                       NoteOn(74, 127)])

        @keybow.on_release(Eb)
        def release_handler(Eb):

            midi.send([NoteOff(63, 127),
                       NoteOff(67, 127),
                       NoteOff(74, 127)])

        E = keys[4]
        @keybow.on_press(E)
        def press_handler(E):

            midi.send([NoteOn(64, 127),
                       NoteOn(68, 127),
                       NoteOn(75, 127)])

        @keybow.on_release(E)
        def release_handler(E):

            midi.send([NoteOff(64, 127),
                       NoteOff(68, 127),
                       NoteOff(75, 127)])

        F = keys[5]
        @keybow.on_press(F)
        def press_handler(F):

            midi.send([NoteOn(65, 127),
                       NoteOn(69, 127),
                       NoteOn(76, 127)])

        @keybow.on_release(F)
        def release_handler(F):

            midi.send([NoteOff(65, 127),
                       NoteOff(69, 127),
                       NoteOff(76, 127)])

        Gb = keys[6]
        @keybow.on_press(Gb)
        def press_handler(Gb):

            midi.send([NoteOn(66, 127),
                       NoteOn(70, 127),
                       NoteOn(77, 127)])

        @keybow.on_release(Gb)
        def release_handler(Gb):

            midi.send([NoteOff(66, 127),
                       NoteOff(70, 127),
                       NoteOff(77, 127)])

        G = keys[7]
        @keybow.on_press(G)
        def press_handler(G):

            midi.send([NoteOn(67, 127),
                       NoteOn(71, 127),
                       NoteOn(78, 127)])

        @keybow.on_release(G)
        def release_handler(G):

            midi.send([NoteOff(67, 127),
                       NoteOff(71, 127),
                       NoteOff(78, 127)])

        Ab = keys[8]
        @keybow.on_press(Ab)
        def press_handler(Ab):

            midi.send([NoteOn(68, 127),
                       NoteOn(72, 127),
                       NoteOn(79, 127)])

        @keybow.on_release(Ab)
        def release_handler(Ab):

            midi.send([NoteOff(68, 127),
                       NoteOff(72, 127),
                       NoteOff(79, 127)])

        A = keys[9]
        @keybow.on_press(A)
        def press_handler(A):

            midi.send([NoteOn(69, 127),
                       NoteOn(73, 127),
                       NoteOn(80, 127)])

        @keybow.on_release(A)
        def release_handler(A):

            midi.send([NoteOff(69, 127),
                       NoteOff(73, 127),
                       NoteOff(80, 127)])

        Bb = keys[10]
        @keybow.on_press(Bb)
        def press_handler(Bb):

            midi.send([NoteOn(70, 127),
                       NoteOn(74, 127),
                       NoteOn(81, 127)])

        @keybow.on_release(Bb)
        def release_handler(Bb):

            midi.send([NoteOff(70, 127),
                       NoteOff(74, 127),
                       NoteOff(81, 127)])

        B = keys[11]
        @keybow.on_press(B)
        def press_handler(B):

            midi.send([NoteOn(71, 127),
                       NoteOn(75, 127),
                       NoteOn(82, 127)])

        @keybow.on_release(B)
        def release_handler(B):

            midi.send([NoteOff(71, 127),
                       NoteOff(75, 127),
                       NoteOff(82, 127)])

                      #Min7 chord
    if not keys[15].pressed and not keys[14].pressed \
    and not keys[13].pressed and keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):

            midi.send([NoteOn(60, 127),
                       NoteOn(63, 127),
                       NoteOn(70, 127)])

        @keybow.on_release(C)
        def release_handler(C):

            midi.send([NoteOff(60, 127),
                       NoteOff(63, 127),
                       NoteOff(70, 127)])

        Db = keys[1]
        @keybow.on_press(Db)
        def press_handler(Db):

            midi.send([NoteOn(61, 127),
                       NoteOn(64, 127),
                       NoteOn(71, 127)])

        @keybow.on_release(Db)
        def release_handler(Db):

            midi.send([NoteOff(61, 127),
                       NoteOff(64, 127),
                       NoteOff(71, 127)])

        D = keys[2]
        @keybow.on_press(D)
        def press_handler(D):

            midi.send([NoteOn(62, 127),
                       NoteOn(65, 127),
                       NoteOn(72, 127)])

        @keybow.on_release(D)
        def release_handler(D):

            midi.send([NoteOff(62, 127),
                       NoteOff(65, 127),
                       NoteOff(72, 127)])

        Eb = keys[3]
        @keybow.on_press(Eb)
        def press_handler(Eb):

            midi.send([NoteOn(63, 127),
                       NoteOn(66, 127),
                       NoteOn(73, 127)])

        @keybow.on_release(Eb)
        def release_handler(Eb):

            midi.send([NoteOff(63, 127),
                       NoteOff(66, 127),
                       NoteOff(73, 127)])

        E = keys[4]
        @keybow.on_press(E)
        def press_handler(E):

            midi.send([NoteOn(64, 127),
                       NoteOn(67, 127),
                       NoteOn(74, 127)])

        @keybow.on_release(E)
        def release_handler(E):

            midi.send([NoteOff(64, 127),
                       NoteOff(67, 127),
                       NoteOff(74, 127)])

        F = keys[5]
        @keybow.on_press(F)
        def press_handler(F):

            midi.send([NoteOn(65, 127),
                       NoteOn(68, 127),
                       NoteOn(75, 127)])

        @keybow.on_release(F)
        def release_handler(F):

            midi.send([NoteOff(65, 127),
                       NoteOff(68, 127),
                       NoteOff(75, 127)])

        Gb = keys[6]
        @keybow.on_press(Gb)
        def press_handler(Gb):

            midi.send([NoteOn(66, 127),
                       NoteOn(69, 127),
                       NoteOn(76, 127)])

        @keybow.on_release(Gb)
        def release_handler(Gb):

            midi.send([NoteOff(66, 127),
                       NoteOff(69, 127),
                       NoteOff(76, 127)])

        G = keys[7]
        @keybow.on_press(G)
        def press_handler(G):

            midi.send([NoteOn(67, 127),
                       NoteOn(70, 127),
                       NoteOn(77, 127)])

        @keybow.on_release(G)
        def release_handler(G):

            midi.send([NoteOff(67, 127),
                       NoteOff(70, 127),
                       NoteOff(77, 127)])

        Ab = keys[8]
        @keybow.on_press(Ab)
        def press_handler(Ab):

            midi.send([NoteOn(68, 127),
                       NoteOn(71, 127),
                       NoteOn(78, 127)])

        @keybow.on_release(Ab)
        def release_handler(Ab):

            midi.send([NoteOff(68, 127),
                       NoteOff(71, 127),
                       NoteOff(78, 127)])

        A = keys[9]
        @keybow.on_press(A)
        def press_handler(A):

            midi.send([NoteOn(69, 127),
                       NoteOn(72, 127),
                       NoteOn(79, 127)])

        @keybow.on_release(A)
        def release_handler(A):

            midi.send([NoteOff(69, 127),
                       NoteOff(72, 127),
                       NoteOff(79, 127)])

        Bb = keys[10]
        @keybow.on_press(Bb)
        def press_handler(Bb):

            midi.send([NoteOn(70, 127),
                       NoteOn(73, 127),
                       NoteOn(80, 127)])

        @keybow.on_release(Bb)
        def release_handler(Bb):

            midi.send([NoteOff(70, 127),
                       NoteOff(73, 127),
                       NoteOff(80, 127)])

        B = keys[11]
        @keybow.on_press(B)
        def press_handler(B):

            midi.send([NoteOn(71, 127),
                       NoteOn(74, 127),
                       NoteOn(81, 127)])

        @keybow.on_release(B)
        def release_handler(B):

            midi.send([NoteOff(71, 127),
                       NoteOff(74, 127),
                       NoteOff(81, 127)])

                     #Majadd9 chord
    if keys[15].pressed and not keys[14].pressed \
    and keys[13].pressed and not keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):

            midi.send([NoteOn(60, 127),
                       NoteOn(64, 127),
                       NoteOn(74, 127)])

        @keybow.on_release(C)
        def release_handler(C):

            midi.send([NoteOff(60, 127),
                       NoteOff(64, 127),
                       NoteOff(74, 127)])

        Db = keys[1]
        @keybow.on_press(Db)
        def press_handler(Db):

            midi.send([NoteOn(61, 127),
                       NoteOn(65, 127),
                       NoteOn(75, 127)])

        @keybow.on_release(Db)
        def release_handler(Db):

            midi.send([NoteOff(61, 127),
                       NoteOff(65, 127),
                       NoteOff(75, 127)])

        D = keys[2]
        @keybow.on_press(D)
        def press_handler(D):

            midi.send([NoteOn(62, 127),
                       NoteOn(66, 127),
                       NoteOn(76, 127)])

        @keybow.on_release(D)
        def release_handler(D):

            midi.send([NoteOff(62, 127),
                       NoteOff(66, 127),
                       NoteOff(76, 127)])

        Eb = keys[3]
        @keybow.on_press(Eb)
        def press_handler(Eb):

            midi.send([NoteOn(63, 127),
                       NoteOn(67, 127),
                       NoteOn(77, 127)])

        @keybow.on_release(Eb)
        def release_handler(Eb):

            midi.send([NoteOff(63, 127),
                       NoteOff(67, 127),
                       NoteOff(77, 127)])

        E = keys[4]
        @keybow.on_press(E)
        def press_handler(E):

            midi.send([NoteOn(64, 127),
                       NoteOn(68, 127),
                       NoteOn(78, 127)])

        @keybow.on_release(E)
        def release_handler(E):

            midi.send([NoteOff(64, 127),
                       NoteOff(68, 127),
                       NoteOff(78, 127)])

        F = keys[5]
        @keybow.on_press(F)
        def press_handler(F):

            midi.send([NoteOn(65, 127),
                       NoteOn(69, 127),
                       NoteOn(79, 127)])

        @keybow.on_release(F)
        def release_handler(F):

            midi.send([NoteOff(65, 127),
                       NoteOff(69, 127),
                       NoteOff(79, 127)])

        Gb = keys[6]
        @keybow.on_press(Gb)
        def press_handler(Gb):

            midi.send([NoteOn(66, 127),
                       NoteOn(70, 127),
                       NoteOn(80, 127)])

        @keybow.on_release(Gb)
        def release_handler(Gb):

            midi.send([NoteOff(66, 127),
                       NoteOff(70, 127),
                       NoteOff(80, 127)])

        G = keys[7]
        @keybow.on_press(G)
        def press_handler(G):

            midi.send([NoteOn(67, 127),
                       NoteOn(71, 127),
                       NoteOn(81, 127)])

        @keybow.on_release(G)
        def release_handler(G):

            midi.send([NoteOff(67, 127),
                       NoteOff(71, 127),
                       NoteOff(81, 127)])

        Ab = keys[8]
        @keybow.on_press(Ab)
        def press_handler(Ab):

            midi.send([NoteOn(68, 127),
                       NoteOn(72, 127),
                       NoteOn(82, 127)])

        @keybow.on_release(Ab)
        def release_handler(Ab):

            midi.send([NoteOff(68, 127),
                       NoteOff(72, 127),
                       NoteOff(82, 127)])

        A = keys[9]
        @keybow.on_press(A)
        def press_handler(A):

            midi.send([NoteOn(69, 127),
                       NoteOn(73, 127),
                       NoteOn(83, 127)])

        @keybow.on_release(A)
        def release_handler(A):

            midi.send([NoteOff(69, 127),
                       NoteOff(73, 127),
                       NoteOff(83, 127)])

        Bb = keys[10]
        @keybow.on_press(Bb)
        def press_handler(Bb):

            midi.send([NoteOn(70, 127),
                       NoteOn(74, 127),
                       NoteOn(84, 127)])

        @keybow.on_release(Bb)
        def release_handler(Bb):

            midi.send([NoteOff(70, 127),
                       NoteOff(74, 127),
                       NoteOff(84, 127)])

        B = keys[11]
        @keybow.on_press(B)
        def press_handler(B):

            midi.send([NoteOn(71, 127),
                       NoteOn(75, 127),
                       NoteOn(85, 127)])

        @keybow.on_release(B)
        def release_handler(B):

            midi.send([NoteOff(71, 127),
                       NoteOff(75, 127),
                       NoteOff(85, 127)])

                     #Minadd9 chord
    if not keys[15].pressed and keys[14].pressed \
    and not keys[13].pressed and keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):

            midi.send([NoteOn(60, 127),
                       NoteOn(63, 127),
                       NoteOn(74, 127)])

        @keybow.on_release(C)
        def release_handler(C):

            midi.send([NoteOff(60, 127),
                       NoteOff(63, 127),
                       NoteOff(74, 127)])

        Db = keys[1]
        @keybow.on_press(Db)
        def press_handler(Db):

            midi.send([NoteOn(61, 127),
                       NoteOn(64, 127),
                       NoteOn(75, 127)])

        @keybow.on_release(Db)
        def release_handler(Db):

            midi.send([NoteOff(61, 127),
                       NoteOff(64, 127),
                       NoteOff(75, 127)])

        D = keys[2]
        @keybow.on_press(D)
        def press_handler(D):

            midi.send([NoteOn(62, 127),
                       NoteOn(65, 127),
                       NoteOn(76, 127)])

        @keybow.on_release(D)
        def release_handler(D):

            midi.send([NoteOff(62, 127),
                       NoteOff(65, 127),
                       NoteOff(76, 127)])

        Eb = keys[3]
        @keybow.on_press(Eb)
        def press_handler(Eb):

            midi.send([NoteOn(63, 127),
                       NoteOn(66, 127),
                       NoteOn(77, 127)])

        @keybow.on_release(Eb)
        def release_handler(Eb):

            midi.send([NoteOff(63, 127),
                       NoteOff(66, 127),
                       NoteOff(77, 127)])

        E = keys[4]
        @keybow.on_press(E)
        def press_handler(E):

            midi.send([NoteOn(64, 127),
                       NoteOn(67, 127),
                       NoteOn(78, 127)])

        @keybow.on_release(E)
        def release_handler(E):

            midi.send([NoteOff(64, 127),
                       NoteOff(67, 127),
                       NoteOff(78, 127)])

        F = keys[5]
        @keybow.on_press(F)
        def press_handler(F):

            midi.send([NoteOn(65, 127),
                       NoteOn(68, 127),
                       NoteOn(79, 127)])

        @keybow.on_release(F)
        def release_handler(F):

            midi.send([NoteOff(65, 127),
                       NoteOff(68, 127),
                       NoteOff(79, 127)])

        Gb = keys[6]
        @keybow.on_press(Gb)
        def press_handler(Gb):

            midi.send([NoteOn(66, 127),
                       NoteOn(69, 127),
                       NoteOn(80, 127)])

        @keybow.on_release(Gb)
        def release_handler(Gb):

            midi.send([NoteOff(66, 127),
                       NoteOff(69, 127),
                       NoteOff(80, 127)])

        G = keys[7]
        @keybow.on_press(G)
        def press_handler(G):

            midi.send([NoteOn(67, 127),
                       NoteOn(70, 127),
                       NoteOn(81, 127)])

        @keybow.on_release(G)
        def release_handler(G):

            midi.send([NoteOff(67, 127),
                       NoteOff(70, 127),
                       NoteOff(81, 127)])

        Ab = keys[8]
        @keybow.on_press(Ab)
        def press_handler(Ab):

            midi.send([NoteOn(68, 127),
                       NoteOn(71, 127),
                       NoteOn(82, 127)])

        @keybow.on_release(Ab)
        def release_handler(Ab):

            midi.send([NoteOff(68, 127),
                       NoteOff(71, 127),
                       NoteOff(82, 127)])

        A = keys[9]
        @keybow.on_press(A)
        def press_handler(A):

            midi.send([NoteOn(69, 127),
                       NoteOn(72, 127),
                       NoteOn(83, 127)])

        @keybow.on_release(A)
        def release_handler(A):

            midi.send([NoteOff(69, 127),
                       NoteOff(72, 127),
                       NoteOff(83, 127)])

        Bb = keys[10]
        @keybow.on_press(Bb)
        def press_handler(Bb):

            midi.send([NoteOn(70, 127),
                       NoteOn(73, 127),
                       NoteOn(84, 127)])

        @keybow.on_release(Bb)
        def release_handler(Bb):

            midi.send([NoteOff(70, 127),
                       NoteOff(73, 127),
                       NoteOff(84, 127)])

        B = keys[11]
        @keybow.on_press(B)
        def press_handler(B):

            midi.send([NoteOn(71, 127),
                       NoteOn(74, 127),
                       NoteOn(85, 127)])

        @keybow.on_release(B)
        def release_handler(B):

            midi.send([NoteOff(71, 127),
                       NoteOff(74, 127),
                       NoteOff(85, 127)])

                    #Half diminished chord
    if keys[15].pressed and keys[14].pressed \
    and keys[13].pressed and keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):

            midi.send([NoteOn(60, 127),
                       NoteOn(66, 127),
                       NoteOn(70, 127)])

        @keybow.on_release(C)
        def release_handler(C):

            midi.send([NoteOff(60, 127),
                       NoteOff(66, 127),
                       NoteOff(70, 127)])

        Db = keys[1]
        @keybow.on_press(Db)
        def press_handler(Db):

            midi.send([NoteOn(61, 127),
                       NoteOn(67, 127),
                       NoteOn(71, 127)])

        @keybow.on_release(Db)
        def release_handler(Db):

            midi.send([NoteOff(61, 127),
                       NoteOff(67, 127),
                       NoteOff(71, 127)])

        D = keys[2]
        @keybow.on_press(D)
        def press_handler(D):

            midi.send([NoteOn(62, 127),
                       NoteOn(68, 127),
                       NoteOn(72, 127)])

        @keybow.on_release(D)
        def release_handler(D):

            midi.send([NoteOff(62, 127),
                       NoteOff(68, 127),
                       NoteOff(72, 127)])

        Eb = keys[3]
        @keybow.on_press(Eb)
        def press_handler(Eb):

            midi.send([NoteOn(63, 127),
                       NoteOn(69, 127),
                       NoteOn(73, 127)])

        @keybow.on_release(Eb)
        def release_handler(Eb):

            midi.send([NoteOff(63, 127),
                       NoteOff(69, 127),
                       NoteOff(73, 127)])

        E = keys[4]
        @keybow.on_press(E)
        def press_handler(E):

            midi.send([NoteOn(64, 127),
                       NoteOn(70, 127),
                       NoteOn(74, 127)])

        @keybow.on_release(E)
        def release_handler(E):

            midi.send([NoteOff(64, 127),
                       NoteOff(70, 127),
                       NoteOff(74, 127)])

        F = keys[5]
        @keybow.on_press(F)
        def press_handler(F):

            midi.send([NoteOn(65, 127),
                       NoteOn(71, 127),
                       NoteOn(75, 127)])

        @keybow.on_release(F)
        def release_handler(F):

            midi.send([NoteOff(65, 127),
                       NoteOff(71, 127),
                       NoteOff(75, 127)])

        Gb = keys[6]
        @keybow.on_press(Gb)
        def press_handler(Gb):

            midi.send([NoteOn(66, 127),
                       NoteOn(72, 127),
                       NoteOn(76, 127)])

        @keybow.on_release(Gb)
        def release_handler(Gb):

            midi.send([NoteOff(66, 127),
                       NoteOff(72, 127),
                       NoteOff(76, 127)])

        G = keys[7]
        @keybow.on_press(G)
        def press_handler(G):

            midi.send([NoteOn(67, 127),
                       NoteOn(73, 127),
                       NoteOn(77, 127)])

        @keybow.on_release(G)
        def release_handler(G):

            midi.send([NoteOff(67, 127),
                       NoteOff(73, 127),
                       NoteOff(77, 127)])

        Ab = keys[8]
        @keybow.on_press(Ab)
        def press_handler(Ab):

            midi.send([NoteOn(68, 127),
                       NoteOn(74, 127),
                       NoteOn(78, 127)])

        @keybow.on_release(Ab)
        def release_handler(Ab):

            midi.send([NoteOff(68, 127),
                       NoteOff(74, 127),
                       NoteOff(78, 127)])

        A = keys[9]
        @keybow.on_press(A)
        def press_handler(A):

            midi.send([NoteOn(69, 127),
                       NoteOn(75, 127),
                       NoteOn(79, 127)])

        @keybow.on_release(A)
        def release_handler(A):

            midi.send([NoteOff(69, 127),
                       NoteOff(75, 127),
                       NoteOff(79, 127)])

        Bb = keys[10]
        @keybow.on_press(Bb)
        def press_handler(Bb):

            midi.send([NoteOn(70, 127),
                       NoteOn(76, 127),
                       NoteOn(80, 127)])

        @keybow.on_release(Bb)
        def release_handler(Bb):

            midi.send([NoteOff(70, 127),
                       NoteOff(76, 127),
                       NoteOff(80, 127)])

        B = keys[11]
        @keybow.on_press(B)
        def press_handler(B):

            midi.send([NoteOn(71, 127),
                       NoteOn(77, 127),
                       NoteOn(81, 127)])

        @keybow.on_release(B)
        def release_handler(B):

            midi.send([NoteOff(71, 127),
                       NoteOff(77, 127),
                       NoteOff(81, 127)])

Behavior

It works as expected on Windows, and if I flash the RP2040 and code it using sudo nano code.py on MacOS, it works too.

However, as soon as I do a hard reset or restart my Mac, the Pico or Keybow is no longer recognised.

Description

On the Console, 6 kernel errors appear when plugging the programmed Pico or Keybow:

130345.648474 IOUSBHostDevice@02241000: IOUSBHostDevice::start_block_invoke: device descriptor fragment is invalid

130345.651657 IOUSBHostFamily::validateEndpointMaxPacketSize: USB 2.0 5.[5-8].3: endpoint 0x00 invalid wMaxPacketSize 0x0000

130345.651866 AppleUSB20HubPort@02241000: AppleUSBHostPort::enumerateDeviceComplete_block_invoke: enumeration failed

130345.651890 AppleUSB20HubPort@02241000: AppleUSBHostPort::terminateDevice: destroying 0x0000/0000/0000 (IOUSBHostDevice): enumeration failure

130345.651963 AppleUSB20HubPort@02241000: AppleUSBHostPort::disconnect: persistent enumeration failures

130345.651990 IOUSBHostDevice@02241000: IOUSBHostDevice::start_block_invoke: device will not be registered for matching

Additional information

Does anyone have any ideas on the issue? I have tried CircuitPython 6 and the 7.1 beta. I've tried creating a boot.py file that delays running code.py, disables USB_HID and enables usb_midi, but this had no effect. I have also tried plugging it in to an old Intel iMac running El Capitan, and it doesn't mount on that either.

Everything initially works as usual on the Mac, the RPi2 drive mounts on first connection and holding BOOTSEL. After flashing with the CircuitPython uf2 it reboots as CIRCUITPY, and mounts without issue. But after adding in my code and the required libraries and files to lib (Adafruit_midi, Keybow_hardware, Adafruit_dotstar.mpy, Keybow.py) and putting my code in code.py, it no longer mounts and presents the above errors in console.

dhalbert commented 2 years ago

I've tried creating a boot.py file that delays running code.py, disables USB_HID and enables usb_midi, but this had no effect. I have also tried plugging it in to an old Intel iMac running El Capitan, and it doesn't mount on that either.

Delay in boot.py won't really change USB startup, because the device doesn't present as USB until boot.py has finished running. Have you tried just inserting a several-second sleep at the beginning of code.py?

Try a really minimal example that just sends a single MIDI note every second, or on a button push, or something like that. Use the minimum number of libraries. I looked at the Keybow library and I don't see anything suspicious, but it's good to narrow the problem down.

Also try some different USB cables. If you are using a USB hub, try not using it. Try to eliminate anything shared between the older iMac and the new Mac.

savt22 commented 2 years ago

Hi Dan,

Thank you for your help. I had a play around yesterday evening and I have narrowed down the problem.

I tried with and without a dock, with different cables, and then I started playing round with the code. The Keybow midi example from their GitHub worked fine, and mounted without issue. So that ruled out it being a general library issue as my code uses the same libraries and builds on that example.

So I started adding more bits from my code until it stopped working.

If I remove the bottom three modifier key combinations, below, it mounts on Mac without issue. With the multiple keypress modifiers, in addition to not mounting, it also appears to temporarily crash the Mac's audio codec.

#majadd9
    if keys[15].pressed and not keys[14].pressed \
    and keys[13].pressed and not keys[12].pressed:
#minadd9
    if not keys[15].pressed and keys[14].pressed \
    and not keys[13].pressed and keys[12].pressed:
#halfdim 
    if keys[15].pressed and keys[14].pressed \
    and keys[13].pressed and keys[12].pressed:

This is my first project, so it's likely there is a better way of doing what I've done. But these key press combos do work without issue on Windows.

dhalbert commented 2 years ago

It looks like you defined some keyrelease handlers only if keys 12-15 are pressed in a certain combination. That would happen on startup only. Is that what you want to do?

If you don't and import and don't use the Keybow library at all, then is there no crash? I am trying to figure out if it's Keybow-related or MIDI-related.

savt22 commented 2 years ago

Here is a video showing the functionality of keys 12-15: https://www.youtube.com/watch?v=sJZyv5DZECY

To help narrow it down, I rewrote it so that I didn't import usb_midi or adafruit_midi. I kept the modifier key combos the same, but programmed it to just change the colour of the keys rather than play midi notes/chords:

import time 
time.sleep(5)
from keybow2040 import Keybow2040
from keybow_hardware.pim56x import PIM56X as Hardware

keybow = Keybow2040(Hardware())
keys = keybow.keys

while True:
    keybow.update()

    if keys[15].pressed and not keys[14].pressed \
    and not keys[13].pressed and not keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):
            keybow.set_all(255, 225, 255)

    if not keys[15].pressed and keys[14].pressed \
    and not keys[13].pressed and not keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):
            keybow.set_all(0, 50, 255)

    if not keys[15].pressed and not keys[14].pressed \
    and keys[13].pressed and not keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):
            keybow.set_all(50, 0, 100)

    if not keys[15].pressed and not keys[14].pressed \
    and not keys[13].pressed and keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):
            keybow.set_all(255, 0, 50)

    if keys[15].pressed and not keys[14].pressed \
    and keys[13].pressed and not keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):
            keybow.set_all(100, 0, 255)

    if not keys[15].pressed and keys[14].pressed \
    and not keys[13].pressed and keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):
            keybow.set_all(255, 0, 0)

    if keys[15].pressed and keys[14].pressed \
    and keys[13].pressed and keys[12].pressed:
        C = keys[0]
        @keybow.on_press(C)
        def press_handler(C):
            keybow.set_all(0, 0, 255)

This code runs completely fine on Mac. So, if I don't import usb_midi or adafruit_midi, but still import Keybow and include the modifier combination key presses, it enumerates and functions as intended.

I think it must be related specifically to midi, then. As the issue is only present when modifier key combinations are used to define midi chords.

I hope this helps, let me know if there is anything else you would like me to test.

EDIT: Actually, this doesn't run as I thought it would - if I use a modifier key combo (one of the bottom three on the code) it sets the colour. However, if I let go of the modifier keys and press keys[0], keys[0] changes the colour again by itself, which it shouldn't do. However, if I wait a little while after setting the colours using the modifier key combos and then press keys[0], the colour doesn't change. If I change the colour using only keys[12-15], pressing keys[0] straight afterwards doesn't change the colour, as expected. There's no enumeration issue, but it's not doing what I hoped it would, and it seems to dislike the multiple key combo modifiers.