element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Summer of Sensors Design Challenge
  • Challenges & Projects
  • Design Challenges
  • Summer of Sensors Design Challenge
  • More
  • Cancel
Summer of Sensors Design Challenge
Blog Designing a Small Health Monitoring System for the Elderly - HMS Blog #3 - First Prototype
  • Blog
  • Forum
  • Documents
  • Design Challenge
  • Leaderboard
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Summer of Sensors Design Challenge to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: milosrasic98
  • Date Created: 10 Nov 2022 8:15 PM Date Created
  • Views 4200 views
  • Likes 11 likes
  • Comments 9 comments
  • mqtt
  • mikroelektronika
  • Summer of Sensors Design Challenge
  • node-red
  • max30100
  • esp8266
  • summer of sensors
  • max30102
  • Health
  • iot
  • adafruit
  • arduino
Related
Recommended

Designing a Small Health Monitoring System for the Elderly - HMS Blog #3 - First Prototype

milosrasic98
milosrasic98
10 Nov 2022
Designing a Small Health Monitoring System for the Elderly - HMS Blog #3 - First Prototype

First Prototype

Table of Contents

  • 1. Introduction
  • 2. Heart Rate Click VS Oximeter 5 Click
  • 3. System Design
  • 4. Electronics
    • Components
      • Arduino Uno
      • Adafruit Feather Huzzah
      • Adafruit 2.8" TFT Touch Shield
      • Heart Rate Click
    • Full Schematic
  • 5. Software
    • Adafruit Feather Huzzah Code
    • Arduino Uno Code
  • 6. Raspberry Pi Server
    • Setting up the Raspberry Pi OS
    • Node-RED
    • Mosquitto MQTT Broker
    • PushStaq
    • Simple PushStaq Test
  • 7. Testing
  • 8. Summary

image1. Introduction

Hi! This will be my third blog for the Summers of Sensors Design Challenge. In the first blog, I've covered my initial idea to then develop it and present it as a plan in the second blog. In this blog, I've finally started to put that plan into motion and managed to get a full working prototype! Through this blog, I'll go through my entire process of what electronics I decided to use and how I use them as well as all of the software for the microcontrollers and the small Raspberry Pi server I set up in my home. Hope you enjoy the blog!

2. Heart Rate Click VS Oximeter 5 Click

In the starter kit, we got 3 click boards from MikroElektronika, 2 of which are for measuring the pulse and SpO2 levels. These boards even have rather different names, but when you take a closer look at their product pages, they essentially do the same thing. Here are the pictures of the boards, with the heart rate click being on the left and the oximeter 5 click on the right.

imageimage

When you continue reading even further on the product pages, you can find the sensors that are on these boards. The heart rate click uses the MAX30100 while the Oximeter 5 uses the MAX30102. If they sound pretty similar in name, it is because the MAX30102 is just a newer version of the MAX30100. When it comes to software, libraries can be found for both the MAX30100 and the MAX30102, though, the MAX30100 one is slightly easier to work with than the other one. So, what are the key differences between these two sensors? Here are a couple of sources I found on the topic if wish to read further:

  • MAX30102: An Improved Heart Rate Sensor for Arduino
  • Difference between Max30100 and Max30102 Sensor

To summarize, here are some notable sensors differences.

MAX30100 MAX30102
ADC Resolution 14 - bit 18 - bit
Red ADC Count 23k - 29k Counts 65536 Counts
IR ADC Count 23k - 29k Counts 65536 Counts
FIFO buffer 16 - bit 32 - bit

There is also a part about logic levels that was fixed on the MAX30102 where the pull resistors are now attached to 3.3V instead of 1.8V. Since both sensors are on MikroElektronika boards, they are both compatible with an Arduino out of the box, so that doesn't make a big difference to me here. My goal is to use both of these sensors in my project, one being part of the main system, while the other one will be a clamp-style oximeter.

3. System Design

As mentioned in the section above, my whole second blog was dedicated to system design, but, at the end of that blog, I said I didn't have a solution yet in place for what I wanted to do for the server side of things. The idea is, I want the system to work in a way that when there is a new measurement, I get a push notification on my phone/computer. 

image

Some of the things I considered were AWS IoT, Google Cloud, and Microsoft Azure, which are great options for systems that need to be scalable, but dougw gave me a great idea for this project, and that is to run a small server on a Raspberry Pi. This idea looked great to me since I already have a lot of experience working with the Raspberry and had a few of them laying around. I searched around a bit and decided to go with Node-Red, and with PushStaq for the notifications. I will get into individual things later in this blog. For now, here is how the whole setup is supposed to work.

image

There are 2 ESP8266 boards in the whole system, one is in the HMS device and the other one is in the clamp. Using MQTT, I want to upload the measurements to the Raspberry Pi server running Node-Red, which then pushes notifications to my phone or laptop using PushStaq. For PushStaq, no app notification is needed, it is browser-based, so all the user needs to do is click a link and subscribe. One thing I also plan to implement is monthly reports where I can send a mail with all of the collected data every month to myself. Every reading sent to the server will also be saved on the server, and I can then run Python scripts to do some data analysis and visualization.

4. Electronics

In the first blog, I featured a short video where you can hear a buzzer sound every time the heart rate click detected a heartbeat. It was connected to the Arduino Uno using the MikroElektronika click shield. This is a feature that is a must-keep in my system, as I've explained before, just, I will not be using the shield to connect everything. Here is the video in question.

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

My goal now is to slowly build on top of this, to get it into a prototype form, before I start packing all of that into an enclosure, which I will do in one of the next blogs. To begin, let's go through the most necessary electronic components for this project to work. I'll now go only through the bigger modules.

Components

{tabbedtable}Components Component

Arduino Uno

As mentioned previously throughout my blogs, this is the component on which the whole project is based. This is also one of the components of the Starter Kit that I received as the challenger for this Design Challenge.

image

As mentioned already, it comes with the ATmega328P microcontroller and is the most recognizable Arduino out there! It doesn't have WiFi capabilities, and that's the reason why I'll be pairing it with an Adafruit Feather Huzzah (ESP8266) so I can connect my project to the internet.

Relevant links:

  • https://store.arduino.cc/products/arduino-uno-rev3-smd
  • https://www.arduino.cc/en/Guide
  • https://export.farnell.com/arduino/a000073/arduino-uno-smd-dev-kit/dp/2285200

Adafruit Feather Huzzah

As mentioned on the Arduino Uno tab, the next important component is the Adafruit Feather Huzzah. The Adafruit Feather Huzzah is an all-in-one ESP8266 WiFi development board with built-in USB and battery charging. It works on a 3.3V logic level so we need to be careful when using it with the Arduino Uno since the Arduino Uno is on a 5V logic level.

image

This is a great all-around board for IoT projects, I'll be only using it as a link to the internet for my project. Arduino will send the data over Serial (Rx & Tx) pins to the Feather Huzzah, and I'll just decode that data and upload it. Even though this board is working at a 3.3V logic level, the Rx pin on the board has a level shifter so it's 5V compatible out of the box!

Relevant links:

  • https://export.farnell.com/adafruit/2821/adafruit-feather-huzzah-esp8266/dp/2816288?ost=adafruit+feather+huzzah
  • https://www.adafruit.com/product/2821

Adafruit 2.8" TFT Touch Shield

Adafruit 2.8" TFT Touch Shield for Arduino with Resistive Touch Screen is another Adafruit product I will be using for my project. I have the one with the resistive touch screen and it comes with a library which is incredibly easy to use. I don't need the touchscreen capabilities of the module, which is a good thing, since I managed to break mine while working on an older project. The display itself still works well though.

image

Picture from the Adafruit product page

Here is a short video showing a simple test running on this display. I featured this video already in my second blog.

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

Relevant links:

  • https://www.adafruit.com/product/1651
  • https://learn.adafruit.com/adafruit-2-8-tft-touch-shield-v2/downloads

Heart Rate Click

The pulse and oxygen saturation sensor that I will be using for this part of the project is the Heart Rate click, this is the board that has the MAX30100 sensor on board. Heart Rate click is a heart rate monitoring and pulse oximetry measuring Click board. It features an advanced oximeter and heart rate monitoring sensor, which relies on two integrated LEDs, a photosensitive element, and a very accurate and advanced low-noise analog front end, to provide clean and accurate readings.

image

The easiest way to connect to it is using the Arduino Uno Click shield, but we can also connect it to the power and to the I2C bus since that is how it communicates with the microcontroller. We only the 3.3V power rail for it, we don't need the 5V.

Relevant links:

  • https://www.mikroe.com/heart-rate-click
  • https://export.farnell.com/mikroelektronika/mikroe-2000/heart-rate-click-easyboard-dev/dp/2786878

Full Schematic

Now that I've covered the main components of the whole system. It's time to connect all of it up so we can proceed to testing and troubleshooting. Here is a picture of the whole schematic.

image

The schematic is pretty simple, you have the main components that I've talked about above and besides that, there's one additional LED for now which is used to signalize the heartbeat when the sensor detects it (the buzzer module works in the same way as the LED) and we have a small push button that is going to be our upload button. Here are some key points for this schematic.

  • The Arduino has a 5V pin while the Adafruit Feather Huzzah has a VUSB pin, which can both be connected directly to 5V to power up these boards 
  • While the Huzzah works on the 3.3V logic level, the Rx pin on the Feather has a level shifter on it, so it's 5V friendly, meaning we can connect the Arduino Tx pin directly to it
  • The click board only needs 4 pins to work: 3.3V, GND, SCL, SDA
  • The button needs to be connected to either pin 2, or pin 3 because those are the only 2 pins that have interrupts on the Arduino Uno
  • While the 2.8" TFT LCD is designed to be used as a shield, it can also be connected with jumper wires in such a way that it doesn't use many pins, using the ICSP header

The only thing left now is to connect everything on a breadboard.

image

The only thing missing here is how the whole project will be powered on once it's all in an enclosure. Rather than having to drag a cable around, my idea is to use a 18650 lithium cell with a boost circuit to get it up to 5V, which is perfect for powering up both the Arduino Uno and Adafruit Feather Huzzah. The board I will be using to boost the voltage of the cell also has a charging circuit for the cell which is convenient. Something I mentioned in previous blogs was adding an RTC and a microSD card module, the RTC I'm still working on, as for the microSD, the display already has a built-in slot for the microSD, so I'll be using that for now.

5. Software

All that's left to do now is to program the Arduino Uno and the Adafruit Feather Huzzah to finish up with the electronics. Before getting into the codes themselves, let's look at what these boards need to do. First off, let's take a look at the simpler of the 2, the Adafruit Feather Huzzah.

Adafruit Feather Huzzah Code

The job of the Huzzah (ESP8266) is to listen to Serial data, and based on that upload the data online. To detect if the Huzzah got new data we can use a SerialEvent() function which will be called anytime any new data appears on the Serial line. In that function, we read the data character by character until we get a string termination character "\n". Once we've got our string, using the library PubSubClient we can use the function client.publish() which will publish the data as we need it. The publish function requires 2 arguments, first is the MQTT topic and the second one is the data we want to send. Rather than sending 2 messages from the Arduino, Arduino will send a single message containing both the topic and the data, which will be separated by the character "&". Here is the final code.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Change the credentials below, so your ESP8266 connects to your router
const char* ssid = "SSID";
const char* password = "PASSWORD";

// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "SERVER_IP";

// Initializes the espClient. You should change the espClient name if you have multiple ESPs running in your home automation system
WiFiClient espClient;
PubSubClient client(espClient);

bool stringComplete = false;
String inputString = "";
String topic = "";
String data = "";


// Don't change the function below. This functions connects your ESP8266 to your router
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected - ESP IP address: ");
  Serial.println(WiFi.localIP());
}

// This functions reconnects your ESP8266 to your MQTT broker
// Change the function below if you want to subscribe to more topics with your ESP8266 
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    /*
     YOU MIGHT NEED TO CHANGE THIS LINE, IF YOU'RE HAVING PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
     To change the ESP device ID, you will have to give a new name to the ESP8266.
     Here's how it looks:
       if (client.connect("ESP8266Client")) {
     You can do it like this:
       if (client.connect("ESP1_Office")) {
     Then, for the other ESP:
       if (client.connect("ESP2_Garage")) {
      That should solve your MQTT multiple connections problem
    */
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");  
      // Subscribe or resubscribe to a topic
      // You can subscribe to more topics (to control more LEDs in this example)
      client.subscribe("room/lamp");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (!client.connected()) {
    reconnect();
  }
  if(!client.loop())
    client.connect("ESP8266Client");

  if(stringComplete){
    if(inputString.indexOf("&") != -1){
      topic = inputString.substring(0, inputString.indexOf("&"));
      data = inputString.substring(inputString.indexOf("&") + 1);
      Serial.print("Topic: ");
      Serial.println(topic);
      Serial.print("Data: ");
      Serial.println(data);
      Serial.println("Publishing....");
      client.publish((char*) topic.c_str(), (char*) data.c_str());
      Serial.println("Done publishing");
    }
    inputString = "";
    stringComplete = false;
  }

}

/*
  SerialEvent occurs whenever a new data comes in the hardware serial RX. This
  routine is run between each time loop() runs, so using delay inside loop can
  delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag so the main loop can
    // do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

Arduino Uno Code

The Arduino Uno has a bit of a tougher job compared to the Huzzah because the Arduino is the board that the user will actually interact with, both with the controls and both through the display, so here is a list of the things that the Arduino needs to do:

  • Read sensor data in a loop
  • Turn on the LED and the Buzzer once a heartbeat is detected
  • Update the display with the newest data with a given refresh rate
  • Send the data to the Huzzah when the user presses the button

Besides that, there will be some additional things that it will need to do, based on what sensors and modules I add on down the line. The button is connected to one of the interrupt pins which has an attached interrupt on the rising edge. Once the user presses the button, the Arduino will send the data over Serial to the Huzzah in the form of topic + & + data, as I've described above. Here is the full code for the Arduino.

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include "Wire.h"
#include "MAX30100_PulseOximeter.h"

// Pin definitions
#define TFT_DC 9
#define TFT_CS 10
#define PIN_LED_HR 6
#define PIN_LED_OXI 7
#define PIN_BUZZ 5
#define PIN_UPLOAD_BTN 3

// Constants
#define REPORTING_PERIOD_MS     1000
#define SIGNAL_MS 70

// MQTT
String mqtt_hr_click = "measurement/hr_click";

volatile int hb1 = 0;
volatile int hb2 = 0;
volatile float spo21 = 0.00;
volatile float spo22 = 0.00;

volatile bool LED_HR = false;
volatile long LED_HR_time = 0;

volatile bool LED_OXI = false;
volatile long LED_OXI_time = 0;

volatile int hb_upload = 0;
volatile float spo2_upload = 0.00;

uint32_t tsLastReport = 0;

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// Heart rate click
PulseOximeter pox;


// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
    //Serial.println("Beat!");
    LED_HR = true;
    LED_HR_time = millis();
    hb_upload = hb1;
    spo2_upload = spo21;
}

void setup() {
  // Serial setup
  Serial.begin(9600);

  //
  //  PINS
  //
  pinMode(PIN_LED_HR, OUTPUT);
  pinMode(PIN_LED_OXI, OUTPUT);
  pinMode(PIN_BUZZ, OUTPUT);
  pinMode(PIN_UPLOAD_BTN, INPUT);

  //
  //  INTERRUPTS
  //
  attachInterrupt(digitalPinToInterrupt(PIN_UPLOAD_BTN), ButtonPress, RISING);

  //
  //  TFT LCD
  //

  tft.begin();
  tft.fillRect(0, 0, 240, 320, ILI9341_WHITE);
  tft.setTextColor(ILI9341_BLACK);
  tft.setTextSize(5);
  // Printing out the starting data
  // Heart Rate Click
  tft.setCursor(10, 10);
  tft.print("HR");
  // BPM
  tft.setCursor(10, 50);
  tft.print(hb1);
  tft.setCursor(140, 50);
  tft.print("BPM");
  // SPO2
  tft.setCursor(10, 90);
  tft.print(spo21);
  tft.setCursor(200, 90);
  tft.print("%"); 
  
  
  // Oxi5 Click
  tft.setCursor(10, 180);
  tft.print("FINAL");
  // BPM
  tft.setCursor(10, 220);
  tft.print(hb_upload);
  tft.setCursor(140, 220);
  tft.print("BPM");
  // SPO2
  tft.setCursor(10, 260);
  tft.print(spo2_upload);
  tft.setCursor(200, 260);
  tft.print("%");
  
  
  //
  //  HR CLICK
  //

  //Serial.print("Initializing pulse oximeter..");
  // Initialize the PulseOximeter instance
  // Failures are generally due to an improper I2C wiring, missing power supply
  // or wrong target chip
  if (!pox.begin()) {
      //Serial.println("FAILED");
      for(;;);
  } else {
      //Serial.println("SUCCESS");
  }

  // The default current for the IR LED is 50mA and it could be changed
  //   by uncommenting the following line. Check MAX30100_Registers.h for all the
  //   available options.
  // pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);

  // Register a callback for the beat detection
  pox.setOnBeatDetectedCallback(onBeatDetected);

}

void UpdateHR(){
  tft.fillRect(0, 50, 130, 80, ILI9341_WHITE);
  tft.setCursor(10, 50);
  tft.print(hb1);
  tft.setCursor(10, 90);
  tft.print(spo21);
}

void ButtonPress(){
  delay(100);
  if(digitalRead(PIN_UPLOAD_BTN) == HIGH){
    //String msg = MQTT_HR_CLICK + DIVIDER + "Heart rate: " + String(hb_upload) + "BPM SpO2: " + String(spo2_upload) + "%";
    Serial.println(mqtt_hr_click + "&" + "Heart rate: " + String(hb_upload) + "BPM SpO2: " + String(spo2_upload) + "%");
  }
}

void UpdateOxi(){
  tft.fillRect(0, 220, 130, 130, ILI9341_WHITE);
  tft.setCursor(10, 220);
  tft.print(hb_upload);
  tft.setCursor(10, 260);
  tft.print(spo2_upload);
}

void loop() {

  // Updating the Heart rate click
  pox.update();

  if(millis() - tsLastReport > REPORTING_PERIOD_MS)
  {
    /*
    Serial.print("Heart rate:");
    Serial.print(pox.getHeartRate());
    Serial.print("bpm / SpO2:");
    Serial.print(pox.getSpO2());
    Serial.println("%");
    */
    hb1 = pox.getHeartRate();
    spo21 = pox.getSpO2();
    UpdateHR();
    
    tsLastReport = millis();
    //UpdateOxi();
  }
  
  // LED Heart rate Click
  if(LED_HR == true)
  {
    digitalWrite(PIN_LED_HR, HIGH);
    digitalWrite(PIN_BUZZ, HIGH);
    if(millis() - LED_HR_time > SIGNAL_MS)
    {
      digitalWrite(PIN_LED_HR, LOW);
      digitalWrite(PIN_BUZZ, LOW);
      UpdateOxi();
      LED_HR = false;
    }
  }

  
}

That wraps up the software part on these 2 boards for now. The Adafruit Feather Huzzah code will probably stay the same, but the Arduino code will most certainly go through some changes as we add new modules or sensors to it.

6. Raspberry Pi Server

Before we can test out the electronics shown in the previous section, we first need to sort out the server side of things. As mentioned above, my original idea was to use one of the services like AWS IoT, Google Cloud, or Microsoft Azure, but dougw gave me a great idea to use a Raspberry Pi as a server, and that's the approach I chose for this project since I have a few of them laying around. In this section of the blog, I will go all over the things that I needed to do to go from a message sent from the ESP8266 to me getting a notification on my phone with all of the relevant data. Let's take a look first at how the whole system is supposed to work.

image

Before I get into setting up everything, let's take a look at what's MQTT. MQTT is an OASIS standard messaging protocol for the Internet of Things (IoT). It is designed as an extremely lightweight publish/subscribe messaging transport that is ideal for connecting remote devices with a small code footprint and minimal network bandwidth. MQTT today is used in a wide variety of industries, such as automotive, manufacturing, telecommunications, oil and gas, etc. If you've worked with things like ROS before, the whole topic idea for messages will sound familiar. To put it simply, topics are channels to which we can either publish (post) messages or subscribe (read) the messages on that topic. For this, to work we need an MQTT broker. The MQTT broker is responsible for receiving all messages, filtering the messages, deciding who is interested in them, and then publishing the message to all subscribed clients. For all of this to work, here are the things I had to set up before I got a simple test to work.

  • Setting up an operating system on the Raspberry Pi 3B+
  • Installing and setting up Node-Red
  • Installing and setting up the Mosquito MQTT Broker
  • Installing PushStaq within Node-Red

You're probably familiar at least with some of these steps, but I'll run through them quickly just in case.

Setting up the Raspberry Pi OS

The first thing we need to do is set up the Raspberry Pi operating system. For that, all we need is a microSD card and a microSD card reader for our computer. Raspberry released an amazing tool for installing operating systems for the Raspberry Pi called the Raspberry Pi Imager.

image

It's as easy as choosing the operating system and the storage to which we want to upload the operating system, with that being our microSD card. One reason I've shown this is because of the new feature they added to the imager that I haven't seen before, it's the little settings icon on the bottom right. There, you can automatically set things like languages, WiFi SSID and Password, and a few other things, which can speed up the process a bit later on.

Node-RED

To begin, what is Node-RED? Node-RED is an open-source tool for building IoT applications with the goal of simplifying the programming component, it runs on the web browser and it uses visual programming that allows you to connect code blocks, known as nodes, together to perform a task. Nodes connected together are called flows. Some of the things that can be done with Node-RED are:

  • Control Raspberry GPIO
  • Establish an MQTT connection with other things like an ESP8266 (the use-case for this project)
  • Communicate with third-party services
  • Get data from the web
  • Store and retrieve data from a database

This operating system doesn't come with Node-Red already installed (though I vaguely remember that older versions of Raspbian came with Node-RED already loaded on the Raspberry), so we'll have to install it ourselves. I found a great tutorial online that goes step by step through the whole installation, you can find it by clicking the link below:

  • Node-RED tutorial: https://randomnerdtutorials.com/getting-started-node-red-raspberry-pi/

One thing I want to add is to read through the prompts as the installation is going on because it gives a lot of useful tips for things like how to secure Node-RED better and how to set up your Raspberry so that Node-RED runs on startup. I would also highly suggest setting up a static IP address for your Raspberry Pi, it will just make things a bit easier (make sure you choose a higher IP address).

  • Raspberry static IP tutorial: https://www.ionos.com/digitalguide/server/configuration/provide-raspberry-pi-with-a-static-ip-address/#:~:text=To%20assign%20an%20IP%20address,255.0).

To access Node-RED now, you can go to any computer that's on your local network and type the IP address of your Raspberry Pi followed by ":1880". For example, if your Raspberry Pi IP address is 192.168.1.120, you would be able to access Node-RED by typing 192.168.1.120:1880 in your browser.

Mosquitto MQTT Broker

With Node-RED all set, now we need to install our MQTT Broker. The one I went with is the Mosquitto MQTT Broker. I found another great tutorial online for the Node-RED, so I advise you to follow that tutorial since it worked out great for me.

  • Mosquitto MQTT Broker tutorial: https://randomnerdtutorials.com/how-to-install-mosquitto-broker-on-raspberry-pi/

After following that tutorial, all we need to do now is to use the Mosquitto MQTT Broker in Node-RED. Here is a way to do that. You first need to add an MQTT node and double-click on it, you will see the add new MQTT-broker option, click on it. Now you need to enter only the Server fields as localhost and 1883.

image

Once that is done, you can click Add and that's it. Now you can add the topic you want to subscribe to, and that's the topic that the Adafruit Feather Huzzah is posting to as we talked about in the Software section of this blog. It should look something like this.

image

As you can see in the picture above, the topic the ESP8266 will be posting to is measurement/hr_click. With that, the MQTT Broker is set up. There's one thing left to do before we can send notifications to our phones.

PushStaq

PushStaq is a real-time messaging platform to share text, links, and media between devices in a chat interface. One great thing about PushStaq is that it is web-browser based and it can push notifications like that to our phones, without us needing to install any additional apps. It can also push notifications to our laptops. To use PushStaq, all we need to do is set up a free account (or log in with our Google account) and create our channel. For someone to subscribe to the notifications, all they need is a link that we can generate in PushStaq that we can send to them. There they have to sign in and click subscribe to receive the notifications. Below you'll find a short tutorial on setting up PushStaq with Node-RED.

  • PushStaq tutorial: https://www.pushstaq.com/blog/node-red-push-notifications-with-pushstaq/

Here is a picture of how the app looks when it receives the data, as described above, it works like a simple messaging app.

image

Simple PushStaq Test

To test whether we're receiving the notifications as we should from our server, we're gonna make a simple test using the Inject node in Node-RED. This will push a message that we've entered to PushStaq that will show up as a notification on our phone. Here is what the flow for this looks like.

image

The nodes that we need from the picture above are the inject node and the PushStaq node. We don't need the 2 nodes on the bottom left for now. The PushStaq node is supposed to be set up as it's shown in the tutorial linked above. Once we click deploy and click the small button next to inject, we should receive a notification on our phone. Here is a short video of that.

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

With that, we have everything tested and working on the server side, the only thing we can further do if we don't want to skip steps is to write a simple ESP8266 program which would just connect to the WiFi and publish a single message to the topic to make sure everything is working correctly.

7. Testing

And finally, in the end, with everything set up, as shown above, we have reached the testing phase. While there will be additional hardware added in the future to the Arduino, the goal, for now, is to test all of the components in the system with a simple test. This test will include me putting my finger on the sensor to get a heart rate and SpO2 reading and then clicking the green button. Clicking the green button should take the final values shown on the bottom of the display and send them over Serial to the Huzzah board with the topic that they need to be sent to. From there, the Huzzah needs to figure out what's the topic and what's the data, publish that, and where the server comes in. When the MQTT Broker catches the message, because of our flow in Node-RED, we will send the data as a message to the PushStaq node which will then push the notification on our phone. The flow for Node-RED is the same as the one shown above. Here is the video of the test running.

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

And it works! It was such a great feeling seeing the notification pop up for the first time. During testing, I've noticed a few small bugs with the sensor that I wish to address down the line, one is that if the device is left alone a bit longer when you try measuring your heart rate, you will get extremely low values as it slowly starts to climb up to realistic values. This is a built-in function, that probably looks at the number of heart beats detected in the last 10 seconds or something like that, so when there's such a big pause, and it detects the first heartbeat, it probably thinks there was only one heartbeat detected in those 10 seconds and it calculated the heart rate based on that. I'll try and write a different function that will for more heartbeats to come in before it starts out giving values, and as soon as it doesn't detect anything for let's say 2 or 3 seconds it would reset. One other thing I've noticed is that for the SpO2 reading, the data can sometimes go over 100% and there can be some outliers in the range of 0-5% for some reason. A simple fix would be to reject any measurement above 100% and any measurement under let's say 50% and present the user with the value calculated as the mean value of the last 5 valid readings or something like that.

8. Summary

The kit being late means that there isn't much time left until the end of the competition, but I'm happy with where I'm at the moment and I think I can still finish up everything I wanted to do for this design challenge. This blog has certainly been a big step up from the first 2 blogs since those 2 were mostly based on the idea and plans for this project. An important thing with this blog is that I managed to get all of the server-side things working, which will make everything else go much easier. There will be a bit of soldering and 3D printing needed for everything to be assembled, but the main things where most of the problems could have risen are all worked out by now. I also managed to get my hands on some tiny tubes for the pressure sensor, so I'll be recording that data as well and trying to extract the blood pressure data from the raw data. There's a week left to go until the deadline, so it's time to continue going forward with the build. Thanks for reading the blog, hope you found it useful and enjoyed reading it!

Milos

  • Sign in to reply
  • emmafisher
    emmafisher over 1 year ago

    A compact health monitoring system for the elderly can make a real difference in improving daily care and early intervention. Ensuring seamless data integration with existing healthcare systems is just as important as the hardware itself. Leveraging FHIR services can help standardize health data exchange, making the system more interoperable and compliant with medical regulations. Solutions like this, combined with robust software frameworks, can enhance remote patient monitoring and streamline healthcare workflows. Looking forward to seeing how this project progresses.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • milosrasic98
    milosrasic98 over 3 years ago in reply to dang74

    Thank you, I'm glad you like it! Just trying to include all of the information and links necessary for someone doing it for the first time, because that's something I appreciate greatly when looking for a tutorial on a certain topic!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • dang74
    dang74 over 3 years ago

    Excellent blog.  I appreciate all the details on the Raspberry pi server.  It can serve as a good starting point for anyone wanting to explore something similar.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • milosrasic98
    milosrasic98 over 3 years ago in reply to rsjawale24

    Thanks, I'm glad you enjoyed it!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • milosrasic98
    milosrasic98 over 3 years ago in reply to genebren

    Thanks! Got most of the core things worked out, so I hope there won't be any major setbacks along the way.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube