Project designed to work with beta 6.0 (released on November 4th, 2021). Created 1/6/2022
In this project, we're going to learn how to wire up a piezo buzzer/speaker to play jingle bells at the press of a button.
The project should be easily modifiable to remove the button if you don't have one.
Meadow.Foundation is a platform for quickly and easily building connected things using.NET on Meadow. Created by Wilderness Labs, It's completely open source and maintained by the Wilderness Labs community.
If you're new working with Meadow, I suggest you go to the Getting Started w/ Meadow by Controlling the Onboard RGB LED project to properly set up your development environment.
Step 1 - Assemble the circuitWire all components as shown in the Fritzing diagram below:
Notice the resistor used on the piezo speaker's circuit. This lowers the volume. The higher your resistor, the lower the volume.
Step 2 - Create a Meadow Application projectCreate a new MeadowApplication project in Visual Studio 2019 or 2022 for Windows or macOS.
Step 3 - Write the codeThis was taken from an old sample for the Meadow F7 Micro board and updated for the latest foundation classes. The original project is here:https://github.com/SuavePirate/Meadow-Piezo-JingleBells
Class members and constructor:
RgbPwmLed onboardLed;
private IPwmPort pwm;
PiezoSpeaker speaker;
PushButton button;
const string NOTES = "eeeeeeegcdefffffeeeeddedgeeeeeeegcdefffffeeeggfdc ";
readonly int[] BEATS = { 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1};
const int TEMPO = 300;
bool playing = false;
public MeadowApp()
{
Initialize();
PlayNote('c', 50).Wait();
PlayJingleBells().ConfigureAwait(false);
}
Initialize the speaker, button, and onboard LED:
void Initialize()
{
Console.WriteLine("Initialize hardware...");
onboardLed = new RgbPwmLed(device: Device,
redPwmPin: Device.Pins.OnboardLedRed,
greenPwmPin: Device.Pins.OnboardLedGreen,
bluePwmPin: Device.Pins.OnboardLedBlue,
3.3f, 3.3f, 3.3f,
Meadow.Peripherals.Leds.IRgbLed.CommonType.CommonAnode);
pwm = Device.CreatePwmPort(Device.Pins.D04, 100, .5f, true);
speaker = new PiezoSpeaker(pwm);
button = new PushButton(Device, Device.Pins.D01);
button.Clicked += (o, e) => { playing = !playing; };
}
We're using an event pattern for the button press, which merely sets a variable that the main song loop looks at to start/stop.
You will need a function to play a note for a given duration, and we will use this function to turn on and off the onboard LED in sync with the music:
private async Task PlayNote(char note, int duration)
{
char[] names = { 'c', 'd', 'e', 'f', 'g', 'a', 'b'};
int[] tones = { 523, 587, 659, 698, 783, 880, 987 };
Color[] colors = { Color.Red, Color.Green, Color.White, Color.Blue, Color.Yellow, Color.Orange, Color.Purple };
// play the tone corresponding to the note name
for (int i = 0; i < names.Length; i++)
{
if (names[i] == note)
{
var tone = tones[i];
onboardLed.SetColor(colors[i], .25f);
onboardLed.IsOn = true;
await speaker.PlayTone(tone, duration);
onboardLed.IsOn = false;
Console.WriteLine($"Playing note {note} tone {tone} for {duration}");
}
}
}
Here is the function to play through the entire song:
protected async Task PlayJingleBells()
{
while (true)
{
if (playing)
{
Console.WriteLine("Playing jingle bells!");
for (int i = 0; i < NOTES.Length && playing; i++)
{
if (NOTES[i] == ' ')
{
await Task.Delay(BEATS[i] * TEMPO); // rest
}
else
{
await PlayNote(NOTES[i], BEATS[i] * TEMPO);
// pause between notes
await Task.Delay(BEATS[i] * TEMPO / 2);
}
}
Console.WriteLine("From the top!");
}
else
{
// Slow the infinite loop down or the button interrupt breaks
await Task.Delay(TEMPO);
}
}
}
This loop plays each note for the specified number of beats and multiplies by tempo. In our case, 300ms is a beat.
Step 4 - Run the projectClick the Run button in Visual Studio. It should work like the following video:
Comments
Please log in or sign up to comment.