Files
LampControler/src/LightControl.cpp
2025-07-01 14:31:37 +08:00

103 lines
3.0 KiB
C++
Raw 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.

// LightControl.cpp
#include "LightControl.h"
#include "Arduino.h"
LightControl::LightControl(BH1750& sensor, DS3502& pot)
: lightSensor(sensor), digitalPot(pot) {}
void LightControl::setTargetLight(float target) {
targetLightLevel = target;
}
float LightControl::getCurrentLight() {
return lightSensor.readLightLevel();
}
// 新增:持续调节函数,每次只调节一步
void LightControl::adjustToTarget() {
static unsigned long lastAdjustTime = 0;
const unsigned long adjustInterval = 300; // 每300ms调节一次
unsigned long currentTime = millis();
if (currentTime - lastAdjustTime < adjustInterval) {
return; // 还没到调节时间
}
const float tolerance = 100.0f; // 容许误差范围±100 lux
float currentLight = getCurrentLight();
float res = targetLightLevel - currentLight;
if (abs(res) <= tolerance) {
// 已达到目标,但不退出,继续监控
lastAdjustTime = currentTime;
return;
}
int lastWiperValue = digitalPot.getWiper();
if (res > 0) {
// 需要增加亮度 -> 增加电位器阻值
if (lastWiperValue < 127) {
lastWiperValue++;
digitalPot.setWiper(lastWiperValue);
Serial.printf("Auto: Current light: %.0f, Target: %.0f, Wiper: %d\n", currentLight, targetLightLevel, lastWiperValue);
}
} else if (res < 0) {
// 需要减少亮度 -> 减少电位器阻值
if (lastWiperValue > 0) {
lastWiperValue--;
digitalPot.setWiper(lastWiperValue);
Serial.printf("Auto: Current light: %.0f, Target: %.0f, Wiper: %d\n", currentLight, targetLightLevel, lastWiperValue);
}
}
lastAdjustTime = currentTime;
}
void LightControl::runUntilTargetReached(float target, int maxAttempts) {
// 保留原有函数,但现在主要用于设置目标值
setTargetLight(target);
Serial.printf("Target light set to: %.0f\n", target);
// 可选:立即进行一次快速调节
const float tolerance = 100.0f;
float currentLight;
float res;
int attempt = 0;
const int max_retries = min(maxAttempts, 10); // 限制快速调节次数
do {
currentLight = getCurrentLight();
res = target - currentLight;
if (abs(res) <= tolerance) {
Serial.println("Initial target reached.");
break;
}
int lastWiperValue = digitalPot.getWiper();
if (res > 0) {
if (lastWiperValue <= 127) {
lastWiperValue++;
}
} else if (res < 0) {
if (lastWiperValue > 0) {
lastWiperValue--;
}
}
digitalPot.setWiper(lastWiperValue);
Serial.printf("Quick adjust: Current light: %.0f, Target: %.0f, Wiper: %d\n", currentLight, target, lastWiperValue);
delay(200);
attempt++;
if (attempt >= max_retries) {
Serial.println("Quick adjust completed, continuing with auto mode.");
break;
}
} while (true);
}