In this project you'll create a multi-channel music player using piezos. The sample code plays the holiday classic Jingle Bells with both a melody and a bass line.
You only need a Netduino and two piezos for this project but I like to use in-line resistors to control the volume. You can optionally add two LEDs that light-up with the music.
All of the hardware is controlled by drivers in Netduino.Foundation and all of the music logic is provided in the GitHub repo. You can even add new songs by editing the SongBook class.
Step 1 - Assemble the circuitFor this project, wire up your breadboard and Netduino as shown in the Fritzing diagram:
We're using pins 2 & 4 for the LEDs but these can be driven by any of the digital output pins.
For the Piezos, we're using pins 9 and 11, these are recommended as they're both PWM enabled pins and they don't share a timer.
Step 2 - Download the source codeGo to https://github.com/adrianstevens/NetduinoSamples and either clone or download the repo. Specifically we want the code in the XMasPlayer folder.
If you've like to learn how to create a new Netduino project, see the getting started project here: https://www.hackster.io/wilderness-labs/getting-started-with-netduino-by-controlling-the-onboard-led-72775e
Step 3 - Open and explore the projectOpen the XMasPlayer project in Visual Studio 2015 on Windows or Visual Studio for Mac on macOS.
Start by opening App.cs, this is where you'll configure your hardware and play the song. The constructor calls the InitializePeripherals method, this is were we setup our piezos and leds. Now is a great time to make sure the pins defined in the code match our physical connections.
We're also creating a PushButton object to connect to the Netduino's onboard button. We'll use this to start playing our song.
private void InitializePeripherals()
{
ledMelody = new Led(N.Pins.GPIO_PIN_D4);
ledBass = new Led(N.Pins.GPIO_PIN_D2);
speakerMelody = new PiezoSpeaker(N.PWMChannels.PWM_PIN_D9);
speakerBass = new PiezoSpeaker(N.PWMChannels.PWM_PIN_D11);
buttonPlay = new PushButton(N.Pins.ONBOARD_BTN, Netduino.Foundation.CircuitTerminationType.Floating);
buttonPlay.Clicked += OnButtonPlay;
}
Next, look at the code in the SongBook folder. This folder has two model objects, one for a Note, and one for a Song. Our songs consist of collections of notes, one for the melody and one for bass. You could extend this class to add additional notes if you wanted more than two voices.
The SongBook class holds a collection of songs, we only have code to add Jingle Bells but others could be added. You'll notice the songs are defined as collections of strings, alternating between the note and the length. We then use reflection in the Note class to load the correct values.
Finally, go back to the App class and look at the PlaySong method. This method loops through all of melody and bass notes, and sets the piezos to the correct frequencies and turns the leds on and off with the music.
private void PlaySong(Song song)
{
//smallest note length is a 32nd note
//change value to adjust tempo
var len32Note = 1500 / 32;
//index of the currently playing note
int melodyIndex = 0;
int bassIndex = 0;
//remaining steps for the currently playing note
int melodyRemaining = 0;
int bassRemaining = 0;
//loop until we've played every melody and bass note
while (melodyIndex < song.Melody.Length &&
bassIndex < song.Bass.Length)
{
if (melodyRemaining == 0 && melodyIndex < song.Melody.Length)
{
speakerMelody.StopTone();
ledMelody.IsOn = false;
//get the length of the next note
melodyRemaining = song.Melody[melodyIndex].Length;
//if the note isn't silence (i.e. don't play rests)
if (song.Melody[melodyIndex].Pitch != 0)
{
speakerMelody.PlayTone(song.Melody[melodyIndex].Pitch);
ledMelody.IsOn = true;
}
melodyIndex++;
}
melodyRemaining--;
if (bassRemaining == 0 && bassIndex < song.Bass.Length)
{
speakerBass.StopTone();
ledBass.IsOn = false;
bassRemaining = song.Bass[bassIndex].Length;
if (song.Bass[bassIndex].Pitch != 0)
{
speakerBass.PlayTone(song.Bass[bassIndex].Pitch);
ledBass.IsOn = true;
}
bassIndex++;
}
bassRemaining--;
Thread.Sleep(len32Note);
}
Thread.Sleep(len32Note * 32);
ledMelody.IsOn = false;
ledBass.IsOn = false;
speakerMelody.StopTone();
speakerBass.StopTone();
}
Step 4 - Run the projectClick the run button in Visual Studio to start playing music! Once the app is deployed, press the Netduino's onboard button to play Jingle Bells!
Check out Netduino.Foundation!There are a lot of ways you could extend this project. You could add more songs, add more piezo speakers, or even add an LED display to show the song name or notes. And this is easy with Netduino.Foundation.
- It comes with a Huge Peripheral Driver Library with drivers for the most common sensors and peripherals available in the market.
- All the peripheral drivers are simplified with built-in functionality, exposed by a clean, modern API.
- This project is backed by a growing community that is constantly working on building cool connected things and always excited to help new-comers and discuss new projects.
Comments