Assignment 7: Musical Instrument

Partner: Hyein Kim

Concept

When we were young, we were taught to sing and play instruments to a song called “떴다 떴다 비행기”. This song is about airplanes and with the introduction to airplanes through this song, we learn more about airplanes and dream of riding it one day. Furthermore, when we played as elementary students in the playground, we always sang this song and looked up to the sky to find some airplanes. Now, as older students, playing this song on our instrument reminds us of our childhood in South Korea.

Circuit

For digital, we used 3 buttons. Each button is connected to the Ground, a 330 ohm resistor and digital input (2, 3, 4). 

For analog, we used a potentiometer and a speaker. The speaker is connected to the Ground and analog input (~9). The potentiometer is connected to 5V, A0, and the Ground.

Playing the song

Changing the tone

Code

We have created a code so that when a button is pressed, the corresponding note is played with a frequency that can be altered up or down by the potentiometer. The constants BASE_NOTE_C4, BASE_NOTE_D4, and BASE_NOTE_E4 are defined at the top of the sketch. To simplify the code, we have used the INPUT_PULLUP function in the ‘setup’ function, which means that the button pin will read HIGH when unpressed and LOW when pressed. 

void setup() {
  for (int i = 0; i < 3; i++) {
    pinMode(buttonPins[i], INPUT_PULLUP); // Setup as pull-up to simplify wiring
  }
  pinMode(buzzerPin, OUTPUT);
}

In the main program loop, the potentiometer’s value is read from ‘potPin’ and mapped from its reading rand (0 to 1023) to a frequency adjustment range of -100 to +100 Hz. The loop checks each button in the buttonPins array to see if it’s pressed (reads LOW due to the pull-up resistor). If a button is pressed, the function playAdjustedTone() is called.

void loop() {
  int frequencyAdjustment = analogRead(potPin); // Read the potentiometer value
  frequencyAdjustment = map(frequencyAdjustment, 0, 1023, -100, 100); // Map the pot value to a frequency range adjustment

  for (int i = 0; i < 3; i++) {
    if (digitalRead(buttonPins[i]) == LOW) { // Check if button is pressed
      playAdjustedTone(i, frequencyAdjustment);
    }
  }
}

We wanted to use the potentiometer to adjust the tone. So we have written the playAdjustedTone() function. It calculates the adjusted frequency for the selected note by adding the frequency adjustment value from the potentiometer to the base frequency of the note. It then uses tone(buzzerPin, adjustedFrequency) to play the adjusted note for 100 milliseconds.

void playAdjustedTone(int noteIndex, int adjustment) {
  int baseFrequencies[] = {BASE_NOTE_C4, BASE_NOTE_D4, BASE_NOTE_E4}; // Base frequencies for C, D, E
  int adjustedFrequency = baseFrequencies[noteIndex] + adjustment; // Adjust the frequency based on potentiometer

  tone(buzzerPin, adjustedFrequency); // Play the adjusted note
  delay(100); // Duration of note
  noTone(buzzerPin); // Stop the tone
}

After playing the note, noTone(buzzerPin) stops the buzzer.

Here is the full version of our code:

// Define frequencies for musical notes C, D, E
#define BASE_NOTE_C4 261
#define BASE_NOTE_D4 294
#define BASE_NOTE_E4 329

// Define pin connections
const int buzzerPin = 9;
const int potPin = A0;
const int buttonPins[] = {2, 3, 4}; // Buttons for C, D, E notes

void setup() {
  for (int i = 0; i < 3; i++) {
    pinMode(buttonPins[i], INPUT_PULLUP); // Setup as pull-up to simplify wiring
  }
  pinMode(buzzerPin, OUTPUT);
}

void loop() {
  int frequencyAdjustment = analogRead(potPin); // Read the potentiometer value
  frequencyAdjustment = map(frequencyAdjustment, 0, 1023, -100, 100); // Map the pot value to a frequency range adjustment

  for (int i = 0; i < 3; i++) {
    if (digitalRead(buttonPins[i]) == LOW) { // Check if button is pressed
      playAdjustedTone(i, frequencyAdjustment);
    }
  }
}

void playAdjustedTone(int noteIndex, int adjustment) {
  int baseFrequencies[] = {BASE_NOTE_C4, BASE_NOTE_D4, BASE_NOTE_E4}; // Base frequencies for C, D, E
  int adjustedFrequency = baseFrequencies[noteIndex] + adjustment; // Adjust the frequency based on potentiometer

  tone(buzzerPin, adjustedFrequency); // Play the adjusted note
  delay(100); // Duration of note
  noTone(buzzerPin); // Stop the tone
}

Reflection

For improvement, we would like to add more buttons so that we can play more musical notes. In this way, the range of songs we can play on the instrument would widen and it would be more entertaining to play along on the instrument. Also, we tried to change the volume of the sound through the potentiometer but was unsuccessful at it. Therefore, for this assignment, we utilized the potentiometer to control the tone instead. In the future, however, we would like to learn and utilize volume control using the potentiometer. 

 

Leave a Reply