From bc2730617d332cb98d2f1ef63cb29eec12bd757c Mon Sep 17 00:00:00 2001 From: Larrius Date: Fri, 16 May 2025 20:14:25 +0000 Subject: [PATCH] Add firmware.c --- firmware.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 firmware.c diff --git a/firmware.c b/firmware.c new file mode 100644 index 0000000..b2dace8 --- /dev/null +++ b/firmware.c @@ -0,0 +1,141 @@ +#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); +}