#include #include const int dfRx = 10; const int dfTx = 11; const int trigPin = 3; const int echoPin = 4; SoftwareSerial dfSerial(dfRx, dfTx); DFPlayerMini_Fast player; bool objectDetected = false; bool isPlaying = false; bool trackStarted = false; unsigned long lastStartTime = 0; unsigned long accumulatedTime = 0; const unsigned long trackDuration = 3966000; // - подставить длину записанного трека на sd-карте, в миллисекундах const int detectionDistance = 100; const int stableCountThreshold = 5; int stableCounter = 0; int currentVolume = 30; int targetVolume = 30; unsigned long lastVolumeStepTime = 0; const unsigned long volumeStepInterval = 100; void setup() { pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); Serial.begin(9600); dfSerial.begin(9600); delay(1500); player.begin(dfSerial); player.volume(currentVolume); Serial.println("🎬 DFPlayer готов, жду объект перед датчиком"); } long measureDistance() { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); long duration = pulseIn(echoPin, HIGH, 25000); return duration * 0.034 / 2; } void setTargetVolume(int vol) { targetVolume = constrain(vol, 0, 30); } void updateVolume() { unsigned long now = millis(); if (now - lastVolumeStepTime >= volumeStepInterval) { if (currentVolume < targetVolume) { currentVolume++; player.volume(currentVolume); } else if (currentVolume > targetVolume) { currentVolume--; player.volume(currentVolume); } lastVolumeStepTime = now; } } void loop() { unsigned long now = millis(); long distance = measureDistance(); // сглаживание дребезга if (distance > 0 && distance < detectionDistance) { if (stableCounter < stableCountThreshold) stableCounter++; } else { if (stableCounter > 0) stableCounter--; } bool currentlyDetected = stableCounter >= stableCountThreshold; // если трек играет — накапливаем время if (isPlaying) { accumulatedTime += now - lastStartTime; } lastStartTime = now; // объект появился if (currentlyDetected && !objectDetected) { if (!trackStarted) { // первый запуск player.play(1); Serial.println("▶️ Объект вернулся → трек с начала (первый запуск)"); trackStarted = true; accumulatedTime = 0; } else if (accumulatedTime >= trackDuration) { // доиграл во время паузы player.pause(); delay(100); player.play(1); Serial.println("▶️ Объект вернулся → трек заново (доиграл)"); accumulatedTime = 0; } else { // продолжить с места player.resume(); Serial.println("▶️ Объект вернулся → продолжаю с места"); } setTargetVolume(30); isPlaying = true; objectDetected = true; lastStartTime = millis(); } // объект ушёл — гасим громкость if (!currentlyDetected && objectDetected) { setTargetVolume(0); Serial.println("🚶 Объект ушёл → гашу громкость"); objectDetected = false; } // пауза после гашения if (!objectDetected && isPlaying && currentVolume == 0) { player.pause(); Serial.println("⏸ Громкость догорела → пауза"); isPlaying = false; } // если трек доиграл во время воспроизведения — перезапуск if (isPlaying && accumulatedTime >= trackDuration) { player.pause(); delay(100); player.play(1); Serial.println("🔁 Трек доиграл → перезапуск"); accumulatedTime = 0; lastStartTime = millis(); } updateVolume(); delay(30); }