Introduction: Smart Switch With Motin Deetection

About: Learning & discovering new things can enrich humanity. Technology can definitely change the world. I like to search problems so that I can find solutions. I don't realise my passion about technology during my …
  • Smart Switch using ESP12F Module for 2 Relay control + Motion deetection using PIR sensor. Motion deetection is selectable. if its enabled then Relay 2 will operate based on PIR sensor. PIR sensor enable is possible using MQTT message.
  • System Overview :-
    • Raspberry PI act as MQTT broker & it connects with Local wireless network using Router.
    • ESP running with MQTT PUBSUB library and connect with same locak wire less network and subscribed to three topics
      1. for Relay 01
      2. for Relay 02
      3. for enable or disable motion sensor functionaliity.
      4. in any hard wired switching ESP will publish stats of relay on respective topic.
  • TWO Hard wired switch connected with ESP input. ESP monitor state of each DI and switch relay accordingly.
  • Motion sensor(PIR) connected with one DI of esp. if motion sensor function is enabled(From MQTT message) then Relay02 will work as per motion sensor.
    1. if motion deetected Relay 02 will turned on.
    2. if motion deetection input is low and Relay02 is On then after 60 seconds Relay will trrned off automatically.
  • MQTT DASH app installed on mobile and mobile is connected with same wifi network on which mqtt broker(PI) is connected.
    • From mobile we send 0 or 100 value on same topic on which ESP is subscribed.
    • whenever mobile published value, accoding that value esp turn on or off relay.
  • Design Consept :- PCB made to install in OLD switch board without changeing any hardware like Switches or wiring scheame so it is easy to install this in any swithc board.
  • Design Basic:-This switch can operte Two relay. operation can be pissible by two method, 1st is by hard wired. 2nd method is using MQTT DASH android app.. Relay 02 can operte using PIR motion sensor.
  • ESP12F wiring:- ESP12F module is 3.3V operated & i used 5VDC for field wiring, so to protect ESP i have used PC817 Opto coupler which convert 5VDC to 3.3VDC visa-versa.
  • ESP12F To relay board wiring :- Relay board is 5 VDC operated so i have modified its circuit. i remove LED of each relay and sorted its two pin. after that each relay works fine with 3.3VDC. Relay coil is 5VDC rated & for that one pin header privided.


  • 1:- 230V to 5 VDC SMPS
  • 2:- 5VDC to 3.3 VDC voltage regulator
  • 3:- ESP12F
  • 4:-Opto couplers PC817
  • 5:- Passiv componants :-Resistors,Capacitors
  • 6:- Male & Female Pin headers & screw terminal
  • 7:- Push Buttons
  • 8:- 2 Chanel Relay board (5VDC operated)
  • 9:- Raspberry PI3B+
  • 10:- 16 GB Class 10 SDcard
  • 11:- HDMI to VGA converter
  • 12:- 5VDC 2.5 Amp. power supply for Raspberry PI
  • 13:- PIR sensor

Step 1: Making of PCB

Images of PCB > Front & Back view


  • 1:- 230V to 5 VDC SMPS
  • 2:- 5VDC to 3.3 VDC voltage regulator
  • 3:- ESP12F
  • 4:-Opto couplers
  • 5:- Passiv componants :-Resistors,Capacitors
  • 6:- Male & Female Pin headers & screw terminal
  • 7:- Push Buttons

based upon Circuit diagram All componant solderd on PCB.

Step 2: ESP Module PINOUT Goude

ALL About ESP12F :- I have made all in one document for ESP12F which shows each pin detail and function of each pin. This PIN guide is suitabel for all ESP8266 modules.

Step 3: PIN Header Detail

For ease of field connection and relay board connection seprate pin headers are provided on PCB

Detail of Field Connection :- to wired this pcb in field various pin headers are privided.

  1. X1 :- for to connect PIR sensor.
  2. X2:- to connect switch 01.
  3. X3:- to connect switch 02.
  4. X4:- to Program ESP module.
  5. X5:- to connect relay board.
  6. X6:- to proive 5VDC to relay board.

After completion of PCB making and checking of all componant properly download coad in to esp using connector X4.

We have to connect FTDI as per below connection


  • TX RX
  • RX TX
  • Gnd Gnd
  • 3.3V 3.3V
  • How to put ESP in Flesh mode:- Two method
    1. Press Flesh button before apply power to esp.
    2. Power up ESP(Connect ftdi in to USP of PC) then first press FLESH button the press & relese Reset pushbutton and after few second relesereles Flesh Button.

Now ESP is ready to flesh.

Step 4: Download Code in to ESP.

Code is as below.

  • in starting of code flow diagram of code is mentioned. and in code i have mentioned description in commect for easy under standign.this code is ready to used only 4 lines in code need to be changed.
    1. SSID of wifi network
    2. Password of Wifi network
    3. MQTT broker username
    4. MQTT broker password

Code :-

<p>//XXXXX Flow diagram XXXXXX<br>//Include Library
//Variable dcleration
  //Serial port initalised
  //Inputs & Outputs Setup
  //Outputs initialised
  //Reading initial input values & store in placeholder
  //Setup WIFI & connectin to WIFI network
  //Connecting MQTT server
      //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
      </p><p>//Library Include

// Update these with values suitable for your network
const char* ssid = "xxxxxxxx";
const char* password = "xxxxxxxx";
const char* mqtt_server = "";
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 );
  //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);
  //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
  // We start by connecting to a WiFi network
  Serial.print("Connecting to ");
  //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
  //Printing connection status after successful connection of ESP12F
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
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.
      digitalWrite(Sts_led, !digitalRead(Sts_led));
      digitalWrite(Sts_led, !digitalRead(Sts_led));
      digitalWrite(Sts_led, !digitalRead(Sts_led));
    else {
      Serial.print("failed, rc=");
      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
  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
  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);
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);
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);
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");
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;
    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);

Step 5: Raspberry PI Setup :-

Raspberry PI B3+ used. 16GB Scan disk SD card used with raspbian os.

  1. First download latest Raspbian from this link :-
  2. unzip download file and store it..
  3. to write image on SD card download Eatcher. download from:->>
  4. Run Etcher and select Raspbian image folder then select approprieate SD card and press Flesh button & wait till process completed.
  5. Then remove SD card and incert in Raspberry PI.
  6. to setup PI you required 5VDC 2.5A power supply(Original Raspberry pi power supply adaptor prefereds) HDMI to VGA converter ( in case HDMI monitor only HDMI Cable required) keyboard & mouce.
  7. After Powerup PI, connect it with internet via ethernet cable or Wifi.i used Wifi as i have Wifi routher running at my home.
  8. once Internet connected open terminal window and apply sudo apt-get update and hit enter.
  9. once update process completed apply sudo apt-get upgrade and hit enter,
  10. while prompet y/n hit Y and press enter & wait untill upgrade process completed.
  11. both of above process take minute or wile based on your internet connection.
  12. Installation of MOSQUITTO Broker:-Open terminal window and apply sudo apt install -y mosquitto mosquitto-clients and press enter.
  13. this will install two componant 1>Mosquitto broker 2> Mosquitto client.
  14. while system prompt Y/N press and hit enter and wait until process completed.

Checking of MQTT BROKER:-

To check MQTT Broker open Terminal window and apply mosquitto -v and hit enter. system will show version of mosquitto broker once you get responce as per below mention window apply hostname -I and press enter, system will respince with IP of mqtt broker(IP of PI) as per below mentioned image.

Step 6: Download MQTT DASH Android App

Android App:-

Open Google Play store and search for MQTT DASH app and install that app.

Link :-

Step 7: Add Connection in MQTT DASH App

Open Mqtt Dash and click + symbol at right top corner.

only two field requried Name :- "Any unique name you like" and enter IP address of mqtt broker.

Step 8: Checking MQTT DASH Connection With MQTT Broker

After creating new connection click on generated connection tab and if you get blank screen then connectin is successful & if your mobile is not on same network on which MQTT broker is running you get "connecting" message with running circle, in that case check your mobile is on same network on which Mqtt broker is running or not.

Step 9: Checking of MQTT Broker Connection

Create sample text publish field:- now add new entry field (Text) and enter topic "testTopic" and not requried any otehr settign to change.

enter any text and hit send button, if you get that text on raspberry pi terminal window then your mqtt connection is successful.

Step 10: Setup Final Setup for Switching Relay01 & Relay 02

Final Setup:- finally add two button, One for relay one and Second for Relay two. in topic field of both button we need to copy tipic text from Arduino Code.