PIR sensor - wake and sleep using CH_PD & thingspeak update.
Posted: Mon Aug 10, 2015 4:21 pm
Hi, welcome to my little project. (EDIT: as pointed out - this is power down & power up, not sleep & wake).
The idea was to create a battery powered PIR (or door contact) that would report when a room was entered or left, that could be ranomly moved around. First attempts that didn't power down the ESP8266-01 proved to be heavy on batteries. Following comments by "torntrousers" on another post it became apparent that:
A GPIO pin "high" could hold CH_PD high to keep the ESP awake & also "low" could power it down.
If the output from a PIR was connected via a diode to CH_PD it could wake an ESP.
The thingspeak side has been done many times.
The PIR is powered & active all the time. When the PIR detects motion it takes the output high, this powers CH_PD and wakes the ESP, it also takes GPIO 0 & GPIO 2 high, required for a normal boot. Once booted the ESP takes GPIO 0 high which maintains a high on CH_PD even if the PIR output resets to low. The diode prevents the PIR pulling CH_PD low. GPIO 2 being connected on the PIR side of the diode can detect the PIR state at all times.
Hi, temp link untill I sort dropbox. http://imgur.com/tHOaPzJ
The code. After boot set GPIO 0 high to keep the ESP awake. Setup WiFi. Connect to thingspeak & send a value of "1" to indicate that the PIR was activated. Read GPIO 2 looping round untill it becomes "0" (PIR not activated). Wait 20 seconds (sort of debounce & thingspeak can only be updated a maximum of every 15 seconds). Connect to thingspeak & send a "0" to indicate that the PIR was deactivated. Close things. Set GPIO 0 low, this removes the power from CH_PD & powers down the ESP.
Random thoughts.
I'm sure there will be some problems, but all seems ok at the moment. It is only intended for use with PIRs that will only have a small quantity of activations (in my case 8 a day). The PIR could be replaced with a reed switch for doors or a button for checking that a location had been visited.
The point at which the PIR output is connected must be taken low, or a diode with a better reverse block than the 1N4007 I used, or GPIO 2 stays high for quite a while. I'm powering with a "power bank " charger as they are easy to change, sort their own charging (just give them 5V) & they don't over discharge. I don't have a scope but estimate that the PIR or whatever you trigger the ESP with needs to be high for about 500ms to give GPIO 2 time to get high & take over. Oh - this is based on an ESP8266-01, with more GPIOs broken out you could report the battery voltage aswell.
Posted as it may be of interest to someone. Feel free to comment on the electronics or the code as I'm sure it can be tweeked.
Update:
Following a quick visit to the pub / resterant & discusing my results with a friend at the bar, I was asked by the owner if this could be used to summon a waiter to to the kitchen when food is ready. Answer was yes, but why just the kitchen, it could summon them to a table if needed.
Update:
Unrequired inverted comma removed from code const char* password = ""<your_router_password>"; as spotted by "tytower"
The "power bank" charger is not working with this setup. When the ESP is powered off the combination of PIR & ESP doesn't draw enough current to keep the charger output switched on. Back to rechargeable batteries, we might have a low enough current draw now though to be able to maintain charge with solar even indoors.
Forgot to mention, the PIR has standard electrical insulating tape on the back. Then all apart from the white plastic hemisphere was wrapped in a single piece of aluminium cooking foil to prevent the rf from the ESP triggering the PIR. Needless to say, don't put the ESP directly infornt of the PIR. Anyware to the sides or behind is fine, but behind may affect your signal strength.
Update:
From testing it looks like the output of the PIR (or whatever you use as a trigger) needs to remain high for a minimum of 325ms. See further along thread for details.
Add a screenshot of thingspeak data. Thingspeak can be found at https://thingspeak.com.
1 = PIR activation, 0 = PIR reset. The popup in the center, is displaying details of one of the points that I had my mouse pointer on. The data can be exported as a CSV.
Update:
Simple push button instead of PIR.
The idea was to create a battery powered PIR (or door contact) that would report when a room was entered or left, that could be ranomly moved around. First attempts that didn't power down the ESP8266-01 proved to be heavy on batteries. Following comments by "torntrousers" on another post it became apparent that:
A GPIO pin "high" could hold CH_PD high to keep the ESP awake & also "low" could power it down.
If the output from a PIR was connected via a diode to CH_PD it could wake an ESP.
The thingspeak side has been done many times.
The PIR is powered & active all the time. When the PIR detects motion it takes the output high, this powers CH_PD and wakes the ESP, it also takes GPIO 0 & GPIO 2 high, required for a normal boot. Once booted the ESP takes GPIO 0 high which maintains a high on CH_PD even if the PIR output resets to low. The diode prevents the PIR pulling CH_PD low. GPIO 2 being connected on the PIR side of the diode can detect the PIR state at all times.
Hi, temp link untill I sort dropbox. http://imgur.com/tHOaPzJ
The code. After boot set GPIO 0 high to keep the ESP awake. Setup WiFi. Connect to thingspeak & send a value of "1" to indicate that the PIR was activated. Read GPIO 2 looping round untill it becomes "0" (PIR not activated). Wait 20 seconds (sort of debounce & thingspeak can only be updated a maximum of every 15 seconds). Connect to thingspeak & send a "0" to indicate that the PIR was deactivated. Close things. Set GPIO 0 low, this removes the power from CH_PD & powers down the ESP.
Code: Select all
#include <ESP8266WiFi.h>
String apiKey = "<your_api_key>"; // your thingspeak API KEY
const char* ssid = "<your_router_SSID>"; // your routers SSID
const char* password = "<your_router_password>"; //your routers PASSWORD
const char* server = "api.thingspeak.com"; // thingspeak server
int holdPin = 0; // defines GPIO 0 as the hold pin (will hold CH_PD high untill we power down).
int pirPin = 2; // defines GPIO 2 as the PIR read pin (reads the state of the PIR output).
int pir = 1; // sets the PIR record (pir) to 1 (it must have been we woke up).
WiFiClient client; // starts a WiFi client.
void setup() {
pinMode(holdPin, OUTPUT); // sets GPIO 0 to output
digitalWrite(holdPin, HIGH); // sets GPIO 0 to high (this holds CH_PD high even if the PIR output goes low)
pinMode(pirPin, INPUT); // sets GPIO 2 to an input so we can read the PIR output state
WiFi.begin(ssid, password); // starts WiFi & login
while (WiFi.status() != WL_CONNECTED) { // loops untill WiFi is connected
delay(500);
}}
void loop() {
if (client.connect(server,80)) { // connects to thingspeak & sends the value of (pir)
String postStr = apiKey;
postStr +="&field1=";
postStr += String(pir);
postStr += "\r\n\r\n";
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n");
client.print(postStr);
}
if((pir) == 0){ // if (pir) == 0, which its not first time through as we set it to "1" above
client.stop(); // close WiFi client
delay(1000); // wait for client to close
digitalWrite(holdPin, LOW); // set GPIO 0 low this takes CH_PD & powers down the ESP
}
else { // if (pir) == 0 is not true
while(digitalRead(pirPin) == 1){ // read GPIO 2, while GPIO 2 = 1 is true, wait (delay below) & read again, when GPIO 2 = 1 is false skip delay & move on out of "while loop"
delay(500);
}
pir = 0; // set the value of (pir) to 0
delay(20000); // wait 20 sec, stopps updating thingspeak to fast (min 15 sec) & acts as a debounce for the PIR.
// end of void loop, returns to start loop again at void loop
}}
Random thoughts.
I'm sure there will be some problems, but all seems ok at the moment. It is only intended for use with PIRs that will only have a small quantity of activations (in my case 8 a day). The PIR could be replaced with a reed switch for doors or a button for checking that a location had been visited.
The point at which the PIR output is connected must be taken low, or a diode with a better reverse block than the 1N4007 I used, or GPIO 2 stays high for quite a while. I'm powering with a "power bank " charger as they are easy to change, sort their own charging (just give them 5V) & they don't over discharge. I don't have a scope but estimate that the PIR or whatever you trigger the ESP with needs to be high for about 500ms to give GPIO 2 time to get high & take over. Oh - this is based on an ESP8266-01, with more GPIOs broken out you could report the battery voltage aswell.
Posted as it may be of interest to someone. Feel free to comment on the electronics or the code as I'm sure it can be tweeked.
Update:
Following a quick visit to the pub / resterant & discusing my results with a friend at the bar, I was asked by the owner if this could be used to summon a waiter to to the kitchen when food is ready. Answer was yes, but why just the kitchen, it could summon them to a table if needed.
Update:
Unrequired inverted comma removed from code const char* password = ""<your_router_password>"; as spotted by "tytower"
The "power bank" charger is not working with this setup. When the ESP is powered off the combination of PIR & ESP doesn't draw enough current to keep the charger output switched on. Back to rechargeable batteries, we might have a low enough current draw now though to be able to maintain charge with solar even indoors.
Forgot to mention, the PIR has standard electrical insulating tape on the back. Then all apart from the white plastic hemisphere was wrapped in a single piece of aluminium cooking foil to prevent the rf from the ESP triggering the PIR. Needless to say, don't put the ESP directly infornt of the PIR. Anyware to the sides or behind is fine, but behind may affect your signal strength.
Update:
From testing it looks like the output of the PIR (or whatever you use as a trigger) needs to remain high for a minimum of 325ms. See further along thread for details.
Add a screenshot of thingspeak data. Thingspeak can be found at https://thingspeak.com.
1 = PIR activation, 0 = PIR reset. The popup in the center, is displaying details of one of the points that I had my mouse pointer on. The data can be exported as a CSV.
Update:
Simple push button instead of PIR.
Code: Select all
int holdPin = 0; // defines GPIO 0 as the hold pin (will hold CH_PD high untill we power down).
void setup() {
pinMode(holdPin, OUTPUT); // sets GPIO 0 to output
digitalWrite(holdPin, HIGH); // sets GPIO 0 to high (this holds CH_PD high when the button is relesed).
}
void loop(){
// do what ever you need whilst the ESP is powered up.
digitalWrite(holdPin, LOW); // set GPIO 0 low this takes CH_PD & powers down the ESP.
}