#define rLedPin 6 //RGB-LED引脚R
#define gLedPin 5 //RGB-LED引脚G
#define bLedPin 3 //RGB-LED引脚B
#define irSensorPin 8 //红外人体感应模块信号输出
#define lightSensorPin A0 //光敏电阻分压电路信号输出
int ledR = 0; //R Led 亮度 (请勿改变数值)
int ledG = 0; //G Led 亮度 (请勿改变数值)
int ledB = 0; //B Led 亮度 (请勿改变数值)
bool irReading; //红外人体感应模块输出
int lightReading; //光敏电阻分压电路信号输出
//用户可以通过变量 maxRVal、maxGVal、maxBVal 自定义RGB-LED颜色
int maxRVal = 125; //夜灯R LED最大亮度 (允许数值:0 - 255)
int maxGVal = 200; //夜灯G LED最大亮度 (允许数值:0 - 255)
int maxBVal = 33; //夜灯B LED最大亮度 (允许数值:0 - 255)
int minRVal = 39; //夜灯呼吸时R LED最小亮度 (允许数值:0 - 255)
int minGVal = 95; //夜灯呼吸时G LED最小亮度 (允许数值:0 - 255)
int minBVal = 11; //夜灯呼吸时B LED最小亮度 (允许数值:0 - 255)
int breathStep = 5; //呼吸起伏速度 数值越大 速度越快
int breathStepDelay = 18; //呼吸起伏速度延迟 数值越大 起伏速度越慢
bool breatheOnOff = 0; //小夜灯呼吸状态
//breatheOnOff = 1 开启呼吸灯模式
//breatheOnOff = 0 关闭呼吸灯模式
bool onOffState; //小夜灯开关状态
bool debugOn = 1;
/*
* Arduino在控制LED亮度变化时,对于时间的要求很苛刻。
* 每一次Arduino通过串口监视器输出信息时都会让Arduino短暂停顿
* 这些短暂停顿会影响小夜灯的渐明渐暗效果。
* 因此建议在程序开发时令debugOn = 1,以便于观察Arduino
* 的工作状态并作出必要的修改。
* 但是在正常工作时,建议将debugOn = 0, 从而确保Arduino
* 的最佳工作效果。
*
*/
void setup() {
//设置引脚为相应工作模式
pinMode(rLedPin, OUTPUT);
pinMode(gLedPin, OUTPUT);
pinMode(bLedPin, OUTPUT);
pinMode(irSensorPin, INPUT);
if(debugOn){
Serial.begin(9600);
Serial.println("Welcome to Taichi-Maker RGB Led Night-Light.");
}
//检测是否LED亮度参数符合程序要求(min数值小于等于 max数值)
if (minRVal > maxRVal || minGVal > maxGVal || minBVal > maxBVal) {
while(true){ //如果出现数值设置问题,持续闪烁红灯
analogWrite(rLedPin, 255);
delay(500);
analogWrite(rLedPin, 0);
delay(500);
Serial.begin(9600);
Serial.println("Bad LED Settings!!!");
}
}
}
void loop() {
irReading = digitalRead(irSensorPin); //读取红外人体感应模块
lightReading = 1023 - analogRead(lightSensorPin); //读取光敏电阻分压电路信号输出
if(irReading == HIGH && lightReading <= 512){ //如感应到人且亮度达到需照明程度
if (onOffState == 0) fadeUp(maxRVal, maxGVal, maxBVal); //点亮小夜灯照明
onOffState = 1; //告知Arduino小夜灯被点亮了
if (breatheOnOff == 1)ledBreathe();
} else { //如未感应到人且亮度未达到需照明程度
if (onOffState == 1) fadeDown(0, 0, 0); //保持小夜灯熄灭
onOffState = 0; //告知Arduino小夜灯被熄灭了
}
//通过串口监视器实时输出各个传感器检测的数据结果
//可用于调试小夜灯工作参数使用
if(debugOn){
Serial.println("");
Serial.println("===========================");
Serial.print("irReading = "); Serial.println(irReading);
Serial.print("lightReading = "); Serial.println(lightReading);
Serial.println("===========================");
delay(500);
}
}
void fadeUp(int rTopVal, int gTopVal, int bTopVal){
while(ledR < rTopVal || ledG < gTopVal || ledB < bTopVal){
if (ledR+breathStep < rTopVal ) {
ledR+=breathStep ;
analogWrite(rLedPin, ledR);
} else {
ledR = rTopVal ;
analogWrite(rLedPin, ledR);
}
if (ledG + breathStep < gTopVal) {
ledG+=breathStep;
analogWrite(gLedPin, ledG);
} else {
ledG = gTopVal ;
analogWrite(gLedPin, ledG);
}
if (ledB + breathStep < bTopVal) {
ledB+=breathStep ;
analogWrite(bLedPin, ledB);
} else {
ledB = bTopVal ;
analogWrite(bLedPin, ledB);
}
delay(breathStepDelay);
if (debugOn){
Serial.println("================");
Serial.print("rVal = "); Serial.println(ledR);
Serial.print("gVal = "); Serial.println(ledG);
Serial.print("bVal = "); Serial.println(ledB);
Serial.println("================");
}
}
}
void fadeDown(int rBottomVal, int gBottomVal, int bBottomVal){
while(ledR > rBottomVal || ledG > gBottomVal || ledB > bBottomVal){
if (ledR-breathStep > rBottomVal) {
ledR-=breathStep;
analogWrite(rLedPin, ledR);
} else {
ledR = rBottomVal;
analogWrite(rLedPin, ledR);
}
if (ledG-breathStep > gBottomVal) {
ledG-=breathStep ;
analogWrite(gLedPin, ledG);
} else {
ledG = gBottomVal;
analogWrite(gLedPin, ledG);
}
if (ledB-breathStep > bBottomVal) {
ledB-=breathStep ;
analogWrite(bLedPin, ledB);
} else {
ledB = bBottomVal;
analogWrite(bLedPin, ledB);
}
delay(breathStepDelay);
if (debugOn){
Serial.println("================");
Serial.print("rVal = "); Serial.println(ledR);
Serial.print("gVal = "); Serial.println(ledG);
Serial.print("bVal = "); Serial.println(ledB);
Serial.println("================");
}
}
}
void ledBreathe(){
//亮度先降低
fadeDown(minRVal, minGVal, minBVal);
//亮度再提高
fadeUp(maxRVal, maxGVal, maxBVal);
}