2025-12-17 13:30:33 +05:00

142 lines
4.0 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <SoftwareSerial.h>
#include <DFPlayerMini_Fast.h>
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);
}