Cris ThomasJiss Joseph Thomas
Published © GPL3+

Remote Patient Monitoring System

Remote Patient Monitoring in extreme scenarios such as the COVID-19 pandemic

AdvancedWork in progressOver 2 days1,483
Remote Patient Monitoring System

Things used in this project

Hardware components

Helium Developer Kit
Helium Developer Kit
×1

Software apps and online services

PlatformIO IDE
PlatformIO IDE

Story

Read more

Schematics

Kit

Code

Tap Code - Helium

C/C++
This is the code to detect TAPs on Helium Development kit using LSM6DSO Sensor
#include <LSM6DSOSensor.h>
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include <CayenneLPP.h>
#include "arduino_lmic_hal_boards.h"

void do_send(osjob_t *);
static uint8_t mydata[] = "Double Tap";
static osjob_t sendjob;

#define DEV_I2C Wire
#define SerialPort Serial
#define INT_1 4

LSM6DSOSensor *accGyr;
int32_t accelerometer[3];
int32_t gyroscope[3];

//Interrupts.
volatile int mems_event = 0;
char report[256];
void INT1Event_cb();

// Replace FILLMEIN with your own data from console
static const u1_t PROGMEM DEVEUI[8] = {FILLMEIN};
void os_getDevEui(u1_t *buf) { memcpy_P(buf, DEVEUI, 8); }
static const u1_t PROGMEM APPEUI[8] = {FILLMEIN};
void os_getArtEui(u1_t *buf) { memcpy_P(buf, APPEUI, 8); }
static const u1_t PROGMEM APPKEY[16] = {FILLMEIN};
void os_getDevKey(u1_t *buf) { memcpy_P(buf, APPKEY, 16); }

void printHex2(unsigned v)
{
  v &= 0xff;
  if (v < 16)
    Serial.print('0');
  Serial.print(v, HEX);
}

void do_send(osjob_t *j)
{
  // Check if there is not a current TX/RX job running
  if (LMIC.opmode & OP_TXRXPEND)
  {
    Serial.println(F("OP_TXRXPEND, not sending"));
  }
  else
  {
    // Prepare upstream data transmission at the next possible time.
    LMIC_setTxData2(1, mydata, sizeof(mydata) - 1, 0);
    Serial.println(F("Packet queued"));
  }
  // Next TX is scheduled after TX_COMPLETE event.
}

void onEvent(ev_t ev)
{
  Serial.print(os_getTime());
  Serial.print(": ");
  switch (ev)
  {
  case EV_SCAN_TIMEOUT:
    Serial.println(F("EV_SCAN_TIMEOUT"));
    break;
  case EV_BEACON_FOUND:
    Serial.println(F("EV_BEACON_FOUND"));
    break;
  case EV_BEACON_MISSED:
    Serial.println(F("EV_BEACON_MISSED"));
    break;
  case EV_BEACON_TRACKED:
    Serial.println(F("EV_BEACON_TRACKED"));
    break;
  case EV_JOINING:
    Serial.println(F("EV_JOINING"));
    break;
  case EV_JOINED:
    Serial.println(F("EV_JOINED"));
    {
      u4_t netid = 0;
      devaddr_t devaddr = 0;
      u1_t nwkKey[16];
      u1_t artKey[16];
      LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
      Serial.print("netid: ");
      Serial.println(netid, DEC);
      Serial.print("devaddr: ");
      Serial.println(devaddr, HEX);
      Serial.print("AppSKey: ");
      for (size_t i = 0; i < sizeof(artKey); ++i)
      {
        if (i != 0)
          Serial.print("-");
        printHex2(artKey[i]);
      }
      Serial.println("");
      Serial.print("NwkSKey: ");
      for (size_t i = 0; i < sizeof(nwkKey); ++i)
      {
        if (i != 0)
          Serial.print("-");
        printHex2(nwkKey[i]);
      }
      Serial.println();
    }
    // Disable link check validation (automatically enabled
    // during join, but because slow data rates change max TX
    // size, we don't use it in this example.
    LMIC_setLinkCheckMode(0);
    break;
  case EV_JOIN_FAILED:
    Serial.println(F("EV_JOIN_FAILED"));
    break;
  case EV_REJOIN_FAILED:
    Serial.println(F("EV_REJOIN_FAILED"));
    break;
    break;
  case EV_TXCOMPLETE:
    Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
    if (LMIC.txrxFlags & TXRX_ACK)
      Serial.println(F("Received ack"));
    if (LMIC.dataLen)
    {
      Serial.println(F("Received "));
      Serial.println(LMIC.dataLen);
      Serial.println(F(" bytes of payload"));
    }
    // Schedule next transmission
    os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(60), do_send);
    break;
  case EV_LOST_TSYNC:
    Serial.println(F("EV_LOST_TSYNC"));
    break;
  case EV_RESET:
    Serial.println(F("EV_RESET"));
    break;
  case EV_RXCOMPLETE:
    Serial.println(F("EV_RXCOMPLETE"));
    break;
  case EV_LINK_DEAD:
    Serial.println(F("EV_LINK_DEAD"));
    break;
  case EV_LINK_ALIVE:
    Serial.println(F("EV_LINK_ALIVE"));
    break;
  case EV_TXSTART:
    Serial.println(F("EV_TXSTART"));
    break;
  case EV_TXCANCELED:
    Serial.println(F("EV_TXCANCELED"));
    break;
  case EV_RXSTART:
    break;
  case EV_JOIN_TXCOMPLETE:
    Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept"));
    break;

  default:
    Serial.print(F("Unknown event: "));
    Serial.println((unsigned)ev);
    break;
  }
}

void setup()
{
  // Led.
  pinMode(LED_BUILTIN, OUTPUT);
  // Initialize serial for output.
  SerialPort.begin(115200);

  // Initialize I2C bus.
  DEV_I2C.begin();

  //Interrupts.
  attachInterrupt(INT_1, INT1Event_cb, RISING);

  accGyr = new LSM6DSOSensor(&DEV_I2C);
  accGyr->Enable_X();
  accGyr->Enable_Double_Tap_Detection(LSM6DSO_INT1_PIN);

#if defined(ARDUINO_DISCO_L072CZ_LRWAN1)
  SPI.setMOSI(RADIO_MOSI_PORT);
  SPI.setMISO(RADIO_MISO_PORT);
  SPI.setSCLK(RADIO_SCLK_PORT);
  SPI.setSSEL(RADIO_NSS_PORT);
#endif

  // LMIC init
  os_init();
  // Reset the MAC state. Session and pending data transfers will be discarded.
  LMIC_reset();

  // allow much more clock error than the X/1000 default.
  // values from 10 (10% error, the most lax) to 1000 (0.1% error, 
  // the most strict) can be used.
  LMIC_setClockError(1 * MAX_CLOCK_ERROR / 40);

  LMIC_setLinkCheckMode(0);
  LMIC_setDrTxpow(DR_SF7, 14);
  LMIC_selectSubBand(6);

  do_send(&sendjob);
}

// For in-depth reference on PIO Helium code structure,
// Refer : https://github.com/helium/longfi-platformio
// Modified to use for Remote Patient Monitoring System

void loop()
{
  if (mems_event)
  {
    mems_event = 0;
    LSM6DSO_Event_Status_t status;
    accGyr->Get_X_Event_Status(&status);
    if (status.DoubleTapStatus)
    {
      // Output data.
      SerialPort.println("Double Tap Detected!");
      do_send(&sendjob);
      // Led blinking.
      digitalWrite(LED_BUILTIN, HIGH);
      delay(100);
      digitalWrite(LED_BUILTIN, LOW);
    }
  }
  os_runloop_once();
}

void INT1Event_cb()
{
  mems_event = 1;
}

Credits

Cris Thomas

Cris Thomas

24 projects • 91 followers
Electronics and Aerospace engineer with a dedicated history in Research and Development. https://www.linkedin.com/in/crisdeodates/
Jiss Joseph Thomas

Jiss Joseph Thomas

21 projects • 55 followers

Comments