Introduction
This article will describe how to build your own motion detector using an ESP8266 + HC-SR501 (PIR) and let it communicate with Domoticz. The purpose of this device is to serve as an alarm device.
One of the goals to achieve is that the motion device must use very little power. So it can run for a very long time on one battery. To achieve this the Deep Sleep mode of the ESP8266 needs to be used.
The functionality is simple only when motion is detected a message will be send to the Domoticz device.
*UPDATE: There is also an advanced version available. See: Advanced motion detector with ESP8266 and HC-SR501
Step 1: Designing the trigger electronics
The ESP8266 will have only one simple task. When it awakes it needs to send a message to the Domoticz device that motion has been detected when that is completed it needs to enter deep sleep again. The ESP8266 will not send a message when the motion has stopped. The trigger mechanism will be build to serve as an alarm device.
The output on the PIR will be set to high when motion is detected. As long as there is motion it will remain high. Setting for the PIR are:
- Repeat Trigger (as long as there is motion, the output will be kept high)
- Time delay at maximum
The signal from the PIR cannot directly be connected to the ESP8266 reset port. The reset port requires a short negative pulse to reset. For this we need a so called "Monostable Flip Flop" to create a short negative pulse to reset the ESP8266.
The circuit is simulated using: http://www.falstad.com/circuit/circuitjs.html
Code used:
$ 1 0.000001 19.867427341514983 69 5 50
r 336 352 336 448 0 47000
g 336 448 336 480 0
w 528 272 336 272 0
w 528 352 624 352 2
d 176 272 336 272 1 0.805904783
r 336 352 432 352 0 47000
w 528 272 528 352 0
I 176 352 272 352 0 0.5 3.3
I 432 352 528 352 0 0.5 3.3
I 96 352 176 352 0 0.5 3.3
w 176 352 176 272 0
c 272 352 336 352 0 1e-7 0.001
x -144 332 50 335 4 16 Output\sPIR\sto\sinput\sInverter
x 565 380 760 383 4 16 Output\sto\sESP8266\sRESET
x 567 403 787 406 4 12 Do\snot\suse\sGPIO16\s(else\sit\swill\snot\swork)
L 96 352 48 352 0 0 false 3.3 0
x 108 400 154 403 4 12 74HC14
o 15 64 0 4099 5 0.00009765625 0 2 15 3
o 3 64 0 4099 5 0.00009765625 0 2 3 3
Step 2: Setting up Domoticz
Configuring Domoticz is not so difficult.
- Create a new virtual hardware device. Goto Setup > Hardware
Choose a name and select type "Dummy (....)" and press Add. - Next "Create Virtual Sensors". You need to make two: "Switch" and "Voltage".
- When done in Setup > Devices you will see:
The "Idx" value is important, this needs to be added/updated in the ESP8266 code below.
Step 3: The ESP8266 code
/* PIR Motion Detection with deep-sleep mode */
ADC_MODE(ADC_VCC); //vcc read
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
// WiFi credentials & Domoticz API IDX.
const char* WIFI_SSID = "<YOUR_WIFI_SSID>";
const char* WIFI_PASS = "<YOUR_WIFI_PASS>";
const char* DOMOTICZ_SRV = "http://192.168.123.100:8080";
const char* DOMOTICZ_SWITCH_IDX = "45";
const char* DOMOTICZ_VOLT_IDX = "22";
void setup() {
HTTPClient http; // HTTP object
String api; // Holds full API string for Domoticz
int httpCode; // Return HTTP code
String response; // Response from HTTP GET request
float vdd; // Internal voltage
String s_vdd; // Internal voltage (formatted as string)
Serial.begin(115200);
Serial.setTimeout(2000);
while (!Serial) { } // Wait for serial to initialize.
Serial.println("");
Serial.println("-------------------------------------");
Serial.println("PIR Motion Detection Firmware!");
Serial.println("-------------------------------------");
// Connect to Wifi.
Serial.print("Connecting to ");
Serial.print(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
// Check to see if
if (WiFi.status() == WL_CONNECT_FAILED) {
Serial.println("");
Serial.println("Failed to connect to WiFi. Please verify credentials!");
delay(10000);
} else {
delay(500);
Serial.print(".");
}
}
Serial.println("");
Serial.print("WiFi connected with IP address: ");
Serial.println(WiFi.localIP());
// Send post request to Domoticz
Serial.println("");
Serial.println("Sending On signal to Domoticz.");
//Build API command
api = DOMOTICZ_SRV;
api += "/json.htm?type=command¶m=switchlight&idx=";
api += DOMOTICZ_SWITCH_IDX;
api += "&switchcmd=On";
http.begin(api); //Specify request destination
httpCode = http.GET(); //Send the request and set return code
Serial.print("Return code: ");
Serial.println(httpCode);
if (httpCode > 0) { //Check the returning code
response = http.getString(); //Get the request response
Serial.println("Response:");
Serial.println(response);
}
http.end(); //Close connection
delay(200);
Serial.print("Sending voltage to Domoticz: ");
vdd = ESP.getVcc() / 1024.0f;
s_vdd = String(vdd, 3);
Serial.println(s_vdd);
api = DOMOTICZ_SRV;
api += "/json.htm?type=command¶m=udevice&idx=";
api += DOMOTICZ_VOLT_IDX;
api += "&nvalue=0&svalue=";
api += s_vdd;
http.begin(api); //Specify request destination
httpCode = http.GET(); //Send the request and set return code
Serial.print("Return code: ");
Serial.println(httpCode);
if (httpCode > 0) { //Check the returning code
response = http.getString(); //Get the request response
Serial.println("Response:");
Serial.println(response);
}
http.end(); //Close connection
Serial.println("");
Serial.println("Going into deep sleep!");
ESP.deepSleep(0); // forever
}
void loop() {
// Never reached!
}
When there is motion detected, the ESP8266 is awoken. It switch on command and the voltage is send to the Domoticz server.
The first prototype: