Robert Persichitte
Created February 23, 2020 © MIT

Performer Locator

Use cheap components and wi-fi to find out the location of performs on a stage or any environment where there is Wi-Fi.

AdvancedFull instructions provided12 hours39
Performer Locator

Things used in this project

Hardware components

Adafruit Feather HUZZAH with ESP8266 WiFi
Adafruit Feather HUZZAH with ESP8266 WiFi
My prototype used the ESP32 HUZZAH!, but for this project there should be no difference between the feather with the ESP32 or the ESP8266.
×1
Proximity Sensor- Pyroelectric Infrared Sensor Module
KEMET Electronics Corporation Proximity Sensor- Pyroelectric Infrared Sensor Module
×1
JST Jumper Bundle for the BeagleBone Blue
Renaissance Robotics JST Jumper Bundle for the BeagleBone Blue
You only need the JST5 cable. If you buy this kit, you will have to strip one end of the wires. The KEMET PIR sensor does not come ship with the JST5 cable. You have 3 options to sole it: 1-Solder directly onto the board (not recommended) 2-Buy a JST5 cable.
×1
Adafruit Lithium Ion Polymer Battery - 3.7v 2500mAh
You can change how much capacity based on how long you want it to last. Enclosure is designed around a 2500mAh battery, but it can be easily adapted.
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Jigsaw
You'll need to make cutouts in some plywood for a durable enclosure.
3D Printer (generic)
3D Printer (generic)
Hot glue gun (generic)
Hot glue gun (generic)

Story

Read more

Custom parts and enclosures

Enclosure lid

This is my attempt at a lid for the enclosure. The sides need to be durable enough to support the weight of a person. This can also be implemented by itself.

Schematics

Wiring diagram

This is an example of how to wire a sensor without an activation switch

Wiring diagram with optional pyrotechnics

This shows an example of how to wire this sensor as a safety switch.

Code

Zipped server files

PHP
These files should be extracted to the server HTML server. The only file that needs to be changes is connection.php it should be updated wiht your MySQL server credientials.
No preview (download only).

MySQL configuration files

SQL
Use the upload feature of MySQL to upload the tables using this format.
-- phpMyAdmin SQL Dump
-- version 4.8.3
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3306
-- Generation Time: Feb 28, 2020 at 11:04 PM
-- Server version: 5.6.44-cll-lve
-- PHP Version: 7.2.7

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `PIR_sensor`
--

-- --------------------------------------------------------

--
-- Table structure for table `session`
--

CREATE TABLE `session` (
  `id` int(11) NOT NULL,
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `ip` varchar(15) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Table structure for table `tracking`
--

CREATE TABLE `tracking` (
  `ID` int(11) NOT NULL,
  `session` int(11) NOT NULL,
  `sensor` int(11) NOT NULL,
  `state` tinyint(1) NOT NULL,
  `color` varchar(6) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


--
-- Indexes for table `session`
--
ALTER TABLE `session`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `tracking`
--
ALTER TABLE `tracking`
  ADD PRIMARY KEY (`ID`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `session`
--
ALTER TABLE `session`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=94;

--
-- AUTO_INCREMENT for table `tracking`
--
ALTER TABLE `tracking`
  MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=93;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

Sensor Code

Arduino
Use Arduino IDE to upload this code to the sensors.
/*
 *  This sketch sends a message to a TCP server based
 *  on feedback from a KEMET pyroelectric sensor.
 *
 */

// Wi-fi requirments
#include <WiFi.h>
#include <WiFiMulti.h>

WiFiMulti WiFiMulti;


///////////////////
// WiFi Settings //
///////////////////

// #include <HTTPClient.h> // For HTTP.
#include <WiFiClientSecure.h> // For HTTPS

// 80 for HTTP; 443 for HTTPS.
#define port 443

// Also change definition of client in the void POST
// To match if you have HTTP or HTTPS.

///////////////////////////
// Customizable settings //
///////////////////////////

int sensor_id = 1001; // sensor_id should be different for each board.
#define wifi_SSID "Robert and Carrie"
#define wifi_pass "Persichitte2527"

// Establish the connection to the server where write.php is serving files.
// ip or dns
#define host "persichitte.com"
#define path "/location_demo/write.php"

// Sensor threshholds
// For failsafes, how many LOW readings before sending the signal to the server
#define min_reads 3

// Define Pyro output PIN
#define Pyro A4

// Define LED; (built in with feather
#define LED 13

// Define safety switch
#define safety 21

// PIR sensor threshhold. With the low power setting, I found
// that setting this to 1,000 works well.
#define threshhold 1000
// Establishes global variables:
bool active = false;
int n_pings = 0;

void setup()
{
    Serial.begin(115200);
    delay(10);

    // We start by connecting to a WiFi network
    WiFiMulti.addAP(wifi_SSID, wifi_pass);

    Serial.println();
    Serial.println();
    Serial.print("Waiting for WiFi... ");

    while(WiFiMulti.run() != WL_CONNECTED) {
        Serial.print(".");
        delay(500);
    }

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

    // Configure pins
    pinMode(LED, OUTPUT);
    pinMode(safety, OUTPUT);
    pinMode(Pyro, INPUT);
}

void post(bool active)
{
  

  // Generate POST payload
  String PostData="sensor=" + String(sensor_id) + "&state="+ String(active);
  Serial.println(PostData);

  /* The following section connects to a server. This is based on the 
  example for basic wifi connections in the Arduino library. The header information
  and how to include a POST is based on information from Arduino forum user enjrolas'
  post https://forum.arduino.cc/index.php?topic=155218.0 */
  
  Serial.print("Connecting to ");
  Serial.println(host);
  
  // Use WiFiClient class to create TCP connections
  WiFiClientSecure client;

  /*
   * If you are only using this code with the 
   * remote server, this code makes sense to uncomment.
   * I took it out because it effectively requires a network
   * connection to update the sensor. If you are using
   * the analog safety mode, this would cause problems.
   */
  /*
  while (!client.connect(host, port)) {
    Serial.println("Connection failed.");
    Serial.println("Waiting 5 seconds before retrying...");
    delay(5000);
    return;
   }
   */
  
  if (client.connect(host, port)) {
    Serial.println("connected");


    client.println("POST "+String(path)+" HTTP/1.1");
    client.println("Host: "+String(host));
    //client.println("User-Agent: Arduino/1.0");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.println("Content-Length: " + String(PostData.length()));
    client.println();
    client.println(PostData);

    //read back one line from the server
    String line = client.readStringUntil('\r');
    Serial.println(line);
  } else {
    Serial.println("connection failed");
  }
}


void loop()
{
  post(active);
  if(active){
    // Handler if the last signal was active.
    // Code hange until getting 3 consecutive 
    // low pings.

    // Turn off LED and switch
    digitalWrite(LED, LOW);
    digitalWrite(safety, LOW);
    
    n_pings = 0;
    while(n_pings<min_reads){
      if(pulseIn(Pyro, HIGH)<threshhold){
        n_pings++;
      }else{
        n_pings=0;
      }
    }
    active = false;
  }else{
    // Handler if the last signal was not active.
    // Hangs untill reading 3 active signals.
    n_pings=0;
    
    // Turn off LED and switch
    digitalWrite(LED, HIGH);
    digitalWrite(safety, HIGH);
    
    while(n_pings<min_reads){
      if(pulseIn(Pyro, HIGH)>threshhold){
        n_pings++;
      }else{
        n_pings=0;
      }
    }
    active=true;
  }
}

Credits

Robert Persichitte

Robert Persichitte

3 projects • 3 followers

Comments