Vadim
Published © GPL3+

Automatic Lighting of the Working Area in Kitchen

Controller is made on a popular Wi-Fi module such as NodeMCU, which is based on the powerful Espressif ESP8266 SoC.

IntermediateFull instructions provided8 hours2,863
Automatic Lighting of the Working Area in Kitchen

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
×1
PIR Motion Sensor (generic)
PIR Motion Sensor (generic)
×1
ESP8266 ESP-12E
Espressif ESP8266 ESP-12E
×1

Software apps and online services

Arduino IDE
Arduino IDE
Cayenne
myDevices Cayenne

Story

Read more

Schematics

Schematic diagram of the Controller on NodeMCU Version

PCB Gerber Files

PCB Project files for controller on NodeMCU

Code

Code snippet #1

Arduino
Defining virtual ports for data exchange with the Cayenne server.
#define VIRTUAL_PIN_0 V0   // Virtual PIN 0: LDR
#define VIRTUAL_PIN_1 V1   // Virtual PIN 1: Current PWM Value
#define VIRTUAL_PIN_2 V2   // Virtual PIN 2: "Enable-100%" Button state
#define VIRTUAL_PIN_3 V3   // Virtual PIN 3: DS18B20 temperature sensor

Code snippet #2

Arduino
Changing the state of the button on the Cayenne dashboard from a remote device.
if ((Cayenne_Button == 1) && (millis() - timeout_3 > interval_4))
{
//manual mode, 2 hour timer interval expired
    Cayenne_Button = 0;
    Cayenne.virtualWrite(V2, Cayenne_Button);  // button deactivation (write 0)
    timeout_3 = millis();                      // reset timer
    mode=3;                                    // return to automatic mode
}

Code snippet #3

Arduino
Cayenne dashboard Button processing.
CAYENNE_IN(V2)
{
  Cayenne_Button = getValue.asInt();
  if (Cayenne_Button == 1) {
    mode=2;
    Mode_Set();
  }
  else {
    mode=3;
    Mode_Set();
  }
}

Kitchen_Light_Controller_NodeMCU_ENG.ino

Arduino
// Controller for automatic lighting of the working area in the kitchen
// NodeMCU Version (ESP12-E)
// Operating principle:
// The sufficient level of lighting in the kitchen and motion is detected - the local lighting does not turn on
// The level of lighting in the kitchen - the average, motion is detected - gradually increase the brightness to 20%, start the timer for 3 minutes
// If for 40 seconds before the end of 3 minutes interval movement is detected - activates the backlight at 100%, run timer for 7 minutes, light level and movement monitoring
// If there is no movement - reduce the level to 20%, and then, after 3 minutes, if the motion not detected - gradually disable the backlight. If motion is detected again, increasing to 100%
// The level of lighting in the kitchen is low (night), motion is detected - turn on the backlight for 10%, start the timer for 3 minutes
// If for 40 seconds before the end of 3 minutes interval movement is detected - increase brightness to 50%, start the timer for 7 minutes. 
// If there is no movement - slowly reduce the level to 10%, a 3-minute hold, then turn off

// LDR connected to A7, Motion sensor connected to D2, PWM output - D5

// mode=1 - gradually increase the brightness to 20%, start the timer for 3 minutes
// mode=2 - gradually increase the brightness from 20% to 100%, start the timer for 7 minutes. Motion Detection reset this 7 min timer 
// mode=3 - gradually decrease the brightness from 100% to 20% (=mode 1)
// mode=4 - gradually increase the brightness to 10%, start the timer for 3 minutes (night).
// mode=5 - gradually increase the brightness from 10% to 50%, start the timer for 7 minutes . Motion Detection reset this 7 min timer
// mode=0 - turn off

//Additional functions
//IoT Device (Sensor Node) - DS18B20 temperature sensor connected to D4 NodeMCU
//Remote temperature monitoring, manual lighting control (on/Off) from mobile application or browser
//The ability to implement various notifications by email
//The ability to adding new automation functions

//#define CAYENNE_PRINT Serial  // Cayenne debug messages
//#define CAYENNE_DEBUG

#include "CayenneDefines.h"
#include "BlynkSimpleEsp8266.h"
#include "CayenneWiFiClient.h"
#include <OneWire.h>
#include <DallasTemperature.h>

#define Light_Sensor A0         //LDR connected to A0
#define Motion_Sensor D2        //motion sensor conneted      D2
#define PWM_Out D5              //D5 - PWM Out
#define Temp_Sensor D4          //DS18B20 conncted to D4

#define VIRTUAL_PIN_0 V0        // Virtual Pin 0: LDR
#define VIRTUAL_PIN_1 V1        // Virtual Pin 1: PWM current value
#define VIRTUAL_PIN_2 V2        // Virtual Pin 2: button status in Cayenne dashboard Enable.-100%
#define VIRTUAL_PIN_3 V3        // Virtual Pin 3: DS18B20- temperature sensor

OneWire oneWire(Temp_Sensor);
DallasTemperature sensors(&oneWire);

boolean Light_On;                                       //true if local lighting is on , false - if local lighting is on
byte mode;                                              //Current operation mode

// Cayenne token for NodeMCU
char token[] = "oss64ax86v";
// SSID and pass for you Wi-Fi
char ssid[] = "SSID";
char password[] = "pass";

int Cayenne_Button;                                   //Cayenne dashboard Button "Enable-100%"
int current_luminosity, previus_luminosity, PWM_Value;
unsigned long interval_1 = 1000;                      //1 s interval 
unsigned long interval_2 = 180000UL;                  //3 min interval
unsigned long interval_3 = 420000UL;                  //7 min interval
unsigned long interval_4 = 7200000UL;                 //2 hour interval for manual mode
unsigned long checkpoint_1 = 150000UL;                //checkpiont: before end of 3 min interval
unsigned long timeout_1;
unsigned long timeout_2;
unsigned long timeout_3;                              

void Mode_Set() {
  switch (mode) {
    case 0:
      for (PWM_Value; PWM_Value > -1; PWM_Value--) {
        analogWrite(PWM_Out, PWM_Value);                  //local lighting turning off 
        delay(10);
      }
      Light_On = false;                          //local lighting is off
      PWM_Value = 0;
      break;

    case 1:
      for (PWM_Value = 0; PWM_Value < 210; PWM_Value++) {
        analogWrite(PWM_Out, PWM_Value);                  //gradually increase the brightness to 20%
        delay(10);
      }
      Light_On = true;
      timeout_2 = millis();                     //start timer for mode 1 
      break;

    case 2:
      for (PWM_Value; PWM_Value < 1023; PWM_Value++) {
        analogWrite(PWM_Out, PWM_Value);                  //gradually increase the brightness to 100%
        delay(5);
      }
      Light_On = true;
      timeout_2 = millis();                     //start timer for mode 2 
      break;

    case 3:
      for (PWM_Value; PWM_Value > 210; PWM_Value--) {
        analogWrite(PWM_Out, PWM_Value);                  //gradually decrease the brightness from 100 to 20%
        delay(5);
      }
      Light_On = true;
      timeout_2 = millis();                     //start timer for mode 1
      mode = 1;                                 //after decreasing this is mode 1
      break;

    case 4:
      for (PWM_Value = 0; PWM_Value < 105; PWM_Value++) {
        analogWrite(PWM_Out, PWM_Value);                  //gradually decrease the brightness from 0 to 10%
        delay(10);
      }
      Light_On = true;
      timeout_2 = millis();                     //start timer for mode 4
      break;

    case 5:
      for (PWM_Value; PWM_Value < 515; PWM_Value++) {
        analogWrite(PWM_Out, PWM_Value);                  //radually decrease the brightness from 10% to 50%
        delay(10);
      }
      Light_On = true;
      timeout_2 = millis();                     
      break;
  }

}

CAYENNE_IN(V2)
{
//  CAYENNE_LOG("Got a value: %s", getValue.asStr());
  Cayenne_Button = getValue.asInt();
  if (Cayenne_Button == 1) {
    mode=2;
    Mode_Set();
  }
  else {
    mode=3;
    Mode_Set();
  }
}

CAYENNE_OUT(V0)                                                           //Lighting
{
  Cayenne.virtualWrite(V0, current_luminosity);
}

CAYENNE_OUT(V1)                                                           //Current PWM value (operation mode)
{
  Cayenne.virtualWrite(V1, PWM_Value);
}

CAYENNE_OUT(V3)                                                           //temperature
{
  sensors.requestTemperatures();
  Cayenne.virtualWrite(V3, sensors.getTempCByIndex(0) );
}

void LightingChange_Det () {
  current_luminosity = analogRead(Light_Sensor);
  if (Cayenne_Button == 0) {
    if ((current_luminosity < 150) && (current_luminosity - previus_luminosity > 40) && (Light_On == false)) {                //local lighting is off and turning on main Lighting
      mode = 1;
      Mode_Set();                                                                                     //turn local lighting On (day mode, step 1)
    }
    if ((current_luminosity - previus_luminosity > 40) && (Light_On == true) && (mode == 1)) {        //local lighting is on (day mode) and turning on main Lighting
      mode = 2;
      Mode_Set();                                                                                     //increasing brightness(day mode, step 2)
    }
    else if ((current_luminosity - previus_luminosity > 40) && (Light_On == true) && (mode == 4)) {  //local lighting is on (night mode) and turning on main Lighting
      mode = 5;
      Mode_Set();                                                                                    //increasing brightness(night mode, step 2)
    }
    previus_luminosity = current_luminosity;
    if ((current_luminosity > 110) && (Light_On == true)) {                                       //Sufficient light level on kitchen
      mode = 0;                                                                                   //local lighting turn off 
      Mode_Set();
    }
  }
}

void setup() {
  pinMode(Motion_Sensor, INPUT_PULLUP);
  analogWrite(PWM_Out, 0);
  previus_luminosity = analogRead(Light_Sensor);
  current_luminosity = analogRead(Light_Sensor);
  timeout_1 = millis();
  PWM_Value = 0;
  mode = 0;
//  Serial.begin(9600);

  Cayenne.begin(token, ssid, password);
}

void loop() {

  Cayenne.run();

  if (millis() - timeout_1 >= interval_1) {
    timeout_1 = millis();
    LightingChange_Det();
  }
  if (Cayenne_Button == 0) {                                                                                    //automatic mode

    if ((digitalRead(Motion_Sensor) == HIGH) && (current_luminosity < 110) && (current_luminosity > 15) && (Light_On == false)) { //motion detected, average lighting in kitchen, local lighting is off
      mode = 1;
      Mode_Set();
    }
    if ((mode == 1) && (millis() - timeout_2 > checkpoint_1) && (digitalRead(Motion_Sensor) == HIGH)) {         //at the end of 3 min interval (30 sec)
      mode = 2;                                                                                                 //if motion is detected, set mode 2
      Mode_Set();
    }
    else if ((mode == 1) && (millis() - timeout_2 > interval_2) && (digitalRead(Motion_Sensor) == LOW)) {       //if motion not detected, set mode 0
      mode = 0;
      Mode_Set();
    }

    if ((mode == 2) && (millis() - timeout_2 > interval_3)) {                                                   
      mode = 3;                                                                                                 //set mode 3 (100%->20%)
      Mode_Set();
    }
    else if ((mode == 2) && (digitalRead(Motion_Sensor) == HIGH)) {
      timeout_2 = millis();                                                                                     //reset 7 min timer if motion is detected
    }

    if ((mode == 0) && (current_luminosity >= 0) && (current_luminosity < 15) && (digitalRead(Motion_Sensor) == HIGH)) {       //night mode, set mode 4
      mode = 4;
      Mode_Set();
    }

    if ((mode == 4) && (millis() - timeout_2 > checkpoint_1) && (digitalRead(Motion_Sensor) == HIGH)) {         //night mode: at the end of 3 min interval (30 sec)
      mode = 5;                                                                                                 //night mode: if motion is detected, set mode 5
      Mode_Set();
    }
    else if ((mode == 4) && (millis() - timeout_2 > interval_2) && (digitalRead(Motion_Sensor) == LOW)) {       //if motion not detected, set mode 0
      mode = 0;
      Mode_Set();
    }

    if ((mode == 5) && (millis() - timeout_2 > interval_3)) {                                                  
      mode = 0;
      Serial.print("mode5->mode0");
      Mode_Set();
    }
    else if ((mode == 5) && (digitalRead(Motion_Sensor) == HIGH)) {
      timeout_2 = millis();                                                                                     //reset 7 min timer if motion is detected
    }
    timeout_3=millis();                                                                                         // 
  }

  if ((Cayenne_Button == 1) && (millis() - timeout_3 > interval_4)) {                                           //in manual mode
    Cayenne_Button = 0;
    Cayenne.virtualWrite(V2, Cayenne_Button);                                                                   //start 2 hour interval. After 2 hour returnt to automatic mode
    timeout_3 = millis();                                                                                       //and deactivation "Enable-100%" Button on Cayenne dashboard
    mode=3;                                                                                                     //Set mode 3
  }
  yield();

}

Credits

Vadim

Vadim

0 projects • 4 followers

Comments