CircuitPython Libraries

The CircuitPython code begins by importing the libraries.

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.

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.

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.

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.

buttons = []
for peg in pegs:
    button = Button(x=peg['pos'][0], y=peg['pos'][1],
                    width=peg['size'][0], height=peg['size'][1],
                    fill_color=None, outline_color=0x5C3C15,

Button State

The note_select state will be used to debounce the touchscreen buttons.

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.

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.

if touch:
        for i in range(6):
            tuning = notes[i]
            button = buttons[i]
          	if button.contains(touch) and not note_select:
                note_select = True
                for z in range(3):

This guide was first published on Jun 09, 2020. It was last updated on May 21, 2024.

This page (CircuitPython Code Walkthrough) was last updated on Mar 08, 2024.

Text editor powered by tinymce.