This is an example of using the tone () function on an Arduino Nano. In the same way you can apply other Arduinos and the like.
2 buttons are used, one starts the music and the second returns the melody to its original tone (Fourth octave).
The 10k potentiometer controls the octave of the melody between the 7 octaves of a piano, raising or lowering the pitch. Each octave is made up of 12 notes, including sustained tones.
The 4 LEDs are included to show relative note changes in light.
I don't use the pitches.h file, instead I use the MIDI note sequence (p), starting with the root note A4 (The 440 MHz). Mathematically, each note can be represented perfectly as an exponential multiple of the note A4, using the following equation:
f = 2 ^ (p - 69) / 12 x 440 Hz
By means of the MeSderM matrix [X][3], where X is the total of notes (depends on the melody, I declare the note number, the note duration factor and the LED that will light up on that note.
In this case and in most melodies, there are parts that repeat, I have created a melodyY function (int RepX, int iniX, int endX) that plays part of the notes (Range: from iniX to endX), the times that as required (RepX).
In the loop the melody is played once button 1 is pressed and during it checks the value of the potentiometer to determine the playing tone of each note and if button 2 is pressed at any time it returns to the original tone.
Likewise, if the melody ends, pressing button 2 will return the melody to its original pitch and the loop will play the melody if button 1 is pressed again.
Finally, by means of a serial monitor, you can view the frequency of each note and the change that occurs when moving the potentiometer throughout its range.
The code is not optimized, it is possible to improve it so in the future I will publish a version 2.
The melody used is as follows: Marvel Spiderman Theme (c)
Additionally, I have made the same example in TinkerCAD (With Arduino Micro) which can be copied and can copy and modify the code to taste.
Reference Links:
Code:
const int LED_GRN = 8;
const int LED_RED = 6;
const int LED_BLE = 4;
const int LED_YLW = 2;
const int BUZZER = 13;
const int BTN1 = 5;
const int BTN2 = 3;
const int POT = A0;
const int MeSderM[] [3] = {{60 ,6, LED_GRN}, {63 ,8, LED_RED}, {67 ,2, LED_BLE}, {66 ,6, LED_BLE}, {63 ,8, LED_RED}, {60 ,2, LED_GRN}, {60 ,6, LED_GRN}, {63 ,8, LED_RED}, {67 ,6, LED_BLE}, {68 ,8, LED_YLW}, {67 ,8, LED_YLW}, {66 ,6, LED_BLE}, {63 ,6, LED_RED}, {60 ,2, LED_GRN}, {65 ,6, LED_RED}, {68 ,8, LED_BLE}, {72 ,2, LED_YLW}, {71 ,6, LED_YLW}, {68 ,8, LED_BLE}, {65 ,2, LED_RED}, {60 ,6, LED_GRN}, {63 ,8, LED_BLE}, {67 ,2, LED_YLW}, {66 ,6, LED_BLE}, {63 ,8, LED_RED}, {60 ,2, LED_GRN}, {68 ,6, LED_YLW}, {67 ,1, LED_BLE}, {67 ,8, LED_BLE}, {65 ,8, LED_RED}, {63 ,8, LED_GRN}, {65 ,8, LED_RED}, {63 ,8, LED_GRN}, {60 ,1, LED_GRN}, {67 ,6, LED_RED}, {68 ,8, LED_BLE}, {70 ,2, LED_YLW}, {68 ,6, LED_YLW}, {67 ,2, LED_BLE}, {65 ,6, LED_RED}, {63 ,8, LED_GRN}, {65 ,2, LED_RED}, {63 ,6, LED_GRN}, {62 ,8, LED_RED}, {63 ,2, LED_GRN}, {67 ,6, LED_RED}, {68 ,8, LED_BLE}, {70 ,2, LED_YLW}, {68 ,6, LED_YLW}, {67 ,2, LED_BLE}, {65 ,6, LED_RED}, {63 ,8, LED_GRN}, {65 ,2, LED_RED}, {63 ,6, LED_GRN}, {65 ,8, LED_RED}, {67 ,1, LED_BLE}, {67 ,8, LED_BLE}, {65 ,8, LED_RED}, {63 ,8, LED_GRN}, {65 ,8, LED_RED}, {63 ,8, LED_GRN}, {60 ,1, LED_GRN}, {67 ,6, LED_BLE}, {65 ,6, LED_RED}, {63 ,8, LED_GRN}, {65 ,6, LED_RED}, {67 ,6, LED_BLE}, {74 ,1, LED_YLW}};
const int LEDS[] = {LED_GRN, LED_RED, LED_BLE, LED_YLW};
int PotV = 0;
int AntO = 0;
int OctX = 0;
void Btn2Read(){
if (digitalRead(BTN2)==HIGH){
OctX=0;
}
}
void melodyY(int RepX, int iniX, int endX) {
for (int RepI = 0; RepI < RepX; RepI++) {
for (int thisNote = iniX; thisNote < endX; thisNote++) {
PotV = map(analogRead(POT), 0, 1023, -3, 4);
if (AntO != PotV){
AntO = PotV;
OctX = PotV;
}
Btn2Read();
int noteDuration = 1000 / MeSderM[thisNote][1];
digitalWrite(MeSderM[thisNote][2], HIGH);
float NteX = MeSderM[thisNote][0]+OctX*12-69;
NteX = pow(2, NteX/12)*440;
String str1 = "Eighth: " + String(4+OctX) + "; Freq: " + String(NteX,3);
Serial.println(str1);
tone(BUZZER, NteX, noteDuration);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes*2/3);
Btn2Read();
digitalWrite(MeSderM[thisNote][2], LOW);
delay(pauseBetweenNotes/3);
Btn2Read();
noTone(BUZZER);
}
}
}
void setup() {
Serial.begin(9600);
for(int i=0; i<4; i++){
pinMode(LEDS[i], OUTPUT);
digitalWrite(LEDS[i], LOW);
}
pinMode(BTN1, INPUT);
pinMode(BTN2, INPUT);
}
void loop() {
if (digitalRead(BTN1)==HIGH)
{
melodyY(2,0,34);
melodyY(1,34,56);
melodyY(1,0,34);
melodyY(1,56,68);
}
Btn2Read();
}
Comments