My Heart Will Go IoT

Măsurarea pulsului, a numărului de bătăi ale inimii pe minut, este un instrument de evaluare atât a stării de sănătate dar și a stării emoționale sau a efortului fizic depus. Apariția de senzori optici performanți fac această evaluare foarte simplă permițând măsurarea pulsului cu telefonul mobil sau cu diverse dispozitive de tip brățară. În cadrul proiectului de față vom explica construirea unui astfel de dispozitiv dar, în plus față de  dispozitivele clasice de măsurare a pulsului, vom înregistra datele obținute în cloud.

Atenție!!! Dispozitivul prezentat nu este un dispozitiv medical! Dispozitivul din acest proiect nu poate fi folosit pentru evaluarea stării de sănătate! Proiectul de față prezintă un principiu de măsurare și înregistrare nu și o metodă exactă de calibrare a datelor măsurate.

Pentru implementarea dispozitivului vom utiliza o placă de dezvoltarea Adafruit Feather M0 WiFi și un senzor de particule și puls MAX30105. Schema de interconectare dintre cele două componente este următoarea:

2

Senzorul comunică cu placa de dezvoltare prin intermediul magistralei I2C și atunci conexiunile dintre cele două componente sunt evidente: pinul SCL al senzorului la pinul 4 (SCL) al plăcii de dezvoltare și pinul SDA al senzorului la pinul 3 (SDA) al plăcii de dezvoltare. Pinul /INT al senzorului nu este folosit. Alimentarea senzorului se va face la 5V – pinul 5V se va conecta la pinul USB al plăcii de dezvoltare atâta timp cât placa se alimentează prin intermediul cablului USB. Dacă doriți să transformați sistemul într-un sistem portabil, alimentând placa de la un acumulator LiPo, atunci pinul de 5V al senzorului se va conecta la pinul BAT al plăcii de dezvoltare – senzorul se va alimenta la 3.7V (producătorul specifică posibilitatea de a alimenta senzorul la tensiuni între 3.3V și 5V dar explică că o tensiune de peste 3.5V va asigura o funcționare mai bună a senzorului).

Pentru punerea în funcțiune și pentru integrarea plăcii de dezvoltare cu mediul Arduino IDE este necesară parcurgerea materialului „Adafruit Feather M0 WiFi with ATWINC1500 – ARM Cortex M0+ with fast & fun wireless built in”. Pentru înțelegerea mai bună a modului de funcționare a senzorului de puls se poate parcurge materialul „MAX30105 Particle and Pulse Ox Sensor Hookup Guide”.

Programul sistemului se bazează pe exemplul Example5_HeartRate al bibliotecii software Sparkfun MAX3010x Pulse and Proximity Sensor Library. Programul a fost testat utilizând Arduino IDE 1.8.3 cu extensia Adafruit SAMD Boards 1.0.17 instalată și bibliotecile WiFi101 0.14.3 și Sparkfun MAX3010x 1.0.0. Atenție!!! Pentru a compila programul pentru placa Feather M0 este necesară adăugarea unei linii (#define BUFFER_LENGTH 32) în fișierul MAX30105.cpp al bibliotecii Sparkfun MAX3010x.

#include <SPI.h>

#include <WiFi101.h>

#define WINC_CS   8

#define WINC_IRQ  7

#define WINC_RST  4

#define WINC_EN   2 

Datele de conectare WiFi trebuie personalizate în program. Programul va înregistra datele măsurate în cloud utilizând serviciul Robofun IoT.

char ssid[] = ““;

char pass[] = ““; 

WiFiClient client;

int status = WL_IDLE_STATUS;

char server[] = “iot.robofun.ro”;

Constanta postingInterval va dicta intervalul (în milisecunde) la care se face înregistrarea datelor în cloud.

unsigned long lastConnectionTime = 0;

const unsigned long postingInterval = 30L * 1000L;

#include <Wire.h>

#include “MAX30105.h”

#include “heartRate.h”

MAX30105 particleSensor;

const byte RATE_SIZE = 4;

byte rates[RATE_SIZE];

byte rateSpot = 0;

long lastBeat = 0;

float beatsPerMinute;

int beatAvg;

Decomentarea directivei debug va permite vizualizarea datelor măsurate în concola serială.

//#define debug

3

În cadrul secțiunii setup() se va inițializa conexiunea WiFi și comunicația cu senzorul de puls. Mesajele de eroare vor apărea în consola serială doar dacă este activată directiva debug.

void setup() {

  #ifdef debug

    Serial.begin(115200);

    while (!Serial) { ; }

    Serial.println(“Initializing…”);

  #endif

  WiFi.setPins( 8,7,4,2);

  if (WiFi.status() == WL_NO_SHIELD) {

    #ifdef debug

      Serial.println(“WiFi shield not present”);

    #endif

    while (true);

  }

  while (status != WL_CONNECTED) {

    #ifdef debug

      Serial.print(“Attempting to connect to SSID: “);

      Serial.println(ssid);

    #endif

    status = WiFi.begin(ssid, pass);

    delay(10000);

  }

  #ifdef debug

    Serial.println(“Connected to wifi”);

  #endif

  if (!particleSensor.begin(Wire, I2C_SPEED_FAST))

  {

    #ifdef debug

      Serial.println(“MAX30105 was not found. Please check wiring/power. “);

    #endif

    while (1);

  }

  #ifdef debug

    Serial.println(“Place your index finger on the sensor with steady pressure.”);

  #endif

  particleSensor.setup();

  particleSensor.setPulseAmplitudeRed(0x0A);

  particleSensor.setPulseAmplitudeGreen(0);

}

În cadrul secțiunii loop() se va efectua atât citirea senzorului de puls (BPM – bătăi pe minut, medie – Avg BPM) cât și postarea către serviciul Robofun IoT. În cadrul codului trebuie personalizată cheia de autentificare (TOKEN) primită la înregistrarea senzorului în cadrul serviciului IoT. Intervalul de postare se contorizează începând cu detecția degetului pe senzor, dacă se ia degetul de pe senzor nu se mai efectuează înregistrarea valorilor în cloud. Se recomandă utilizarea unui elastic pentru a asigura o presiune constantă pe senzor.

4

void loop() {

  long irValue = particleSensor.getIR();

  if (checkForBeat(irValue) == true)

  {

    long delta = millis() – lastBeat;

    lastBeat = millis();

    beatsPerMinute = 60 / (delta / 1000.0);

    if (beatsPerMinute < 255 && beatsPerMinute > 20) {

      rates[rateSpot++] = (byte)beatsPerMinute;

      rateSpot %= RATE_SIZE;

      beatAvg = 0;

      for (byte x = 0 ; x < RATE_SIZE ; x++)

        beatAvg += rates[x];

      beatAvg /= RATE_SIZE; }

  }

  #ifdef debug

    Serial.print(“IR=”);

    Serial.print(irValue);

    Serial.print(“, BPM=”);

    Serial.print(beatsPerMinute);

    Serial.print(“, Avg BPM=”);

    Serial.print(beatAvg);

  #endif

  if (irValue < 50000) {

    #ifdef debug

      Serial.print(” No finger?”);

    #endif

    lastConnectionTime = millis();

  }

  #ifdef debug

    Serial.println();

  #endif

  if ((millis() – lastConnectionTime > postingInterval) && (beatAvg > 20))

  {   String temp = “GET /api/v1/senzor/TOKEN/input?value=” + String(beatAvg) + ” HTTP/1.1″;

      char param[100];

      temp.toCharArray(param,temp.length()+1);

      if (client.connect(server, 80)) {

        client.println(param);

        client.println(“Host: iot.robofun.ro”);

        client.println(“Connection: close”);

        client.println();

      }

      client.stop();

      lastConnectionTime = millis();

      lastBeat = 0;

  }

}

Pentru a utiliza serviciul Robofun IoT este necesară înregistrarea gratuită.

4

După înregistrare și conectare este necesară definirea unui noi senzor (Adauga senzor).

5

După definirea senzorului este necesar să copiem cheia de autentificare (Token) pentru a o utiliza în program.

3

După configurarea serviciului IoT și încărcarea programului pe placa de dezvoltare putem începe utilizarea dispozitivului și putem observa datele înregistrate on-line:

5

O facilitate foarte interesantă a serviciului Robofun IoT este posibilitatea de partajare a graficelor (Share senzor) sau de integrare a acestora în alte pagini web. Putem astfel să adăugăm paginii web personale sau blog-ului personal un grafic live cu numărul de bătăi ale propriei inimi.

6