Make with Mouser IoT Design Contest

MenoPLAY #1 - Introduction

Menopause, also known as the climacteric, is the time in most women's lives when menstrual periods stop permanently, and they are no longer able to bear children. Menopause typically occurs between 45 and 55 years of age. Medical professionals often define menopause as having occurred when a woman has not had any menstrual bleeding for a year. It may also be defined by a natural decline in reproductive hormone production by the ovaries when a woman reaches her 40s or 50s.

Recent studies show that many of the symptoms are undetected as menopausal symptoms and a majority of women are unwilling to disclose their symptoms even to personal physicians and this makes the situation worse.



Some of the symptoms are-

Night sweats

Hot Flashes

Osteoporosis

Incontinence

Mood Swings

and many more...



Solution

MenoPlay is a revolutionary wearable technology that combines the power of sensors, Augmented Reality(AR) and data analysis to ensure that menopause isn`t a pause. Enough of the chartbuster stuff(I know I am bad at marketing). Let`s get to the point.



The underlying philosophy was to take all the good features in the products available in this market and design something that is -



- Affordable



- Minimalist



- Able to treat many symptoms



- Hardware complemented with insightful software



MenoPLAY tries to overcome all this by targeting many symptoms like hot flashes, osteoporosis, mood swings, incontinence, sexual discomfort, skipped periods and hormonal imbalance. It logs important biophysical parameters to implement augmented reality techniques to deliver valuable, anonymous and timely advice to the user. The user`s progress is monitored and important notifications are issued in pseudo-scientific manner through a connected mobile application and cloud facility.



Implementation

The device is based around the APPD4100Z pulse meter sensor frontend interfaced over SPI to an Arduino MKR1010 Wifi dev board connected to the Arduino IoT Cloud. The patient`s blood pressure and heart rate are logged to determine whether the patient is currently experiencing a hot flash or not. A hot flash is a sudden rise in the amount of blood flowing to the extremities of the body which creates and uneasy feeling. almost 90% of menopausal women consider this as the most irritable symptom of menopause.

As soon as this condition is detected by analysing the sensor data using stock DSP algorithms on the microcontroller, a cooling module fitted to the back of the neck of the patient is activated to provide a cooling sensation and thus remove the source of irritation.

If the woman feels dizzy, the fall sensor module logs the event and immediately informs near ones by sending MQTT messages over the cloud. Further, the Sp02 readings are logged and stored in a local database that is periodically analysed and inferences drawn are published onto the cloud for the patient`s doctors to study and suggest course of further medication.





I had an Arduino MKR1010 Wifi from a previous project lying around. The acelerometers were readilly available at a local store. I used the MPU9250 with temperature sensor. With one set, I made necessary connections on the I2C line of the NRF master, connecting the oximeter and the MPU9250. I soldered everything directly for a small form factor and reliable connections. I hot glued them on top of an old ring I sourced from my mother`s discarded collection(Don`t tell her). For power source, I used a 3.7V/1100mAh Li-ion battery.

View attachment 238399
Accelerometer testing

I put the example BLE sketch in the Arduino Wifi examples on the board, added the I2C sensors as inputs and broadcasted the data. On the NRF Connect app on my laptop and analysed the plots. After I was convinced with the results, I took two minuscule pieces of Al foil and placed them at the two inside ends of a ring, to measure resistance. Since I did not have sample data this took me about an hour, to ascertain abnormal limits. I also discovered a way to trigger an alarm by analysing the heart rate data, thanks to the NRF Connect app. The trick here lies in detecting an 18-20 beats per minute rise in heart rate from normal. I simulated this by skipping in the process of which the hot glue came off and the solder too. My Bad. I soon did over the mess and started with the cooler module for the neck.

View attachment 238400
The box I used(background removed)

I salvaged a RasPi heat sink, a fan for the same and a peltier module. I connected the other NRF module, attached the battery, the accelerometer and put everything in a plastic cards box with the peltier module facing the skin. FIrst, I tried with the fan. The cooling was good but the power consumption very high. I tried with the heat sink and the results were good enough. The accelerometer data received was also good enough.

MenoPLAY #2 - The Hardware
The EVAL-ADPD4100Z-PPG evaluation board provides users with a simple means of evaluating the ADPD4100/ADPD4101 photometric front end.
The EVAL-ADPD4100Z-PPG evaluation board implements a simple discrete optical design for vital signs monitoring applications, specifically wrist-based photoplethysmography (PPG).
View attachment 238397
The bottom view exposing the photosensor
View attachment 238398
The top view showing the sensor frontends

The EVAL-ADPD4100Z-PPG has three green light emitting diodes (LEDs), one infrared (IR), and one red LED, all separately driven. A single 7 mm2 photodiode (PD) is populated on the board.It’s a complete Multimodal Sensor Front End, can be considered to be an all-rounder in biomedical sensor design. The AFE is based on Trans Impedance Amplifier [TIA].

AFE consists of a trans-impedance amplifier (TIA), a band-pass filter (BPF), an integrator (INT), and an analog-to-digital converter (ADC) stages. Dual-channel processing provides a simultaneous sampling of two different parameters or a single differential signal.
A selectable second- to fourth-order cascaded integrator comb (CIC) filter provides on-chip digital filtering.

The evaluation board is populated with ADPD4100 which supports SPI interface and operates @ 1.8v [analog core] and 1.8v / 3.3v [digital I/O].

ADPD4101-1.png

The block diagram of the board

Along with this, it has the capability of driving up to eight light-emitting diodes (LEDs) at a total 400mA peak current and measuring current inputs through eight separate channels. Twelve separate time slots can be utilized to measure parameters in a single sampling period. It has a programmable sampling rate from 0.004 Hz to 9 kHz using internal oscillators.

What`s More.....
The EVAL-ADPD4100Z-PPG board is powered by the EVAL-ADPDUCZ microcontroller board (obtained from the EVAL-ADPD4100Z-PPG product page). In addition to the power requirements, serial port interface (SPI) (default) or I2 C data streams are received from the ADPD4100 by the microcontroller. A ribbon cable connects the two boards. The microcontroller repackages the data, sending it to a virtual serial port over the USB to the PC, displayed on the Wavetool Evaluation Software. The EVAL-ADPD4100Z-PPG can also be connected directly to the microcontroller development system of the user, using the SPI for the ADPD4100 (or I2C for the ADPD4101).

The full evaluation system includes the Wavetool Evaluation Software graphical user interface (GUI) that provides users with low level register access and high-level system configurability. Raw data streamed to this tool can be displayed in real time with limited latency. Views are provided for both frequency and time domain analysis.

A user datagram protocol (UDP) transfer capability from the Wavetool Evaluation Software (available for download on the EVAL-ADPD4100Z-PPG product page) allows data stream connections and register configurability to external analysis programs, such as LabVIEW® or MATLAB®, in real time.


Working Mode

This layout shows the potential modes of operation for measuring SpO2 value from my ADPD4100Z evaluation board.

spo2 configuration layout.jpg


Basic PPG circuitry, SpO2 measurement as explained needs two such configurations

In summary,
The evaluation board is a great piece of hardware that comes with quality software supplementing it. The only catch is that it requires the EVAL-ADPDUCZ microcontroller board for testing even the example applications and evaluating the software tool. So, the evaluation board in itself is quite meaningless - at least the name
  • Board supports ADPD4100 and ADPD4101 population
  • ADPD4100 (SPI) is the default board population
  • All inputs and outputs are accessible to the user
  • 3 separately driven green LEDs included
  • 1 red and 1 IR LED included
  • Metal baffle to block optical crosstalk
  • Works with the Wavetool Evaluation Software allowing
    • Time-domain graphing and logging
    • Frequency domain graphing
    • Statistical analysis
    • Data streaming to other applications

MenoPLAY #3 - Connecting Sensors to the Cloud

Connecting to Arduino IoT Cloud


Go
to Arduino IoT Cloud

Make an account and verify your email address(not helping you with that)

Go to the Devices tab and connect your Arduino MKR1010 Wifi to your computer via a microUSB-B cable

On successful detection, you should see this

View attachment 238401


Board found

Give a name to your device(No spaces or special characters)

View attachment 238402

View attachment 238403

Create a new Thing

View attachment 238404

Give the thing a name
View attachment 238405
Go to the Add Property tab and add all the necessary data configuration

View attachment 238406
Your device is all set to send data to the cloud

View attachment 238407

Edit the automatically generated Sketch and upload to your board using Arduino Create Agent which you will be prompted to download for your preferred browser
View attachment 238408
View attachment 238409
Go to your Dashboards tab and view the incoming data



View attachment 238410

Connecting with Google Sheets for visualisation and easy cross-platform access

In the Web Editor we need to add some code to the template sketch that has been generated. First, before the setup function, we define three constants for the board pins that will be used:

#define PIN_TEMP A1

#define PIN_HUM A2

#define PIN_BATT 5

Next, in the setup function, we initialize pin modes:

pinMode(PIN_TEMP, INPUT);

pinMode(PIN_HUM, INPUT);

pinMode(PIN_BATT, INTPUT);

In the loop function we read analog values from the sensors:

int wd_temp = (analogRead(PIN_TEMP) * 3.3) / 1024.0 - 0.5) * 100.0;

int wd_hum = analogRead(PIN_HUM)*100*RHF;

float batt_percent = analogRead(PIN_BATT)/4.2 * constB;

Now we must fill the Secret Tab with our WiFi credentials and then upload the sketch to our Arduino board. When the sketch is uploaded, the board should connect to the cloud (we can check by opening the Serial Monitor) and we should see values changing every 30s in the dashboard view of IoT Cloud.

Google Apps Script

Now let’s put aside the Arduino part of this project and let’s concentrate on the Google app.

First thing first, go to Google Sheets and create a new blank spreadsheet. Rename the sheet to something like “RoboData”, then click on Tools > Script Editor to open Google Apps Script.


Go to Tools > Script Editor to open Google Apps Script

In the window that appears we can write some code that will be executed whenever a message is sent from the IoT Cloud using webhooks. Our goal is to read incoming data from the cloud and write them in a spreadsheet as a table. We want to write not only the properties’ values but also the date and time at which they are updated.

First, we define variables for our spreadsheet and for the sheet which will contain numerical data:

var sheet = SpreadsheetApp.getActiveSheet().getSheetByName('RoboData');

Here we define some constants:

var MAX_ROWS = 1440; // max number of data rows to display

var HEADER_ROW = 1; // row index of header

var TIMESTAMP_COL = 1; // column index of the timestamp column

We define MAX_ROWS because we want to maintain constant the number of rows of our table, i.e. each time an extra row is written, we delete the last one. In order to define MAX_ROWS we have chosen a total buffer time of 12 hours, then considering that the Cloud updates properties every 30 seconds, we can calculate MAX_ROWS = 3600s / 30s * 12h = 1440.

The function doPost(e) {} receives post request from the IoT Cloud and stores the incoming data into the variable e. Inside this function, we will automatically update our spreadsheet.

In order to get sensible data from e, we have to interpret it as a JSON object:

var cloudData = JSON.parse(e.postData.contents);

cloudData is now a JSON object with the following structure:

{webhook_id: 312064b8-ea32-5711-959b-6643b8ce8d2c,

device_id: 268a4d5e-d882-4961-9fff-abc42b641142,

thing_id: d161b2f0-a830-4c01-b0d7-6cdf0d9f6456,

values: [{id: 1552695e-50b8-4cd3-b2c7-826bdeedb0ec,

name: power_switch,

value: true,

persist: false,

updated_at: 2019-02-25T09:59:52.14Z,

created_by: f5d24652-25f8-4295-abce-d056ac47b3d8},...,{}]}

Notice that the values field is itself an array of JSON objects!

We can extract parameters from cloudData in the following way:

var webhook_id = cloudData.webhook_id;

var device_id = cloudData.device_id;

var thing_id = cloudData.thing_id;

var values = cloudData.values;

Next, we store names and values in separate arrays just to make things more manageable:

var incLength = values.length;

var incNames = [];

var incValues = [];

for (var i = 0; i < incLength; i++) {

incNames = values.name;

}

Now we read the timestamp of the incoming message and we turn it into a javascript date object. Since the timestamp is already formatted as yyyy-MM-ddTHH:mm:ss.mmmZ, we can use the Date.parse() method:

var timestamp = values[0].updated_at;

var date = new Date(Date.parse(timestamp));

Due to inconsistency and presence of duplicate messages, we add some checks so to accept messages in ascending order with respect to time:

if (date.getYear() > 2018) {

// discard all messages that arrive 'late'

if (sheet.getRange(HEADER_ROW+1, 1).getValue() != '') { // for the first time app is run

var now = new Date();

var COMM_TIME = 5; // rough overestimate of communication time between cloud and app

if (now.getTime() - date.getTime() > COMM_TIME * 1000) {

return;

}

}

}

Important note: adjust COMM_TIME based on the WiFi connection quality of your board! Moreover, COMM_TIME must be smaller than the update interval chosen in the IoT Cloud (30s in our case).

If the incoming message gets through previous checks, we can start writing data into our spreadsheet.

The following code block automatically detects properties’ names and writes them in the header row.

sheet.getRange(HEADER_ROW, 1).setValue('timestamp');

for (var i = 0; i < incLength; i++) {

var lastCol = sheet.getLastColumn();

if (lastCol == 1) {

sheet.getRange(HEADER_ROW, lastCol + 1).setValue(incNames);

} else {

// check if the name is already in header

var found = 0;

for (var col = 2; col <= lastCol; col++) {

if (sheet.getRange(HEADER_ROW, col).getValue() == incNames) {

found = 1;

break;

}

}

if (found == 0) {

sheet.getRange(HEADER_ROW, lastCol+1).setValue(incNames);

}

}

}

Next, we delete the last row, if the maximum number of rows has been reached:

var lastCol = sheet.getLastColumn();

var lastRow = sheet.getLastRow();

if (lastRow > MAX_ROWS + HEADER_ROW - 1) {

sheet.deleteRow(lastRow);

}

We insert a new row, specifying its style:

sheet.insertRowAfter(HEADER_ROW);

var range = sheet.getRange('A2:Z2');

range.setFontColor('#000000');

range.setFontSize(10);

range.setFontWeight('normal');

And finally, we write the timestamp and all other values:

sheet.getRange(HEADER_ROW+1, TIMESTAMP_COL).setValue(date).setNumberFormat("yyyy-MM-dd HH:mm:ss");

// first copy previous values

// this is to avoid empty cells if not all properties are updated at the same time

sheet.getRange(HEADER_ROW+1, col).setValue(sheet.getRange(HEADER_ROW+2, col).getValue());

for (var i = 0; i < incLength; i++) {

var currentName = sheet.getRange(HEADER_ROW, col).getValue();

if (currentName == incNames) {

// turn boolean values into 0/1, otherwise google sheets interprets them as labels in the graph

if (incValues == true) {

incValues = 1;

} else if (incValues == false) {

incValues = 0;

}

sheet.getRange(HEADER_ROW+1, col).setValue(incValues);

}

}

}

In order to actually use this code we first need to publish it, thus go to Publish > Deploy as web app. If you’ve never saved the project before you will be asked to name it. In the popup window select a new project version and make sure to give access to the app to “anyone, even anonymous”, then click on deploy.




View attachment 238411
Select New Project Version and give access to anyone

Copy the web app URL that appears and click OK.




View attachment 238412
Copy the web app URL

The copied URL will be our webhook the IoT Cloud will use to access the Google app. We must copy this URL in the IoT Cloud edit view under webhook and click Update.
View attachment 238413
Paste the URL under webhook in the IoT Cloud

At this point, let’s power our circuit! If everything is working correctly, after the board is connected to the cloud we should see rows appearing in our spreadsheet once every 30 seconds. Remember that there is a bit of delay between the cloud and the spreadsheet updates, so don’t worry if the timestamps don’t match up perfectly with the actual time: they should have a delay of some seconds, depending on the quality of the WiFi connection.

Making Sense of the Data - with Charts

The only thing that remains to do is to create cool charts and add some style to the spreadsheet. For example, we can make the header text bold, change its color and set alternating colours for other rows. We can also choose specific date and number formats for each column by going to Format > Number.
View attachment 238414

In order to add a chart, select the timestamp column and another column (you need to select the entire column, not a limited range), then click on the chart icon, and a new chart will be created. To avoid problems due to scrolling of the sheets when a new row is added, click on the three dots on the top right of the chart window and click on Move to own sheet. This will move the chart into a new sheet and from there we can customize it as we want by clicking the Edit button.


MenoPLAY #4 - The Final Setup
Finally lets have a look at the code that helps us acquire the data from the much-hyped sensor frontend
Sadly, there is no example code that AD has made available for quick prototyping on this board. However, all hope is not lost. After wandering all sorts of websites and forums for more than a week I finally figured out that to get the sensor front ends to send meaningful data, a repository does exist that can be modified to get the desired data

Log on to : https://github.com/analogdevicesinc/adpd-drivers

Clone the repo locally and look for the driver files for the evaluation board. All the drivers are made for the ADPD-4000 variant and not the 4100 variant of the board. To use the code available you will have to use Mbed libraries. Assuming that you already have a Development environment like KeiluVision or Segger Embedded Studio, it should not take much time to set up the project

Steps to load mbed program:
1. Create the account at https://os.mbed.com/ and log in.
2. Click the https://os.mbed.com/platforms/Arduino_wrapper/ , the target board will displayed and add to the compiler.
3. In the mbed online compiler, click the import option and click the import from the url.
4. A popup window will be opened. In that enter the Source URL, choose the Import as a Program and click Import.
5. After the importing has been done successfully, click the compile option in the mbed online compiler. A binary file will be downloaded after successful compilation.
6. Plug the hardware to USB socket of the PC with USB mini cable. The drive partition will be displayed in PC with name as SDP_K1.
7. Open Tera Term serial console and select the com port of the MCU. Identify the COM port by opening Device Manager in the host PC.
8. Click the Setup option, in that choose the serial port. Select the baud rate/Speed as 115200 and hit OK or New Setting.
9. Drag and drop the downloaded binary file into the Arduino MKR1010 drive partition on PC.

I made changes to the files in the repo and was very near to actually acquiring the data when my signal generator malfunctioned and it is very hard to debug the circuit now. Therefore, I am unable to complete the quest I had embarked on and was so near to accomplishing.
I have created an Arduino Wrapper library for the ADPD4100Z board which will surely make the lives of fellow developers easier.


Acknowledgments

I am really thankful to Analog Devices for providing this great piece of hardware that is sure to take the wearables industry by storm. I would also like to thank the team at allaboutcircuits for managing the entire event very well and delivering the hardware to me in such a difficult time. I received the hardware just 9 days back and therefore it was really difficult for me to get my concept working in this short time. However, I have not lost hope. I will keep working towards my project and make it a success and post updates on the community

Blog entry information

Author
moi121
Views
516
Last update

More entries in Design Contest

Share this entry

Top