Patient Monitoring System using 96Boards
This repository consists of instructions to set up a Patient Monitoring
Systems using 96Boards with the help of BLE Mesh network.
Below steps are used to setup the nodes and Gateway in BLE Mesh network. In this
project 2 Carbon boards will be used as Server nodes and one Carbon board will be
used as a Client node. Dragonboard410c will be used as a Gateway.
Following steps are used to setup the BLE Mesh nodes:
[Execute this section on all Carbon boards using Host machine]
Follow the below steps to flash the hci_spi sample application
to the nRF co-processor on 96Boards Carbon using a Linux enabled host
machine.
First setup the development environment as mentioned here.
$ git clone https://github.com/Mani-Sadhasivam/zephyr.git
$ cd zephyr
$ git checkout ble_mesh_3
$ source zephyr-env.sh
$ samples/bluetooth/hci_spi
$ mkdir build
$ cd build
$ cmake -DBOARD=96b_carbon_nrf51 ..
$ make
Once the application is successfully built, flash the binary onto the
nRF chip by following this guide.
Now, this chip can provide HCI interface to STM32 via SPI.
[Execute this section on the Carbon boards to be used as Server nodes using Host machine]
Next step is to program the Sensor Server application to the STM32 chip
on the Carbon boards to act as a Sensor Servers.
Move to the top of the cloned Zephyr repository.
$ cd zephyr
$ cd samples/bluetooth/ble_mesh_srv
$ mkdir build
$ cd build
$ cmake -DBOARD=96b_carbon ..
$ make
Note: You should set different
NODE_ID
inble_mesh_srv/src/main.c
for different
Server nodes. For this project, it is assumed that first node containsNODE_ID
of 1
and second node containsNODE_ID
of 2.
Now, the built binary can be flashed by following this guide.
Once the application binary is flashed, connect the UART port of Carbon
board to the Host machine using USB-A to USB-B Micro cable and bring up
the serial emulation tool like minicom on the corresponding port.
After board reset you should see the below message on the serial port:
Initializing...
Bluetooth initialized
Mesh initialized
[Execute this section on the Carbon board to be used as a Client node using Host machine]
As like the Sensor Server application, Sensor Client application is also
need to be programmed on another Carbon board.
Move to the top of the cloned Zephyr repository.
$ cd zephyr
$ cd samples/bluetooth/ble_mesh_cli
$ mkdir build
$ cd build
$ cmake -DBOARD=96b_carbon ..
$ make
Now, the built binary can be flashed by following this guide.
Once the application binary is flashed, connect the UART port of Carbon
board to the Host machine using USB-A to USB-B Micro cable and bring up
the serial emulation tool like minicom on the corresponding port.
After board reset you should see the below message on the serial port:
Initializing...
Bluetooth initialized
Mesh initialized
[Execute this section on all Carbon boards using Host machine]
Next step is to provision and configure both the nodes to be used in BLE Mesh network.
This requires the meshctl
utility in Bluez stack.
Install Bluez by following the below steps.
$ git clone https://git.kernel.org/pub/scm/bluetooth/bluez.git
$ cd bluez
$ bootstrap
$ ./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc --localstatedir=/var --enable-mesh
$ make
$ sudo make install
Above commands will install Bluez on the host machine with BLE mesh support.
[Execute the below section on the Carbon boards to be used as Server using Host machine]
Now, execute the below steps for provisioning and configuring the Server node:
$ cd bluez/mesh
$ meshctl
This will bring up the meshctl command prompt.
[meshctl]# discover-unprovisioned on
[meshctl]# provision dddd
Here we are provisioning the node dddd
which is default address for all
un-provisioned nodes.
Now, enter the OOB number displayed in the Server’s serial terminal here.
[meshctl]# menu config
[meshctl]# target 0100
Here 0100 is the node address after provision. Modify it based on the assigned address.
Now, generate AppKey and bind it to the 0th element of models 1100 and 1000.
[meshctl]# appkey-add 1
[meshctl]# bind 0 1 1100
[meshctl]# bind 0 1 1000
Next, add the subscription and publish info to the models.
[meshctl]# sub-add 017a c000 1100
[meshctl]# pub-set 017a c000 1 0 0 1100
[meshctl]# pub-set 017a c000 1 0 0 1000
Once, all the above commands are executed successfully, we can assume that
the Sensor node is configured.
[Execute the below section for the Carbon board to be used as Client using Host machine]
Now, execute the below steps for provisioning and configuring the Client node:
$ cd bluez/mesh
$ meshctl
[meshctl]# discover-unprovisioned on
[meshctl]# provision dddd
Now, enter the OOB number displayed in the Client’s serial terminal here.
[meshctl]# menu config
[meshctl]# target 0101
Here 0101 is the node address after provision. Modify it based on the assigned address.
Now, generate AppKey and bind it to the 0th element of Client Sensor model (1102).
[meshctl]# appkey-add 1
[meshctl]# bind 0 1 1102
[meshctl]# bind 0 1 1001
Next, add the subscription and publish info to the models.
[meshctl]# pub-set 017b c000 1 0 0 1102
[meshctl]# sub-add 017b c000 1102
[meshctl]# sub-add 017b c000 1001
Once, all the above commands are executed successfully, we can assume that
the Client node is configured.
We are going to use ThingSpeak as the cloud service
provider and Twilio for sending emergency alerts.
Using Thingspeak is very straightforward and easy task. Just create an account
on their website then sign-in and follow the below steps:
After Signing in, you will be provided with a window having a button
named New Channel. Click it and it will proceed to create a new channel
in Thingspeak.
In the next window, provide the following information to create our channel:
Then click, Save Channel to save the channel information.
Note: Note down Write API Key, Read API Key and Channel ID for future use.
Now our channel is created and we have declared 3 fields: Temperature, Co2
and Emergency Button. These are the parameters which will be streamed from
the BLE mesh network.
Next step is to add visualizations for the created fields. Goto Apps->Plugins.
Click New. There will be 3 options for creating the visualization, for this
project we will be using Google Gauge. So, select it and click Create.
In the next window, enter Name as Temperature and replace the
Javascript code with below so that we can create a Google gauge for
Temperature readings:
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'></script>
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
<script type='text/javascript'>
// set your channel id here
var channel_id = 404689;
// set your channel's read api key here if necessary
var api_key = 'A173BFJ51PIY91RZ';
// name of the gauge
var gauge_name = 'Temp';
// global variables
var chart, charts, data;
// load the google gauge visualization
google.load('visualization', '1', {packages:['gauge']});
google.setOnLoadCallback(initChart);
// display the data
function displayData(point) {
data.setValue(0, 0, gauge_name);
data.setValue(0, 1, point);
chart.draw(data, options);
}
// load the data
function loadData() {
// variable for the data point
var p;
// get the data from thingspeak
$.getJSON('https://api.thingspeak.com/channels/' + channel_id + '/feed/last.json?api_key=' + api_key, function(data) {
// get the data point
p = data.field1;
// if there is a data point display it
if (p) {
displayData(p);
}
});
}
// initialize the chart
function initChart() {
data = new google.visualization.DataTable();
data.addColumn('string', 'Label');
data.addColumn('number', 'Value');
data.addRows(1);
chart = new google.visualization.Gauge(document.getElementById('gauge_div'));
options = {width: 220, height: 220, max: 80, redFrom: 60, redTo: 80, yellowFrom:40, yellowTo: 60, greenFrom: 20, greenTo:40, minorTicks: 10};
loadData();
// load new data every 15 seconds
setInterval('loadData()', 15000);
}
</script>
Then, click Save
Note: Replace channel_id and api_key with your ID and key.
Next, repeat Step 4, 5 to create another gauge for Co2 readings.
Enter Name as Co2 Concentration and paste
the below contents in Javascipt code editor.
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'></script>
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
<script type='text/javascript'>
// set your channel id here
var channel_id = 404689;
// set your channel's read api key here if necessary
var api_key = 'A173BFJ51PIY91RZ';
// name of the gauge
var gauge_name = 'Co2';
// global variables
var chart, charts, data;
// load the google gauge visualization
google.load('visualization', '1', {packages:['gauge']});
google.setOnLoadCallback(initChart);
// display the data
function displayData(point) {
data.setValue(0, 0, gauge_name);
data.setValue(0, 1, point);
chart.draw(data, options);
}
// load the data
function loadData() {
// variable for the data point
var p;
// get the data from thingspeak
$.getJSON('https://api.thingspeak.com/channels/' + channel_id + '/feed/last.json?api_key=' + api_key, function(data) {
// get the data point
p = data.field2;
// if there is a data point display it
if (p) {
displayData(p);
}
});
}
// initialize the chart
function initChart() {
data = new google.visualization.DataTable();
data.addColumn('string', 'Label');
data.addColumn('number', 'Value');
data.addRows(1);
chart = new google.visualization.Gauge(document.getElementById('gauge_div'));
options = {width: 220, height: 220, max: 2000, greenFrom: 500, greenTo:1200, redFrom: 1600, redTo: 2000, yellowFrom:1200, yellowTo: 1750, minorTicks: 10};
loadData();
// load new data every 15 seconds
setInterval('loadData()', 15000);
}
</script>
Then, click Save.
Note: Replace channel_id and api_key with your ID and key.
Now, we have created two Google gauges for displaying the Temperature
and Co2 readings. Next step is to add those to our channel. Goto Channels->My Channels
and select the channel Patient 1. In the channel dashboard, click
Add Visualizations.
Select the following widgets:
Finally, click Save.
Once all of the above mentioned steps are executed successfully we will have 4
widgets appearing on our channel.
For sending the Emergency Alert, we will be using Twilio.
Create an account there and follow the below steps:
Sign-in to the Twilio Console and note down
the displayed ACCOUNT SID and AUTH TOKEN fields.
Now, verify
a mobile number for which Twilio can send Emergency alerts.
Go to the Patient 1 dashboard we created on Thingspeak and select Apps->ThingHTTP->New ThingHTTP.
Enter the following credentials:
Note: Enter your Twilio number in From= field and destination number in To= field.
Click Save ThingHTTP.
3(Emergency Button)
is equal to
1
Patient Monitoring Alert
Click Save React.
Now, we are done with all settings needed to visualize the data from mesh network on
cloud and also an Emergency alert when the push button is pressed
Note: You need to setup Thingspeak channel for all Server nodes used. Just replace
the Read API key, channel ID and channel name accordingly. For this project,
we need to setup two channels for two Server nodes.
Once the nodes are configured as mentioned above, the gateway needs to be setup
in order to receive data from the client node via USB to UART. For this, we
are going to use one python script which captures and uploads the data to cloud.
The following instructions assume that the Dragonboard410c(Gateway) has been
setup properly with latest Debian release from Linaro.
First, install the required packages:
$ pip install --user pyserial
$ pip install --user thingspeak
Next, save the below contents to a file named pyserial.py
import serial
import sys
from time import sleep
import urllib2
key1 = 'Enter your Write key for channel 1'
baseURL1 = 'https://api.thingspeak.com/update?api_key=%s' % key1
key2 = 'Enter your Write key for channel 2'
baseURL2 = 'https://api.thingspeak.com/update?api_key=%s' % key2
# open serial
ser = serial.Serial('/dev/ttyUSB0', 115200)
while True:
try:
# Read serial
ser_data = ser.readline()
sen_data = ser_data.split(',')
if (sen_data[0] == '1'):
# Upload data to thinkspeak channel 1
thing_status = urllib2.urlopen(baseURL1 + "&field1=%s&field2=%s&field3=%d" % (sen_data[1], sen_data[2], int(sen_data[3])))
print thing_status.read()
thing_status.close()
if (sen_data[0] == '2'):
# Upload data to thinkspeak channel 2
thing_status = urllib2.urlopen(baseURL2 + "&field1=%s&field2=%s&field3=%d" % (sen_data[1], sen_data[2], int(sen_data[3])))
print thing_status.read()
thing_status.close()
# Thingspeak only accepts data once every 15 seconds
sleep(15)
except KeyboardInterrupt:
print "Exiting..."
sys.exit()
Note: Enter your Write API key in key1/key2 variables with single quotes (‘’).
Note: At this point both the Carbon boards should be provisioned and the Gateway should be setup.
Once everything is setup as mentioned above, execute the python script on the gateway
to deploy the patient monitoring system.
Now, the Dashboard on Thingspeak will get updated as below and if the emergency button
is pressed, the registered user will get an emergency alert SMS.