Wireless BLE MIDI Robot Xylophone - Adafruit Industries · Xylophone is also comparatively easier...

53
Wireless BLE MIDI Robot Xylophone Created by Liz Clark Last updated on 2021-03-10 01:24:46 PM EST

Transcript of Wireless BLE MIDI Robot Xylophone - Adafruit Industries · Xylophone is also comparatively easier...

  • Wireless BLE MIDI Robot XylophoneCreated by Liz Clark

    Last updated on 2021-03-10 01:24:46 PM EST

  • 24449999

    10121212121213131314141416171818192020212424242424252525252526262627282829313333343537

    Guide Contents

    Guide ContentsOverview

    The Xylophone/GlockenspielParts

    ElectronicsCircuit DiagramHow It WorksWiringData Signal Flow

    3D PrintingParts ListCAD AssemblySolenoid MountsAdditional PartsItsyBitsy CasePerma-Proto Back PlateDouble Corner Brace, Single Corner Brace and 3 Hole Coupling Plate

    CircuitPython for ItsyBitsy nRF52840 ExpressSet up CircuitPython Quick Start!Further Information

    CircuitPython LibrariesInstalling the CircuitPython Library BundleExample Files

    Copying Libraries to Your BoardExample: ImportError Due to Missing LibraryLibrary Install on Non-Express BoardsUpdating CircuitPython Libraries/Examples

    Coding the BLE MIDI Robot XylophoneCircuitPython Code Walkthrough

    LibrariesI2C SetupSolenoidsMIDI Note NumbersBLE SetupMIDI SetupBegin AdvertisingSolenoid DelayThe LoopMIDI MessagesArrays of ArraysLet the Solenoids Play!Reconnect BLE

    Solenoid Mount AssemblyMount Assembly for Sharps/FlatsTriple Mount for Natural NotesInsert the Solenoids

    Perma-Proto Board Mount AssemblyMount PrepMount 1 AssemblyMount 2 AssemblyMount 3 and 4 Assembly

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 2 of 53

  • 3939394043454747475050

    Mounting to the Aluminum ExtrusionsAdding the Solenoid MountsExtrusion FeetAttach the Proto Board Mounts

    WiringWiring the ItsyBitsy

    Final AssemblyPerma-Proto Back PlateMounting the ItsyBitsy's Case

    MIDI Setup and UsageWindows BLE MIDI Setup

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 3 of 53

  • OverviewThis project converts a xylophone* into a MIDI instrument, but not just any MIDI instrument: a Bluetooth

    Low Energy (BLE) MIDI instrument. This means that it can be setup within range of a Bluetooth connection

    and receive MIDI data without being tied down with a bunch of cables (besides power of course).

    30 solenoids sit comfortably over the xylophone keys, waiting to strike up melodies and chords either live

    with a MIDI keyboard or playing along with MIDI data from a digital audio workstation (DAW). It has a lot of

    potential as either a live instrument or for some extra fun in the studio.

    *Yes, technically this is a bell kit, or glockenspiel, and not a xylophone. However, most people willrecognize instruments in the mallet family colloquially as xylophones. Xylophone is also comparativelyeasier to say and more commonly heard than glockenspiel or bell kit.

    The Xylophone/GlockenspielThe model instrument used for this project is fairly common in the United States, as it is often distributed

    to students in school who begin taking percussion lessons in music programs. You can find the identical

    model by searching for "Ludwig Educational Bell Kit". There's quite a few available new and used on

    Ebay, Amazon, Reverb, Guitar Center or perhaps your cousin's attic.

    Of course, you can also modify the mounting system to fit your chosen mallet instrument, or any other

    instrument. As long as it has metal bars it will sound nicely with the solenoids. Any other material bar

    should have some sort of dampener attached to the solenoid since they could damage softer materials,

    such as wood.

    Parts

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 4 of 53

    https://www.adafruit.com/product/4481https://www.adafruit.com/product/2776https://www.adafruit.com/product/970https://www.adafruit.com/product/732https://www.adafruit.com/product/3306

  • Adafruit ItsyBitsy nRF52840 Express - Bluetooth LE

    What's smaller than a Feather but larger than a Trinket? It's an Adafruit ItsyBitsy nRF52840 Express

    featuring the Nordic nRF52840 Bluetooth LE...

    $17.95

    In Stock

    Your browser does not support the video tag.

    Mini Push-Pull Solenoid - 5V

    Solenoids are basically electromagnets: they are made of a coil of copper wire with an armature (a slug of

    metal) in the middle. When the coil is energized, the slug is pulled into the...

    $4.95

    In Stock

    Add to Cart

    Add to Cart

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 5 of 53

    https://www.adafruit.com/product/4481https://www.adafruit.com/product/4481https://www.adafruit.com/product/2776https://www.adafruit.com/product/2776

  • ULN2803: 8 Channel Darlington Driver (Solenoid/Unipolar Stepper)

    Bring in some muscle to your output pins with 8 mighty Darlingtons! This DIP chip contains 8 drivers that

    can sink 500mA from a 50V supply and has kickback diodes included inside for...

    Out of Stock

    Out ofStock

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 6 of 53

    https://www.adafruit.com/product/970https://www.adafruit.com/product/970

  • MCP23017 - i2c 16 input/output port expander

    Add another 16 pins to your microcontroller using a MCP23017 port expander. The MCP23017 uses two

    i2c pins (these can be shared with other i2c devices), and in exchange gives you 16...

    Out of Stock

    Illuminated Toggle Switch with Cover - Blue

    Fire up your engines because these are the hot-rods of toggle switches! Equipped with an aerodynamic

    blue protective casing, and a diffused blue LED at the tip of the switch, this...

    $2.95

    In Stock

    1 x 1/2 Perma-Proto Breadboards - 3 Pack

    Adafruit Perma-Proto Half-sized Breadboard PCB - 3 Pack

    1 x Perma-Proto Quarter-sized Breadboard

    Adafruit Perma-Proto Quarter-sized Breadboard PCB - Single

    1 x Through-Hole Resistors - 2.2K ohm 5% 1/4W

    2.2K ohm resistors - Pack of 25

    1 x CONN IC DIP SOCKET 28POS

    28 Pin DIP socket - DigiKey

    Out ofStock

    Add to Cart

    Add to Cart

    Add to Cart

    Add to Cart

    Buy Now

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 7 of 53

    https://www.adafruit.com/product/732https://www.adafruit.com/product/732https://www.adafruit.com/product/3306https://www.adafruit.com/product/3306https://www.adafruit.com/product/2782https://www.adafruit.com/product/2782https://www.adafruit.com/product/1608https://www.adafruit.com/product/1608https://www.adafruit.com/product/2782https://www.adafruit.com/product/2782https://www.digikey.com/product-detail/en/on-shore-technology-inc/ED281DT/ED3050-5-ND/4147600https://www.digikey.com/product-detail/en/on-shore-technology-inc/ED281DT/ED3050-5-ND/4147600

  • 2 x CONN IC DIP SOCKET 18POS

    18 Pin DIP socket - DigiKey

    1 x Hook-up Wire

    Hook-up Wire Spool Set - 22AWG Solid Core - 10 x 25ft

    30 x JST-PH Extension Cable

    JST-PH Battery Extension Cable - 500mm

    2 x 20x20 Aluminum Extrusion

    Slotted Aluminum Extrusion - 20mm x 20mm - 610mm long

    2 x Coupling Plate

    Coupling Plate - 3 Holes - 20x20 Aluminum Extrusion

    4 x Double Corner Brace

    Aluminum Extrusion Double Corner Brace Support (for 20x20)

    1 x Slim T-Nuts

    Aluminum Extrusion Slim T-Nut for 20x20 - M4 Thread - pack of 50

    1 x M4 Button Hex Screws

    Button Hex Machine Screw - M4 thread - 8mm long - pack of 50

    1 x M3 Standoffs - Variety pack

    M3 standoffs

    1 x M3 Screws - Variety pack

    M3 screws

    Buy Now

    Add to Cart

    Out ofStock

    Out ofStock

    Add to Cart

    Add to Cart

    Add to Cart

    Add to Cart

    Buy Now

    Buy Now

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 8 of 53

    https://www.digikey.com/product-detail/en/on-shore-technology-inc/ED18DT/ED3047-5-ND/4147597https://www.digikey.com/product-detail/en/on-shore-technology-inc/ED18DT/ED3047-5-ND/4147597https://www.adafruit.com/product/3174https://www.adafruit.com/product/3174https://www.adafruit.com/product/1131https://www.adafruit.com/product/1131https://www.adafruit.com/product/1221https://www.adafruit.com/product/1221https://www.adafruit.com/product/1216https://www.adafruit.com/product/1216https://www.adafruit.com/product/1259https://www.adafruit.com/product/1259https://www.adafruit.com/product/1157https://www.adafruit.com/product/1157https://www.adafruit.com/product/1160https://www.adafruit.com/product/1160https://www.amazon.com/Litorange-Standoff-Threaded-Motherboard-Assortment/dp/B07D7828LC/https://www.amazon.com/Litorange-Standoff-Threaded-Motherboard-Assortment/dp/B07D7828LC/https://www.amazon.com/gp/product/B07YXXK4HB/https://www.amazon.com/gp/product/B07YXXK4HB/

  • ElectronicsCircuit Diagram

    How It WorksThe ItsyBitsy nRF52840 is running CircuitPython code that allows for MIDI to be received over BLE.

    Additionally, it's communicating over I2C between two MCP23017's.

    The MCP23017 is a multiplexer that expands the number of digital inputs and outputs that a

    microcontroller can communicate with. In this case, they're allowing for 30 additional outputs for the

    solenoid motors.

    Before the solenoids can be triggered through, the MCP23017's output their signal to a ULN2803. The

    ULN2803 is a darlington motor driver, which is great for driving solenoids and they can take in 3.3V or 5V

    logic.

    https://adafru.it/Lkc

    https://adafru.it/Lkd

    The CircuitPython code on the IstyBitsy nRF52840 sends on and off signals over I2C to the MCP23017's

    depending on the MIDI note that it receives over BLE. The MCP23017 then sends an on signal, followed

    quickly by an off signal, to a ULN2308 driver. Finally, the ULN2308 triggers the solenoid to hit a note on

    the xylophone.

    Although there's quite a bit of wiring between the IC's and solenoids, the ItsyBitsy is only using 5 pins, and

    that's counting power and ground. The use of I2C keeps things nice and compact.

    WiringPower:

    https://adafru.it/Lkc

    https://adafru.it/Lkd

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 9 of 53

    https://learn.adafruit.com/using-mcp23008-mcp23017-with-circuitpythonhttps://cdn-shop.adafruit.com/datasheets/ULN2803A.pdf

  • 3V from the ItsyBitsy to VDD and RESET on both MCP23017's

    3V from the ItsyBitsy to A0 on the second MCP23017

    USB from the ItsyBitsy to the switch

    COMMON on all four ULN2308's to USB from the switch

    Ground:

    GND from the ItsyBitsy to VSS, A2 and A1 on both MCP23017's

    GND from the ItsyBitsy to A0 in the first MCP23017

    GND from the ItsyBitsy to GND on all four ULN2308's

    I2C:

    2.2K pull-up resistor on both SCL and SDA on the first MCP23017

    SCL from the ItsyBitsy to SCL on both MCP23017's

    SDA from the ItsyBitsy to SDA on both MCP23017's

    Solenoids:

    The solenoid's wire 1 to the output pins (O1-O8) on all four ULN2803's

    The solenoid's wire 2 to USB from the switch

    � A0, A1 and A2 on the MCP23017 determine the I2C address, which is why the wiring differs betweenthe two.

    Data Signal FlowThe chart below explains the pinouts for the multiplexers to the drivers and what MIDI note they

    correspond with.

    Note (Name and MIDI

    #)

    MUX (#, Pin Name, Pin

    #)

    Driver (#, Pin Name, Pin

    Number)

    G2 (55) MUX1, GPA0, Pin 21 Driver 1, I1, Pin 1

    G#2 (56) MUX1, GPA1, Pin 22 Driver 1, I2, Pin 2

    A2 (57) MUX1, GPA2, Pin 23 Driver 1, I3, Pin 3

    A#2 (58) MUX1, GPA3, Pin 24 Driver 1, I4, Pin 4

    B2 (59) MUX1, GPA4, Pin 25 Driver 1, I5, Pin 5

    C3 (60) MUX1, GPA5, Pin 26 Driver 1, I6, Pin 6

    C#3 (61) MUX1, GPA6, Pin 27 Driver 1, I7, Pin 7

    D3 (62) MUX1, GPA7, Pin 28 Driver 1, I8, Pin 8

    D#3 (63) MUX1, GPB0, Pin 1 Driver 2, I1, Pin 1

    E3 (64) MUX1, GPB1, Pin 2 Driver 2, I2, Pin 2

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 10 of 53

  • F3 (65) MUX1, GPB2, Pin 3 Driver 2, I3, Pin 3

    F#3 (66) MUX1, GPB3, Pin 4 Driver 2, I4, Pin 4

    G3 (67) MUX1, GPB4, Pin 5 Driver 2, I5, Pin 5

    G#3 (68) MUX1, GPB5, Pin 6 Driver 2, I6, Pin 6

    A3 (69) MUX1, GPB6, Pin 7 Driver 2, I7, Pin 7

    A#3 (70) MUX1, GPB7, Pin 8 Driver 2, I8, Pin 8

    B3 (71) MUX2, GPA0, Pin 21 Driver 3, I1, Pin 1

    C4 (72) MUX2, GPA1, Pin 22 Driver 3, I2, Pin 2

    C#4 (73) MUX2, GPA2, Pin 23 Driver 3, I3, Pin 3

    D4 (74) MUX2, GPA3, Pin 24 Driver 3, I4, Pin 4

    D#4 (75) MUX2, GPA4, Pin 25 Driver 3, I5, Pin 5

    E4 (76) MUX2, GPA5, Pin 26 Driver 3, I6, Pin 6

    F4 (77) MUX2, GPA6, Pin 27 Driver 3, I7, Pin 7

    F#4 (78) MUX2, GPA7, Pin 28 Driver 3, I8, Pin 8

    G4 (79) MUX2, GPB0, Pin 1 Driver 4, I1, Pin 1

    G#4 (80) MUX2, GPB1, Pin 2 Driver 4, I2, Pin 2

    A4 (81) MUX2, GPB2, Pin 3 Driver 4, I3, Pin 3

    A#4 (82) MUX2, GPB3, Pin 4 Driver 4, I4, Pin 4

    B4 (83) MUX2, GPB4, Pin 5 Driver 4, I5, Pin 5

    C5 (84) MUX2, GPB5, Pin 6 Driver 4, I6, Pin 6

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 11 of 53

  • 3D PrintingParts ListSTL files for 3D printing are oriented to print "as-is" on FDM

    style machines. Parts are designed to 3D print without any

    support material. Original design source may be downloaded

    using the links below.

    base-foot-left.stl

    base-foot-right.stl

    rail-mount.stl

    noid-mount.stl

    https://adafru.it/Lla

    CAD AssemblyThe left and right base feet are secured to the two pieces of

    2020 aluminum stock using M4 hardware screws and nuts.

    The rail mount is fitted into the slotted profiles. The solenoid

    mount is secured to the rail mount using two M3 x 10mm

    screws. The mini 5V solenoid is press fitted into the solenoid

    mount.

    Solenoid MountsThe rail and solenoid mounts feature recesses for M3 hex

    nuts. The slotted tabs on the solenoid mount allow for z-

    height adjustment. Holes in the center allow for wire and

    cable pass-through.

    Additional PartsIn addition to the solenoid mounts and legs, there are few other 3D printed parts available:

    itsyBitsyXyloCaseBody.stl

    itsyBitsyXyloCaseTop.stl

    permaProtoBackPlate.stl

    doubleBrace.stl

    https://adafru.it/Lla

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 12 of 53

    https://learn.adafruit.com//assets/91475https://a360.co/2ZASlP4https://learn.adafruit.com//assets/91476https://learn.adafruit.com//assets/91480

  • 3-holeCouplingPlate.stl

    singleBrace.stl

    ItsyBitsy CaseThe ItsyBitsy case is a snap fit case and the design is

    parametric. It allows for the ItsyBitsy's 1/4 Perma-Proto to be

    mounted at the bottom with stand-offs. Additionally, there is a

    hole for a USB power cable and slots on both sides for the

    power and I2C wires to run from the ItsyBitsy to the other

    Perma-Proto boards on the xylophone. Finally, a power switch

    is mounted at the top and the lid has a hole for the switch to

    mount to.

    The case mounts to the 20x20 aluminum extrusion using M4

    screws and T-Nuts.

    https://adafru.it/Llb

    Perma-Proto Back PlateThe Perma-Proto back plate snap fits onto the 1/2 Perma-

    Proto boards. It allows for the solder joints to be protected

    from any damage or shorts. The Perma-Proto's mounting

    holes are included on the back plate so that they can mount

    to the xylophone.

    https://adafru.it/Llc

    Double Corner Brace, Single CornerBrace and 3 Hole Coupling PlateThese parts are CAD recreations of the original aluminum

    versions, with the exception of the single corner brace which

    is custom. You can use either the 3D printed versions or the

    aluminum versions.

    The single corner brace is used to help support the ItsyBitsy

    case.

    https://adafru.it/Lld

    https://adafru.it/Llb

    https://adafru.it/Llc

    https://adafru.it/Lld

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 13 of 53

    https://learn.adafruit.com//assets/91576https://myhub.autodesk360.com/ue2aa0ab1/g/shares/SH56a43QTfd62c1cd968522b508527a5d8bc?viewState=NoIgbgDAdAjCA0IDeAdEAXAngBwKZoC40ARXAZwEsBzAOzXjQEMyzd1C0IBWAFgE4uAY1wATALQQA7JIhiegyVzEAjEQDNxADhg9cfAMz7lkniJFoAviAC6QAhttps://learn.adafruit.com//assets/91577https://myhub.autodesk360.com/ue2aa0ab1/g/shares/SH56a43QTfd62c1cd9680704593dd7ccd807?viewState=NoIgbgDAdAjCA0IDeAdEAXAngBwKZoC40ARXAZwEsBzAOzXjQEMyzd1C1cAzATgGNcEGIwC0MLoJEAWKQGYATCIAcuKQHZlSqfNl81jAEZ8AJjzQBfEAF0gAhttps://learn.adafruit.com//assets/91578https://myhub.autodesk360.com/ue2aa0ab1/g/shares/SH56a43QTfd62c1cd968b5ec7bd637b40c52?viewState=NoIgbgDAdAjCA0IDeAdEAXAngBwKZoC40ARXAZwEsBzAOzXjQEMyzd1C0AWAMwGNuArABMBvALQB2XAE4ATGJ4AjAMxjFnIdzECY-IZwkwhjRgA40AXxABdIA

  • CircuitPython for ItsyBitsy nRF52840 ExpressCircuitPython (https://adafru.it/tB7) is a derivative of MicroPython (https://adafru.it/BeZ) designed to

    simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get

    prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the

    CIRCUITPY drive to iterate.

    � Set up CircuitPython Quick Start!Follow this quick step-by-step for super-fast Python power :)

    https://adafru.it/Ie7

    Further InformationFor more detailed info on installing CircuitPython, check out Installing CircuitPython (https://adafru.it/Amd).

    Click the link above and download the latest UF2 file.

    Download and save it to your desktop (or wherever is handy).

    Plug your Itsy nRF52840 into your computer using a known-

    good USB cable.

    A lot of people end up using charge-only USB cables and it

    is very frustrating! So make sure you have a USB cable you

    know is good for data sync.

    In the image, the Reset button is indicated by the magenta

    arrow, and the BTLE status LED is indicated by the green

    arrow.

    Double-click the Reset button on your board (magenta arrow),

    and you will see the BTLE LED (green arrow) will pulse

    quickly then slowly blue. If the DotStar LED turns red, check

    the USB cable, try another USB port, etc.

    If double-clicking doesn't work the first time, try again.

    Sometimes it can take a few tries to get the rhythm right!

    https://adafru.it/Ie7

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 14 of 53

    https://github.com/adafruit/circuitpythonhttps://micropython.orghttps://circuitpython.org/board/itsybitsy_nrf52840_express/https://learn.adafruit.com/welcome-to-circuitpython/installing-circuitpythonhttps://learn.adafruit.com//assets/87069https://learn.adafruit.com//assets/87086

  • You will see a new disk drive appear called ITSY840BOOT.

    Drag the adafruit_circuitpython_etc.uf2 file to

    ITSY840BOOT.

    The LED will flash. Then, the ITSY840BOOT drive will

    disappear and a new disk drive called CIRCUITPY will

    appear.

    That's it, you're done! :)

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 15 of 53

    https://learn.adafruit.com//assets/87081https://learn.adafruit.com//assets/87089https://learn.adafruit.com//assets/87093

  • CircuitPython Libraries� As we continue to develop CircuitPython and create new releases, we will stop supporting olderreleases. Visit https://circuitpython.org/downloads to download the latest version of CircuitPython for

    your board. You must download the CircuitPython Library Bundle that matches your version of

    CircuitPython. Please update CircuitPython and then visit https://circuitpython.org/libraries to

    download the latest Library Bundle.

    Each CircuitPython program you run needs to have a lot of information to work. The reason CircuitPython

    is so simple to use is that most of that information is stored in other files and works in the background.

    These files are called libraries. Some of them are built into CircuitPython. Others are stored on yourCIRCUITPY drive in a folder called lib. Part of what makes CircuitPython so awesome is its ability to store

    code separately from the firmware itself. Storing code separately from the firmware makes it easier to

    update both the code you write and the libraries you depend.

    Your board may ship with a lib folder already, it's in the base directory of the drive. If not, simply create the

    folder yourself. When you first install CircuitPython, an empty lib directory will be created for you.

    CircuitPython libraries work in the same way as regular Python modules so the Python

    docs (https://adafru.it/rar) are a great reference for how it all should work. In Python terms, we can place

    our library files in the lib directory because its part of the Python path by default.

    One downside of this approach of separate libraries is that they are not built in. To use them, one needs

    to copy them to the CIRCUITPY drive before they can be used. Fortunately, we provide a bundle full of

    our libraries.

    Our bundle and releases also feature optimized versions of the libraries with the .mpy file extension.

    These files take less space on the drive and have a smaller memory footprint as they are loaded.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 16 of 53

    https://circuitpython.org/downloadshttps://circuitpython.org/librarieshttps://docs.python.org/3/tutorial/modules.html

  • Installing the CircuitPython Library BundleWe're constantly updating and improving our libraries, so we don't (at this time) ship our CircuitPython

    boards with the full library bundle. Instead, you can find example code in the guides for your board that

    depends on external libraries. Some of these libraries may be available from us at Adafruit, some may be

    written by community members!

    Either way, as you start to explore CircuitPython, you'll want to know how to get libraries on board.

    You can grab the latest Adafruit CircuitPython Bundle release by clicking the button below.

    Note: Match up the bundle version with the version of CircuitPython you are running - 3.x library for

    running any version of CircuitPython 3, 4.x for running any version of CircuitPython 4, etc. If you mix

    libraries with major CircuitPython versions, you will most likely get errors due to changes in library

    interfaces possible during major version changes.

    https://adafru.it/ENC

    If you need another version, you can also visit the bundle release page (https://adafru.it/Ayy) which will let

    you select exactly what version you're looking for, as well as information about changes.

    Either way, download the version that matches your CircuitPython firmware version. If you don't know

    the version, look at the initial prompt in the CircuitPython REPL, which reports the version. For example, if

    you're running v4.0.1, download the 4.x library bundle. There's also a py bundle which contains the

    uncompressed python files, you probably don't want that unless you are doing advanced work onlibraries.

    After downloading the zip, extract its contents. This is usually done by double clicking on the zip. On Mac

    OSX, it places the file in the same directory as the zip.

    Open the bundle folder. Inside you'll find two information files, and two folders. One folder is the lib

    bundle, and the other folder is the examples bundle.

    https://adafru.it/ENC

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 17 of 53

    https://circuitpython.org/librarieshttps://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/latest/

  • Now open the lib folder. When you open the folder, you'll see a large number of mpy files and folders

    Example FilesAll example files from each library are now included in the bundles, as well as an examples-only bundle.

    These are included for two main reasons:

    Allow for quick testing of devices.

    Provide an example base of code, that is easily built upon for individualized purposes.

    Copying Libraries to Your BoardFirst you'll want to create a lib folder on your CIRCUITPY drive. Open the drive, right click, choose the

    option to create a new folder, and call it lib. Then, open the lib folder you extracted from the downloaded

    zip. Inside you'll find a number of folders and .mpy files. Find the library you'd like to use, and copy it to

    the lib folder on CIRCUITPY.

    This also applies to example files. They are only supplied as raw .py files, so they may need to be

    converted to .mpy using the mpy-cross utility if you encounter MemoryErrors . This is discussed in theCircuitPython Essentials Guide (https://adafru.it/CTw). Usage is the same as described above in the

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 18 of 53

    https://learn.adafruit.com/circuitpython-essentials/circuitpython-expectations#how-can-i-create-my-own-mpy-files-18-6

  • Express Boards section. Note: If you do not place examples in a separate folder, you would remove the

    examples from the import statement.

    � If a library has multiple .mpy files contained in a folder, be sure to copy the entire folder toCIRCUITPY/lib.

    Example: ImportError Due to Missing LibraryIf you choose to load libraries as you need them, you may write up code that tries to use a library you

    haven't yet loaded. We're going to demonstrate what happens when you try to utilise a library that you

    don't have loaded on your board, and cover the steps required to resolve the issue.

    This demonstration will only return an error if you do not have the required library loaded into the lib

    folder on your CIRCUITPY drive.

    Let's use a modified version of the blinky example.

    import boardimport timeimport simpleio

    led = simpleio.DigitalOut(board.D13)

    while True: led.value = True time.sleep(0.5) led.value = False time.sleep(0.5)

    Save this file. Nothing happens to your board. Let's check the serial console to see what's going on.

    We have an ImportError . It says there is no module named 'simpleio' . That's the one we just included in ourcode!

    Click the link above to download the correct bundle. Extract the lib folder from the downloaded bundle

    file. Scroll down to find simpleio.mpy. This is the library file we're looking for! Follow the steps above to

    load an individual library file.

    The LED starts blinking again! Let's check the serial console.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 19 of 53

  • No errors! Excellent. You've successfully resolved an ImportError !

    If you run into this error in the future, follow along with the steps above and choose the library that

    matches the one you're missing.

    Library Install on Non-Express BoardsIf you have a Trinket M0 or Gemma M0, you'll want to follow the same steps in the example above to

    install libraries as you need them. You don't always need to wait for an ImportError as you probably knowwhat library you added to your code. Simply open the lib folder you downloaded, find the library you

    need, and drag it to the lib folder on your CIRCUITPY drive.

    You may end up running out of space on your Trinket M0 or Gemma M0 even if you only load libraries as

    you need them. There are a number of steps you can use to try to resolve this issue. You'll find them in

    the Troubleshooting page in the Learn guides for your board.

    Updating CircuitPython Libraries/ExamplesLibraries and examples are updated from time to time, and it's important to update the files you have on

    your CIRCUITPY drive.

    To update a single library or example, follow the same steps above. When you drag the library file to your

    lib folder, it will ask if you want to replace it. Say yes. That's it!

    A new library bundle is released every time there's an update to a library. Updates include things like bug

    fixes and new features. It's important to check in every so often to see if the libraries you're using have

    been updated.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 20 of 53

  • Coding the BLE MIDI Robot XylophoneOnce you've finished setting up your ItsyBitsy nRF52840 Express with CircuitPython, you can add these

    libraries to the lib folder:

    adafruit_ble

    adafruit_bluefruit_connect

    adafruit_bus_device

    adafruit_mcp230xx

    adafruit_midi

    adafruit_ble_midi.mpy

    Then, you can click on the Download: Project Zip link above the code to download the code file.

    import timeimport boardimport busiofrom adafruit_mcp230xx.mcp23017 import MCP23017from digitalio import Directionimport adafruit_blefrom adafruit_ble.advertising.standard import ProvideServicesAdvertisementimport adafruit_ble_midi

    # These import auto-register the message type with the MIDI machinery.# pylint: disable=unused-importimport adafruit_midifrom adafruit_midi.control_change import ControlChangefrom adafruit_midi.midi_message import MIDIUnknownEventfrom adafruit_midi.note_off import NoteOfffrom adafruit_midi.note_on import NoteOnfrom adafruit_midi.pitch_bend import PitchBend

    # i2c setupi2c = busio.I2C(board.SCL, board.SDA)

    # i2c addresses for muxesmcp1 = MCP23017(i2c, address=0x20)mcp2 = MCP23017(i2c, address=0x21)

    # 1st solenoid array, corresponds with 1st muxnoids0 = []

    for pin in range(16): noids0.append(mcp1.get_pin(pin))for n in noids0: n.direction = Direction.OUTPUT

    # 2nd solenoid array, corresponds with 2nd muxnoids1 = []

    for pin in range(16): noids1.append(mcp2.get_pin(pin))for n in noids1: n.direction = Direction.OUTPUT

    # MIDI note arrays. notes0 = noids0; notes1 = noids1notes0 = [55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70]notes1 = [71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86]

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 21 of 53

  • # setup MIDI BLE servicemidi_service = adafruit_ble_midi.MIDIService()advertisement = ProvideServicesAdvertisement(midi_service)

    # BLE connection setupble = adafruit_ble.BLERadio()if ble.connected: for c in ble.connections: c.disconnect()

    # MIDI in setupmidi = adafruit_midi.MIDI(midi_in=midi_service, in_channel=0)

    # start BLE advertisingprint("advertising")ble.start_advertising(advertisement)

    # delay for solenoidsspeed = 0.01

    while True:

    # waiting for BLE connection print("Waiting for connection") while not ble.connected: pass print("Connected") # delay after connection established time.sleep(1.0)

    while ble.connected:

    # msg holds MIDI messages msg = midi.receive()

    for i in range(16): # states for solenoid on/off # noid0 = mux1 # noid1 = mux2 noid0_output = noids0[i] noid1_output = noids1[i]

    # states for MIDI note recieved # notes0 = mux1 # notes1 = mux2 notes0_played = notes0[i] notes1_played = notes1[i]

    # if NoteOn msg comes in and the MIDI note # matches with predefined notes: if isinstance(msg, NoteOn) and msg.note is notes0_played: print(time.monotonic(), msg.note)

    # solenoid is triggered noid0_output.value = True # quick delay time.sleep(speed) # solenoid retracts noid0_output.value = False

    # identical to above if statement but for mux2 if isinstance(msg, NoteOn) and msg.note is notes1_played: print(time.monotonic(), msg.note)

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 22 of 53

  • noid1_output.value = True

    time.sleep(speed)

    noid1_output.value = False

    # if BLE disconnects try reconnecting print("Disconnected") print() ble.start_advertising(advertisement)

    Your ItsyBitsy CIRCUITPY drive should look like this after you load the libraries and code.py file:

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 23 of 53

  • CircuitPython Code WalkthroughLibrariesFirst, the CircuitPython libraries are imported.

    import timeimport boardimport busiofrom adafruit_mcp230xx.mcp23017 import MCP23017from digitalio import Directionimport adafruit_blefrom adafruit_ble.advertising.standard import ProvideServicesAdvertisementimport adafruit_ble_midi

    # These import auto-register the message type with the MIDI machinery.# pylint: disable=unused-importimport adafruit_midifrom adafruit_midi.control_change import ControlChangefrom adafruit_midi.midi_message import MIDIUnknownEventfrom adafruit_midi.note_off import NoteOfffrom adafruit_midi.note_on import NoteOnfrom adafruit_midi.pitch_bend import PitchBend

    I2C SetupNext, I2C and the two MCP23017's are setup.

    # i2c setupi2c = busio.I2C(board.SCL, board.SDA)

    # i2c addresses for muxesmcp1 = MCP23017(i2c, address=0x20)mcp2 = MCP23017(i2c, address=0x21)

    SolenoidsThis is followed by the arrays ( noids0 and noids1 ) that will hold the solenoids that are connected to thetwo multiplexers. This allows them to be accessed as digital outputs.

    # 1st solenoid array, corresponds with 1st muxnoids0 = []

    for pin in range(16): noids0.append(mcp1.get_pin(pin))for n in noids0: n.direction = Direction.OUTPUT

    # 2nd solenoid array, corresponds with 2nd muxnoids1 = []

    for pin in range(16): noids1.append(mcp2.get_pin(pin))for n in noids1: n.direction = Direction.OUTPUT

    MIDI Note NumbersFollowing the solenoid arrays are two arrays for the MIDI note numbers. notes0 will correspond with

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 24 of 53

  • noids0 and notes1 will correspond with noids1 . Later in the loop, these arrays will be used to matchagainst incoming NoteOn MIDI messages.

    # MIDI note arrays. notes0 = noids0; notes1 = noids1notes0 = [55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70]notes1 = [71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86]

    BLE SetupThe BLE MIDI service is setup, followed by the BLE connection.

    # setup MIDI BLE servicemidi_service = adafruit_ble_midi.MIDIService()advertisement = ProvideServicesAdvertisement(midi_service)

    # BLE connection setupble = adafruit_ble.BLERadio()if ble.connected: for c in ble.connections: c.disconnect()

    https://adafru.it/Lke

    MIDI Setupmidi is setup to be a MIDI-in device on MIDI channel 1. Channel 1 is defined as 0 in the CircuitPython MIDIlibrary. A MIDI-in device is able to receive MIDI output from a digital audio workstation (DAW) or other

    MIDI communication method.

    # MIDI in setupmidi = adafruit_midi.MIDI(midi_in=midi_service, in_channel=0)

    Begin AdvertisingWith everything setup, BLE can begin advertising for a connection.

    # start BLE advertisingprint("advertising")ble.start_advertising(advertisement)

    Solenoid DelayThe last step before the loop is setting up speed to hold the delay between solenoids triggering andretracting. You can adjust this depending on your preferences.

    # delay for solenoidsspeed = 0.01

    The LoopThe loop begins with the initial BLE connection. Once a connection is established, " Connected " will print tothe REPL. This is followed by a delay that helps to stabilize the BLE MIDI communications before

    everything begins.

    https://adafru.it/Lke

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 25 of 53

    https://github.com/adafruit/Adafruit_CircuitPython_BLE_MIDI

  • while True:

    # waiting for BLE connection print("Waiting for connection") while not ble.connected: pass print("Connected") # delay after connection established time.sleep(1.0)

    MIDI MessagesOnce BLE is connected, msg is setup to hold the incoming MIDI messages.

    while ble.connected:

    # msg holds MIDI messages msg = midi.receive()

    Arrays of ArraysThe for statement allows for the ItsyBitsy to identify if an individual MIDI note number has been receivedand control individual solenoids attached to the multiplexers. notes0_played and notes1_played will handlethe MIDI note numbers. noid0_output and noid1_output will handle the multiplexer outputs.

    for i in range(16): # states for solenoid on/off # noid0 = mux1 # noid1 = mux2 noid0_output = noids0[i] noid1_output = noids1[i]

    # states for MIDI note recieved # notes0 = mux1 # notes1 = mux2 notes0_played = notes0[i] notes1_played = notes1[i]

    Let the Solenoids Play!The following if statements, nested in the previous for statement, are where the action is. The code islooking for a NoteOn message that contains one of the MIDI notes in either notes0_played ornotes1_played . If there's a match, then the solenoid in the corresponding array index will trigger andretract with the predefined speed acting as the delay.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 26 of 53

  • # if NoteOn msg comes in and the MIDI note # matches with predefined notes: if isinstance(msg, NoteOn) and msg.note is notes0_played: print(time.monotonic(), msg.note)

    # solenoid is triggered noid0_output.value = True # quick delay time.sleep(speed) # solenoid retracts noid0_output.value = False

    # identical to above if statement but for mux2 if isinstance(msg, NoteOn) and msg.note is notes1_played: print(time.monotonic(), msg.note)

    noid1_output.value = True

    time.sleep(speed)

    noid1_output.value = False

    Why is it only looking for a NoteOn message? The way that mallet instruments work is that they have tobe struck quickly in order for the note to resonate properly. If the code were waiting for a NoteOffmessage, then for longer note values the solenoid may not retract quickly enough to sound the note.

    That's why everything is relying on that initial NoteOn message.

    Reconnect BLEThe code ends by checking if BLE disconnects. If it does, then BLE will begin advertising again to

    reconnect and print to the REPL that it has disconnected.

    # if BLE disconnects try reconnecting print("Disconnected") print() ble.start_advertising(advertisement)

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 27 of 53

  • Solenoid Mount Assembly

    The solenoids sit snugly in mounts that slide onto the 20x20 aluminum extrusion pieces. They are

    assembled using M3 screws and nuts. The sharps and flat notes, at the top of the xylophone, will have a

    single mount for each note. The natural notes, at the bottom of the xylophone, will use two rail mounts

    and three solenoid mounts together for proper spacing.

    Mount Assembly for Sharps/Flats

    You'll need:

    One rail mount

    One solenoid mount

    Two M3 nuts

    Two M3x10 screws

    Turn the rail mount on its side and place the two M3 nuts into

    their slots.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 28 of 53

    https://learn.adafruit.com//assets/91505https://learn.adafruit.com//assets/91506

  • Attach the solenoid mount to the rail mount by screwing the

    two M3 screws into the slotted nuts.

    The fully assembled single mount. Assemble 12 total.

    Triple Mount for Natural Notes

    You'll need:

    Two rail mounts

    Three solenoid mounts

    Four M3 nuts

    Four M3x10 screws

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 29 of 53

    https://learn.adafruit.com//assets/91507https://learn.adafruit.com//assets/91508https://learn.adafruit.com//assets/91509

  • Take the first rail mount and place one M3 nut in the mount's

    slot on the right.

    Attach one solenoid mount to the first rail mount using one

    M3 screw.

    With the second rail mount, place one M3 nut in the mount's

    left-hand slot.

    Attach one solenoid mount to the second rail mount using

    one M3 screw. This will leave an empty space for the third

    solenoid mount to be attached.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 30 of 53

    https://learn.adafruit.com//assets/91510https://learn.adafruit.com//assets/91511https://learn.adafruit.com//assets/91512https://learn.adafruit.com//assets/91513

  • Insert M3 nuts into the two remaining slots on both rail

    mounts.

    Attach the third solenoid mount with M3 screws so that it's

    sitting on top of the original solenoid mounts. Assemble 6

    total.

    Insert the Solenoids

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 31 of 53

    https://learn.adafruit.com//assets/91514https://learn.adafruit.com//assets/91516

  • Insert the solenoids into the solenoid mounts so that their

    wires are running up the cable channel on the mount.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 32 of 53

    https://learn.adafruit.com//assets/91517https://learn.adafruit.com//assets/91518

  • Perma-Proto Board Mount AssemblyThe circuit for the xylophone lives primarily on three proto boards. These boards are mounted vertically

    on the 20x20 aluminum extrusions with braces and coupling plates. You can use either aluminum

    versions of these pieces or 3D print them.

    You'll need:

    Four double corner braces

    Two 3 hole coupling plates

    Five M4 screws

    Five M3x10 screws

    One M3x16 screw

    One M4 nut

    Four slim T-Nuts

    Six M3 standoffs

    Six M3 washers (optional)

    The washers are helpful if you're using the aluminum versions of the parts, since the holes can be slightly

    over-sized for the M3 hardware.

    Mount Prep

    Take the four double corner braces, four M4 screws and four

    slim T-Nuts.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 33 of 53

    https://learn.adafruit.com//assets/91527

  • Attach a t-nut to one of the far holes on each double corner

    brace with an M4 screw.

    These will eventually mount to the 20x20 extrusions.

    Mount 1 Assembly

    Attach an M3 standoff in the center hole of the coupling plate

    using an M3 screw.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 34 of 53

    https://learn.adafruit.com//assets/91523https://learn.adafruit.com//assets/91528https://learn.adafruit.com//assets/91521

  • Bring in one of the assembled double corner braces, one M3

    standoff and the M3x16 screw.

    Using the opposite far hole on the double corner brace,

    attach the 3 hole coupling plate with the M3x16 through the

    coupling plate's left hole. Attach the standoff to the screw.

    The completed assembly.

    Mount 2 Assembly

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 35 of 53

    https://learn.adafruit.com//assets/91529https://learn.adafruit.com//assets/91530https://learn.adafruit.com//assets/91531

  • Attach M3 standoffs to the 3 hole coupling plate's left and

    right holes with M3 screws.

    Using one of the assembled double corner braces, insert an

    M4 screw into the open far hole.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 36 of 53

    https://learn.adafruit.com//assets/91533https://learn.adafruit.com//assets/91536

  • Attach the coupling plate to the corner brace using the M4

    screw and the coupling plate's center hole. Secure it with an

    M4 nut.

    Mount 3 and 4 Assembly

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 37 of 53

    https://learn.adafruit.com//assets/91537https://learn.adafruit.com//assets/91538

  • With the two remaining assembled corner braces, attach an

    M3 standoff with an M3 screw in the open far hole.

    When you're finished, the four mounts should look like the four pictured below.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 38 of 53

    https://learn.adafruit.com//assets/91539https://learn.adafruit.com//assets/91540

  • Mounting to the Aluminum Extrusions

    Adding the Solenoid MountsThe 20x20 aluminum extrusions will sit towards the back of

    each set of notes so that the solenoids will strike towards the

    middle of the keys for the best possible tone. Slide the

    assembled solenoid mounts onto the rails.

    Extrusion FeetThe two 3D printed feet allow for the extrusions to sit at the correct angle across the keys and at the right

    height as well.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 39 of 53

    https://learn.adafruit.com//assets/91542https://learn.adafruit.com//assets/91543

  • To assemble, take two slim T-Nuts and two M4 screws. Screw

    them loosely together through the top holes on both legs.

    After the solenoid mounts are on the aluminum extrusions, you can slide the legs on either side of the

    extrusions and tighten the M4 screws so that they're secured using the T-Nuts.

    Attach the Proto Board Mounts

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 40 of 53

    https://learn.adafruit.com//assets/91544https://learn.adafruit.com//assets/91545https://learn.adafruit.com//assets/91546

  • In the center of the 2nd, 3rd, 4th and 5th triple solenoid

    mounts, place the slim T-Nuts from proto board mounts. Turn

    them so that they're locked in.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 41 of 53

    https://learn.adafruit.com//assets/91547https://learn.adafruit.com//assets/91548https://learn.adafruit.com//assets/91549

  • Attach each mount with the M4 screw to the T-Nut.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 42 of 53

    https://learn.adafruit.com//assets/91550https://learn.adafruit.com//assets/91551

  • WiringThe electronics for the xylophone are setup identically to the Fritzing circuit diagram on the

    Electronics (https://adafru.it/Lkf) page. The ItsyBitsy will live on a 1/4 Perma-Proto and then three 1/2

    Perma-Proto boards will be used for the MCP23017's and the four ULN2308's.

    One board will have the two MCP32017's and then the two remaining boards will have two ULN2308's

    each. To begin wiring, solder the IC sockets onto the boards. Then, run the wires for power, ground and

    I2C.

    Mount the boards to the xylophone. The screw ends of the M3 stand-offs are facing out so that they can

    slot into the boards' mounting holes and then be secured with some M3 nuts. By doing this, you'll know

    exactly how long the wires have to be between the multiplexers and drivers, followed by the driver boards

    and the solenoids.

    All of the outputs from the multiplexers will connect to the inputs of the drivers, which should be oriented

    to face towards the bottom of the xylophone. This way, the outputs of the drivers will be at the top and

    easier to access for the solenoids.

    The solenoids will connect using a JST extension cable. Cut

    them to length based on the location of the solenoid and the

    driver output.

    Don't get rid of the other connection end though! They'll

    come in handy for future projects. You can never have too

    many JST connectors.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 43 of 53

    https://learn.adafruit.com/admin/guides/3006/editor/19475https://learn.adafruit.com//assets/91554

  • Strip back a few millimeters of wire on the JST extension and

    then tin them for soldering. Solder one wire to the driver's

    output and the second wire to the power rail, which will carry

    5V. Solenoids do not have polarity, so it doesn't matter in this

    case which wire is connected to either soldering point.

    Continue this for all of the solenoids.

    The process of wiring up the multiplexers to the drivers can

    be a little tedious. To avoid any major mistakes you can wire

    up one driver to each multiplexer to make sure that I2C is

    working and that both driver boards are outputting to the

    solenoids as expected.

    It also helps to have a cat inspect the circuit's progress.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 44 of 53

    https://learn.adafruit.com//assets/91555https://learn.adafruit.com//assets/91556https://learn.adafruit.com//assets/91557

  • Wiring the ItsyBitsy

    The ItsyBitsy is attached to the 1/4 Perma-Proto with socket

    headers. Power, ground and I2C signals are run via long

    wires to the other Perma-Protos through the case's wiring

    slots at the bottom.

    A toggle switch is in-line with the USB power signal from the

    ItsyBitsy that supplies the ULN2308's. This allows you to have

    control over the solenoids receiving power in case of a

    problem.

    This particular toggle switch also has an LED at the top that

    lights up when power is engaged.

    The toggle switch's GND is connected to the ItsyBitsy's

    GND

    The toggle switch's + pin is connected to the ItsyBitsy's

    USB pin

    The toggle switch's headlamp pin is connected to the

    ItsyBitsy's USB pin

    https://adafru.it/LkA

    https://adafru.it/LkA

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 45 of 53

    https://learn.adafruit.com//assets/91559https://learn.adafruit.com//assets/91560https://www.adafruit.com/product/3306

  • With everything wired up, it's time for the final assembly.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 46 of 53

  • Final Assembly

    Perma-Proto Back PlateBefore mounting the Perma-Proto boards, snap on their 3D

    printed back plates. These will help to protect the solder

    points from damage and shorts.

    Mount the Perma-Proto boards and plug in the solenoid

    motors to their respective cables.

    Mounting the ItsyBitsy's Case

    Attach two M3 stand-offs with two M3 screws into two of the

    holes in the bottom of the case as pictured. Then, with one

    M4 screw and a T-Nut, mount the case to the aluminum

    extrusion.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 47 of 53

    https://learn.adafruit.com//assets/91562https://learn.adafruit.com//assets/91563https://learn.adafruit.com//assets/91564

  • A 3D printed single corner brace is secured to the side of the

    aluminum extrusion using an M4 screw and a T-Nut. The

    remaining hole from the case is secured to the corner brace

    with an M4 screw and M4 nut.

    The ItsyBitsy's 1/4 Perma-Proto can then be mounted to the

    M3 stand-offs with M3 nuts.

    The ItsyBitsy is ready to be powered-up to run the BLE MIDI

    xylophone! For best results, use an external 5V USB power

    supply rated for at least 2A.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 48 of 53

    https://learn.adafruit.com//assets/91566https://learn.adafruit.com//assets/91567https://learn.adafruit.com//assets/91568

  • © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 49 of 53

  • MIDI Setup and UsageThe process for using this xylophone with your DAW or MIDI controller will depending on your computer's

    operating system. BLE MIDI is supported natively in macOS. Apple has great instructions on how to easily

    connect your BLE MIDI peripherals here (https://adafru.it/Ksa).

    Windows BLE MIDI SetupOn Windows, there is a little more setup involved. In order to have your DAW or USB MIDI controller

    connect, you'll need a software bridge to connect the ItsyBitsy to your desired MIDI input. There are a few

    available, but MIDIberry (https://adafru.it/LkB) is a freeware option that is available through the Microsoft

    store. It allows you to select the input, output and monitor the MIDI messages being sent.

    If you just want to play your xylophone live, then you can use MIDIberry on its own to control it. However,

    if you want to send MIDI out from a DAW for the xylophone to play for recording or live purposes, you'll

    want to setup a virtual MIDI loopback.

    Most DAW's look for a MIDI hardware connection to assign MIDI input and outputs. By using a virtual MIDI

    loopback, you can trick the DAW into thinking you have different MIDI hardware devices plugged into

    your computer or even give your MIDI hardware extra functionality.

    One of the most common solutions for this is the loopMIDI (https://adafru.it/LkC) project by Tobias

    Erichsen. It allows you to easily add virtual MIDI loopbacks on the fly.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 50 of 53

    https://support.apple.com/guide/audio-midi-setup/set-up-bluetooth-midi-devices-ams33f013765/machttps://www.microsoft.com/en-us/p/midiberry/9n39720h2m05?activetab=pivot:overviewtabhttp://www.tobias-erichsen.de/software/loopmidi.html

  • In MIDIberry, you can define the virtual loopback as an input

    with the ItsyBitsy as an output. This means that there is a

    virtual cable connecting the two together, allowing the

    ItsyBitsy to receive MIDI data from a DAW over BLE.

    After setting up your virtual loopback, you can define it as a

    MIDI out in your preferred DAW.

    You can setup a MIDI track to send MIDI data out to the

    virtual loopback and your xylophone should begin playing

    along.

    Playing the xylophone live with a MIDI keyboard is very fun and can allow you to play pieces that

    previously would've been impossible when limited to four mallets; especially on a bell kit/glockenspiel.

    Taking in MIDI data from a DAW is really where things get interesting though, since you can record music

    live that previously would've been through a software synth. It could also make be a great addition to a

    live music setup whether it's for a traditional duet or for electro-acoustic music.

    © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 51 of 53

    https://learn.adafruit.com//assets/91573https://learn.adafruit.com//assets/91572https://learn.adafruit.com//assets/91574

  • © Adafruit Industries https://learn.adafruit.com/wireless-ble-midi-robot-xylophone Page 52 of 53

  • © Adafruit Industries Last Updated: 2021-03-10 01:24:46 PM EST Page 53 of 53

    Guide ContentsOverviewThe Xylophone/GlockenspielParts

    ElectronicsCircuit DiagramHow It WorksWiringData Signal Flow

    3D PrintingParts ListCAD AssemblySolenoid MountsAdditional PartsItsyBitsy CasePerma-Proto Back PlateDouble Corner Brace, Single Corner Brace and 3 Hole Coupling Plate

    CircuitPython for ItsyBitsy nRF52840 ExpressSet up CircuitPython Quick Start!Further Information

    CircuitPython LibrariesInstalling the CircuitPython Library BundleExample Files

    Copying Libraries to Your BoardExample: ImportError Due to Missing LibraryLibrary Install on Non-Express BoardsUpdating CircuitPython Libraries/Examples

    Coding the BLE MIDI Robot XylophoneCircuitPython Code WalkthroughLibrariesI2C SetupSolenoidsMIDI Note NumbersBLE SetupMIDI SetupBegin AdvertisingSolenoid DelayThe LoopMIDI MessagesArrays of ArraysLet the Solenoids Play!Reconnect BLE

    Solenoid Mount AssemblyMount Assembly for Sharps/FlatsTriple Mount for Natural NotesInsert the Solenoids

    Perma-Proto Board Mount AssemblyMount PrepMount 1 AssemblyMount 2 AssemblyMount 3 and 4 Assembly

    Mounting to the Aluminum ExtrusionsAdding the Solenoid MountsExtrusion FeetAttach the Proto Board Mounts

    WiringWiring the ItsyBitsy

    Final AssemblyPerma-Proto Back PlateMounting the ItsyBitsy's Case

    MIDI Setup and UsageWindows BLE MIDI Setup