ashish_8284
Published

Smart Switch with Motion Detection Using an ESP-12F

ESP-12F-based smart switch for two relays and motion detection. Two-way operation hard wired + Android app. Voice control also possible.

IntermediateFull instructions providedOver 1 day3,131
Smart Switch with Motion Detection Using an ESP-12F

Things used in this project

Hardware components

ESP8266 ESP-12E
Espressif ESP8266 ESP-12E
I have used ESP 12 F with 4MB flesh memory
×1
Raspberry Pi 3 Model B
Raspberry Pi 3 Model B
i have used Raspberry PI 3B+
×1
Optocoupler, Transistor Output
Optocoupler, Transistor Output
PC817 opcocoupler
×1
Grove - 4-Channel SPDT Relay
Seeed Studio Grove - 4-Channel SPDT Relay
×1
Pushbutton switch 12mm
SparkFun Pushbutton switch 12mm
×1
HIDIOT HI-LINK SMPS 230VAC - 5VDC 3W
×1
Voltage Regulator 5VDC to 3.3VDC
×1
Prototype PCB
×1

Software apps and online services

MQTT DASH
Raspbian
Raspberry Pi Raspbian
Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
Helping Hand Tool, with Magnifying Glass
Helping Hand Tool, with Magnifying Glass

Story

Read more

Schematics

PCB circuit diagram

PCB circuit. Relayboard is seprate.

Code

Smart Switch

Arduino
This code can used as it is. only Wifi setting need to be changed and MQTT broker setting need to be changed. For more detail visit youtube video. almost all line of code is commented for easy undestanding.
//XXXXX Flow diagram XXXXXX
//Include Library
//Variable dcleration
//Setup
  //Serial port initalised
  //Inputs & Outputs Setup
  //Outputs initialised
  //Reading initial input values & store in placeholder
  //Setup WIFI & connectin to WIFI network
  //Connecting MQTT server
//LOOP
      //Checking MQTT connectivity & reconnect if not connected
      //Checking Switch01 input & call funciton for relay 01
      //Checking Switch02 input & call funciton for relay 02
      //Checking PIR input & call function for trun on or or relay 02
      //Checking MQTT message & turn on/off relay accordingly
      

//Library Include
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// Update these with values suitable for your network
const char* ssid = "xxxxxxxx";
const char* password = "xxxxxxxx";
const char* mqtt_server = "192.168.1.100";
const char* mqttUser = "xxxxxxx"; //in case you dont set MQTT username & Password comment this line
const char* mqttPassword = "xxxxxxxx"; //in case you dont set MQTT username & Password comment this line
//Output defination
byte Switch_01 = 4 ; // Input pin for switch 01
byte Switch_02 = 5 ; // Input pin for switch 01
byte PIR_01  = 14 ; // Input pin for PIR sernsor deetection
//Input defination
byte Rly_1 = 12 ; // Output pin for Relay 01
byte Rly_2 = 13 ; // Output pim for Relay 02
byte Sts_led  = 16  ;
//Input Bit Status
byte Switch_01_sts;
byte Switch_02_sts;
byte Pir_01_sts;
//Input debounse delay
unsigned long Switch_01_dly;
unsigned long Switch_02_dly;
unsigned long Pir_on_dly;
unsigned long Pir_off_dly;
//Output Place Holder
byte Rly_01_sts;
byte Rly_02_sts;
//Wifi Client instance declaration
WiFiClient espClient3;
PubSubClient client(espClient3);
//Generic Variables
long lastMsg = 0;
char msg[50];
long value ;
void setup() {
  //Output Setup
  pinMode ( Rly_1  , OUTPUT  );
  pinMode ( Rly_2  , OUTPUT  );
  pinMode ( LED_BUILTIN , OUTPUT );
  //Output initialised
  digitalWrite ( Rly_1  , HIGH );
  digitalWrite ( Rly_2 , HIGH );
  //Input Setup
  pinMode ( Switch_01 , INPUT  );//Internal Pullup not used as hardware pullup implemented in PCB
  pinMode ( Switch_02 , INPUT  );// Internal Pullup not used as hardware pullup implemented in PCB
  pinMode ( PIR_01    , INPUT  );// Internal Pullup not used as hardware pullup implemented in PCB
  //Initialise Serial Port & read input status
  Serial.begin(115200 );
  Serial.println();
  //Storing initial state of inputs
  Switch_01_sts = digitalRead(Switch_01);
  Switch_02_sts = digitalRead(Switch_02);
  Pir_01_sts = digitalRead(PIR_01);
  //Printing initial state of inputs
  Serial.print  ("Switch_01_sts  "); Serial.println    ( Switch_01_sts  );
  Serial.print  ("Switch_02_sts "); Serial.println    ( Switch_02_sts );
  Serial.print  ("Pir_sts  "); Serial.println    ( Pir_01_sts  );
  //Setup WiFI
  setup_wifi(); //Call of Wifi setup function
  //MQTT client setup
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  //Read millis value & store in to debounce place holder
  Switch_01_dly = millis();
  Switch_02_dly = millis();
  Pir_on_dly = millis();
  Pir_off_dly = millis();
}
void setup_wifi() {//Connecting WIFI network
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  //WIFI connection begin with SSID & Password
  WiFi.begin(ssid, password);
  IPAddress ip(192, 168, 1, 103);//Fix ip assigned to ESP12F , For each new module we have to change this address.
  IPAddress gateway(192, 168, 1, 1);//Gateway setting of ESP12F & it will remain same for all other modules on same network
  IPAddress subnet(255, 255, 255, 0); //Subnet mask , it will remain same for all other modules on same network
  WiFi.config(ip, gateway, subnet); //Assign Above three setting to ESP12F module
  //Connection initilased
  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));//Led blinks untill connection not established
    delay(200);
    Serial.print(".");
  }
  //Printing connection status after successful connection of ESP12F
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) { //This function read MQTT messages & convert its payload into integer value
  String payloadval_str;
  int payloadval_int, payload_pwm;
  for (int i = 0; i < length; i++) payloadval_str += (char)payload[i];
  payloadval_int = payloadval_str.toInt();
  if (payloadval_int == 100) payload_pwm = 1;
  else if (payloadval_int == 0) payload_pwm = 0;
  else payload_pwm = 0;
  recieved_cmd(topic, payloadval_int, payload_pwm);//Checking Recivied MQTT command & its payload & generate outputs accordingly.
}
void reconnect() { // This function provide connectivity with MQTT server
  if (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("UID_1", mqttUser, mqttPassword ))//Different UID required for each module other wise we will face problem. Comment this line if you have un secure MQTT broker.
    //if (client.connect("UID_1", mqttUser, mqttPassword ))//If MQTT broker USER name & Password not set then uncomment this line & Comment above line.
    {
      Serial.println("connected");
      digitalWrite(Sts_led, !digitalRead(Sts_led));
      delay(50);
      digitalWrite(Sts_led, !digitalRead(Sts_led));
      delay(50);
      digitalWrite(Sts_led, !digitalRead(Sts_led));
      delay(200);
    }
    else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
    }
  }
  Serial.println("Pub start");//MQTT connection establihsed
}
void loop() {
//Checking MQTT connectivity & reconnect if connection failed  
  if (!client.connected()) {//checking if MQTT server connection status
    reconnect();// if MQTT server not connected then try to reconnect
  }
  else client.loop();
//Switch 1 input chekcing
  if (digitalRead(Switch_01) != Switch_01_sts) { //Switch_01 input changed/toggled deetection
    Switch_01_call();
  }
  else Switch_01_dly = millis();//Switch_01 on delay time rollout if not activated deetected
//Switch 2 input checking 
  if (digitalRead(Switch_02) != Switch_02_sts) {//Switch_02 input changed/toggled deetection
    Switch_02_call();
  }
  else Switch_02_dly = millis();//Switch_02 on delay roolout if no activity deetected
//PIR input checking  
  if (!digitalRead(PIR_01) &  Pir_01_sts) 
    Pir_01_on_call();//PIR deetected motion
  else Pir_on_dly = millis();//PIR_01 on delay timer rollout if no motion deetected
  if ( digitalRead(PIR_01) & !Pir_01_sts) 
    Pir_01_off_call();//PIR not deetected motion
  else Pir_off_dly = millis();//PIR_01 off delay time rollout if no motion deetected
}
void recieved_cmd(String in_str, int in_int1, int in_int2) { // in_str :- Topic string ,in_int1 :- Payload Value 0 to 100, in_int2 :- Mapped Payload value 0 to 1
  if (in_str == "ashish/bed1/Washroom/sb/cmd/Switch_01") {
    Serial.print("Switch_01 >> Rly_01_sts "); Serial.println(in_int1);
    Rly_01_sts = in_int2;
    snprintf (msg, 5, "#%ld", in_int1);
    client.publish("ashish/bed1/Washroom/sb/sts/Switch_01", msg);
    Serial.print("Switch_01 status "); Serial.println(Switch_01_sts);
  }
  if (in_str == "ashish/bed1/Washroom/sb/cmd/Switch_02") {
    Serial.print("Switch_02 >> Rly_02_sts "); Serial.println(in_int1);
    Rly_02_sts = in_int2;
    snprintf (msg, 5, "#%ld", in_int1);
    client.publish("ashish/bed1/Washroom/sb/sts/Switch_02", msg);
    Serial.print("Switch_02 status "); Serial.println(Switch_02_sts);
  }
  output_writ();
}
void Switch_01_call() { //Switch_01 toggle funciton. if Input pin state cahgned mor ethen 200  milli second then output toggled
  if (millis() - Switch_01_dly > 200) { //Debounce filteration time
    Switch_01_sts = ! Switch_01_sts;
    Rly_01_sts = !Rly_01_sts;
    if (Rly_01_sts == 1) client.publish("ashish/bed1/Washroom/sb/sts/Switch_01", "100");
    if (Rly_01_sts == 0) client.publish("ashish/bed1/Washroom/sb/sts/Switch_01", "0");
    Serial.print("Switch_01 Status "); Serial.println(Switch_01_sts);
    output_writ();
  }
}
void Switch_02_call() { //Switch_01 toggle funciton. if Input pin state cahgned mor ethen 200  milli second then output toggled
  if (millis() - Switch_02_dly > 200) {//Debounce Fileration time
    Switch_02_sts = ! Switch_02_sts;
    Rly_02_sts = !Rly_02_sts;
    if (Rly_02_sts == 1) client.publish("ashish/bed1/Washroom/sb/sts/Switch_02", "100");
    if (Rly_02_sts == 0) client.publish("ashish/bed1/Washroom/sb/sts/Switch_02", "0");
    Serial.print("Switch_02 Status "); Serial.println(Switch_02_sts);
    output_writ();
  }
}
void Pir_01_on_call() { //If PIR sensor activated then Relay2 started after 200 milli seconds
  if (millis() - Pir_on_dly > 200) {
    client.publish("ashish/bed1/Washroom/sb/sts/PIR", "100");
    Serial.print("Switch_02 >PIR> Motion "); Serial.println("1");
    Pir_01_sts = LOW;
    Rly_02_sts = 1;
    client.publish("ashish/bed1/Washroom/sb/sts/Switch_02", "100");
    output_writ();
  }
}
void Pir_01_off_call() { //If PIR sensor deactivated then Relay2 stopped after 3 second
  if (millis() - Pir_off_dly > 3000) {
    client.publish("ashish/bed1/Washroom/sb/sts/PIR", "0");
    Serial.print("Switch_02 >PIR> Motion "); Serial.println("0");
    Pir_01_sts = HIGH;
    Rly_02_sts = 0;
    output_writ();
    client.publish("ashish/bed1/Washroom/sb/sts/Switch_02", "0");
  }
}
void output_writ() {
  digitalWrite(Rly_1, !Rly_01_sts);
  digitalWrite(Rly_2, !Rly_02_sts);
  Serial.print(", Relay_01/02 Status "); Serial.print(Rly_01_sts); Serial.print(" / "); Serial.println(Rly_02_sts);
}

Credits

ashish_8284

ashish_8284

10 projects • 34 followers

Comments