04 - Lab Classic Melody Maestro

Video

# Lab: Classic Melody Maestro - Play Famous Songs with TinkerBlock ## **Objective** Create a complete music player system using the TK37 passive buzzer to play full melodies, including popular songs like "Twinkle Twinkle Little Star," "Happy Birthday," and "Jingle Bells." Learn to structure music using arrays and implement proper musical timing and rhythm. ## **Required Components** ![](https://cdn.shopify.com/s/files/1/0331/9994/7908/files/Pasted_image_20250723155115.png?v=1753858090) 1. **Lonely Binary UNO R3** - Main Arduino board 2. **TinkerBlock UNO R3 Shield** - Expansion shield that plugs onto the UNO R3 3. **TinkerBlock TK37** - Passive Buzzer Module ## **Theory** ### **Music Structure and Arrays** - **Melody Arrays**: Store note frequencies in sequence - **Duration Arrays**: Corresponding timing for each note - **Synchronization**: Notes and durations must be perfectly aligned - **REST Notes**: Silence periods represented by frequency 0 ### **Musical Timing** - **Note Durations**: Whole, half, quarter, eighth notes - **Tempo Control**: Beats per minute (BPM) for rhythm - **Rhythm Patterns**: Consistent timing creates musical flow - **Pause Management**: Proper spacing between notes ### **Song Structure** - **Phrases**: Musical sentences with natural breaks - **Repetition**: Repeating motifs and patterns - **Variation**: Changes in melody and rhythm - **Closure**: Natural ending points in music ## **Wiring Instructions** ### **TK37 Passive Buzzer Pinout** - **GND** → Arduino GND - **VCC** → Arduino 5V - **NC** → No Connection - **Signal** → Arduino Digital Pin D7 ### **Connection Diagram** ![](https://cdn.shopify.com/s/files/1/0331/9994/7908/files/Pasted_image_20250723155214.png?v=1753858104) ``` UNO R3 + Shield └── Digital Pin D7 ──→ TK37 Signal ``` ## **Melody Player with Note Arrays** ```cpp // Melody Player with TK37 Passive Buzzer // Pin definitions #define BUZZER_PIN 7 // Musical note frequencies #define NOTE_B0 31 #define NOTE_C1 33 #define NOTE_CS1 35 #define NOTE_D1 37 #define NOTE_DS1 39 #define NOTE_E1 41 #define NOTE_F1 44 #define NOTE_FS1 46 #define NOTE_G1 49 #define NOTE_GS1 52 #define NOTE_A1 55 #define NOTE_AS1 58 #define NOTE_B1 62 #define NOTE_C2 65 #define NOTE_CS2 69 #define NOTE_D2 73 #define NOTE_DS2 78 #define NOTE_E2 82 #define NOTE_F2 87 #define NOTE_FS2 93 #define NOTE_G2 98 #define NOTE_GS2 104 #define NOTE_A2 110 #define NOTE_AS2 117 #define NOTE_B2 123 #define NOTE_C3 131 #define NOTE_CS3 139 #define NOTE_D3 147 #define NOTE_DS3 156 #define NOTE_E3 165 #define NOTE_F3 175 #define NOTE_FS3 185 #define NOTE_G3 196 #define NOTE_GS3 208 #define NOTE_A3 220 #define NOTE_AS3 233 #define NOTE_B3 247 #define NOTE_C4 262 #define NOTE_CS4 277 #define NOTE_D4 294 #define NOTE_DS4 311 #define NOTE_E4 330 #define NOTE_F4 349 #define NOTE_FS4 370 #define NOTE_G4 392 #define NOTE_GS4 415 #define NOTE_A4 440 #define NOTE_AS4 466 #define NOTE_B4 494 #define NOTE_C5 523 #define NOTE_CS5 554 #define NOTE_D5 587 #define NOTE_DS5 622 #define NOTE_E5 659 #define NOTE_F5 698 #define NOTE_FS5 740 #define NOTE_G5 784 #define NOTE_GS5 831 #define NOTE_A5 880 #define NOTE_AS5 932 #define NOTE_B5 988 #define NOTE_C6 1047 #define NOTE_CS6 1109 #define NOTE_D6 1175 #define NOTE_DS6 1245 #define NOTE_E6 1319 #define NOTE_F6 1397 #define NOTE_FS6 1480 #define NOTE_G6 1568 #define NOTE_GS6 1661 #define NOTE_A6 1760 #define NOTE_AS6 1865 #define NOTE_B6 1976 #define NOTE_C7 2093 #define NOTE_CS7 2217 #define NOTE_D7 2349 #define NOTE_DS7 2489 #define NOTE_E7 2637 #define NOTE_F7 2794 #define NOTE_FS7 2960 #define NOTE_G7 3136 #define NOTE_GS7 3322 #define NOTE_A7 3520 #define NOTE_AS7 3729 #define NOTE_B7 3951 #define NOTE_C8 4186 #define NOTE_CS8 4435 #define NOTE_D8 4699 #define NOTE_DS8 4978 // Note duration constants #define WHOLE_NOTE 1600 #define HALF_NOTE 800 #define QUARTER_NOTE 400 #define EIGHTH_NOTE 200 #define SIXTEENTH_NOTE 100 // Rest note (silence) #define REST 0 void setup() { Serial.begin(9600); pinMode(BUZZER_PIN, OUTPUT); delay(1000); Serial.println("TK37 Melody Player"); Serial.println("=================="); Serial.println("Playing melodies..."); Serial.println(); } void loop() { // Play "Twinkle Twinkle Little Star" Serial.println("Playing: Twinkle Twinkle Little Star"); playTwinkleTwinkle(); delay(2000); // Play "Happy Birthday" Serial.println("Playing: Happy Birthday"); playHappyBirthday(); delay(2000); // Play "Jingle Bells" Serial.println("Playing: Jingle Bells"); playJingleBells(); delay(2000); Serial.println("All melodies complete. Restarting..."); Serial.println(); } // Function to play a melody from arrays void playMelody(int melody[], int durations[], int length) { for (int i = 0; i < length; i++) { int noteDuration = durations[i]; if (melody[i] == REST) { delay(noteDuration); } else { tone(BUZZER_PIN, melody[i], noteDuration); delay(noteDuration + 50); // Small pause between notes } } noTone(BUZZER_PIN); } // Twinkle Twinkle Little Star melody void playTwinkleTwinkle() { int melody[] = { NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_C4, NOTE_G4, NOTE_G4, NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_G4, NOTE_G4, NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_C4 }; int durations[] = { QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE }; playMelody(melody, durations, 42); } // Happy Birthday melody void playHappyBirthday() { int melody[] = { NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_F4, NOTE_E4, NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_G4, NOTE_F4, NOTE_C4, NOTE_C4, NOTE_C5, NOTE_A4, NOTE_F4, NOTE_E4, NOTE_D4, NOTE_AS4, NOTE_AS4, NOTE_A4, NOTE_F4, NOTE_G4, NOTE_F4 }; int durations[] = { QUARTER_NOTE, EIGHTH_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE, QUARTER_NOTE, EIGHTH_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE, QUARTER_NOTE, EIGHTH_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE, QUARTER_NOTE, EIGHTH_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE }; playMelody(melody, durations, 24); } // Jingle Bells melody void playJingleBells() { int melody[] = { NOTE_E4, NOTE_E4, NOTE_E4, REST, NOTE_E4, NOTE_E4, NOTE_E4, REST, NOTE_E4, NOTE_G4, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_F4, NOTE_F4, NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_D4, NOTE_E4, NOTE_D4, NOTE_G4 }; int durations[] = { QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, EIGHTH_NOTE, EIGHTH_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, QUARTER_NOTE, HALF_NOTE }; playMelody(melody, durations, 26); } ``` ## **Code Explanation** ### **Note Frequency Definitions** ```cpp #define NOTE_C4 262 #define NOTE_D4 294 #define NOTE_E4 330 // ... (complete set of notes) ``` - **Comprehensive Coverage**: Includes all notes from B0 to D8 (8+ octaves) - **Standard Tuning**: Frequencies follow A4=440Hz standard - **Mathematical Accuracy**: Each octave doubles the frequency - **Sharps Included**: CS (C#), DS (D#), etc. for complete musical range ### **Duration Constants** ```cpp #define WHOLE_NOTE 1600 #define HALF_NOTE 800 #define QUARTER_NOTE 400 #define EIGHTH_NOTE 200 #define SIXTEENTH_NOTE 100 ``` - **Musical Notation**: Standard musical duration values - **Mathematical Relationship**: Each duration is half the previous - **Flexible Timing**: Can be adjusted for different tempos - **REST Support**: REST = 0 for silence periods ### **Melody Playing Function** ```cpp void playMelody(int melody[], int durations[], int length) { for (int i = 0; i < length; i++) { int noteDuration = durations[i]; if (melody[i] == REST) { delay(noteDuration); } else { tone(BUZZER_PIN, melody[i], noteDuration); delay(noteDuration + 50); } } noTone(BUZZER_PIN); } ``` - **Array Processing**: Loops through melody and duration arrays - **REST Handling**: Special case for silence (frequency = 0) - **Note Timing**: Each note plays for its specified duration - **Pause Management**: 50ms pause between notes for clarity ### **Song Structure Implementation** #### **Twinkle Twinkle Little Star** ```cpp int melody[] = { NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4, NOTE_G4, // ... (complete melody) }; ``` - **Classic Melody**: Well-known children's song - **Simple Structure**: Repeating patterns and phrases - **Educational Value**: Perfect for learning music programming - **Clear Rhythm**: Consistent quarter and half notes #### **Happy Birthday** ```cpp int melody[] = { NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_F4, NOTE_E4, // ... (complete melody) }; ``` - **Celebration Song**: Universal birthday celebration - **Mixed Rhythms**: Combination of quarter and eighth notes - **Melodic Range**: Uses multiple octaves (C4 to C5) - **Cultural Significance**: Recognizable worldwide #### **Jingle Bells** ```cpp int melody[] = { NOTE_E4, NOTE_E4, NOTE_E4, REST, // ... (complete melody) }; ``` - **Holiday Classic**: Popular Christmas song - **REST Notes**: Includes silence for rhythmic effect - **Energetic Tempo**: Fast-paced, upbeat melody - **Wide Range**: Uses notes from C4 to G4 ### **Key Programming Concepts** #### **Array Management** - **Parallel Arrays**: Melody and duration arrays must stay synchronized - **Index Alignment**: Same index in both arrays represents one note - **Length Control**: Array length determines song length - **Memory Efficiency**: Compact storage of musical data #### **Musical Timing** - **Duration Control**: Each note plays for exact specified time - **Rhythm Accuracy**: Proper timing creates musical rhythm - **Pause Integration**: Small pauses between notes for clarity - **Tempo Consistency**: Uniform timing throughout the song #### **Code Organization** - **Modular Functions**: Each song is a separate function - **Reusable Framework**: playMelody() works for any song - **Easy Maintenance**: Add new songs by creating new functions - **Clear Structure**: Logical organization of musical data ### **Musical Theory Integration** - **Note Relationships**: Understanding of musical intervals - **Rhythm Patterns**: Recognition of musical timing - **Song Structure**: Awareness of musical phrases and repetition - **Harmony Concepts**: Foundation for more complex musical programming ## **Expected Output** ### **Serial Monitor Output** ``` TK37 Melody Player ================== Playing melodies... Playing: Twinkle Twinkle Little Star [Twinkle Twinkle melody plays - 42 notes] Playing: Happy Birthday [Happy Birthday melody plays - 24 notes] Playing: Jingle Bells [Jingle Bells melody plays - 26 notes] All melodies complete. Restarting... ``` ### **Audio Output** - **Twinkle Twinkle**: Clear, recognizable children's song melody - **Happy Birthday**: Familiar birthday celebration tune - **Jingle Bells**: Upbeat holiday song with rhythmic pauses - **Note Clarity**: Each note should be distinct and in tune - **Rhythm Accuracy**: Proper timing creates musical flow ### **Performance Characteristics** - **Song Duration**: Each song plays for approximately 10-15 seconds - **Transition Timing**: 2-second pause between songs - **Loop Behavior**: Continuous playback with 6-second cycle - **Memory Usage**: Efficient array-based storage system ## **Troubleshooting** ### **No sound from buzzer:** - **Check Wiring**: Verify TK37 is connected to D7 pin - **Power Supply**: Ensure 5V and GND connections are secure - **Pin Configuration**: Confirm pinMode(BUZZER_PIN, OUTPUT) is set - **Test Simple Tone**: Try tone(BUZZER_PIN, 440, 1000) for basic test ### **Incorrect melody playback:** - **Array Synchronization**: Check melody and duration arrays have same length - **Note Frequencies**: Verify note definitions are correct - **Duration Values**: Ensure duration constants are appropriate - **Index Errors**: Check for off-by-one errors in array access ### **Timing issues:** - **Note Duration**: Adjust duration constants if tempo is too fast/slow - **Pause Timing**: Modify 50ms pause between notes if needed - **Song Length**: Check array lengths match actual song structure - **Loop Timing**: Adjust 2-second delays between songs ### **Memory issues:** - **Array Size**: Large note arrays may exceed available memory - **Variable Scope**: Ensure arrays are properly declared - **Stack Overflow**: Check for excessive function calls - **Optimization**: Consider using PROGMEM for large arrays ### **Song quality issues:** - **Note Accuracy**: Verify frequencies match musical standards - **Rhythm Problems**: Check duration values for proper timing - **Octave Issues**: Ensure notes are in appropriate octave range - **REST Implementation**: Verify REST notes (frequency 0) work correctly ## **Applications** ### **Educational** - **Music Education**: Learn musical notes, timing, and structure - **Programming Practice**: Array manipulation and loop control - **Audio Engineering**: Introduction to digital music generation - **Cultural Learning**: Understanding different musical traditions ### **Entertainment** - **Musical Toys**: Create interactive musical devices - **Game Development**: Background music and sound effects - **Party Entertainment**: Musical greeting cards and decorations - **Performance Art**: Audio installations and exhibits ### **Commercial** - **Product Alerts**: Musical notification systems - **User Interfaces**: Audio feedback for device interactions - **Marketing**: Musical branding and advertising - **Accessibility**: Audio cues for visually impaired users ### **Prototyping** - **Audio Prototypes**: Quick musical feedback during development - **Concept Testing**: Validate musical requirements early - **User Experience**: Test audio interaction patterns - **Integration Testing**: Verify audio system integration ## **Customization Ideas** ### **Add More Songs:** - **Classical Music**: Beethoven, Mozart, Bach melodies - **Popular Songs**: Contemporary hits and classics - **Folk Music**: Traditional songs from different cultures - **Original Compositions**: Create your own melodies ### **Enhance Musical Features:** - **Tempo Control**: Adjustable speed for different moods - **Volume Variation**: Dynamic volume changes within songs - **Harmony**: Add multiple simultaneous notes - **Effects**: Echo, reverb, or other audio effects ### **Add Interactive Elements:** - **Button Control**: Use buttons to select different songs - **Potentiometer Control**: Adjust tempo with analog input - **Light Sensor**: Change songs based on light intensity - **Motion Sensor**: Trigger music with movement ### **Advanced Features:** - **Song Library**: Store multiple songs in memory - **Random Play**: Shuffle through available songs - **Playlist System**: Create custom song sequences - **MIDI Integration**: Connect to professional music equipment ## **Next Steps** - **Learn Music Theory**: Study musical composition and theory - **Explore Advanced Libraries**: Investigate Arduino music libraries - **Build Musical Instruments**: Create complete electronic instruments - **Study Audio Processing**: Learn about digital signal processing - **Experiment with Effects**: Add reverb, echo, or other audio effects ## **Resources** - **Musical Frequencies**: Standard note frequency tables and calculators - **Music Theory**: Basic music theory and composition principles - **Arduino Tone Library**: Advanced tone generation and control - **Audio Engineering**: Digital audio processing and synthesis concepts - **Classical Music**: Sheet music and musical analysis resources