# PyPortal Guitar Tuner

## Overview

https://youtu.be/3Dv8U8P0iCo

## CircuitPython Power!

Build a simple Guitar Tuner with CircuitPython and Adafruit PyPortal! Use the touch screen to tap on tuning pegs and play music notes. The notes are pre-recorded wav audio files of guitar strings. The graphic of the head stock is a single bitmap. This uses the _displayio_ library for CircuitPython and can be customized to make a unique sound board.

![3d_printing_hero-blue.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/821/medium640/3d_printing_hero-blue.jpg?1591653229)

## 3D Printed PyPortal Case

The Adafruit PyPortal and a mini oval speaker are secured to a 3D printed enclosure using M2.5 screws and standoffs. The PyPortal is mounted vertically and features a built-in holder for a speaker.

![3d_printing_final-back.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/823/medium640/3d_printing_final-back.jpg?1591653511)

## Parts
### Adafruit PyPortal - CircuitPython Powered Internet Display

[Adafruit PyPortal - CircuitPython Powered Internet Display](https://www.adafruit.com/product/4116)
 **PyPortal** , our easy-to-use IoT device that allows you to create all the things for the “Internet of Things” in minutes. Make custom touch screen interface GUIs, all open-source, and Python-powered using&nbsp;tinyJSON / APIs to get news, stock, weather, cat photos,...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4116)
[Related Guides to the Product](https://learn.adafruit.com/products/4116/guides)
![Front view of a Adafruit PyPortal - CircuitPython Powered Internet Display with a pyportal logo image on the display. ](https://cdn-shop.adafruit.com/640x480/4116-00.jpeg)

### Mini Oval Speaker - 8 Ohm 1 Watt

[Mini Oval Speaker - 8 Ohm 1 Watt](https://www.adafruit.com/product/3923)
Hear the good news! This wee speaker&nbsp;is&nbsp;a&nbsp;great addition to any audio project where you need 8 ohm impedance and 1W or less of power. We particularly like this&nbsp;speaker&nbsp;as it is&nbsp;small and comes with nice skinny wires with a connector on the end. It has a handy...

In Stock
[Buy Now](https://www.adafruit.com/product/3923)
[Related Guides to the Product](https://learn.adafruit.com/products/3923/guides)
![Small, black, oval speaker with Pico Blade connector.](https://cdn-shop.adafruit.com/640x480/3923-06.jpg)

### Fully Reversible Pink/Purple USB A to micro B Cable - 1m long

[Fully Reversible Pink/Purple USB A to micro B Cable - 1m long](https://www.adafruit.com/product/4111)
This cable is not only super-fashionable, with a woven pink and purple Blinka-like pattern, it's also fully reversible! That's right, you will save _seconds_ a day by not having to flip the cable around.

First let's talk about the cover and over-molding. We got these...

In Stock
[Buy Now](https://www.adafruit.com/product/4111)
[Related Guides to the Product](https://learn.adafruit.com/products/4111/guides)
![Fully Reversible Pink/Purple USB A to micro B Cable](https://cdn-shop.adafruit.com/640x480/4111-02.jpg)

### Black Nylon Machine Screw and Stand-off Set – M2.5 Thread

[Black Nylon Machine Screw and Stand-off Set – M2.5 Thread](https://www.adafruit.com/product/3299)
Totaling 380 pieces, this **M2.5 Screw Set** &nbsp;is a must-have for your workstation.&nbsp;You'll have enough screws, nuts, and hex standoffs to fuel your maker tendencies&nbsp;for days on end! M2.5 size screws fit almost all of the Adafruit breakout/dev board mounting holes...

In Stock
[Buy Now](https://www.adafruit.com/product/3299)
[Related Guides to the Product](https://learn.adafruit.com/products/3299/guides)
![Black Nylon Screw and Stand-off Set with M2.5 Threads, kit box](https://cdn-shop.adafruit.com/640x480/3299-00.jpg)

![](https://cdn-learn.adafruit.com/assets/assets/000/091/822/medium800/3d_printing_guide-hero.jpg?1591653318)

# PyPortal Guitar Tuner

## 3D Printing

## Parts List

STL 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.

- frame.stl
- screen-cover.stl
- pcb-plate.stl

![3d_printing_3d-parts-cropped.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/798/medium640/3d_printing_3d-parts-cropped.jpg?1591545344)

[Download CAD files from Fusion 360](https://a360.co/2XHthEY)
[Download CAD files from Thingiverse](https://www.thingiverse.com/thing:4438992)
## CAD Assembly

The PyPortal is secured to the PCB plate using M2.5 hardware screws and standoffs. The screen cover is press fitted over the PyPortal's display. The PCB plate is secured to the frame using M2.5 hardware screws and hex nuts. The speaker is press fitted into the holder in the center of the PCB plate.

![3d_printing_cad-explode.gif](https://cdn-learn.adafruit.com/assets/assets/000/091/813/medium640thumb/3d_printing_cad-explode.jpg?1591562885)

## Slicing Parts

No supports are required. Slice with settings for PLA material.&nbsp;

The parts were sliced using CURA using the slice settings below.

- PLA filament 220c extruder
- 0.2 layer height
- 10% gyroid infill
- 60mm/s print speed
- 60c heated bed

![3d_printing_slice-pcbplate.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/815/medium640/3d_printing_slice-pcbplate.jpg?1591563351)

## Design Source Files

The project assembly was designed in Fusion 360. This can be downloaded in different formats like STEP, STL and more. Electronic components like Adafruit's board, displays, connectors and more can be downloaded from the [Adafruit CAD parts GitHub Repo](https://github.com/adafruit/Adafruit_CAD_Parts).

![3d_printing_pyportal.gif](https://cdn-learn.adafruit.com/assets/assets/000/091/816/medium640thumb/3d_printing_pyportal.jpg?1591566145)

https://youtu.be/lxHRu3iCVZM

# PyPortal Guitar Tuner

## Install CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) 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** &nbsp;"flash" drive to iterate.

The following instructions will show you how to install CircuitPython. If you've already installed CircuitPython but are looking to update it or reinstall it, the same steps work for that as well!

## Set up CircuitPython Quick Start!

Follow this quick step-by-step for super-fast Python power :)

[Download the latest version of CircuitPython for the PyPortal via CircuitPython.org](https://circuitpython.org/board/pyportal/)
[Download the latest version of CircuitPython for the PyPortal Pynt via CircuitPython.org](https://circuitpython.org/board/pyportal_pynt/)
 **Click the link above to download the latest version of CircuitPython for the PyPortal.**

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

![circuitpython_pyportal-uf2.png](https://cdn-learn.adafruit.com/assets/assets/000/073/615/medium640/circuitpython_pyportal-uf2.png?1553610968)

Plug your PyPortal 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.**

Double-click the **Reset** button on the top in the middle (magenta arrow) on your board, and you will see the NeoPixel RGB LED (green arrow) turn green. If it turns red, check the USB cable, try another USB port, etc.&nbsp; **Note:** The little red LED next to the USB connector will pulse red. That's ok!

If double-clicking doesn't work the first time, try again. Sometimes it can take a few tries to get the rhythm right!

![circuitpython_PyPortalResetNeoPIxel.jpg](https://cdn-learn.adafruit.com/assets/assets/000/071/993/medium640/circuitpython_PyPortalResetNeoPIxel.jpg?1551213425)

You will see a new disk drive appear called **PORTALBOOT**.

Drag the **adafruit-circuitpython-pyportal-\<whatever\>.uf2** file to **PORTALBOOT.**

![circuitpython_PyPortal_PORTALBOOT.png](https://cdn-learn.adafruit.com/assets/assets/000/072/029/medium640/circuitpython_PyPortal_PORTALBOOT.png?1551287972)

![circuitpython_PyPortal_Drag_UF2.png](https://cdn-learn.adafruit.com/assets/assets/000/072/030/medium640/circuitpython_PyPortal_Drag_UF2.png?1551287983)

The LED will flash. Then, the **PORTALBOOT** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

If you haven't added any code to your board, the only file that will be present is **boot\_out.txt**. This is absolutely normal! It's time for you to add your **code.py** and get started!

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

![circuitpython_PyPortalCIRCUITPY.png](https://cdn-learn.adafruit.com/assets/assets/000/071/995/medium640/circuitpython_PyPortalCIRCUITPY.png?1551213875)

## PyPortal Default Files

Click below to download a zip of the files that shipped on the PyPortal or PyPortal Pynt.

[PyPortal Default Files](https://github.com/adafruit/circuitpython-default-files/tree/main/boards/pyportal/4.x)
[PyPortal Pynt Default Files](https://github.com/adafruit/circuitpython-default-files/tree/main/boards/pyportal_pynt/5.x)
# PyPortal Guitar Tuner

## Coding the PyPortal Guitar Tuner

## Installing Project Code

To use with CircuitPython, you need to first install a few libraries, into the lib folder on your **CIRCUITPY** drive. Then you need to update **code.py** with the example script.

Thankfully, we can do this in one go. In the example below, click the **Download Project Bundle** button below to download the necessary libraries and the **code.py** file in a zip file. Extract the contents of the zip file, open the directory **PyPortal\_Guitar\_Tuner/** and then click on the directory that matches the version of CircuitPython you're using and copy the contents of that directory to your **CIRCUITPY** drive.

Your **CIRCUITPY** drive should now look similar to the following image:

![CIRCUITPY](https://adafruit.github.io/Adafruit_Learning_System_Guides/PyPortal_PyPortal_Guitar_Tuner.png )

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/PyPortal/PyPortal_Guitar_Tuner/code.py

# PyPortal Guitar Tuner

## CircuitPython Code Walkthrough

## Setup
### CircuitPython Libraries
The CircuitPython code begins by importing the libraries.

```python
import time
from adafruit_button import Button
from adafruit_pyportal import PyPortal
```

### Display Setup
First, `pyportal` is setup as a PyPortal object. The PyPortal's default background is also setup to be the guitar headstock image, **stock-pyportal.bmp**. This means that on boot, the PyPortal will display the bitmap with just one line of code.

```python
pyportal = PyPortal(default_bg="/stock-pyportal.bmp")
```

### Loading Audio Files
The audio file locations are assigned to variables so that they can be easily referenced in the code. Then, files are put into the `notes` array in order from low to high.

```python
lowE = "/sounds/lowE.wav"
A = "/sounds/A.wav"
D = "/sounds/D.wav"
G = "/sounds/G.wav"
B = "/sounds/B.wav"
highE = "/sounds/highE.wav"

notes = [lowE, A, D, G, B, highE]
```

### Touchscreen Buttons
The PyPortal will have six buttons that sit on top of the guitar headstock image. Instead of setting each button up individually, their parameters are setup as a group in an array, called `pegs`, of dictionary entries. This way you can easily denote the buttons' label, position and size.

```python
pegs = [
    {'label': "lowE", 'pos': (53, 0), 'size': (65, 90)},
    {'label': "A", 'pos': (124, 0), 'size': (65, 90)},
    {'label': "D", 'pos': (194, 0), 'size': (65, 90)},
    {'label': "G", 'pos': (194, 150), 'size': (65, 90)},
    {'label': "B", 'pos': (124, 150), 'size': (65, 90)},
    {'label': "highE", 'pos': (53, 150), 'size': (65, 90)}
    ]
```

Finally, this information for the buttons are assigned as `Button` objects using the adafruit\_button CircuitPython library. Using the `pegs` array, all of the information from the dictionaries can be pulled in to complete the setup for the buttons. These buttons are then added to the PyPortal's display.

```python
buttons = []
for peg in pegs:
    button = Button(x=peg['pos'][0], y=peg['pos'][1],
                    width=peg['size'][0], height=peg['size'][1],
                    style=Button.RECT,
                    fill_color=None, outline_color=0x5C3C15,
                    name=peg['label'])
    pyportal.root_group.append(button.group)
    buttons.append(button)
```

### Button State
The `note_select` state will be used to debounce the touchscreen buttons.

```python
note_select = None
```

## The Loop
The loop begins with `touch` setup to hold the PyPortal's touchscreen functionality.

Next, touchscreen button debouncing is setup. You only need to setup one instance rather than one for each individual button because you are essentially checking to see if the touchscreen is being touched in any location.

```python
while True:
    touch = pyportal.touchscreen.touch_point
    
    if not touch and note_select:
        note_select = False
```

### Play Notes
The final portion of the loop is how notes are played through the PyPortal. First, it checks to see if the touchscreen has been touched.

This is followed by a `for` statement. In this `for` statement, `tuning` and `button` are setup to hold the array index locations for the `notes` and `buttons` arrays. Since there are six indexes in each of these arrays, this allows for the sound files to match up with the touchscreen buttons and play when pressed.

Finally, an `if` statement checks if the touchscreen was touched in the proximity of the coordinates of one of the button locations. If it was, then the name of the button is printed to the REPL. This is followed by a final `for` statement. This `for` statement allows for the corresponding note's audio file to play three times.

This is followed by a delay. The length of the delay will determine the amount of time between each time the audio files are played. You may want to adjust it depending on your guitar tuning preferences.

```python
if touch:
        for i in range(6):
            tuning = notes[i]
            button = buttons[i]
          	if button.contains(touch) and not note_select:
                print("Touched", button.name)
                note_select = True
                for z in range(3):
                    pyportal.play_file(tuning)
    time.sleep(0.1)
```

# PyPortal Guitar Tuner

## Assembly

## Hardware Setup

Use 4x M2.5 x 6mm long FF standoffs and 4x M2.5 x 6mm long screws to secure the PCB plate to the PyPortal.&nbsp;

![3d_printing_pcb-plate-screws.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/799/medium640/3d_printing_pcb-plate-screws.jpg?1591550811)

## Install Standoffs

Insert M2.5 x 6mm screws through the top of the mounting tabs on PyPortal. Fasten M2.5 x 6mm long standoffs onto the threads of the screws.

![3d_printing_standoffs-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/800/medium640/3d_printing_standoffs-install.jpg?1591550833)

## Screen Cover

Orient the screen cover with the display on the PyPortal. Use the photo to reference the correct orientation.

![3d_printing_screen-cover.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/801/medium640/3d_printing_screen-cover.jpg?1591550868)

## Install Screen Cover

Fit the PyPortal display into the recess on the screen cover. Press the screen to fully seat into the screen cover.

![3d_printing_screen-cover-tabs.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/802/medium640/3d_printing_screen-cover-tabs.jpg?1591550891)

## Installed Screen Cover

The screen cover helps to keep the display attached to the PyPortal. The viewing area is exposed and does not obstruct display. This also hides the screens bezel.

![3d_printing_screen-cover-installed.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/803/medium640/3d_printing_screen-cover-installed.jpg?1591550922)

## Installing Plate and Speaker

The PyPortal is secured to the PCB plate using 4x M2.5 x 6mm screws. The mini oval speaker is press fitted onto the speaker holder on the PCB plate.

![3d_printing_pcb-plate-speaker.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/804/medium640/3d_printing_pcb-plate-speaker.jpg?1591550945)

## Connect Speaker

Plug in the molex pico connector from the speaker to the speaker port on the back of the PyPortal.

![3d_printing_speaker-plugin.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/806/medium640/3d_printing_speaker-plugin.jpg?1591550984)

## Install Speaker

Press fit the body of the speaker into the speaker holder in the center of the PCB plate. Reference the photo for best orientation.&nbsp;

![3d_printing_pcb-plate-speaker-install.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/805/medium640/3d_printing_pcb-plate-speaker-install.jpg?1591550968)

## Secure PyPortal

Place the PCB plate to the back of the PyPortal with the mounting holes lined up with the standoffs.

![3d_printing_pcb-plate-secure-pyportal.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/807/medium640/3d_printing_pcb-plate-secure-pyportal.jpg?1591551015)

## Install Frame

Orient the frame with the mount tabs on the PCB plate. Line up the mounting holes in the frame with the mounting tabs on the PCB.

![3d_printing_pcb-plate-frame-lineup.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/808/medium640/3d_printing_pcb-plate-frame-lineup.jpg?1591551036)

## Secure Frame

Insert 4x M2.5 x 6mm screws into the side of the frame and through the mounting tabs on the PCB plate. Insert and fasten 4x M2.5 hex nuts onto threads of the screws and tighten.

![3d_printing_pcb-plate-frame-secure.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/809/medium640/3d_printing_pcb-plate-frame-secure.jpg?1591551055)

## Final Build

And now we're ready for some guitar tuning!

![3d_printing_final-front.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/810/medium640/3d_printing_final-front.jpg?1591551070)

## Going Further

The frame has adequate amount of space for a USB battery or other components.

![3d_printing_final-back.jpg](https://cdn-learn.adafruit.com/assets/assets/000/091/811/medium640/3d_printing_final-back.jpg?1591551087)


## Featured Products

### Adafruit PyPortal - CircuitPython Powered Internet Display

[Adafruit PyPortal - CircuitPython Powered Internet Display](https://www.adafruit.com/product/4116)
 **PyPortal** , our easy-to-use IoT device that allows you to create all the things for the “Internet of Things” in minutes. Make custom touch screen interface GUIs, all open-source, and Python-powered using&nbsp;tinyJSON / APIs to get news, stock, weather, cat photos,...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4116)
[Related Guides to the Product](https://learn.adafruit.com/products/4116/guides)
### Mini Oval Speaker - 8 Ohm 1 Watt

[Mini Oval Speaker - 8 Ohm 1 Watt](https://www.adafruit.com/product/3923)
Hear the good news! This wee speaker&nbsp;is&nbsp;a&nbsp;great addition to any audio project where you need 8 ohm impedance and 1W or less of power. We particularly like this&nbsp;speaker&nbsp;as it is&nbsp;small and comes with nice skinny wires with a connector on the end. It has a handy...

In Stock
[Buy Now](https://www.adafruit.com/product/3923)
[Related Guides to the Product](https://learn.adafruit.com/products/3923/guides)
### Fully Reversible Pink/Purple USB A to micro B Cable - 1m long

[Fully Reversible Pink/Purple USB A to micro B Cable - 1m long](https://www.adafruit.com/product/4111)
This cable is not only super-fashionable, with a woven pink and purple Blinka-like pattern, it's also fully reversible! That's right, you will save _seconds_ a day by not having to flip the cable around.

First let's talk about the cover and over-molding. We got these...

In Stock
[Buy Now](https://www.adafruit.com/product/4111)
[Related Guides to the Product](https://learn.adafruit.com/products/4111/guides)
### Black Nylon Machine Screw and Stand-off Set – M2.5 Thread

[Black Nylon Machine Screw and Stand-off Set – M2.5 Thread](https://www.adafruit.com/product/3299)
Totaling 380 pieces, this **M2.5 Screw Set** &nbsp;is a must-have for your workstation.&nbsp;You'll have enough screws, nuts, and hex standoffs to fuel your maker tendencies&nbsp;for days on end! M2.5 size screws fit almost all of the Adafruit breakout/dev board mounting holes...

In Stock
[Buy Now](https://www.adafruit.com/product/3299)
[Related Guides to the Product](https://learn.adafruit.com/products/3299/guides)

## Related Guides

- [Adafruit PyPortal - IoT for CircuitPython](https://learn.adafruit.com/adafruit-pyportal.md)
- [MatrixPortal CircuitPython Animated Message Board](https://learn.adafruit.com/matrixportal-circuitpython-animated-message-board.md)
- [PyPortal Oblique Strategies](https://learn.adafruit.com/pyportal-oblique-strategies.md)
- [PyPortal View Master](https://learn.adafruit.com/pyportal-view-master.md)
- [Making a PyPortal User Interface with DisplayIO](https://learn.adafruit.com/making-a-pyportal-user-interface-displayio.md)
- [Espresso Water Tank Meter](https://learn.adafruit.com/espresso-water-tank-meter.md)
- [Program in Logo on an Apple II](https://learn.adafruit.com/program-logo-on-an-apple-ii.md)
- [Saving CircuitPython Bitmaps and Screenshots](https://learn.adafruit.com/saving-bitmap-screenshots-in-circuitpython.md)
- [Pico W YBox3](https://learn.adafruit.com/pico-w-ybox3.md)
- [TFT Spirit Board](https://learn.adafruit.com/tft-spirit-board.md)
- [LED Matrix Scoreboard](https://learn.adafruit.com/led-matrix-scoreboard.md)
- [PyPortal Titano Weather Station](https://learn.adafruit.com/pyportal-titano-weather-station.md)
- [PyPortal IoT Plant Monitor with Google Cloud IoT Core and CircuitPython](https://learn.adafruit.com/pyportal-iot-plant-monitor-with-google-cloud-iot-core-and-circuitpython.md)
- [PyPortal LIFX Lighting Controller ](https://learn.adafruit.com/pyportal-lifx-lighting-controller.md)
- [Monitor Your Greenhouse with a No-Code Environmental Sensor](https://learn.adafruit.com/monitor-your-greenhouse-with-a-no-code-environmental-sensor.md)
- [Raspberry Pi Zero Stand](https://learn.adafruit.com/raspberry-pi-zero-stand.md)
