Introduction: Alzheimer's Assistant
1 in 9 people aged 65 and older has Alzheimer’s disease”
“Family caregivers spend more than $5000 an year caring for someone with Alzheimer’s. For some families this means missing a vacation. But for others, it may mean going hungry”
These facts quoted straight from the Alzheimer’s Association website are enough to give anyone an idea of the problems a person has to go through if they, or their loved ones have Alzheimer’s disease.
Being a maker, I thought about this and decided that I will build a wearable device, a system which can help both patients and their caretakers. This system should be able to carry out at least the following tasks:
- Reminding the patient of carrying out tasks, he/she has to do daily (such as medications, exercise, etc)
- Monitor where the patient is in the house
- Alert the caretakers in case of an emergency of any sort
- Display the time (it's a watch, after all!)
- It should be portable, and easy to use, even for an elder patient
- The cost should be kept to a minimum
When I saw Infineon’s Sensor Hub Nano, it appeared to be a good candidate in such a project, because of its very small size and BLE capabilities. With the accurate pressure sensing, it could be used to detect if the patient has fallen and also tell where exactly the patient is in the house.
I will be using the following parts for the bare-bones project to function:
- Infineon's Sensor Hub Nano
- Arduino MKR1000
- HC-05 Bluetooth Module
- Nokia 5110 Display
You will know what I mean by “bare-bones project” when you read the 'Personalising Alzheimer’s Assistant' section.
Step 1: How It Works
In this section, I will briefly describe how the watch works and outline the steps we have to go through to make it work.
Infineon's Sensor Hub Nano evaluation board has a DPS310 barometric pressure sensor, which sends its data through the evaluation board via bluetooth. The pressure, altitude and temperature values can be viewed in the Android app by Infineon (download here) as well as SES2G evaluation software. Users can also build applications for Android with the library Infineon provides, based on their own requirement.
You can find more information about the Sensor Hub Nano here.
But, I want Alzheimer's Assistant to work without an Android phone in between. It should be a wearable which can work by itself, as well as have the ability to connect to a smartphone to view the sensor data. So, I decided that I will use an Arduino MKR1000 board due to its small form factor and WiFi capability, and connect it by some method to the Sensor Hub Nano.
Attached is the pinout for the Arduino MKR1000 which you will find handy.
I had an HC-05 bluetooth module, and so I had to use that for the connection between the Arduino MKR1000 and the Sensor Hub Nano. But first, we need to get the HC-05 properly connected to the Arduino's hardware Tx and Rx pins, taking into account the logic levels. My bluetooth module works at the 3.3v, which is the same as the MKR1000 so there was no need for any voltage level shifter. But if you're bluetooth module works at the 5v level, you may need to use a level shifter similar to the one shown.
After matching the voltage levels, we need to pair the HC-05 with the Sensor Hub Nano to start data communication between them, and find an easy way to get them to pair automatically every time the Sensor Hub Nano gets in bluetooth range of the HC-05.
To do that, I thought of configuring the HC-05 to act as a bluetooth 'master' device, and pair it only with a specific MAC address; that of the Sensor Hub Nano. So after configuring it like that, once you turn on the HC-05, it searches for a device with a specific MAC address (that of the Sensor Hub Nano), and automatically pairs with it, leaving it up to the user to send and receive data.
This is done using AT mode commands for the HC-05 and is covered in the "Configuring the Bluetooth Module" section.
Note: I have attached a document I found online, which lists all AT commands the HC-05 supports, so use them as needed.
Once it is paired and connected properly, sending commands to the Sensor Hub Nano is like a bluetooth terminal. You can use the commands I specified above by simply printing them as a String, through the hardware serial port the HC-05 is connected to. For example, this is the command you will send to start the flow of sensor data:
$start_sensor id=1 //To start the flow of sensor data
Here is a list of the commands I know:
<p>$hello id= //Hello<br>$info id= //Info $sinfo id=1 //Sensor Info $set_mode sid=1;md=mode;val=bg //Low energy $set_mode sid=1;md=prs_osr;val=16 //Standard mode $set_mode sid=1;md=prs_mr;val=32 //High precision $start_sensor id=1 //Start $stop id= //Stop</p>
The sensor data coming from the Sensor Hub Nano is in this format:
<p>$1,t,36.9299,1154206 //Temperature<br>$1,p,997.6813,1154206 //Pressure $1,a,130.4305,1154206 //Altitude</p>
Note: I would like to give a reference to Peter Smith's blog post, which helped me to start the communication with the Sensor Hub Nano using bluetooth.
Once we are able to start the flow of data from the module, we need a way to parse the data from it. This was, I must admit, the toughest part of the project; once you send the command for starting the flow of data, the Sensor Hub Nano just sends a stream of data, leaving it up to the device receiving the data to parse anything sensible from it. So, after trying out many methods of varying complexity (which I won't go through here), this was the simplest and the most efficient method which I came up with, to parse data from the Sensor Hub Nano.
<p>void getSensorValues() { <br> //Retrieves the sensor values from the Sensor Hub Nano through the Serial1 port String junkVal; if (Serial1.available()) { junkVal = Serial1.readStringUntil('\n'); junkVal = Serial1.readStringUntil('t'); t = Serial1.parseFloat(); junkVal = Serial1.readStringUntil('p'); p = Serial1.parseFloat(); junkVal = Serial1.readStringUntil('a'); a = Serial1.parseFloat(); junkVal = Serial1.readStringUntil('\n'); } }</p>
A display will also be connected to the Arduino to interact with the user, and show any messages, or to display the time or the data from the sensor (More on this as you read on).
Once you get the data in the Arduino MKR1000, due to its wireless connectivity, you can send the data to a number of different IoT platforms, such as Cayenne or Blynk.
I had decided to use Cayenne for this, as I was impressed by its beautiful interface and easy setup. But, sadly, it had some bugs with the MKR1000 WiFi connection which prevented us from selecting pins. I should mention that the guys over at Cayenne were very helpful, but still the problem wasn't resolved. Therefore, I decided to use Blynk in the end, but they are very similar in usage, so just by changing a few lines of Arduino code, you can switch over from Blynk to Cayenne if you want to test it out or once the issue is resolved. Both have the same features, more or less, so its just your own preference. But the only advantage of Cayenne is that you can access it on a PC as well, while Blynk only works on smartphones.
Now, we have received data from the Sensor Hub Nano, got it into the Arduino, and transferred it over to an IoT platform (I'll say Blynk from now on), and so, now you will just need to personalize Alzheimer's Assistant according to your own needs, and that is dealt with in another section (Fall and location detection are discussed there).
Note: I have tried to document each and every step in detail, but if you do not know something (like to upload code to your Arduino), it would be a better idea to go to the Arduino homepage, be familiar with it for a while and then come back for this, once you know at least the basics.
Step 2: The Code
Note: Read through the documentation first before uploading these codes to your Arduino, as modifications have to be made for Alzheimer's Assistant to work
AT Commands:
// Original sketch from Martyn Currey's blog here:
// http://www.martyncurrey.com/arduino-with-hc-05-bl... // // Sketch modified by me to work with Arduino MKR1000! // // Basic Bluetooth sketch // Connect the HC-05 module and communicate using the serial monitor // // The HC-05 defaults to commincation mode when first powered on. // Needs to be placed in to AT mode // After a factory reset the default baud rate for communication mode is 38400char c = ' ';
void setup() { // start the serial communication with the host computer Serial.begin(9600); Serial.println("Arduino with HC-05 is ready");
// start communication with the HC-05 using 38400 Serial1.begin(38400); Serial.println("Serial1 started at 38400"); }
void loop() { // Keep reading from HC-05 and send to Arduino Serial Monitor if (Serial1.available()) { c = Serial1.read(); Serial.write(c); }
// Keep reading from Arduino Serial Monitor and send to HC-05 if (Serial.available()) { c = Serial.read();
// mirror the commands back to the serial monitor // makes it easy to follow the commands Serial.write(c); Serial1.write(c); } }
Alzheimer's Assistant:
//Including required libraries
#include #include #include #include #include #include// You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = ""; //Enter your Blynk auth token here
// Your WiFi credentials. // Set password to "" for open networks. char ssid[] = ""; char pass[] = "";
//Defining Sensor Hub Nano board commands #define HELLO "$hello id=" #define INFO "$info id=" #define SENSOR_INFO "$sinfo id=1" #define LOW_ENERGY "$set_mode sid=1;md=mode;val=bg" #define STANDARD_MODE "$set_mode sid=1;md=prs_osr;val=16" #define HIGH_PRECISION "$set_mode sid=1;md=prs_mr;val=32" #define START "$start_sensor id=1" #define STOP "$stop id="
//Defining fall and clearance thresholds //You may need to change them, but I found these values to be good #define FALL 0.7 #define CLEARANCE 0.2
//Defining Blynk virtual pins #define vTEMPERATURE_PIN V0 #define vPRESSURE_PIN V1 #define vALTITUDE_PIN V2 #define vEVENTOR_PIN V3 #define vFALL_PIN V4
//Declaring required variables float t, p, a, previousA;
//Boolean which tells tells if a fall is detected or not boolean fallState;
//Variables needed for the fall detection algorithm unsigned long previousMillis = 0; const long interval = 1000;
//BTconnected is false when not connected and true when connected boolean BTconnected = false;
//Defining BT state and LCD backlight pins int btStatePin = 9; int backlightPin = 2;
BlynkTimer timer; WidgetRTC rtc;
//Nokia 5110 Display wiring U8G2_PCD8544_84X48_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 7, /* data=*/ 8, /* cs=*/ 3, /* dc=*/ 5, /* reset=*/ 4);
void setup() { //Initialize both serial ports: Serial.begin(115200); Serial1.begin(115200);
//Setup the timed fuctions timer.setInterval(1000L, sendSensorValues); timer.setInterval(3000L, showTimeAndDate);
//Setting up required inputs and outputs pinMode(btStatePin, INPUT); pinMode(backlightPin, OUTPUT); digitalWrite(backlightPin, LOW);
u8g2.begin();
showStartMessage(); delay(2000);
// wait until the bluetooth module has made a connection while (!BTconnected) { if (digitalRead(btStatePin) == HIGH) { BTconnected = true; } else { showWaitingFor(); } }
initSensorHub();
Blynk.begin(auth, ssid, pass); rtc.begin();
setBlynkWidgets(); showTimeAndDate(); sendCommand(START); }
void loop() { Blynk.run(); timer.run(); getSensorValues(); checkIfFalling(); }
void sendCommand (String sensorCommand) { //This function sends commands through the bluetooth module on the hardware serial port to the the Sensor Hub Nano //For example: "sendCommand(START);", starts the flow of data from the sensor //The full list of commands I know are defined at the top of the sketch Serial1.println(sensorCommand); }
void initSensorHub() { //Initialise the Sensor Hub Nano, and give an error if there is any problem String junkVal; sendCommand(INFO); while (Serial1.find("IFX_NanoHub") == false) { sendCommand(INFO); Serial.println("ERROR"); showErrorMessage(); } junkVal = Serial1.readStringUntil('\n'); junkVal = ""; showConnectedMessage(); delay(1500); }
void getSensorValues() { //Retrieves the sensor values from the Sensor Hub Nano through the Serial1 port String junkVal; if (Serial1.available()) { junkVal = Serial1.readStringUntil('\n');
junkVal = Serial1.readStringUntil('t'); t = Serial1.parseFloat();
junkVal = Serial1.readStringUntil('p'); p = Serial1.parseFloat();
junkVal = Serial1.readStringUntil('a'); a = Serial1.parseFloat();
junkVal = Serial1.readStringUntil('\n'); } }
void sendSensorValues() { //Sending the sensor values to the Blynk server Blynk.virtualWrite(vTEMPERATURE_PIN, t); Blynk.virtualWrite(vPRESSURE_PIN, p); Blynk.virtualWrite(vALTITUDE_PIN, a); }
void checkIfFalling() { //Algorithm to check if the patient is falling unsigned long currentMillis = millis(); if ((currentMillis - previousMillis) >= interval) { float diff = previousA - a; if ((diff >= (FALL - CLEARANCE)) && (diff <= (FALL + CLEARANCE))) { fallState = true; //Here insert what you need to do if fall is detected, such as sending a notification or email with Blynk //Or you could also use IFTTT to call or send an sms to alert the caretaker (more info in the project documentation) Serial.println("Falling"); showFallMessage(); //In this example, vFALL_PIN (virtual pin 4) is set to 255 if fall is detected Blynk.virtualWrite(vFALL_PIN, 255); //You can send a notification using only the notification widget too! //Blynk.notify("DPS310 detected a fall!"); } previousA = a; previousMillis = currentMillis; fallState = false; //Set vFALL_PIN to 0 if a fall isn't detected Blynk.virtualWrite(vFALL_PIN, 0); } }
void showStartMessage() { //Shows the start-up message u8g2.clearBuffer(); u8g2.drawRFrame(3, 7, 75, 31, 7); u8g2.setFont(u8g2_font_prospero_bold_nbp_tf); u8g2.drawStr(8, 19, "Alzheimer's"); u8g2.drawStr(12, 35, "Assistant"); u8g2.sendBuffer(); }
void showWaitingFor() { //Shows the waiting for Sensor Hub Nano message u8g2.clearBuffer(); u8g2.setFont(u8g2_font_prospero_bold_nbp_tf); u8g2.drawStr(9, 15, "Waiting for"); u8g2.drawStr(8, 28, "Sensor Hub"); u8g2.drawStr(22, 41, "Nano !!!"); u8g2.sendBuffer(); }
void showConnectedMessage() { //Shows the connected message u8g2.clearBuffer(); u8g2.setFont(u8g2_font_7x13B_tf); u8g2.drawStr(0, 10, "Connected to"); u8g2.drawStr(8, 22, "Infineon's"); u8g2.drawStr(7, 34, "Sensor Hub"); u8g2.drawStr(29, 46, "Nano"); u8g2.sendBuffer(); }
void showErrorMessage() { //Shows the error message u8g2.clearBuffer(); // clear the internal memory u8g2.setFont(u8g2_font_fub14_tf); // choose a suitable font u8g2.drawStr(9, 30, "ERROR"); // write something to the internal memory u8g2.sendBuffer(); // transfer internal memory to the display }
void showSensorValues() { //Shows the sensor values on the display char bufT[10]; char bufP[10]; char bufA[10];
String(t).toCharArray(bufT, 10); String(p).toCharArray(bufP, 10); String(a).toCharArray(bufA, 10);
u8g2.clearBuffer(); u8g2.setFont(u8g2_font_6x10_tf ); //Display the temperature u8g2.drawStr(0, 10, "T:"); u8g2.drawStr(12, 10, bufT); u8g2.drawStr(73, 10, "C"); u8g2.drawCircle(70, 4, 1, U8G2_DRAW_ALL); u8g2.drawHLine(0, 12, 85); //Display the pressure u8g2.drawStr(0, 26, "P:"); u8g2.drawStr(12, 26, bufP); u8g2.drawStr(60, 26, "mBar"); u8g2.drawHLine(0, 28, 85); //Display the altitude u8g2.drawStr(0, 42, "A:"); u8g2.drawStr(12, 42, bufA); u8g2.drawStr(72, 42, "m"); u8g2.drawHLine(0, 44, 85); //Send the values to the display u8g2.sendBuffer(); }
void showFallMessage() { //Show the fall detected message u8g2.clearBuffer(); u8g2.setFont(u8g2_font_7x13B_tf); u8g2.drawStr(27, 20, "Fall"); u8g2.drawStr(13, 32, "Detected!"); u8g2.sendBuffer(); delay(1000); }
void showPillReminder() { //Show the pill reminder message u8g2.clearBuffer(); u8g2.setFont(u8g2_font_7x13B_tf); u8g2.drawStr(0, 20, "Time to take"); u8g2.drawStr(5, 32, "your pills!"); u8g2.sendBuffer(); }
void showExerciseReminder() { //Show the exercise reminder message u8g2.clearBuffer(); u8g2.setFont(u8g2_font_7x13B_tf); u8g2.drawStr(16, 20, "Time to"); u8g2.drawStr(12, 32, "exercise!"); u8g2.sendBuffer(); }
void showTimeAndDate() { //Displays the time and date from the RTC widget in Blynk in 24 hours format if (year() == 1970) { //Serial.println("Time not yet synced"); } else if (year() != 1970) { char bufHours[3]; char bufColon[2]; char bufMinutes[3]; char bufDate[11]; String currentHours = String(hour()); String colon = ":"; String currentMinutes = String(minute()); String currentDate = String(day()) + "/" + month() + "/" + year();
String(currentHours).toCharArray(bufHours, 3); String(colon).toCharArray(bufColon, 2); String(currentMinutes).toCharArray(bufMinutes, 3); String(currentDate).toCharArray(bufDate, 11);
u8g2.clearBuffer(); u8g2.setFont(u8g2_font_inr33_mf); u8g2.drawStr(30, 30, bufColon); u8g2.setFont(u8g2_font_logisoso32_tn); u8g2.drawStr(0, 32, bufHours); u8g2.drawStr(45, 32, bufMinutes); u8g2.setFont(u8g2_font_saikyosansbold8_8n); u8g2.drawHLine(0, 35, 85); u8g2.drawStr(0, 46, bufDate); u8g2.sendBuffer(); } }
BLYNK_WRITE(vEVENTOR_PIN) { //Use the Eventor widget to check if it's time to do a task (take medication in this case) int currentValue = param.asInt(); // 0 to 1 if (currentValue == 1) { showPillReminder(); //Serial.println("Time to take your pills"); } else { //Serial.println("Not the time to take pills"); } }
void setBlynkWidgets() { //This sets the colour of each widget in the Blynk app //You may remove this from the sketch if you want to set colours manually through the Blynk app //You could also specifiy the hex value of each colour you need
//Set temperature widget color to white Blynk.setProperty(vTEMPERATURE_PIN, "color", "#FFFFFF");
//Set pressure widget color to blue Blynk.setProperty(vPRESSURE_PIN, "color", "#00BBFF");
//Set altitude widget color to yellow Blynk.setProperty(vALTITUDE_PIN, "color", "#FFFF00"); }
BLYNK_CONNECTED() { //Synchronize time on connection, if connection drops rtc.begin(); }
Step 3: Configuring the Bluetooth Module
The first thing you will need to do is to get the MAC address of your Sensor Hub Nano Evaluation Kit. There will be many different ways to do that, but I will tell how I did it.
Pair the Sensor Hub Nano with your smartphone.
Download Infineon's Sensor Hub Nano Evaluation app (for Android) from here and switch on your Sensor Hub Nano. Open the app, and it will display the Sensor Hub Nano as "IFX_NANOHUB", with the MAC address below it.
Note this down as you will need it later.
Note: You would be better off un-pairing the Sensor Hub Nano from your smartphone if you aren't using it now because if your phone is nearby with bluetooth on and the Sensor Hub Nano paired, the phone automatically connects with it. And when you set up the HC-05 and try to get it to pair with the Nano Hub, it simply won't connect.
Getting the HC-05 to AT mode:
AT mode allows us to configure settings of the HC-05 bluetooth module; set the baud rate or set whether to connect as a slave or master device and more. We will need to change some settings for the module to allow it to retrieve data successfully from Infineon’s Sensor Hub Nano.
First, upload the "AT Commands" sketch to the Arduino MKR1000. This will allow us to give commands to the Bluetooth module in AT mode, through the Arduino MKR1000.
<p>// Original sketch from Martyn Currey's blog here: <br>// <a href="http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/" rel="nofollow"> http://www.martyncurrey.com/arduino-with-hc-05-bl...</a> // // Sketch modified by me to work with Arduino MKR1000! // // Basic Bluetooth sketch // Connect the HC-05 module and communicate using the serial monitor // // The HC-05 defaults to commincation mode when first powered on. // Needs to be placed in to AT mode // After a factory reset the default baud rate for communication mode is 38400 char c = ' '; void setup() { // start the serial communication with the host computer Serial.begin(9600); Serial.println("Arduino with HC-05 is ready"); // start communication with the HC-05 using 38400 Serial1.begin(38400); Serial.println("Serial1 started at 38400"); } void loop() { // Keep reading from HC-05 and send to Arduino Serial Monitor if (Serial1.available()) { c = Serial1.read(); Serial.write(c); } // Keep reading from Arduino Serial Monitor and send to HC-05 if (Serial.available()) { c = Serial.read(); // mirror the commands back to the serial monitor // makes it easy to follow the commands Serial.write(c); Serial1.write(c); } }</p>
Then wire up only the bluetooth module to the Arduino MKR1000 following the diagram attached above.
Note: It would be a good idea to wire it all up first on a breadboard, and proceed to proper wiring once you’ve set it up properly.
If you try to turn on the Sensor Hub Nano and the HC-05, you will see that they do not connect automatically at this time. This is what you would see:
To change the HC-05 settings, you will need to get your bluetooth module in AT mode. The method for doing this depends upon which breakout board you have and so you may have to do it differently. If you have a module that is different than the one I have, head over to Martyn Currey’s blog here where you can find detailed information about how to get the HC-05 bluetooth modules in AT mode. If you’re stuck, google your problem or comment and I’ll try to help.
My bluetooth module has the button switch, so I have to do the following steps to get it in AT command mode (Don't forget to upload the AT command code to the Arduino):
- Disconnect the module’s power. (TX and RX lines are still connected!)
- Press and hold the button switch on the module closed
- Apply power while still holding down the button switch
- When the LED comes on, release the switch
A video showing how to get the HC-05 in AT mode:
Once in AT mode you will notice a considerable difference in the pattern of LED blinks on the HC-05. In communication mode, the LED blinks quickly, about 5 times a second while in AT mode the LED blinks once every couple of seconds.
Setting up the HC-05 module:
Open the serial monitor, set the baud rate to 9600 and select “Both NL & CR”.
Note: You will need to set it to newline and carriage return, or AT commands don’t work.
Type “AT” in the serial monitor and you should receive an “OK”. If you do, then you can proceed further and give the commands as I did.
Basically, we need to change these settings in AT mode:
- Delete all currently paired devices
- Get it to connect only to a specified Bluetooth MAC address
- Set bluetooth connection mode to ‘Master’
- Specify the MAC address we need it to connect to
- Set the baud rate to 115200, stop bit to be 2 bits and even parity
The above instructions were given so that you can use them even if you have another Bluetooth module, by referring to the commands and what they do. But now I will list the commands I gave for the HC-05 to pair with the Sensor Hub Nano.
- AT+RMAAD
- AT+CMODE=0
- AT+ROLE=1
- AT+BIND=1234,56,abcdef (Replace with the MAC address of the Sensor Hub Nano)
- AT+UART=115200,0,0
Attached is a log of my AT commands for your reference.
You should now un-plug the Arduino to turn off the Bluetooth module. This will get it back in communication mode.
Note: If you mess anything up in the HC-05 settings, it would be a good idea to reset the module to the default settings and start from scratch with the command: AT+ORGL
Testing the connection:
Now, you will need to test if the last step was successful; you can do that by turning on the Sensor Hub Nano. The blue LED will blink very slowly, once every couple of seconds. Then, plug in your Arduino to your PC, and note the change in the LED blinks on both the HC-05 and Sesnor Hub Nano.
Look at the blinking now and compare it with the blinking before:
There is a noticeable difference, and you should get to know that both the modules are connected. You can now move over to next part, of wiring up the project and testing it.
Note: If you have paired your smartphone with the Sensor Hub Nano before, you may have to un-pair it otherwise it would cause connection problems. It can only connect to one device at a time.
Attachments
Step 4: Testing the Bare-bones Project
Once you have confirmed a proper connection between the HC-05 and the Sensor Hub Nano by the LED blinking patterns, proceed to setting up the Blynk app in smartphone.
Setting up the Blynk app:
Download the Blynk app (if you haven't already) for your iOS or Android device from here, and scan the QR code through the Blynk app. It will automatically replicate the basic widgets necessary at this time.
You will see the project widgets set up automatically.
Do not make any changes here at this point, and just read on.
Installing the required libraries:
You will need to have two different libraries for the Arduino IDE installed to get the code to compile without errors. They are:
- Blynk, to connect it to your smartphone
- u8g2lib, for the display
There are two ways to install the required libraries. The first is through the ‘Library Manager’ which is available in the newer versions of the Arduino IDE, and the second is the manual installation. Both methods are described in detail here so check the link out as I won’t be going through that.
Uploading the code and testing:
Once you have installed the libraries, download the attached code and make some changes to it. You will need to add your authentication code from Blynk (That is e-mailed to you when a new project is made in Blynk), as well as your WiFi SSID and password. Once that is done, upload the code to the MKR1000.
After uploading the code, wire up the circuit according to the schematic.
Then open the Blynk app in your smartphone, and open the Alzheimer’s Assistant project and press the play button. Plug in the MKR1000 (with the HC-05 and display wired up), and you should see the logo, Alzheimer’s Assistant on the display. It will stay for a moment and then you can see the message “Waiting for Sensor Hub Nano”. Turn on the small switch on the Sensor Hub Nano, ensuring that you’re within bluetooth range of the HC-05 module. It should say "Connected to Infineon’s Sensor Hub Nano", and after a few seconds, you should see pressure temperature and altitude values on your smartphone.
And after a few seconds you will also see the time in 24 hours format, as well as the date, and that syncs with the the internet.
This is a video of testing it out:
If so, congratulations, you have completed the hard part of setting it up, and now comes personalizing it for individual patients, according to their preferences.
Step 5: Personalizing Alzheimer’s Assistant
Up till now, what we have set up retrieves sensor data from Infineon’s DPS310 in a neat and elegant setup, but to make something useful from that, we have to configure the setup according to individual requirement and preferences. Therefore, in this section, I will talk about the code and how to modify Alzheimer’s Assistant to work according to each user’s preference. I will give the code snippet for each ‘feature’ and you can simply add it in the main code with a little changes.
Note: When you look at the code I attached for the 'bare-bones project', you will see that it uses functions wrapped in the BlynkTimer. I would be a good idea to use them if you want to do any customization as it can carry out tasks at a specified interval, and also, prevent the Blynk flood error which happens when your hardware sends a lot of requests to Blynk. Also, the code is 'bare-bones' in the sense that all functions are present but not included in the main code; the user has to edit the main code according to requirement, and may have to adjust the time interval at which each function runs.
The DPS310:-
Infineon’s DPS310 is a low cost digital barometric pressure sensor which provides very high accuracy, in a very small form factor. Because of that, it is perfect to use in such a project, and the values can be used to detect falls in an elderly patient, or in which room the patient is exactly.
Note: I did not make the smartwatch enclosure yet, so am using the Sensor Hub Nano on my hand, connected with the Arduino via Bluetooth, like in the image above.
Fall detection: To detect falls, we will need to give a fall value (The difference in air pressure, between two readings over a specified time), and set up a clearance. For example, if the change in altitude between two successive values (over a time of let’s say a second) is between the fall value ± the clearance value, a fall will be detected.
I have done a couple of tests and found the fall value should be 0.7, and the clearance value should be ±0.2, but they may not work in all situations. This is due to a simple and understandable reason that when a person falls it can occur in many different ways. Therefore, the use of a secondary sensor (probably an accelerometer) will be necessary to gain more accuracy in the fall detection system, and that will be added to the future work. But it could always be possible that there are other, more accurate algorithms for detecting falls, and I am open to hearing them; feel free to comment if you any ideas on this.
A video, demonstrating fall detection:
Detecting where the patient is: This works similarly to the fall detection algorithm. For example, if you need to know on which floor the patient is, you can get the take the current altitude value and subtract it from the previous. And then compare the difference to a pre-defined value. This will indicate on which floor the patient is.
It would just be a matter of using simple if and else logic to determine on which floor the patient is (Altitude values are already present in the main code). That could be indicated using the LED widgets in Blynk.
Note: I have not included the location detection in the main code but users can add it as needed, just don't forget to use it as a Blynk timer function.
The same technique could also be used to detect in which room a person is. In that case, a secondary sensor such as a motion sensor would be necessary otherwise there could be a lot of false triggers.
Temperature: The DPS310 also shows the temperature value which we can use to alert us about any mishap that could happen to the patient, for instance a fire. If the temperature increases to a specific value, let's say 45℃ it alerts the caretaker.
But because the DPS310 sensor is not attached directly to the skin (at least in this use-case) what we get isn't the body temperature, but it would be more accurate to say that it's the temperature of the Sensor Hub Nano.
The code for this is very simple (use it anywhere in the main loop) and could be something like this:
<p>if (t > maxTemp) { <br> //Do what you want if temperature is higher than maximum } else { //Do what you want if temperature is lower than maximum }</p>
Note: All of the above graphs are created using SESG2 Evaluation software provided by Infineon.
A buzzer and a switch:-
I have not mentioned this before, but a buzzer and a switch should also be present in the system and they will be very helpful too. For example, a buzzer could be used to attract the patient's attention, when it would be time to take medicine for instance, and the switch could be used as a safety device.
And because we will be using Blynk, the button switch could be set up in a way that when pressed, a notification would appear on the caretaker's phone or it would call or send an SMS (that could be done using IFTTT and is given later on). This could be the code snippet to do that:
<p>void emailOnButtonPress() <br>{ // *** WARNING: You are limited to send ONLY ONE E-MAIL PER 15 SECONDS! *** // Let's send an e-mail when you press the button // connected to digital pin 2 on your Arduino int isButtonPressed = !digitalRead(2); // Invert state, since button is "Active LOW" if (isButtonPressed) // You can write any condition to trigger e-mail sending { Serial.println("Button is pressed."); // This can be seen in the Serial Monitor Blynk.email("your_email@mail.com", "Subject: Button Logger", "You just pushed the button..."); // Or, if you want to use the email specified in the App (like for App Export): //Blynk.email("Subject: Button Logger", "You just pushed the button..."); } }</p>
It is taken from the Blynk sample code, and uses an interrupt to check the button. This could be used by the patient to alert the caretaker in any emergency, like a fall which wasn't detected by the fall detection algorithm. You can get the full sample code here, which sends an email once a button is pressed.
The buzzer could be used to produce tones (using the Arduino tone() command - more information here), to remind the patient for a task such as medication or exercise.
The Display:-
A major part of the project, which the user actually looks at, is the display. The Nokia 5110 displays are commonly available, easy to set up and cheap, but they aren’t that flashy, especially when used in such a system. OLED displays with a higher resolution will be a very good alternative to it, and you can easily modify the code to work with one because I used the u8g2 library (github here). Choose any of the display models from here, and add it to the start of the sketch (removing the Nokia 5110 line, of course!). You will need to wire it up according to what it is in the code and you’re ready to go. You can also use bitmap images with a higher resolution display. You can also change the font for the text on the display, select fonts from the huge list here and edit the name of the font in the code.
Note: You may have to change the pixel positions for the text in the code if you use a display with a higher resolution.
That was just a brief description of the library used to get the display working. But, now I will tell you how to edit the code to get Alzheimer's Assistant to show the time or the Sensor Hub Nano data (temperature, Altitude and pressure).
Displaying time: To display the time, you could simply use an RTC (or time keeping module) but as we're connected to the Internet, it would be much more easier to use the Internet to sync the time. And as we're using Blynk that would make it even more simpler. You just need the RTC widget in your project. Now with a few lines of code, you can automatically retrieve the time from the Blynk server (Make sure to set your timezone from the Blynk widget). The main code is set to display the time by default (not the sensor values, discussed next).
Note: The time displayed on the screen could go up or down a minute, as it is synced from the internet, but despite that, I have tested it for a long time and have found it to be very accurate (just a difference of a few seconds).
Displaying the Sensor Hub Nano data: We could just as well display data from the Sensor Hub Nano in the display. Not that it would benefit the patient, but its good for debugging purposes, should you need it. That can be done with the following code snippet:
<p>void showSensorValues() { <br> //Shows the sensor values on the display char bufT[10]; char bufP[10]; char bufA[10]; String(t).toCharArray(bufT, 10); String(p).toCharArray(bufP, 10); String(a).toCharArray(bufA, 10); u8g2.clearBuffer(); u8g2.setFont(u8g2_font_6x10_tf ); //Display the temperature u8g2.drawStr(0, 10, "T:"); u8g2.drawStr(12, 10, bufT); u8g2.drawStr(73, 10, "C"); u8g2.drawCircle(70, 4, 1, U8G2_DRAW_ALL); u8g2.drawHLine(0, 12, 85); //Display the pressure u8g2.drawStr(0, 26, "P:"); u8g2.drawStr(12, 26, bufP); u8g2.drawStr(60, 26, "mBar"); u8g2.drawHLine(0, 28, 85); //Display the altitude u8g2.drawStr(0, 42, "A:"); u8g2.drawStr(12, 42, bufA); u8g2.drawStr(72, 42, "m"); u8g2.drawHLine(0, 44, 85); //Send the values to the display u8g2.sendBuffer(); }</p>
Don't forget to run this command to get the sensor data below:
<p>getSensorValues();</p>
But that's not all for the display. As I said in the start, Alzheimer's Assistant should be able to remind the patient of the tasks which need to be done daily, such as when to take medications or to remind the patient to exercise.
Using Eventor widget to remind:-
For that, we will be using the Eventor widget (check here for details) in Blynk.
Add the Eventor widget into your project (It's already there if you scanned the QR code above), and just follow the screenshots to see how to set it up.
In the above example, the Eventor widget is used to set up a fall detection notification.
Using the Eventor widget to remind is done by this code:
<p>BLYNK_WRITE(vEVENTOR_PIN) { <br> //Use the Eventor widget to check if it's time to do a task (take medication in this case) int currentValue = param.asInt(); // 0 to 1 if (currentValue == 1) { //Do here what you want to when its time for medication showPillReminder(); playBuzzerReminder(); //This is just a tone, I haven't made it in the main code, but you can if you want! } else { //If it's not the time for medication, do nothing } }</p>
Attached is the result on the display when it is the time for medication.
And the same for exercise.
This is done by typing:
showExerciseReminder();
Instead of:
showPillReminder();
The eventor widget could, as said above, be used for a number of things. For example, you could set that an increase in temperature could result in sending an e-mail, and with no code modification!
Using different modes of the Sensor Hub Nano:-
You can test out the use of different modes for the Sensor Hub Nano. Using the following commands:
<p>sendCommand(LOW_ENERGY);</p><p>sendCommand(STANDARD_MODE);</p><p>sendCommand(HIGH_PRECISION);</p>
Using Blynk to switch modes could be more efficient. For that, set up your Blynk app like in the screenshot.
As this had no use for me, I did not add it it in the main code, but you could always do so as needed (The commands are present, you just need to add them with a bit of logic in the main sketch).
Using Blynk and IFTTT:-
Blynk can allow any Arduino project to easily harness the power of IFTTT.
This is because you can use Blynk to send a webhook request to the IFTTT Webhooks channel (previously called Maker channel), and you could create an IFTTT applet which waits for the webhook to be triggered (from the Blynk and Arduino side) and you could get it to trigger anything else in response to that.
A simple example on how to use IFTTT and Blynk with webhooks:
The Blynk webhook widget could be used to send a webhook request like in the screenshot above.
Attached is a screenshot of the IFTTT webhook channel.
And using webhooks to trigger IFTTT is not the only method. IFTTT can also be triggered by using Blynk to send emails and tweets.
You have now made an applet. Time to test it.
Open "Services" in IFTTT and then select "Webhooks". Go to "Settings" and there you will see a URL. Copy that and open it in a new tab. There, instead of {event}, type the event name (which you set earlier). That was "button_pressed" for me, and so when I click on "Test it", I get an SMS for which I have attached the screenshot above.
Now that you have confirmed the Webhook works, you can just write the URL in the Blynk webhook settings and get a GET or POST request (through the Blynk webhook widget)
And, instead of SMS, you could just as well use phone calls, or even Twitter and Facebook, if you want, and it's just as simple That is the power of IFTTT.
It's the same thing as my smart home controller project here, and I also discussed it in detail there, but it is a great thing which I couldn't go by without mentioning.
Step 6: Final Touches
By now, almost all of the electronics part of the project is complete, but a few things still remain. Read on for them, and in the end, I will list the future work which should be done to improve this project.
Battery and charging:
The MKR1000 has a port for a LiPo battery, which means you could attach one. But I don't have one at the moment so I will not be going into that but you should check out the website for the Arduino MKR1000 if you need information on that.
For charging, you have two options, using the MKR1000 USB port directly, and the other one is to use wireless charging, if you have it. I will be using the wireless charging for it. This is because I already have a wireless charging receiver and transmitter made by Futara Elettronica.
To use the receiver and transmitter, it's just a simple matter of providing the specified voltage to the transmitter. That will be the 'dock', where you can place Alzheimer's Assistant to charge. At the receiver side, you will just have to cut and attach a spare USB micro B cable (which goes to the MKR1000 USB port) and connect the other side to VCC and ground by looking at the pinout.
Just look at the images attached to see how to wire it up.
And the end result is also shown above.
Step 7: The Enclosure
As with every project, an enclosure is required for this too, and I have attached a picture of how I intend Alzheimer's Assistant to look like.
Note: I do not yet have the privilege of a laser cutter or 3D printer, so the STL file is just intended for showing how the final project looks like and it's not to scale.
This concludes the documentation for Alzheimer's Assistant, but I would still like to include the future work section to describe the things which I very much wanted to do for the project, but couldn't, due to some reason or the other.
Step 8: Future Work
As I said before, these are the things which I wanted to include in the project, which I will add in future, should I get the time:
- Making a proper enclosure for it. Now I am just testing it on a breadboard but if I get access to a laser cutter or 3D printer I will update the documentation with that.
- Using a Bluetooth 4.0 module instead of this one.
- Or even better, using just the DPS310 Sensor instead of the Sensor Hub Nano. This would decrease the cost for the project overall, as it will eliminate the use of the Sensor Hub Nano and the bluetooth module; the DPS310 itself is a available for cheap. It's a matter of editing the main code to get temperature, pressure and altitude values from the DPS310 only, the rest of the part is done.
- Using a secondary sensor to work along with the DPS310 for fall detection and the location detection. This would decrease the occurrence of both, false positive and false negative alerts. Most probably an accelerometer and a motion detector will be needed for both.
- Adding a pulse sensor. I did not have one, so I couldn't add that. It should be a great addition to the project.
- Using a higher resolution display, preferably an OLED. With that, graphics can also be included and that would be pretty neat.
- Working on improving the battery life for the project. This can be done by using a deep sleep mode in the MKR1000, but I haven't used it in the code yet.
Thanks for reading, and hope you liked my project. Feel free to give me your opinions and ideas about the project.