-->
Page 1 of 19

PIR sensor - wake and sleep using CH_PD & thingspeak update.

PostPosted: Mon Aug 10, 2015 4:21 pm
by Barnabybear
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.
Image
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.
Image
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.
Image
Code: Select allint 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.
}

Re: PIR sensor - wake and sleep using CH_PD & thingspeak upd

PostPosted: Tue Aug 11, 2015 4:46 pm
by tytower
Good stuff thanks
Code needs small correction to remove one of the inverted commas
const char* password = ""<your_router_password>"; //your routers PASSWORD to
const char* password = "<your_router_password>"; //your routers PASSWORD

Then it compiles fine.
Do you have a thingspeak public link so that I can see the results?

Re: PIR sensor - wake and sleep using CH_PD & thingspeak upd

PostPosted: Tue Aug 11, 2015 6:42 pm
by Michaelo
Looks interesting... have you determined the set up time for the ESP?

I assume if the PIR output goes high, you could actually regard that as a trigger event, so the code might simply send an alarm once the ESP wakes up... The duration of the PIR output must exceed the ESP wake up time for the circuit to work... assume it's capable of outputting a high for a fixed duration?

I'm doing something very similar using a piezo sensor so that the sensor part of my circuit draws no appreciable current. Assuming I can extend the piezo output a little I could use your wake up method in place of code and reduce my current requirement even further... If that worked, in theory the battery would last a very long time...

Also, why not set up a local server for testing and avoid the need for thingspeak altogether...
Mike

Re: PIR sensor - wake and sleep using CH_PD & thingspeak upd

PostPosted: Wed Aug 12, 2015 5:39 am
by Barnabybear
Hi Michaelo, I saw your post on the project it looks good. Have you got any further with it yet?
Michaelo wrote:Looks interesting... have you determined the set up time for the ESP?

The data sheet for the PIR I'm using (KC7783R had some left from another attempt at this using rf a few years ago) states that on detection the output is taken high for 500ms which works. I don't have a scope so the only way I could think of to test the actual setup time would be to setup a second ESP with a loop taking a GPIO high for slowly increasing perids of time & using that as a trigger untill a stable value is reached.
Michaelo wrote:I assume if the PIR output goes high, you could actually regard that as a trigger event, so the code might simply send an alarm once the ESP wakes up... The duration of the PIR output must exceed the ESP wake up time for the circuit to work... assume it's capable of outputting a high for a fixed duration?

Yes it actualy does that, with the code above it should only report to thinkspeak twice. On the first pass it sends a "1" as it assumes that if it is awake the sensor has been triggered, so this value is sent without reading the PIR output. It only then sits in a "while" loop reading the PIR output untill low, then sends a "0" and powers down. If you don't need the "0" you could just, wake - report -shut down. You might need a delay between report & shut down as a sort of debounce to prevent the ESP being woken straight away (you could proberbly disconnect and power off the WiFi during this delay if need to save battery). I may do this as it means I could use the second GPIO to check battery voltage (more on that later).
Michaelo wrote:I'm doing something very similar using a piezo sensor so that the sensor part of my circuit draws no appreciable current. Assuming I can extend the piezo output a little I could use your wake up method in place of code and reduce my current requirement even further... If that worked, in theory the battery would last a very long time...

Having read how capacative the gate of some FETs can be I'm sure one could be used to extend the output of the piezo. The problem you might have is getting it to swich back off.
Michaelo wrote:Also, why not set up a local server for testing and avoid the need for thingspeak altogether...

I'm sure thats a good idear but way beyond my skills at this time.