Introduction: TechnoTrombone - Trombone Tutor With Neopixels

This project is to build the Techno-Trombone. The Techno-Trombone is a electronic attachment to a trombone that uses an LED strip in order to determine whether or not the instrument is in tune.

For necessary code for this project, get it from the TechnoTrombone GitHub Repository!

https://github.com/sako0938/TechnoTrombone

Step 1: Required Materials

Step 2: Design the PCB

Shown are the schematic and the PCB layout for the PCB. In the final PCB the top layer of the board is not printed out, instead the red wires are "vias" in order to simplify the routing and the manufacturing. These Eagle files are located in the GitHub Repository. Notice the 3.3V to 5V level shifter necessary for the 3.3V Raspberry Pi to communicate with the 5V NeoPixel strips. Also notice the 1000uF capacitor on the 5V line. This is to buffer that power line since the NeoPixel draw a lot of current. The RGB status LEDs are a bit of flair, they could easily just be a single LED and remove the other pin connections. The buttons have external pull-down resistors, though apparently that can be done less reliably in software.

Step 3: Make the Circuit Board

  1. Print page and align toner transfer paper to the PCB printout.
  2. Print out the image on the toner transfer paper and remove.
  3. Use a laminator and with the paper toner side down run the copper sheet through 4-5 times. If a laminator is not available an iron can also be used. The laminator allows for significantly more reliable results.
  4. Put the laminated copper sheet and toner transfer paper into a container of water. Let it sit and the toner transfer paper should release from the copper.
  5. If everything goes as planned, the toner will have transferred onto the copper sheet. Be sure that none of the traces of the board fell off in the process.
  6. Using a green material called TRF foil, re-laminate the board a few times. This foil is unique in that it will stick to the tonor on the circuit board. This foil covering is not completely necessary, but acts to further protect the traces of the board when it goes into the chemical bath.
  7. Put the board into the chemical bath. Notice that the traces are green because they are being protected by the TRF foil. This process will take 10-20 minutes for all of the copper than isn't being protected by tonor and foil to be dissolved away.
  8. Once all of the copper has been dissolved, using gloves remove the board from the chemical bath and rinse with water. Using an abrasive material like an SOS pad, rub away the TRF foil and tonor.
  9. Success! We have a circuit board! However notice that the holes for the components are still missing. This is probably the most tedious part of the process, especially if the board has a lot of holes. This one has a 40 Pin header for the Raspberry Pi, which is a process to drill out. Using a drill press and small drill bits drill out the entire board. Especially if you have a big header like this board, it is essential to drill consistently in order for the components to fit into the holes.
  10. Solder in all the components. If everything goes well everything should work!

Step 4: Install the OS and All Necessary Software

Here are some commands that will make things possible and easier to do:

  1. If you have a Mac, the command is this to burn the OS onto the MicroSD card. It is almost exactly the same on Linux: sudo dd bs=1m if=/Users/{USERNAME}/Documents/Transmission\ Downloads/2015-02-16-raspbian-wheezy.img of=/dev/rdisk1
  2. Install VIM, the better text editor: sudo apt-get install vim
  3. Install Pure Data, for audio processing: sudo apt-get install pure-data
  4. Install GPIO Library(Probably Already Newest Version):
    sudo apt-get install python-rpi.gpio python3-rpi.gpio
  5. Install Raspberry Pi Neopixel Library:
    sudo apt-get install build-essential python-dev git scons swig ;git clone https://github.com/jgarff/rpi_ws281x.git ; cd rpi_ws281x; scons ;cd python; sudo python setup.py install
  6. More information about this process: https://learn.adafruit.com/neopixels-on-raspberry-...
  7. Install things to get the email on networking interface up: sudo apt-get install ssmtp mailutils mpack
  8. sudo vim /etc/ssmtp/ssmtp.conf

mailhub=smtp.gmail.com:587
hostname=raspberrypi

AuthUser=YOU@gmail.com

AuthPass=PASSWORD

useSTARTTLS=YES

9. Put the network script called "emailme" into /etc/networking/if-up.d/emailme

10. sudo reboot

Step 5: Step 4: Building the PureData File

Pure Data (pd) is an open source visual programming language that allows for manipulation of sound. It has an initial learning curve, but once you get started you can pick it up pretty quickly. Take a look at these guides to get started https://www.instructables.com/id/Beginner-Pure-Data-Tutorial-Basic-Synth/

First we’re going to start by creating a fiddle to read in frequency from a mic.

  • [loadbang] - Tells the pd program to begin once it’s loaded.
  • [delay 100] – Waits 100 ms so drivers are properly loaded [; pd dsp 1( - turns on dsp [adc~] - Analog to digital converter that reads in values from the mic.
  • [fiddle~ 1024 1 20] - Built in pd function to gather frequency.
  • [mtof] - Converts the midi values from the fiddle to a frequency.
  • [ \ - Number symbol to display the frequency

Go ahead and connect the objects as seen in the picture above.

Now that we have the basic setup for our pure data file we need to get the Raspberry Pi to recognize our usb mic.

Step 6: Step 5: Connecting the Mic

First connect the mic to the raspberry pi.

Now go ahead and open up terminal and type “arecord –l”. This should display all connect audio devices that could record including the usb mic.

If you don’t see your mic listed, go ahead and restart the Pi and try again.

First load the usb driver “sudo modprobe snd_bcm2835”

Next we need to edit the ALSA-base configuration file: “sudo nano /etc/modprobe.d/alsa-base.conf” Inside the config file change: “options snd-usb-audio index=-2”

To: “options snd-usb-audio index=0”

and add: “options snd_bcm2835 index=1”

This forces ALSA to look for usb audio before the default bcm2835.

Reboot and test the audio by recording a test file:

“arecord test.wav”

and play it back:

“aplay test.wav”

Now that we have the usb mic installed we can go back to pd and change the audio to Media>ALSA

At this point pd should be reading in frequency values and display them in the message. Next we need to connect pd with python to use the NeoPixel library.

Step 7: Step 6: Patchbay

There are many different ways to use python with pd, pyext, pyata, and pd’s netsend/netrecieve. We’re going to use the netsend function in pd and a python library called patchbay to connect with it. Patchbay can be found here: https://github.com/hyrfilm/patchbay

Go ahead and place the patchbay.py file in your folder with the pd file and then we are going to add in the pd netsend functionality and create a python file to read the pd values.

Starting with the python we’re going to follow the patchbay example.

Start by importing patchbay: “from patchbay import create_remot_patch, Trigger, Slider”

Next we are going to create a function to call when a value is received from pd.

“def trigger_func(): value = float(frequency.value) * 10 print(value)”

Then to call the function we need create a patchbay object: “patch = create_remote_patch(use_udp=False)”

then listen for bangs and retrieve the frequency: “patch.bind(channel=1, event_handler=Trigger(trigger_func)) frequency = patch.bind(channel = 2, event_handler=Slider())”

last we are going run a loop so it is constantly listening for pd bangs: “while True: patch.route_events()”

Once all complete you’re python code should look like the above image.

Now that we have the python code put together we need to netsend values from pd.

Start by adding the following to your pd file:

  • [connect localhost 13000{ – Connects to the socket
  • [metro 10] – Bangs every 10 ms
  • [send 1( - Sends the bang
  • [netsend] – Sends the data across the socket
  • [ \ - Number which indicates connection
  • [/ 10] – divides the frequency by 10 to fit in slider’s 0 – 127 range
  • A slider to pass the values
  • [send 2 $1( - Sends the slider value as a variable $1

Then connect it as seen in the graph above.

Once you have both the pd file and python file ready go ahead and close pure data.

To get the values in python the puredata and python code needs to be run in a specific order.

Start by running the python code: “sudo python ‘mycode’.py”

and once you see the waiting for connection message open the pd file.

Now your terminal should be printing the frequency.

Step 8: Lighting Up the Neopixels

All implementation for lighting up the Adafruit Neopixel strip is in the file strandtest.py.

In this we implemented certain animations that were used to determine whether a person was playing the correct frequency related to a note.

These animations include:

Solid Blue: turnOnBlue()

Rapid Yellow Blinking: mostAccurate()

Slower Yellow Blinking: moreAccurate()

Slowest Yellow Blinking: leastAccurate()

The colors we chose were Blue and Yellow but if you would like you can choose any color.

If you would like to change the color scheme, the part of code you would have to change is "color = Color(255,255,0)" in each animation function. In order to change the color you would have to input Color(R,G,B) where the R, G, and B would be in the range from 0-255.

The rest of the animation functions that are available to use in strandtest.py came with the Neopixel library.

An array of numbers is listed in the code these values are specific frequencies of notes that a trombone is capable of playing.

Using these values we created an error acceptance by partitioning each range between two notes into eight sections.

The first and eighth segments would light up blue telling the user that they are on pitch by calling the turnOnBlue() function.

The second and seventh segments would light up with a rapid blinking yellow light letting the user know that they are close to the actual notes by calling the mostAccurate() function.

The third and sixth segments would light up with a slower frequency of blinking yellow by calling the moreAccurate() function.

The forth and fifth segments would light up with the slowest frequency of blinking yellow telling the user that they are the furthest way from hitting either the notes by calling the leastAccurate() function.

Step 9: Step 9: Finishing Touches

At this point you have essentially put together your own TechnoTrombone. However, you probably don't want to have to ssh in to your Pi every time you want to use it, so here is how to create a script that will run our code at startup.

We're going to edit a file named rc.local that can be found in the etc folder. rc.local is a bash script that executes at startup after the operating system is loaded.

Go ahead and open up rc.local.

"sudo nano /etc/rc.local"

Inside the file we're going to add a couple of lines to execute our python code and run pd from command line.

Below the "fi" add the lines:

"sudo python (full path to your python file) &"

"sleep 10"

"pd -nogui /home/pi/TechnoTrombone/test.pd &"

We need to sleep 10 seconds between running the python script and opening pd to make sure that python is loaded and looking for a connection.

And there you have it! Now every time you restart the pi it should load up the library and be working. Check out a short video of our finished version in action above!

Thank you for checking out our project!

Sam, Deep, and Logan