Aswin Sivakumar
Created February 25, 2020 © GPL3+

Sense 'N' Switch applications with Kemet's SS-430 PyroSensor

Low power, motion-activated switch for home automation, health and wearables applications

Intermediate2 hours101
Sense 'N' Switch applications with Kemet's SS-430 PyroSensor

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
×1
Proximity Sensor- Pyroelectric Infrared Sensor Module
KEMET Electronics Corporation Proximity Sensor- Pyroelectric Infrared Sensor Module
×1
Kasa Smart Wi-Fi Plug HS100
×1
Battery, 3.7 V
Battery, 3.7 V
×1
Cable Tie, Double Sided
Cable Tie, Double Sided
×1
Slide Switch
Slide Switch
×1
SparkFun Cable - 5 Pin 1mm Pitch - 200mm
×1
Beetle - The Smallest Arduino
DFRobot Beetle - The Smallest Arduino
×1
Logic Level FET N-Channel
Logic Level FET N-Channel
×1
Standoff, Screw, Nut assortment kit
×1
Gravity: I2C BME680 Environmental Sensor
DFRobot Gravity: I2C BME680 Environmental Sensor
×1
LED (generic)
LED (generic)
×1
Ribbon Cable, Flat
Ribbon Cable, Flat
×1

Software apps and online services

Maker service
IFTTT Maker service
Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Smart Headphones / Smart Air Freshener Board Schematics

Smart Headphones / Smart Air Freshener Board Layout

Smart Cabin / Sleep Monitor Board Schematics

Smart Cabin / Sleep Monitor Board Layout

Code

Smart Wireless Headphone

Arduino
Please refer to the schematics for wiring. No external libraries needed.
// Code produced by Aswin Sivakumar https://www.hackster.io/aswin-sivakumar
// Initialize Variables
int Pyro = A1;
unsigned long PyroRead = 0;
unsigned long IR_threshold = 198000;
int LED = 7;
int DETECTED = HIGH;
int IR_sensed = 0;

void setup() 
{
  pinMode (Pyro,INPUT); // Kemet Sensor Comparator input connected to A1
  pinMode (9, OUTPUT);  // Headphone control signal
  Serial.begin(115200);
}

void loop() 
{
  while ((IR_sensed < 2))  // Wait for 2 triggers before toggling the headphone power state
  {
    PyroRead = pulseIn(Pyro,HIGH); 
    if(PyroRead > IR_threshold)
    { 
      IR_sensed++;
    }
  }

  if(DETECTED == HIGH)
  {
    DETECTED=LOW;
    digitalWrite(9, HIGH);
    Serial.println("Headphone turned on...");
  }
  else
  {
    DETECTED=HIGH;
    digitalWrite(9, LOW);
    Serial.println("Headphone turned off...");
  }
  // Reset readings
  PyroRead = 0; 
  IR_sensed = 0;  
  
  delay(3000); // Wait time before accepting next trigger
}

Smart Cabin Lighting

Arduino
Please refer to Schematics for wiring. Need to install ESP8266 support for Arduino IDE (Refer to the link provided)
// Code produced by Aswin Sivakumar https://www.hackster.io/aswin-sivakumar
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>

//Initialize variables
int Pyro =0; 
unsigned long PyroRead = 0;
unsigned long IR_threshold = 198000;
int DETECTED = HIGH;
int IR_sensed = 0;
unsigned long cmillis =0;
int switch_status=0;

void setup() 
{
  Serial.begin(115200); 
  Serial.println("Entering Sleep Mode");
  WiFi.forceSleepBegin();// turn off ESP8266 RF to save power
  delay(3000); 
  pinMode (Pyro,INPUT);  // Kemet Sensor Comparator input to pin D3. GPIO 0 maps to pin D3 in NodeMCU
}

void loop() 
{
  // Set time counter
  cmillis=millis();
  // Wait to detect human motion
  detect_motion(2, 0, switch_status);
  switch_status = 1;
  Serial.println("Motion detected...Turning ON Smart Plug");
  // Send a web Request with event and key as arguments
  send_event("Moved","XXXXXXXXXXXXXXXXXXXXXX"); // Replace XX with your key
  // Reset time counter
  cmillis=millis();
  int flag=detect_motion(2,60000,switch_status); //60s timeout for detecting 'No-Motion' condition to turn OFF Smart Plug 
  if(flag)
  {
    Serial.println("No motion detected...Turning OFF switch");
    switch_status = 0;
    // Send a web Request with event and key as arguments
    send_event("Moved","XXXXXXXXXXXXXXXXXXX"); // Replace XX with your key
  } 
}

int detect_motion(int triggers, int timeout, int status)
{
   while ((IR_sensed < triggers)) // Wait for 2 triggers
   { 
      /* For Debug
      Serial.print(" Current Time count: ");
      Serial.print(millis()-cmillis);
      Serial.print(" Timeout: ");
      Serial.print(timeout);  
      Serial.print("\r\n");  
       */
      if(millis()-cmillis > timeout && timeout !=0)
      {
        return 1;
      }
      PyroRead = pulseIn(Pyro, HIGH);
      if(PyroRead > IR_threshold)
      { 
        if(status==0)
        {
          IR_sensed++;
        }
        else
        {
         cmillis=millis();
        }
      }
    }
    // Reset readings
    PyroRead = 0; 
    IR_sensed = 0; 
}

void send_event(const char *event, const char *key)
{
   WiFi.forceSleepWake(); // turn back on ESP8266 RF                 
   delay(1);  
   Serial.println("RF On...");
   connect_wifi("SSID","PASS"); // Replace with your Network ID credentials
   const char *host = "maker.ifttt.com";
   WiFiClient client;
   const int httpPort = 80;
   if (!client.connect(host, httpPort)) 
   {
     Serial.println("Connection failed");
     return;
   }
   else
   {
     Serial.print("Connected to ");
     Serial.println(host);
   }
  String url = "/trigger/";
  url += event;
  url += "/with/key/";
  url += key;
   client.print(String("GET ") + url + " HTTP/1.1\r\n"  +
               "Host: " + host  + "\r\n" +
               "Connection: close\r\n" + 
               "\r\n");
   while(client.available())
    {
      String line = client.readStringUntil('\r');
      Serial.print(line);
    } 
   client.stop();
   Serial.println("Entering Sleep Mode");
   WiFi.forceSleepBegin();                  // turn off ESP8266 RF to save power
   delay(1); 
}

void connect_wifi(const char *ssid, const char *pass)
{
   WiFi.begin(ssid, pass);
   while (WiFi.status() != WL_CONNECTED) 
   {  
      //Wait for the WiFI connection completion
      delay(300);
      Serial.println("Waiting for connection");
   }
}

Sleep Monitor

Arduino
Please refer to the schematics for wiring. Need to install ESP8266 support for Arduino IDE and Adafruit's BME860 library (please refer to the links provided)
/*Code produced by Aswin Sivakumar https://www.hackster.io/aswin-sivakumar */
/*Code includes the following library:
***************************************************************************
  This a library for the BME680 gas, humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BME680 Breakout
  ----> http://www.adafruit.com/products/3660

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/

#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

//Initialize variables
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME680 bme; // I2C
int Pyro =0;
int LED = 15;
unsigned long PyroRead = 0;
unsigned long IR_threshold = 198000;
int DETECTED = HIGH;
int IR_sensed = 0;
unsigned long cmillis =0;
int switch_status=0;

void setup() 
{
  Serial.begin(115200);
  Serial.println("Entering Sleep Mode");
  WiFi.forceSleepBegin(); // turn off ESP8266 RF to save power
  delay(3000); 
  pinMode (Pyro,INPUT);   // Sensor connected to pin D3. GPIO 0 maps to pin D3
  if (!bme.begin()) 
  {
    Serial.println("Could not find a valid BME680 sensor, check wiring!");
    // Set up oversampling and filter initialization
    bme.setTemperatureOversampling(BME680_OS_8X);
    bme.setHumidityOversampling(BME680_OS_2X);
    bme.setPressureOversampling(BME680_OS_4X);
    bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
    bme.setGasHeater(320, 150); // 320*C for 150 ms
  }
  pinMode(LED,OUTPUT); // LED connected to pin GPIO15 (D8) in NodeMCU
}

void loop() 
{
  // Set time counter
  cmillis=millis();
  // Wait to detect human motion
  detect_motion(2, 0, switch_status);
  switch_status = 1;
  Serial.println("Motion detected (Sleep Disturbance)...");
  digitalWrite(LED,HIGH);
  if (! bme.performReading()) 
  {
    Serial.println("Failed to perform reading :(");
    return;
  }
  // Send a web request with event, key & environmental parameters as arguments (Replace 'xx' with you key)
  send_event("Moved","xxxxxxxxxxxxxxxxxxx", bme.temperature, bme.humidity, bme.gas_resistance);
  digitalWrite(LED,LOW);
  // Reset time counter
  cmillis=millis();
  int flag=detect_motion(2,60000,switch_status); //60s timeout for detecting 'No-Motion' condition (Sleep state)   
  if(flag)
  {
  Serial.println("No motion detected...Turning OFF switch");
  switch_status = 0;
  }  
}

int detect_motion(int triggers, int timeout, int status)
{
  while ((IR_sensed < triggers))
  { 
     /* For Debug
      Serial.print(" Current Time count: ");
      Serial.print(millis()-cmillis);
      Serial.print(" Timeout: ");
      Serial.print(timeout);  
      Serial.print("\r\n");  
       */
     if(millis()-cmillis >300000) // Periodically record environmental conditions (say every 5th minute) during 'No-Motion' (Sleep) state
     {
       cmillis=millis();
       
       if (! bme.performReading()) {
       Serial.println("Failed to perform reading :(");
      }
      // Send a web request with event, key & environmental parameters as arguments  (Replace 'xx' with you key)
      send_event("Deepsleep","xxxxxxxxxxxxxxxxxxx", bme.temperature, bme.humidity, bme.gas_resistance);
    }
    if(millis()-cmillis > timeout && timeout !=0)
    {
      IR_sensed=0;
      return 1;
    }
    PyroRead = pulseIn(Pyro, HIGH);
    if(PyroRead > IR_threshold)
      { 
        if(status==0)
        {
          IR_sensed++;
          cmillis=millis();
        }
        else
        {
         cmillis=millis();
        }
      }
   }
   IR_sensed=0;
}

void send_event(const char *event, const char *key ,float temp, float humid, float voc)
{
  WiFi.forceSleepWake();   // turn back on ESP8266 RF               
  delay(1);  
  Serial.println("RF On...");
  connect_wifi("SSID","Password");   // Use your network's SSID and Password
  const char *host = "maker.ifttt.com";
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) 
  {
    Serial.println("Connection failed");
    return;
  }
  else
  {
    Serial.print("Connected to ");
    Serial.println(host);
  } 
  String url = "/trigger/";
  url += event;
  url += "/with/key/";
  url += key;
  float v1 = temp;
  float v2 = humid;
  float v3 = (float)voc/1000.0;
  String data = "{\"value1\":\""+String(v1)+"\",\"value2\":\""+String(v2)+"\",\"value3\":\""+String(v3)+"\"}";
  client.print(String("POST ") + url + " HTTP/1.1\r\n" +
               "Host: " + host  + "\r\n" +
               "Connection: close\r\n" + 
               "Content-Type: application/json"+"\r\n" +
               "Content-Length:"+  String(data.length()) + 
               "\r\n" + 
               "\r\n"+
               data);
  while(client.available())
    {
      String line = client.readStringUntil('\r');
      Serial.print(line);
    } 
  client.stop();
  Serial.println("Entering Sleep Mode");
  WiFi.forceSleepBegin();                  // turn off ESP8266 RF to save power
  delay(1); 
}
void connect_wifi(const char *ssid, const char *pass)
{
   WiFi.begin(ssid, pass);
   while (WiFi.status() != WL_CONNECTED) 
   {  
      //Wait for the WiFI connection completion
      delay(300);
      Serial.println("Waiting for connection");
   }
}

Smart AirFreshner

Arduino
Please refer to schematics for wiring. No external libraries needed.
// Code produced by Aswin Sivakumar https://www.hackster.io/aswin-sivakumar
// Initialize Variables
int Pyro = A1;
unsigned long PyroRead = 0;
unsigned long IR_threshold = 198000;
int LED = 7;
int DETECTED = HIGH;
int IR_sensed = 0;
unsigned long cmillis =0;
int switch_status=0;

void setup() 
{
  pinMode (Pyro,INPUT); // Kemet Sensor Comparator input connected to A1
  pinMode (9, OUTPUT);  // Trigger OUT signal to AirFreshner 
  Serial.begin(115200);
}

void loop() 
{
   // Set time counter
   cmillis=millis();
   // Wait to detect human motion
   detect_motion(2,0,switch_status); 
   switch_status = 1;
   Serial.println("Motion detected...Turning on timer check");
   // Reset time counter
   cmillis=millis();
   int flag=detect_motion(2,20000,switch_status); //20s timeout for detecting 'No-Motion' condition to trigger AirFreshner
   if(flag)
   {
    digitalWrite(9,HIGH);
    Serial.println("No motion detected...Triggering Air Freshner");
    switch_status = 0;
    delay(5000);
    digitalWrite(9,LOW);
   }
}

int detect_motion(int triggers, int timeout, int status)
{
    while ((IR_sensed < triggers)) // Wait for 2 triggers 
    { 
      /* For Debug
      Serial.println(" Current Time count: ")
      Serial.print(millis()-cmillis);
      Serial.print(" Timeout: ")
      Serial.print(timeout);  
       */
      if(millis()-cmillis > timeout && timeout !=0)
      {
        return 1;
      }
      PyroRead = pulseIn(Pyro, HIGH);
      if(PyroRead > IR_threshold)
      { 
        if(status==0)
        {
          IR_sensed++;
        }
        else
        {
         cmillis=millis();
        }
      }
    }
   // Reset readings
   PyroRead = 0; 
   IR_sensed = 0; 
}

Credits

Aswin Sivakumar

Aswin Sivakumar

1 project • 3 followers

Comments