# Circuit Playground-O-Phonor

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/082/520/medium800/circuitpython_Holophonor_banner.jpg?1571420380)

Remember the [holophonor](https://futurama.fandom.com/wiki/Holophonor) from [Futurama](https://en.wikipedia.org/wiki/Futurama)? It was (will be?) a musical instrument that would project holograms depending on the mood of the note played.

Being a futuristic instrument, the inner workings of the holophonor are unknown. However, the basic idea of being able to detect the frequency of musical notes is something we can possibly emulate. And that is what we'll explore in this guide using a fairly simple technique.

We'll also use the frequency detection to drive NeoPixels (our version of the holophonor) and also show how a [TFT Gizmo](https://www.adafruit.com/product/4367) can be used to display the note information.

## Which Circuit Playground?

The technique used here to estimate the audio frequency is fairly simple. It relies on constantly sampling the microphone and analyzing the results. Therefore, the more powerful the processor, the better.

Info: 

## Parts

The following parts are used in this project:

### Circuit Playground Bluefruit - Bluetooth® Low Energy

[Circuit Playground Bluefruit - Bluetooth® Low Energy](https://www.adafruit.com/product/4333)
 **Circuit Playground Bluefruit** is our third board in the Circuit Playground series, another step towards a perfect introduction to electronics and programming. We've taken the popular Circuit Playground Express and made it even better! Now the main chip is an nRF52840...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4333)
[Related Guides to the Product](https://learn.adafruit.com/products/4333/guides)
![shot of a Black woman's neon-green manicured hand holding up a Circuit Playground Bluefruit glowing rainbow LEDs.](https://cdn-shop.adafruit.com/640x480/4333-11.jpg)

### Circuit Playground TFT Gizmo - Bolt-on Display + Audio Amplifier

[Circuit Playground TFT Gizmo - Bolt-on Display + Audio Amplifier](https://www.adafruit.com/product/4367)
Extend and expand your Circuit Playground projects with a bolt on TFT Gizmo that lets you add a lovely color display in a sturdy and reliable fashion. This PCB looks just like a round TFT breakout but has permanently affixed M3 standoffs that act as mechanical and electrical...

In Stock
[Buy Now](https://www.adafruit.com/product/4367)
[Related Guides to the Product](https://learn.adafruit.com/products/4367/guides)
![Hand pressing buttons on circuit playground, then turning over to show TFT gizmo display an image of a friendly robot or snake](https://cdn-shop.adafruit.com/product-videos/640x480/4367-05.jpg)

### USB cable - USB A to Micro-B

[USB cable - USB A to Micro-B](https://www.adafruit.com/product/592)
This here is your standard A to micro-B USB cable, for USB 1.1 or 2.0. Perfect for connecting a PC to your Metro, Feather, Raspberry Pi or other dev-board or microcontroller

Approximately 3 feet / 1 meter long

In Stock
[Buy Now](https://www.adafruit.com/product/592)
[Related Guides to the Product](https://learn.adafruit.com/products/592/guides)
![USB cable - USB A to Micro-B - 3 foot long](https://cdn-shop.adafruit.com/640x480/592-01.jpg)

# Circuit Playground-O-Phonor

## How It Works

The technique we use in this guide to determine the frequency is pretty straight forward. It's sometimes called "zero crossing" or "mean crossing" as we use the time between crossings of a zero or mean level to estimate the frequency.

Let's look at this in more detail.

## Pure Tone Basics

A fundamental assumption of this technique is that we are dealing with a sound which is a pure tone. That means it is a nice clean signal that just repeats over and over again at a single frequency. If we recorded such a signal with a microphone and plotted the results, it would look something like this:

![](https://cdn-learn.adafruit.com/assets/assets/000/082/521/medium800/circuitpython_plot1.png?1571420429)

This is an example of a signal with an offset, since the line is not crossing back and forth through the zero line on the graph. In this case, a zero level represents silence and all noises will have a positive value. So we end up with a signal oscillating back and forth around some offset.

There are several key features to this signal as shown below. The offset mentioned above is called the **MEAN**.

![](https://cdn-learn.adafruit.com/assets/assets/000/082/522/medium800/circuitpython_plot2.png?1571420438)

 **MEAN** is just another word for average, and that is how this value can be determined - by averaging the entire sample. The **PERIOD** is the total time it takes to make one cycle of the pattern, which then repeats over and over. We are interested in the frequency, **f** , of this signal, which is simply the inverse of the **PERIOD**.

## Computing Frequency From Mic Data

When we sample the microphone, we don't get the orange line above. Instead we get a bunch of individual data points, like the black circles below.

![](https://cdn-learn.adafruit.com/assets/assets/000/082/523/medium800/circuitpython_plot3.png?1571420448)

These will all fall on the orange line as shown. Just keep in mind that the microphone sample data is a series of discrete data points. We can then work with these data points to estimate the frequency.

![](https://cdn-learn.adafruit.com/assets/assets/000/082/524/medium800/circuitpython_plot4.png?1571420463)

Here's how the "mean crossing" technique works:

1. Find the first point which is greater than the **MEAN** value plus the **THRESHOLD**. Set a "has crossed" flag to True.
2. Find the first point after the "has crossed" flag has been set True that goes below the **MEAN** value. Store this location and clear the "has crossed" flag.
3. We now repeat the process, so this is the next point like 1.
4. And this is the next point like 2. Compute the delta between 2 and 4 and save it.

We do the above across the entire mic sample and then take an average of the deltas. The average delta is in terms of number of samples, **N** , in one cycle. The microphone sample rate sets the time, **DT** , between samples. So we can compute the **PERIOD** as simply **N \* DT**. And the frequency of the mic data is then just the reciprocal of the **PERIOD**.

# Circuit Playground-O-Phonor

## Frequency Basics

OK, let's actually implement the "mean crossing" technique and see if it works. We'll start simple and just print the computed results to the serial monitor. Here's the complete code:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Circuit_Playground_O_Phonor/freq_basic/code.py

The part of the code that does the main work for the mean crossing estimation of frequency is this:

```python
# Compute deltas between mean crossing points
    # (this bit by Dan Halbert)
    deltas = []
    last_xing_point = None
    crossed_threshold = False
    for i in range(SAMPLES-1):
        sample = samples[i]
        if sample &gt; threshold:
            crossed_threshold = True
        if crossed_threshold and sample &lt; mean:
            if last_xing_point:
                deltas.append(i - last_xing_point)
            last_xing_point = i
            crossed_threshold = False
```

Compare that to the explanation in the previous section. You can see how it is looping over the entire mic **SAMPLES** , checking for **crossed\_threshold** and storing all of the **deltas**.

Once that loop is complete, the actual frequency computation is straight forward. The **deltas** are averaged:

```python
# Average the deltas
    mean = sum(deltas) / len(deltas)
```

And the frequency ( **freq** ) is then just:

```python
# Compute frequency
    freq = SAMPLERATE / mean
```

## Tone Test

Here is a nice website that provides a pure tone generator we can use for testing:

[Online Tone Generator](https://www.szynalski.com/tone-generator/)
Run the basic frequency example program above and watch the output on the serial monitor. Then use the website to generate some tones of various frequencies. Like this:

Here **190** is registering at about **~188** :

![](https://cdn-learn.adafruit.com/assets/assets/000/082/628/medium800/circuitpython_freq_ex_190.jpg?1571679554)

Here **446** is registering at about **~442** :

![](https://cdn-learn.adafruit.com/assets/assets/000/082/629/medium800/circuitpython_freq_ex_446.jpg?1571679568)

Here **1500** is registering at about **~1487** :

![](https://cdn-learn.adafruit.com/assets/assets/000/082/630/medium800/circuitpython_freq_ex_1500.jpg?1571679583)

The results are not exact, but pretty close. Not too bad for a technique this simple.

Now let's add some fun NeoPixel response based on the estimated frequency.

# Circuit Playground-O-Phonor

## Frequency and NeoPixels

We'll look at determining musical notes in a bit. But for making the NeoPixels respond to the mic data, we can just work in terms of frequency. The idea is pretty simple - we'll set a **LOW** frequency and a **HIGH** frequency. The NeoPixels will then light up individually for any frequency in this range.

Here's the complete code:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Circuit_Playground_O_Phonor/freq_neopixel/code.py

This code is largely the same as the previous example. All that has been added is some NeoPixel output based on frequency. You can set the **LOW** and **HIGH** frequency and the NeoPixel **COLORS** at the top of the code in these lines:

```python
FREQ_LOW = 520
FREQ_HIGH = 990
COLORS = (
    (0xFF, 0x00, 0x00) , # pixel 0
    (0xFF, 0x71, 0x00) , # pixel 1
    (0xFF, 0xE2, 0x00) , # pixel 2
    (0xAA, 0xFF, 0x00) , # pixel 3
    (0x38, 0xFF, 0x00) , # pixel 4
    (0x00, 0xFF, 0x38) , # pixel 5
    (0x00, 0xFF, 0xA9) , # pixel 6
    (0x00, 0xE2, 0xFF) , # pixel 7
    (0x00, 0x71, 0xFF) , # pixel 8
    (0x00, 0x00, 0xFF) , # pixel 9
)
```

The part of the code that does the actual NeoPixel lighting is at the bottom:

```python
# Show on NeoPixels
    pixels.fill(0)
    pixel = round(simpleio.map_range(freq, FREQ_LOW, FREQ_HIGH, 0, 9))
    pixels[pixel] = COLORS[pixel]
    pixels.show()
```

It uses the **simpleio.map\_range()** function to map the computed frequency to the range of NeoPixels. So the **LOW** frequency will light NeoPixel #0, the **HIGH** frequency will light NeoPixel #9, and any in between frequencies will light the others.

## Circuit Playground-O-Phonor

We can use the above sketch to make our Circuit Playground-O-Phonor. As a substitute for a real holophonor, we'll use a very common flute like instrument called a [recorder](https://en.wikipedia.org/wiki/Recorder_(musical_instrument)). They look like this:

![](https://cdn-learn.adafruit.com/assets/assets/000/082/666/medium800/circuitpython_recorder.jpg?1571691523)

These come in different shapes and sizes with corresponding differences in their note ranges. You'll need to figure out what range of notes, and in what octave, your recorder produces. The code above has been setup to run from a 5th octave C (~520Hz) to a 5th octave B (~990Hz). If your recorder is different, change these two lines as needed:

```python
FREQ_LOW = 520
FREQ_HIGH = 990
```

Once you've got that setup, run the code above and try playing notes on your recorder. You should get the NeoPixels to light up.

![](https://cdn-learn.adafruit.com/assets/assets/000/082/670/medium800thumb/circuitpython_phonor.jpg?1571693603)

# Circuit Playground-O-Phonor

## Musical Note Basics

So what about musical notes? The ones with letters, like ABCDEFG. Every Good Bird Does Fly. And all that.

Determining notes is essentially just a matter of mapping the computed frequency to specific notes. This mapping is well known and you can read more about it here:

[Musical Notes and Frequencies](https://en.wikipedia.org/wiki/Musical_note#Note_frequency_(hertz))
Here's the complete code that includes note detection:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Circuit_Playground_O_Phonor/notes_basic/code.py

This also largely the same as our original code. The main new item is a table that maps **NOTES** at various **OCTAVES** to their corresponding frequency:

```python
#        octave = 1    2    3    4    5     6     7     8
NOTES = { "C" : (33,  65, 131, 262, 523, 1047, 2093, 4186),
          "D" : (37,  73, 147, 294, 587, 1175, 2349, 4699),
          "E" : (41,  82, 165, 330, 659, 1319, 2637, 5274),
          "F" : (44,  87, 175, 349, 698, 1397, 2794, 5588),
          "G" : (49,  98, 196, 392, 785, 1568, 3136, 6272),
          "A" : (55, 110, 220, 440, 880, 1760, 3520, 7040),
          "B" : (62, 123, 247, 494, 988, 1976, 3951, 7902)}
```

And then once we have our frequency estimate, we just figure out where it is located in this table (coded to be plus or minus 3%):

```python
# Find corresponding note
    for note in NOTES:
        for octave, note_freq in enumerate(NOTES[note]):
            if note_freq * 0.97 &lt;= freq &lt;= note_freq * 1.03:
                print("-"*10)
                print("NOTE = {}{}".format(note, octave + 1))
                print("-"*10)
```

## Notes Test

We can use the same website we used for the tones test to also test musical notes.

[Musical Note Generator](https://www.szynalski.com/tone-generator/)
The simple sketch above does not have entries for sharp and flat notes. So we'll test just the primary notes. To bring up a table of pre-defined musical note frequencies, click this button:

![](https://cdn-learn.adafruit.com/assets/assets/000/082/639/medium800/circuitpython_notes_gen1.jpg?1571683776)

And then, with the above code running, try different notes. Here's **C4** :

![](https://cdn-learn.adafruit.com/assets/assets/000/082/660/medium800/circuitpython_note_c4.jpg?1571689741)

Here's **A4** :

![](https://cdn-learn.adafruit.com/assets/assets/000/082/663/medium800/circuitpython_note_a4.jpg?1571689779)

Here's **E6** :

![](https://cdn-learn.adafruit.com/assets/assets/000/082/664/medium800/circuitpython_note_e6.jpg?1571689791)

Pretty good. As you get lower in octave (the number, like 4 and 6 above), you'll probably find it doesn't work quite as well. That's mainly due to the absolute frequency differences between the notes getting smaller in the lower octaves. And since our technique isn't super accurate, it has trouble distinguishing between consecutive note frequencies. It should get pretty close though.

# Circuit Playground-O-Phonor

## Notes and TFT Gizmo

All of the examples so far have outputted to the serial monitor. If you have a [TFT Gizmo](https://www.adafruit.com/product/4367), we can use that instead to display information. That way you don't need to open a terminal to watch the serial output or be attached to a computer.

Let's adapt our basic notes program to output to the TFT Gizmo. Start by first going through this guide to get the TFT Gizmo setup and running:

[Adafruit Circuit Playground TFT Gizmo](https://learn.adafruit.com/adafruit-tft-gizmo)
We'll also use some special fonts for the display. Here's a zip file containing the font files. Both of these font files were created from the [Mono MMM 5](https://www.dafont.com/monommm-5.font) font.

[fonts.zip](https://cdn-learn.adafruit.com/assets/assets/000/082/665/original/fonts.zip?1571690527)
Download that zip file, unzip the contents, and add the two font files to your **CIRCUITPY** drive which shows up when your board is connected to your computer via a known good data + power USB cable.

Here's the complete code for displaying note info to the TFT Gizmo:

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Circuit_Playground_O_Phonor/notes_tft/code.py

With this code running, try making some musical notes. Use either a musical instrument, like a recorder, or the tone generator website used previously.

It will display the note along with the octave (the subscript number). The actual frequency is also shown at the bottom:

![](https://cdn-learn.adafruit.com/assets/assets/000/082/676/medium800thumb/circuitpython_20191021_145003.jpg?1571695169)


## Featured Products

### Circuit Playground Bluefruit - Bluetooth® Low Energy

[Circuit Playground Bluefruit - Bluetooth® Low Energy](https://www.adafruit.com/product/4333)
 **Circuit Playground Bluefruit** is our third board in the Circuit Playground series, another step towards a perfect introduction to electronics and programming. We've taken the popular Circuit Playground Express and made it even better! Now the main chip is an nRF52840...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4333)
[Related Guides to the Product](https://learn.adafruit.com/products/4333/guides)
### Circuit Playground TFT Gizmo - Bolt-on Display + Audio Amplifier

[Circuit Playground TFT Gizmo - Bolt-on Display + Audio Amplifier](https://www.adafruit.com/product/4367)
Extend and expand your Circuit Playground projects with a bolt on TFT Gizmo that lets you add a lovely color display in a sturdy and reliable fashion. This PCB looks just like a round TFT breakout but has permanently affixed M3 standoffs that act as mechanical and electrical...

In Stock
[Buy Now](https://www.adafruit.com/product/4367)
[Related Guides to the Product](https://learn.adafruit.com/products/4367/guides)
### USB cable - USB A to Micro-B

[USB cable - USB A to Micro-B](https://www.adafruit.com/product/592)
This here is your standard A to micro-B USB cable, for USB 1.1 or 2.0. Perfect for connecting a PC to your Metro, Feather, Raspberry Pi or other dev-board or microcontroller

Approximately 3 feet / 1 meter long

In Stock
[Buy Now](https://www.adafruit.com/product/592)
[Related Guides to the Product](https://learn.adafruit.com/products/592/guides)
### Adafruit Circuit Playground Bluefruit Express Starter Kit

[Adafruit Circuit Playground Bluefruit Express Starter Kit](https://www.adafruit.com/product/4504)
If you missed out on ADABOX 014, its not too late for you to pick up the parts necessary to build many of the projects! This kit pack doesn't come with tissue paper or the nifty extras, but it does have all the electronic goodies you need  
  
This project pack features...

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

## Related Guides

- [Adafruit Circuit Playground Bluefruit](https://learn.adafruit.com/adafruit-circuit-playground-bluefruit.md)
- [Adafruit Circuit Playground TFT Gizmo](https://learn.adafruit.com/adafruit-tft-gizmo.md)
- [Turtle Graphics in CircuitPython on TFT Gizmo](https://learn.adafruit.com/turtle-graphics-gizmo.md)
- [No-Solder LED Disco Tie with Bluetooth](https://learn.adafruit.com/no-solder-circuit-playground-bluetooth-disco-tie.md)
- [TFT Gizmo Animated Eye](https://learn.adafruit.com/tft-gizmo-animated-eye.md)
- [¡Bienvenido a CircuitPython!](https://learn.adafruit.com/bienvenido-a-circuitpython-2.md)
- [Circuit Playground Bluefruit Pumpkin with Lights and Sounds ](https://learn.adafruit.com/pumpkin-with-circuit-playground-bluefruit.md)
- [AdaBox 014](https://learn.adafruit.com/adabox014.md)
- [MagicLight Bulb Color Mixer with Circuit Playground Bluefruit](https://learn.adafruit.com/magiclight-bulb-mixer.md)
- [TFT Gizmo Turtle](https://learn.adafruit.com/tft-gizmo-turtle.md)
- [PyLeap Blink Animation](https://learn.adafruit.com/pyleap-device-enabled-blinky.md)
- [PyLeap NeoPixel Sound Meter for Circuit Playground Bluefruit](https://learn.adafruit.com/pyleap-neopixel-sound-meter.md)
- [CircuitPython TFT Candy Hearts](https://learn.adafruit.com/circuit-python-tft-gizmo-candy-hearts.md)
- [Cyberpunk Santa Eye](https://learn.adafruit.com/cyberpunk-santa-eye.md)
- [Easy No-Soldering Bluetooth Controlled Room Lights](https://learn.adafruit.com/easy-no-solder-bluetooth-controlled-room-lights.md)
- [Bluefruit Playground Hide and Seek](https://learn.adafruit.com/hide-n-seek-bluefruit-ornament.md)
- [Adafruit Mini I2C STEMMA QT Gamepad with seesaw](https://learn.adafruit.com/gamepad-qt.md)
