WiFi PIR Sensor

What IoT (“internet of things”) setup would be complete without the wireless PIR (passive infrared) motion sensor? And anyway, at this pace of ESP8266 projects, soon everything in my house will have an IP address.

This sensor is the next in a series, intended to fulfill a purpose, provide a general template for device-to-internet communication, and aid in me figuring out better and more compact ways to build these devices.

Generic input sensor interface
Generic input sensor interface

The above image shows an ESP-01 board piggybacked onto a 3.3V LDO board, which was included with an order of ESP-01’s on eBay (5 ESPs, 5 LDO breakout boards, $16.70 shipped).

Reverse side
Reverse side

The above board accepts input power and has female jumper leads for +3.3V out, ground, GPIO0 and GPIO2. Since discovering this discussion, I figured out that GPIO2 can be successfully used as an input pin as long as a high-value resistor is used. In my tests with a PIR sensor, I used a 100k resistor in series with the sensor output.

For programming, TX/RX are placed loosely in the corresponding holes on the ESP-01. In retrospect, I could have done this as well for GPIO0.

The code for this project just sends packets off on a pin state change, limited to once per minute. Note, the first minute running, it won’t do anything, due to millis() being an unsigned long. To do the conversion with a signed long for lasttime, might cut the range in half – as it stands, features relying on millis() will encounter issues when it loops at around day 42 of continuous run time.

Actually, a simple fix was added to remedy the day 42 loop.

/*  This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Description: Monitor a pin for a state change and send packets to
       recipient devices when that happens. Limit this to once per
       minute, Also send a ping packet every 5 minutes.

    by Derek Yerger
    */
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char* ssid = "naaaa";
const char* password = "naaaa";
IPAddress terra(172, 21, 42, 3);
IPAddress exa(172, 21, 42, 4);
IPAddress sw200(172, 21, 42, 18);
unsigned long lasttime = 0;
int laststate = 0;
const int inputPin = 2;

void beepC() {
  WiFiUDP Udp;
  Udp.beginPacket(terra, 42003);
  Udp.print("pir");
  Udp.endPacket();

  Udp.beginPacket(exa, 42003);
  Udp.print("pir");
  Udp.endPacket();

  Udp.beginPacket(sw200, 42001);
  Udp.print("110");
  Udp.endPacket();

}

void pingC() {
  WiFiUDP Udp;
  Udp.beginPacket(exa, 42004);
  Udp.print("ping");
  Udp.endPacket();
}

void setup() {
  pinMode(inputPin, INPUT);
  WiFi.begin(ssid, password);
  WiFi.config(IPAddress(172,21,42,19),IPAddress(172,21,42,1),IPAddress(255,255,255,0));
    while (WiFi.status() != WL_CONNECTED) delay(50);
}

void loop() {
  if ((millis() % 300000) < 500) {
    pingC();
    delay(500);
  }
  int val = digitalRead(inputPin);
  if (val != laststate) {
    laststate = val;
    if ((millis()-lasttime)>60000) {
      lasttime = millis();
      beepC();
    }
  }
  if (lasttime > millis()) lasttime=millis();
}