Jack Wilker
Created February 27, 2020 © LGPL

PEAN (Patient Environment Analyzer and Notifier)

A meaningful WiFi notified intelligent sensor that recognizes movement, direction of movement, and determine a patient's activity level.

AdvancedShowcase (no instructions)-240 minutes61

Things used in this project

Hardware components

SparkFun ESP32 Thing
SparkFun ESP32 Thing
Primary microcontroller module used for the PEAN. The WROOM module is also provided on the PCB.
×1
Proximity Sensor- Pyroelectric Infrared Sensor Module
KEMET Electronics Corporation Proximity Sensor- Pyroelectric Infrared Sensor Module
Digital Sensor that is the active sensing component of the design. Kemet PL-N823 analog sensors are provided for environment and allow stereoscopic measurements of speed and direction.
×1

Software apps and online services

Arduino IDE
Arduino IDE
Software Development Tool for the ESP32

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Prototyping Kit, Breadboard
Prototyping Kit, Breadboard
Instead of PCB, can utilize a simple breadboard. Gerber files are provided for the complete PCB

Story

Read more

Custom parts and enclosures

PEAN BOM AND PARTS LIST

Complete BOM for the PEAN project module

PCB FILES FOR PCB

This is the complete PCB for the PEAN, which includes support for analog sensor pair, dual digital sensors, power supplies, instrumentation amplifiers, WROOM and/or THING, and development area.

PEAN OPERATION VIDEO

Video showing operation of the PEAN unit.

Schematics

Schematic Instrumentation

Analog Sensors, Power Supplies, and the USB power interface schematic. Shows interfaces to the WROOM and Sparkfun THING. Future enhancements shown and documented for the PCB.

PEAN Schematic

Schematic of the complete PEAN module that has additional future expansions of the analog type sensors, instrumentation amplifiers, and power supplies. Allows use of USB type connectivity, and shows the two IoT modules that allow complete WiFi and Bluetooth BLE connectivity to the sensors.

Code

Software MAIN file for the PEAN Project

Arduino
Arduino environment that would be setup for the ESP32 (see THING ESP32 instructions at the Sparkfun site) and operates the entire PEAN microcontroller (THING) and KEMET digital sensor pairs, along with audio alarm and notifier (web site). Set the website up per the instructions in the Software Story page.
/* main.h
    Main include file for PEAN
   Version B_1_1
   Bill Riley
   PEAN Release 2/29/20
   Build with Arduino 1.8.10

*/

const char* ssid = "PEAN_Access_Point";
const char* password = "farmboy1";  // Must be 8 characters
int ledPinD1 = 18;
int ledPinD2 = 5;      // this is also on board LED for Thing non-plus
int ledPinD3 = 17;
int ledPinD4 = 16;
int ledPinD5 = 0;
int onBoardSwitch = 21;  //For Thing Plus Board
int blinkrate = 250;    // milliseconds
int buzzer = 25;
/*
   SERVER WEB PAGE
   Auto Refresh
   Round button
*/

String html1 = "<!DOCTYPE html> \
<html> \
<title>P.E.A.N.</title> \
<body> \
<center><h1>Patient Environment Analyzer and Notification</h1></center> \
<center><h2>P.E.A.N.  Web Server</h2></center> \
<meta charset=\"utf-8\" /> \
<title>WebSocket Test</title> \
<script language=\"javascript\" type=\"text/javascript\"> \
var output; \
var button; \
var canvas; \
var context; \
function init() { \
button = document.getElementById(\"toggleButton\"); \
output = document.getElementById(\"output\"); \
canvas = document.getElementById(\"led\"); \
context = canvas.getContext(\"2d\"); \
context.arc(25, 25, 15, 0, Math.PI * 2, false); \
context.lineWidth = 3; \
context.strokeStyle = \"black\"; \
context.stroke();";


String html3 = " context.fill(); \
} \
setInterval(\'window.location.reload()\', 2000); \
window.addEventListener(\"load\", init, false); \
</script> \
<table> \
<tr> \
<td><button id=\"toggleButton\" onclick=\"onPress()\" disabled>Patient Status</button></td> \
<td></td> \
<td><canvas id=\"led\" width=\"50\" height=\"50\"></canvas></td> \
</tr> \
</table> \
</body> \
</html>";

PEAN_B_1_1.ino

Arduino
Operates the PEAN microcontroller (THING). This is the INO file for the Arduino develop environment. Reference many sources for the operation of the INO files in the Arduino space.
/*  Version B_1_1
    Bill Riley 2/14/20
    PEAN Release 2/29/20
    Build with Arduino 1.8.10
*/

#include "main.h";
#include "WiFi.h"


String html2 = "";
bool exitStatus = false;

//Interrupt handlers******************************
const byte interruptPin = 15;
volatile int interruptCounter = 0;
int numberOfInterrupts = 0;
volatile int tic_interruptCounter = 0;
int tic_secInterval = 0;
int tic_secCounter = 0;
bool alertEnabled = false;
hw_timer_t * tic_timer = NULL;
portMUX_TYPE tic_timerMux = portMUX_INITIALIZER_UNLOCKED;
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;

void IRAM_ATTR handleInterrupt() {
  portENTER_CRITICAL_ISR(&mux);
  interruptCounter++;
  portEXIT_CRITICAL_ISR(&mux);
}

void IRAM_ATTR tic_onTimer() {
  portENTER_CRITICAL_ISR(&tic_timerMux);
  tic_interruptCounter++;
  portEXIT_CRITICAL_ISR(&tic_timerMux);
}


WiFiServer server(80);


//Utility routines ******************************

void timerTics()
{
  if (tic_interruptCounter > 0) {

    portENTER_CRITICAL(&tic_timerMux);
    tic_interruptCounter--;
    portEXIT_CRITICAL(&tic_timerMux);

    tic_secInterval++;
    tic_secCounter++;
  }
}

void sensorPulses() {
  if (interruptCounter > 0) {
    portENTER_CRITICAL(&mux);
    interruptCounter--;
    portEXIT_CRITICAL(&mux);
    numberOfInterrupts++;
  }
}


int blinkLEDs(int numBlinks)
{
  int i;
  if (numBlinks < 1)exit(0);
  for (i = 0; i < numBlinks; i++)
  {
    digitalWrite(ledPinD1, HIGH);   //ON
    digitalWrite(ledPinD2, HIGH);
    digitalWrite(ledPinD3, HIGH);
    digitalWrite(ledPinD4, HIGH);
    digitalWrite(ledPinD5, HIGH);
    digitalWrite(buzzer, HIGH);
    delay(blinkrate);
    digitalWrite(ledPinD1, LOW);    //OFF
    digitalWrite(ledPinD2, LOW);
    digitalWrite(ledPinD3, LOW);
    digitalWrite(ledPinD4, LOW);
    digitalWrite(ledPinD5, LOW);
    digitalWrite(buzzer, LOW);
    delay(blinkrate);
  }
}

void init_GPIOs()
{
  pinMode(ledPinD1, OUTPUT);      // set the LEDs pin mode
  pinMode(ledPinD2, OUTPUT);
  pinMode(ledPinD3, OUTPUT);
  pinMode(ledPinD4, OUTPUT);
  pinMode(ledPinD5, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(onBoardSwitch, INPUT_PULLUP);
  pinMode(interruptPin, INPUT_PULLUP);
  blinkLEDs(2);                    // blink all LEDs on start
}

void patientOK()
{
  html2 = " context.fillStyle = \"green\"; ";
  digitalWrite(buzzer, LOW);
}
void patientAlert()
{
  html2 = " context.fillStyle = \"red\"; ";
  digitalWrite(buzzer, HIGH);

}


//Setup / Init ******************************


void setup()
{
  Serial.begin(115200);
  init_GPIOs();
  Serial.println("Setting soft access point mode");
  WiFi.softAP(ssid, password);
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);
  server.begin();
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
  tic_timer = timerBegin(0, 80, true);
  timerAttachInterrupt(tic_timer, &tic_onTimer, true);
  timerAlarmWrite(tic_timer, 1000000, true);
  timerAlarmEnable(tic_timer);
}

// Main Loop ******************************


void loop()
{
  WiFiClient client = server.available();
  if (client)
  {
    String request = client.readStringUntil('\r');
    if (request.indexOf("LED0=ON") != -1)digitalWrite(ledPinD1, HIGH);
    if (request.indexOf("LED0=OFF") != -1)digitalWrite(ledPinD1, LOW);
    if (request.indexOf("LED1=ON") != -1)digitalWrite(ledPinD2, HIGH);
    if (request.indexOf("LED1=OFF") != -1)digitalWrite(ledPinD2, LOW);

    Serial.print("numberOfInterrupts = ");
    Serial.print(numberOfInterrupts);
    Serial.print("   tic_secInterval = ");
    Serial.println(tic_secInterval);

    if (tic_secInterval >= 4)
    {
      if (numberOfInterrupts > 1)
      {
        patientOK();
        numberOfInterrupts = 0;
        tic_secInterval = 0;
        Serial.println("Patient OK");
      }
      else
      {
        patientAlert();
        tic_secInterval = 0;
        Serial.println("Patient Alert");
      }
    }
    client.print(html1 + html2 + html3);
    request = "";
    timerTics();
    sensorPulses();
  }
}

Credits

Jack Wilker

Jack Wilker

2 projects • 1 follower
Thanks to Carl (Bill) Riley.

Comments