#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);
}
$abcdeabcde151015202530354045505560fghijfghij