const int buzzerPin = D10; const int buttonPin = D7; // ---------- Notes ---------- #define NOTE_C4 262 #define NOTE_D4 294 #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_B4 494 #define NOTE_C5 523 #define NOTE_D5 587 #define NOTE_E5 659 #define NOTE_F5 698 #define NOTE_FS5 740 #define NOTE_G5 784 #define NOTE_GS5 831 #define NOTE_A5 880 // ---------- Melody ---------- int melody[] = { NOTE_A4, NOTE_A4, NOTE_A4, NOTE_F4, NOTE_C5, NOTE_A4, NOTE_F4, NOTE_C5, NOTE_A4, NOTE_E5, NOTE_E5, NOTE_E5, NOTE_F5, NOTE_C5, NOTE_GS4, NOTE_F4, NOTE_C5, NOTE_A4, NOTE_A5, NOTE_A4, NOTE_A4, NOTE_A5, NOTE_GS5, NOTE_G5, NOTE_FS5, NOTE_F5, NOTE_FS5 }; int noteDurations[] = { 500, 500, 500, 350, 150, 500, 350, 150, 650, 500, 500, 500, 350, 150, 500, 350, 150, 650, 500, 350, 150, 500, 250, 250, 125, 125, 250, 250 }; // ---------- Button handling ---------- bool lastButtonReading = HIGH; unsigned long lastDebounceTime = 0; const unsigned long debounceDelay = 30; int clickCount = 0; unsigned long firstClickTime = 0; const unsigned long doubleClickGap = 350; // ---------- Music state ---------- bool musicPlaying = false; int currentNote = 0; unsigned long noteStartTime = 0; unsigned long noteTotalTime = 0; bool noteActive = false; void setup() { pinMode(buzzerPin, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); } // Aggressive sci-fi shoot sound void playShootSound() { noTone(buzzerPin); for (int burst = 0; burst < 3; burst++) { for (int freq = 2200; freq >= 700; freq -= 120) { tone(buzzerPin, freq); delay(10); } noTone(buzzerPin); delay(15); } noTone(buzzerPin); } // Start melody from beginning void startMusic() { musicPlaying = true; currentNote = 0; noteActive = false; } // Stop melody void stopMusic() { musicPlaying = false; currentNote = 0; noteActive = false; noTone(buzzerPin); } // Non-blocking melody player void updateMusic() { if (!musicPlaying) return; int totalNotes = sizeof(melody) / sizeof(melody[0]); if (currentNote >= totalNotes) { stopMusic(); return; } if (!noteActive) { int duration = noteDurations[currentNote]; tone(buzzerPin, melody[currentNote]); noteStartTime = millis(); noteTotalTime = duration; noteActive = true; return; } unsigned long elapsed = millis() - noteStartTime; if (elapsed >= noteTotalTime) { noTone(buzzerPin); } if (elapsed >= (unsigned long)(noteTotalTime * 1.3)) { currentNote++; noteActive = false; } } // Detect click and single/double click logic void updateButton() { bool reading = digitalRead(buttonPin); if (reading != lastButtonReading) { lastDebounceTime = millis(); lastButtonReading = reading; } if ((millis() - lastDebounceTime) > debounceDelay) { static bool lastStableState = HIGH; if (reading != lastStableState) { lastStableState = reading; if (lastStableState == LOW) { // button pressed clickCount++; if (clickCount == 1) { firstClickTime = millis(); } else if (clickCount == 2) { // Double click detected clickCount = 0; noTone(buzzerPin); startMusic(); } } } } // If only one click happened and time expired -> single click action if (clickCount == 1 && (millis() - firstClickTime > doubleClickGap)) { clickCount = 0; if (!musicPlaying) { playShootSound(); } } } void loop() { updateButton(); updateMusic(); }