/*
程序名称:Light-activated_Lamp
描述:根据光敏电阻,调节LED灯亮度,要求LED灯亮度变化平缓,不会出现亮度抖动
1. 所需硬件:
- Arduino Uno开发板 *1
- 面包板 *1
- 杜邦线 *若干
- 光敏电阻模块 *1
- LED *1
- 150Ω电阻 *1
作者:CT-LAB
*/
/*--------------------------------------------------------------------------1--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------本程序所引用库--------------------------------------------------------------------*/
// 无
/*--------------------------------------------------------------------------2--------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------声明定义-----------------------------------------------------------------------*/
/*****************************< 常量声明 >*****************************/
#define DARK_LDR 800 // 暗环境下的LDR数值
#define BRIGHT_LDR 200 // 亮环境下的LDR数值
/*****************************< 引脚定义 >*****************************/
const int LED_Pin = 3; // 设置LED引脚
const int LDR_Pin = A0; // 光敏电阻模块信号脚
/*****************************< 变量定义 >*****************************/
// 无
/*****************************< 对象声明 >*****************************/
// 无
/*****************************< 函数声明 >*****************************/
// 无
/*--------------------------------------------------------------------------3--------------------------------------------------------------------------*/
/*-------------------------------------------------------------------setup()程序初始化------------------------------------------------------------------*/
void setup() {
/******************************< 启动串口通讯 >******************************/
Serial.begin(9600); // 初始化串口通信,并设置波特率为9600
/******************************< 设置引脚模式 >******************************/
pinMode(LED_Pin, OUTPUT); // 设置引脚为输出模式
}
/*--------------------------------------------------------------------------4--------------------------------------------------------------------------*/
/*-------------------------------------------------------------------loop()基础循环体-------------------------------------------------------------------*/
void loop() {
int LDR_Value = analogRead(LDR_Pin); // 读取LDR_Pin的输入
float Smooth_Value = filter_Value(LDR_Value, 0.1); // 使用指数移动平均进行平滑处理
int LED_Brightness = linear_Map(Smooth_Value, BRIGHT_LDR, DARK_LDR, 0, 255); // 将平滑后的值映射到0到255之间,用于PWM输出
analogWrite(LED_Pin, LED_Brightness); // 设置LED灯亮度
Serial.print(LDR_Value); // 打印原始光敏电阻读数
Serial.print(",");
Serial.print(Smooth_Value); // 打印滤波后光敏电阻读数
Serial.print(",");
Serial.println(LED_Brightness); // 打印出LED亮度
delay(1); // 延迟以确保稳定性
}
/*--------------------------------------------------------------------------5--------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------函数定义-----------------------------------------------------------------------*/
/*****************************************************************************************************
* 函数:filter_Value(float Value, float Smoothing_Factor)
* 作用:使用指数移动平均算法对输入值进行平滑处理
* 参数:
* - Value: 当前测量值
* - Smoothing_Factor: 平滑因子(范围:0.01 - 1)
* 返回值:平滑处理后的值
*****************************************************************************************************/
float filter_Value(float Value, float Smoothing_Factor) {
static float Last_Value = 0.0; // 静态局部变量,保留上一次的测距数据
// 限制滤波因子,最小为0.01,最大为1
if (Smoothing_Factor <= 0) Smoothing_Factor = 0.01;
if (Smoothing_Factor > 1) Smoothing_Factor = 1;
// 在首次调用时初始化 Last_Value
if (Last_Value == 0.0) {
Last_Value = Value;
}
// 使用指数移动平均算法进行平滑处理
float Smoothed_Value = (Value * Smoothing_Factor) + (Last_Value * (1.0 - Smoothing_Factor));
// 更新上一次的测距数据
Last_Value = Smoothed_Value;
return Smoothed_Value; // 返回平滑处理后的值
}
/*****************************************************************************************************
* 函数:linear_Map(float Value, float In_Left, float In_Right, float Out_Left, float Out_Right)
* 作用:将输入范围内的值线性映射到输出范围内
* 参数:
* - Value: 需要映射的值
* - In_Left: 输入范围的左极值
* - In_Right: 输入范围的右极值
* - Out_Left: 输出范围的左极值
* - Out_Right: 输出范围的右极值
* 返回值:映射后的值
*****************************************************************************************************/
float linear_Map(float Value, float In_Left, float In_Right, float Out_Left, float Out_Right) {
// 使用 constrain 函数限制输入范围
if (In_Left > In_Right) {
Value = constrain(Value, In_Right, In_Left);
} else {
Value = constrain(Value, In_Left, In_Right);
}
// 计算映射值
return Out_Left + (Out_Right - Out_Left) * (Value - In_Left) / (In_Right - In_Left);
}