3magku
Created March 26, 2017 © CC BY-NC

BLE Breathing Movement Monitor (Scratch)

Highly sensitive non-touch baby breathing and movement monitor.

BeginnerWork in progress7.2 hours343
BLE Breathing Movement Monitor (Scratch)

Things used in this project

Hardware components

Arduino 101
Arduino 101
×1
SparkFun Barometric Pressure Sensor Breakout - BMP180
×1
Seeed Studio Grove - LCD RGB Backlight
×1
Seeed Studio Grove Base Shield v2
×1
Inflatable Pillow
×1

Software apps and online services

nRF Toolbox App by Nordic Semiconductor

Hand tools and fabrication machines

Hot glue gun (generic)
Hot glue gun (generic)

Story

Read more

Custom parts and enclosures

Setup

An Arduino/Genuino 101, a BMP180 barometric pressure sensor glued into an inflatable pillow and a RGB LCD display connected via Grove Base Shield v2 (both from the Starter Kit). Based on the "Arduino/Genuino 101 CurieBLE Heart Rate Monitor" example: The breath rate is propagated by implementing the tandard BLE "Heart Rate Monitor" service to a smartphone with the nRF Toolbox App.

Sensor Setup

BMP180 barometric pressure sensor, wiring, glued into an inflatable pillow ...

Schematics

Arduino 101 / BMP180

Code

BMP180_CurieBLEBreathRateMonitor_with_LCD

Arduino
Based on the "Arduino/Genuino 101 CurieBLE Heart Rate Monitor" example (https://www.arduino.cc/en/Tutorial/Genuino101CurieBLEHeartRateMonitor): Simple code to read pressure changes from a BMP180 sensor, "calculate" a breath rate and propagate it by implementing the tandard BLE "Heart Rate Monitor" service ("enriched" with status messages on a LCD display).
#include <BLEAttribute.h>
#include <BLECentral.h>
#include <BLECharacteristic.h>
#include <BLECommon.h>
#include <BLEDescriptor.h>
#include <BLEPeripheral.h>
#include <BLEService.h>
#include <BLETypedCharacteristic.h>
#include <BLETypedCharacteristics.h>
#include <BLEUuid.h>
#include <CurieBLE.h>

#include <CurieBle.h>

#include <SFE_BMP180.h>
#include "rgb_lcd.h"
#include <Wire.h>

SFE_BMP180 bmp180;
rgb_lcd lcd;
double previousPressureReading = 1000;
long previousMillis = 0;
int updateCount = 0;
int pressureChangeCount = 0;
int heartRate = 0;


BLEPeripheral blePeripheral;
BLEService heartRateService("180D"); // BLE Heart Rate Service

// BLE Heart Rate Measurement Characteristic"
BLECharacteristic heartRateChar("2A37",  // standard 16-bit characteristic UUID
                                BLERead | BLENotify, 2);  // remote clients will be able to get notifications if this characteristic changes
// the characteristic is 2 bytes long as the first field needs to be "Flags" as per BLE specifications
// https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml


void setup() {
  Serial.begin(115200);    // initialize serial communication
  Serial.println("INITIALIZING ...");

  lcd.begin(16, 2);
  lcd.setRGB(255, 0, 0);
  lcd.print("INITIALIZING ...");
  lcd.setCursor(0, 1);

  Serial.println("BMP180: initiatlizing ...");
  if (bmp180.begin()) {
    lcd.print("BMP180: online");
    Serial.println("BMP180 sensor initialized.");
  }
  else
  {
    lcd.clear();
    lcd.print("BMP180: failure.");
    Serial.println("BMP180: init failure.\n\n");
    while (1);
  }

  delay(500);

  blePeripheral.setLocalName("BreathRateMonitor");
  blePeripheral.setAdvertisedServiceUuid(heartRateService.uuid());
  blePeripheral.addAttribute(heartRateService);
  blePeripheral.addAttribute(heartRateChar);

  blePeripheral.begin();
  Serial.println("Bluetooth device active, waiting for connections ...");
  lcd.clear();
  lcd.setRGB(0, 255, 0);
  lcd.print("READY");
  lcd.setCursor(0, 1);
  lcd.print("awaiting central ...");

  delay(500);
}

void loop() {
  BLECentral central = blePeripheral.central();

  if (central) {
    lcd.clear();
    lcd.setRGB(0,  0, 255);
    lcd.print("CONNECTED");
    lcd.setCursor(0, 1);
    lcd.print("to BLE central.");
    Serial.print("Connected to central: ");
    Serial.println(central.address());

    while (central.connected()) {
      update();
    }
  }
  lcd.clear();
  lcd.setRGB(255, 0, 0);
  lcd.print("DISCONNECTED");
  lcd.setCursor(0, 1);
  lcd.print("from BLE central.");
  Serial.print("Disconnected from central: ");
  Serial.println(central.address());
  delay(3000);
}


void update() {
  char status;
  double T, P, d;

  status = bmp180.startTemperature();
  if (status != 0)
  {
    delay(status);
    status = bmp180.getTemperature(T);
    if (status != 0)
    {
      status = bmp180.startPressure(3);
      if (status != 0)
      {
        delay(status);
        status = bmp180.getPressure(P, T);
        d = abs(previousPressureReading - P);
        previousPressureReading = P;
        if (status != 0)
        {
          Serial.print("BMP180: absolute pressure = ");
          Serial.print(P, 2);
          Serial.print(" mb");
          Serial.print(" (delta =  ");
          Serial.print(d, 2);
          Serial.println(")");
        }
        else Serial.println("BMP180: error retrieving pressure measurement\n");
      }
      else Serial.println("BMP180: error starting pressure measurement\n");
    }
    else Serial.println("BMP180: error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");

  if ( d > 0.1 ) {
    pressureChangeCount++;
  }
  updateCount++;

  long currentMillis = millis();
  long millisElapsed = currentMillis - previousMillis;
  previousMillis = currentMillis;

  lcd.clear();
  lcd.print("ONLINE");
  lcd.setCursor(0, 1);
  lcd.print("# ");
  lcd.print(updateCount);
  lcd.print(" (");
  lcd.print(millisElapsed);
  lcd.print(") ");
  lcd.print(": ");
  lcd.print(pressureChangeCount);

  if ( updateCount > 59 ) {
    heartRate = pressureChangeCount * 6;
    updateCount = 0;
    pressureChangeCount = 0;
    lcd.clear();
    lcd.print("O N L I N E");
    lcd.setCursor(0, 1);
    lcd.print(currentMillis);
    lcd.print(": ");
    lcd.print(heartRate);

    Serial.print("Breath rate is now: ");
    Serial.println(heartRate);
    const unsigned char heartRateCharArray[2] = { 0, (char)heartRate };
    heartRateChar.setValue(heartRateCharArray, 2);
  }

  delay(122);
}

Credits

3magku

3magku

4 projects • 10 followers

Comments