Sketch: Mashup: ESP8266 w/PIR sensor sending Mqtt messages

Thanks for the help guys-I hope this helps folks.

Another quick example for publishing sensor data from wemos d1 (esp8266) through Mqtt.

pir_mqttESPmashup.ino (6.09 KB)

1 Like

Posted inline for easier reading. Thanks for sharing.

/* A Mash up of TWO example sketches thank you guys...
 *  When the PIR sensor senses motion it publishes to serial and to MQTT. 
 *  Uses Knolleary's awesome pubsubclient http://pubsubclient.knolleary.net/index.html  
 //////////////////////////////////////////////////
 //making sense of the Parallax PIR sensor's output
 //////////////////////////////////////////////////
 
 Switches a LED according to the state of the sensors output pin.
 Determines the beginning and end of continuous motion sequences.
 
 The sensor's output pin goes to HIGH if motion is present.
 However, even if motion is present it goes to LOW from time to time,
 which might give the impression no motion is present.
 This program deals with this issue by ignoring LOW-phases shorter than a given time,
 assuming continuous motion is present during these phases.
 
*/
/*
 Basic ESP8266 MQTT example
 
 This sketch demonstrates the capabilities of the pubsub library in combination
 with the ESP8266 board/library.
 
 It connects to an MQTT server then:
 - publishes "hello world" to the topic "outTopic" every two seconds
 - subscribes to the topic "inTopic", printing out any messages
    it receives. NB - it assumes the received payloads are strings not binary
 - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
    else switch it off
 
 It will reconnect to the server if the connection is lost using a blocking
 reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
 achieve the same result without blocking the main loop.
 
 To install the ESP8266 board, (using Arduino 1.6.4+):
 - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
 http://arduino.esp8266.com/stable/package_esp8266com_index.json
 - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
 - Select your ESP8266 in "Tools -> Board"
 
*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "YOUR SSID";
const char* password = "YOUR PASSWORD";
const char* mqtt_server = "192.168.1.220";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;




/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;

boolean lockLow = true;
boolean takeLowTime;

int pirPin = 0;    //the digital pin connected to the PIR sensor's output
int ledPin = 2;

void setup_wifi() {
 
 delay(10);
 // We start by connecting to a WiFi network
 Serial.println();
 Serial.print("Connecting to ");
 Serial.println(ssid);
 
 WiFi.begin(ssid, password);
 
 while (WiFi.status() != WL_CONNECTED) {
 delay(500);
 Serial.print(".");
 }
 
 Serial.println("");
 Serial.println("WiFi connected");
 Serial.println("IP address: ");
 Serial.println(WiFi.localIP());
}

void callback(char* topic, byte * payload, unsigned int length) {
 Serial.print("Message arrived [");
 Serial.print(topic);
 Serial.print("] ");
 for (int i = 0; i < length; i++) {
 Serial.print((char)payload[i]);
 }
 Serial.println();
}
void reconnect() {
 // Loop until we're reconnected
 while (!client.connected()) {
 Serial.print("Attempting MQTT connection...");
 // Attempt to connect
 if (client.connect("pirsensor", "pirsensor", "YOUR Client password")) {
 Serial.println("connected");
 // Once connected, publish an announcement...
 client.publish("outTopic", "hello world");
 // ... and resubscribe
 client.subscribe("kerroffice/light/overhead");
 } else {
 Serial.print("failed, rc=");
 Serial.print(client.state());
 Serial.println(" try again in 5 seconds");
 // Wait 5 seconds before retrying
 delay(5000);
 }
 }
}

/////////////////////////////
//SETUP

void setup() {
 
 Serial.begin(115200);
 pinMode(pirPin, INPUT);
 pinMode(ledPin, OUTPUT);
 digitalWrite(pirPin, LOW);
 setup_wifi();
 client.setServer(mqtt_server, 1883);
 client.setCallback(callback);
 client.subscribe("kerroffice/light/overhead");
 //give the sensor some time to calibrate
 Serial.print("calibrating sensor ");
 for (int i = 0; i < calibrationTime; i++) {
 Serial.print(".");
 delay(1000);
 }
 Serial.println(" done");
 Serial.println("SENSOR ACTIVE");
 delay(50);
}

void loop() {
 
 if (!client.connected()) {
 reconnect();
 }
 client.loop();
 
 long now = millis();
 if (now - lastMsg > 2000) {
 lastMsg = now;
 ++value;
 snprintf (msg, 75, "hello world #%ld", value);
 Serial.print("Publish message: ");
 Serial.println(msg);
 client.publish("outTopic", msg);
 }
 if (digitalRead(pirPin) == HIGH) {
 digitalWrite(ledPin, HIGH);   //the led visualizes the sensors output pin state
 if (lockLow) {
 //makes sure we wait for a transition to LOW before any further output is made:
 lockLow = false;
 Serial.println("---");
 Serial.print("motion detected at "); 
 //tring this out
 client.publish("kerroffice/Presence", "ON");
 Serial.print(millis() / 1000);
 Serial.println(" sec");
 delay(50);
 }
 takeLowTime = true;
 }
 
 if (digitalRead(pirPin) == LOW) {
 digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state
 
 if (takeLowTime) {
 lowIn = millis();          //save the time of the transition from high to LOW
 takeLowTime = false;       //make sure this is only done at the start of a LOW phase
 }
 //if the sensor is low for more than the given pause,
 //we assume that no more motion is going to happen
 if (!lockLow && millis() - lowIn > pause) {
 //makes sure this block of code is only executed again after
 //a new motion sequence has been detected
 lockLow = true;
 Serial.print("motion ended at ");      //output
 Serial.print((millis() - pause) / 1000);
 Serial.println(" sec");
 delay(50);
 }
 }
}

How do i go about adding mqtt username and password?

rw950431:
Posted inline for easier reading. Thanks for sharing.

/* A Mash up of TWO example sketches thank you guys...

*  When the PIR sensor senses motion it publishes to serial and to MQTT.
*  Uses Knolleary’s awesome pubsubclient http://pubsubclient.knolleary.net/index.html 
//////////////////////////////////////////////////
//making sense of the Parallax PIR sensor’s output
//////////////////////////////////////////////////

Switches a LED according to the state of the sensors output pin.
Determines the beginning and end of continuous motion sequences.

The sensor’s output pin goes to HIGH if motion is present.
However, even if motion is present it goes to LOW from time to time,
which might give the impression no motion is present.
This program deals with this issue by ignoring LOW-phases shorter than a given time,
assuming continuous motion is present during these phases.

/
/

Basic ESP8266 MQTT example

This sketch demonstrates the capabilities of the pubsub library in combination
with the ESP8266 board/library.

It connects to an MQTT server then:

  • publishes “hello world” to the topic “outTopic” every two seconds
  • subscribes to the topic “inTopic”, printing out any messages
        it receives. NB - it assumes the received payloads are strings not binary
  • If the first character of the topic “inTopic” is an 1, switch ON the ESP Led,
        else switch it off

It will reconnect to the server if the connection is lost using a blocking
reconnect function. See the ‘mqtt_reconnect_nonblocking’ example for how to
achieve the same result without blocking the main loop.

To install the ESP8266 board, (using Arduino 1.6.4+):

*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = “YOUR SSID”;
const char* password = “YOUR PASSWORD”;
const char* mqtt_server = “192.168.1.220”;

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;

boolean lockLow = true;
boolean takeLowTime;

int pirPin = 0;    //the digital pin connected to the PIR sensor’s output
int ledPin = 2;

void setup_wifi() {

delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

Serial.println("");
Serial.println(“WiFi connected”);
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}

void callback(char* topic, byte * payload, unsigned int length) {
Serial.print(“Message arrived [”);
Serial.print(topic);
Serial.print("] “);
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void reconnect() {
// Loop until we’re reconnected
while (!client.connected()) {
Serial.print(“Attempting MQTT connection…”);
// Attempt to connect
if (client.connect(“pirsensor”, “pirsensor”, “YOUR Client password”)) {
Serial.println(“connected”);
// Once connected, publish an announcement…
client.publish(“outTopic”, “hello world”);
// … and resubscribe
client.subscribe(“kerroffice/light/overhead”);
} else {
Serial.print(“failed, rc=”);
Serial.print(client.state());
Serial.println(” try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}

/////////////////////////////
//SETUP

void setup() {

Serial.begin(115200);
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(pirPin, LOW);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
client.subscribe(“kerroffice/light/overhead”);
//give the sensor some time to calibrate
Serial.print(“calibrating sensor “);
for (int i = 0; i < calibrationTime; i++) {
Serial.print(”.”);
delay(1000);
}
Serial.println(" done");
Serial.println(“SENSOR ACTIVE”);
delay(50);
}

void loop() {

if (!client.connected()) {
reconnect();
}
client.loop();

long now = millis();
if (now - lastMsg > 2000) {
lastMsg = now;
++value;
snprintf (msg, 75, “hello world #%ld”, value);
Serial.print(“Publish message: “);
Serial.println(msg);
client.publish(“outTopic”, msg);
}
if (digitalRead(pirPin) == HIGH) {
digitalWrite(ledPin, HIGH);  //the led visualizes the sensors output pin state
if (lockLow) {
//makes sure we wait for a transition to LOW before any further output is made:
lockLow = false;
Serial.println(”—”);
Serial.print(“motion detected at “);
//tring this out
client.publish(“kerroffice/Presence”, “ON”);
Serial.print(millis() / 1000);
Serial.println(” sec”);
delay(50);
}
takeLowTime = true;
}

if (digitalRead(pirPin) == LOW) {
digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state

if (takeLowTime) {
lowIn = millis();          //save the time of the transition from high to LOW
takeLowTime = false;      //make sure this is only done at the start of a LOW phase
}
//if the sensor is low for more than the given pause,
//we assume that no more motion is going to happen
if (!lockLow && millis() - lowIn > pause) {
//makes sure this block of code is only executed again after
//a new motion sequence has been detected
lockLow = true;
Serial.print(“motion ended at “);      //output
Serial.print((millis() - pause) / 1000);
Serial.println(” sec”);
delay(50);
}
}
}

Jonny190:
How do i go about adding mqtt username and password?

unless your mqtt requires user/pass, just ignore it :slight_smile:
im having problems with the code, it works fins as long as it is connected to arduino IDE and serial monitor, but as soon as i disconnect it and put it where i need to use it it keeps pulling high as if there was movement…
here is the code im using if anyone can help?

/* A Mash up of TWO example sketches thank you guys...
 *  When the PIR sensor senses motion it publishes to serial and to MQTT. 
 *  Uses Knolleary's awesome pubsubclient http://pubsubclient.knolleary.net/index.html  
   //////////////////////////////////////////////////
   //making sense of the Parallax PIR sensor's output
   //////////////////////////////////////////////////

   Switches a LED according to the state of the sensors output pin.
   Determines the beginning and end of continuous motion sequences.

   The sensor's output pin goes to HIGH if motion is present.
   However, even if motion is present it goes to LOW from time to time,
   which might give the impression no motion is present.
   This program deals with this issue by ignoring LOW-phases shorter than a given time,
   assuming continuous motion is present during these phases.

*/
/*
 Basic ESP8266 MQTT example

 This sketch demonstrates the capabilities of the pubsub library in combination
 with the ESP8266 board/library.

 It connects to an MQTT server then:
  - publishes "hello world" to the topic "outTopic" every two seconds
  - subscribes to the topic "inTopic", printing out any messages
    it receives. NB - it assumes the received payloads are strings not binary
  - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
    else switch it off

 It will reconnect to the server if the connection is lost using a blocking
 reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
 achieve the same result without blocking the main loop.

*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "PiWiFi";
const char* password = "31536064";
const char* mqtt_server = "192.168.1.3";

WiFiClient espClientPIR;
PubSubClient client(espClientPIR);
long lastMsg = 0;
char msg[50];
int value = 0;




/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000;

boolean lockLow = true;
boolean takeLowTime;

int pirPin = 4;    //the digital pin connected to the PIR sensor's output
int ledPin = 14;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte * payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("pirsensor", "pirsensor", "YOUR Client password")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "cmnd/sonoffD/power1");
      // ... and resubscribe
      client.subscribe("cmnd/sonoffD/power1");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

/////////////////////////////
//SETUP

void setup() {

  Serial.begin(115200);
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  digitalWrite(pirPin, LOW);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  client.subscribe("cmnd/sonoffD/power1");
  //give the sensor some time to calibrate
  Serial.print("calibrating sensor ");
  for (int i = 0; i < calibrationTime; i++) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println(" done");
  Serial.println("SENSOR ACTIVE");
  delay(50);
}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 5000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 75, "PIR #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
  if (digitalRead(pirPin) == HIGH) {
    digitalWrite(ledPin, HIGH);   //the led visualizes the sensors output pin state
    if (lockLow) {
      //makes sure we wait for a transition to LOW before any further output is made:
      lockLow = false;
      Serial.println("---");
      Serial.print("motion detected at "); 
      //tring this out
      client.publish("cmnd/sonoffD/power1", "1");
      Serial.print(millis() / 1000);
      Serial.println(" sec");
      delay(50);
    }
    takeLowTime = true;
  }

  if (digitalRead(pirPin) == LOW) {
    digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state

    if (takeLowTime) {
      lowIn = millis();          //save the time of the transition from high to LOW
      takeLowTime = false;       //make sure this is only done at the start of a LOW phase
    }
    //if the sensor is low for more than the given pause,
    //we assume that no more motion is going to happen
    if (!lockLow && millis() - lowIn > pause) {
      //makes sure this block of code is only executed again after
      //a new motion sequence has been detected
      lockLow = true;
      Serial.print("motion ended at ");      //output
      client.publish("cmnd/sonoffD/power1", "0");
      Serial.print((millis() - pause) / 1000);
      Serial.println(" sec");
      delay(50);
    }
  }
}