Monitoramento da saúde do paciente com base em IoT no servidor da Web ESP32

Tempo de leitura: 8 minutes

Visão geral

Com toneladas de novas empresas de tecnologia de saúde, a IoT está revolucionando rapidamente o setor de saúde. Acompanhar o estado de saúde do seu paciente em casa é uma tarefa difícil devido às agendas lotadas e ao nosso trabalho diário. Especialmente os pacientes idosos devem ser monitorados periodicamente. Por isso propomos um sistema inovador que automatizou esta tarefa com facilidade. Nosso dispositivo apresenta um sistema inteligente de rastreamento da saúde do paciente usando o servidor Web para que os parâmetros de saúde do paciente, como frequência cardíaca e nível de oxigênio no sangue, juntamente com a temperatura corporal, possam ser monitorados.

Portanto, neste projeto, aprenderemos como fazer um projeto de sistema de monitoramento da saúde do paciente baseado em IoT. Usaremos o sensor de oxímetro de pulso MAX30100/102 para medir a frequência cardíaca/pulso (BPM), bem como o nível de oxigênio no sangue (SpO2). Usaremos um sensor de temperatura DS18B20 para medir a temperatura do corpo. Da mesma forma, o paciente deve ser colocado em uma sala com um determinado nível de temperatura e umidade para não se sentir desconfortável. Para fazer isso, também precisamos monitorar a temperatura e a umidade do ambiente. Portanto, estaremos usando o sensor de umidade e temperatura DHT11.

Lista de Materiais

A seguir estão os componentes necessários para fazer este projeto. Todos os componentes podem ser adquiridos na Amazon. O link dos componentes adquiridos é fornecido abaixo.

Nome dos ComponentesDescriçãoQuantidade
1ESP32 BoardPlaca de desenvolvimento ESP32 ESP-32S (ESP-WROOM-32)1https://amzn.to/3iGSGrd
2Pulse Oximeter SensorMAX30100 / MAX30102 Sensor de Oxímetro de Pulso I2C1ML (Link)
3DS18B20 SensorDS18B20 Sensor de temperatura à prova d’água de um fio1https://amzn.to/39TIsQ6
4DHT11 SensorSensor digital de temperatura de umidade DHT111https://amzn.to/39Vu75P
5Resistor4.7K1https://amzn.to/3ca6CbN
6Fios de ConexãoFios de Conexão Arduino10https://amzn.to/3iG9wGp
7ProtoBoardhttps://amzn.to/3pdREFv

 

Oxímetro de pulso MAX30100

O sensor é uma solução integrada de sensor de oximetria de pulso e monitor de frequência cardíaca. Ele combina dois LEDs, um fotodetector, óptica otimizada e processamento de sinal analógico de baixo ruído para detectar sinais de pulso e frequência cardíaca. Ele opera com fontes de alimentação de 1,8 V e 3,3 V e pode ser desligado por meio de software com corrente de espera insignificante, permitindo que a fonte de alimentação permaneça conectada o tempo todo.

 

Características

1. Consome energia muito baixa (opera de 1,8 V e 3,3 V)
2. Corrente de desligamento ultrabaixa (0,7 µA, típico)
3. Capacidade de saída rápida de dados

 

Funcionamento do oxímetro de pulso MAX30100 e do sensor de frequência cardíaca

O aparelho possui dois LEDs, um emitindo luz vermelha e outro emitindo luz infravermelha. Para a taxa de pulso, apenas a luz infravermelha é necessária. Tanto a luz vermelha quanto a infravermelha são usadas para medir os níveis de oxigênio no sangue.

Quando o coração bombeia sangue, há um aumento no sangue oxigenado como resultado de ter mais sangue. Conforme o coração relaxa, o volume de sangue oxigenado também diminui. Conhecendo o tempo entre o aumento e a diminuição do sangue oxigenado, a taxa de pulso é determinada.

Acontece que o sangue oxigenado absorve mais luz infravermelha e passa mais luz vermelha, enquanto o sangue desoxigenado absorve a luz vermelha e passa mais luz infravermelha. Esta é a principal função do MAX30100: ele lê os níveis de absorção de ambas as fontes de luz e os armazena em um buffer que pode ser lido via I2C.

Para saber mais sobre o oxímetro de pulso MAX30100, você pode seguir este post: Monitor de oxigênio no sangue e frequência cardíaca com MAX30100 e Arduino

 

Sensor de Temperatura DS18B20

Esta é uma versão pré-cabeada e à prova d’água do sensor DS18B20. Útil para quando você precisa medir algo longe ou em condições úmidas. O sensor pode medir a temperatura entre -55 a 125°C (-67°F a +257°F). O cabo é revestido em PVC.

Por ser digital, não há degradação do sinal mesmo em longas distâncias. Esses sensores de temperatura digitais de 1 fio são bastante precisos, ou seja, ± 0,5°C em grande parte da faixa. Ele pode fornecer até 12 bits de precisão do conversor digital para analógico integrado. Eles funcionam muito bem com qualquer microcontrolador usando um único pino digital.

A única desvantagem é que eles usam o protocolo Dallas 1-Wire, que é um tanto complexo e requer muitos códigos para analisar a comunicação. Lançamos um resistor de 4,7k, que é necessário como um pullup de DATA para a linha VCC ao usar o sensor.

Para saber mais sobre o sensor de temperatura DS18B20 você pode seguir este post: Interface do sensor de temperatura DS18B20 com o Arduino

 

Sensor de umidade e temperatura DHT11

O DHT11 é um sensor digital básico de temperatura e umidade de baixo custo. Ele usa um sensor de umidade capacitivo e um termistor para medir o ar circundante e emite um sinal digital no pino de dados (não são necessários pinos de entrada analógica).

É bastante simples de usar, mas requer um tempo cuidadoso para obter os dados. A única desvantagem real deste sensor é que você só pode obter novos dados dele uma vez a cada 2 segundos, portanto, ao usar a biblioteca, as leituras do sensor podem ter até 2 segundos.

Para saber mais sobre o sensor de umidade/temperatura DHT11 você pode seguir este post: Interface do sensor de umidade e temperatura DHT11 com Arduino e LCD

 

Monitoramento da saúde do paciente com base em IoT no servidor da Web ESP32

Agora, vamos começar com o projeto do monitoramento da saúde do paciente baseado em IoT no servidor da Web ESP32. Portanto, o diagrama do circuito para fazer a interface do MAX30100, DHT11 e DS18B20 com o ESP32 é fornecido abaixo.

Todo o sensor pode funcionar em 3,3 V VCC. Portanto, conecte seu VCC à fonte de alimentação de 3,3V. Conecte o GND ao GND. MAX30100 é um Sensor I2C, então conecte seu pino SDA e SCL a GPIO21 e GPIO22. Conecte seu pino INT ao GPIO19 do ESP32. O pino de saída do DHT11 é conectado ao GPIO18 do ESP32. Da mesma forma, o pino de saída do DS18B20 é conectado ao GPIO5 do ESP32. Um resistor pull-up de 4.7K é conectado entre o pino de saída e o pino VCC do DS18B20.

 

Código Fonte/Programa

O Programa/Código-fonte para monitoramento da saúde do paciente baseado em IoT no ESP32 Web Server é fornecido abaixo. Você precisa instalar algumas bibliotecas para compilar o código-fonte. O link da biblioteca também é fornecido abaixo. Baixe todas as bibliotecas e adicione ao Arduino IDE.

1. Biblioteca Arduino MAX30100
2. Biblioteca OneWire
3. Biblioteca de temperatura de Dallas
4. Biblioteca DHT11

Faça alterações no SSID e senha do Wifi.

#include <WiFi.h>
#include <WebServer.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#include <dht.h>  
 
#define DHT11_PIN 18
#define DS18B20 5
#define REPORTING_PERIOD_MS     1000
 
float temperature, humidity, BPM, SpO2, bodytemperature;
 
/*Put your SSID & Password*/
const char* ssid = "Alexahome";     //Insira o SSID aqui
const char* password = "12345678";  //Digite a senha aqui
 
dht DHT;
PulseOximeter pox;
uint32_t tsLastReport = 0;
OneWire oneWire(DS18B20);
DallasTemperature sensors(&oneWire);
 
 
WebServer server(80);             
 
void onBeatDetected()
{
  Serial.println("Beat!");
}
 
void setup() {
  Serial.begin(115200);
  pinMode(19, OUTPUT);
  delay(100);   
 
  Serial.println("Conectando à");
  Serial.println(ssid);
 
  //connect to your local wi-fi network
  WiFi.begin(ssid, password);
 
  //verifique se o wi-fi está conectado à rede wi-fi
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi conectado ..!");
  Serial.print("IP obtido: "); 
  Serial.println(WiFi.localIP());
 
  server.on("/", handle_OnConnect);
  server.onNotFound(handle_NotFound);
 
  server.begin();
  Serial.println("HTTP server started");
 
  Serial.print("Inicializando oxímetro de pulso..");
 
  if (!pox.begin()) {
    Serial.println("FAILED");
    for (;;);
  } else {
    Serial.println("SUCCESS");
    pox.setOnBeatDetectedCallback(onBeatDetected);
  }
 
   pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
 
  // Registre um retorno de chamada para a detecção de batida
 
}
void loop() {
  server.handleClient();
  pox.update();
  sensors.requestTemperatures();
  int chk = DHT.read11(DHT11_PIN);
  
  temperature = DHT.temperature;
  humidity = DHT.humidity;
  BPM = pox.getHeartRate();
  SpO2 = pox.getSpO2();
  bodytemperature = sensors.getTempCByIndex(0);
 
  
  if (millis() - tsLastReport > REPORTING_PERIOD_MS) 
  {
    Serial.print("Temperatura do quarto: ");
    Serial.print(DHT.temperature);
    Serial.println("°C");
    
    Serial.print("Umidade do quarto: ");
    Serial.print(DHT.humidity);
    Serial.println("%");
    
    Serial.print("BPM: ");
    Serial.println(BPM);
    
    Serial.print("SpO2: ");
    Serial.print(SpO2);
    Serial.println("%");
 
    Serial.print("Temperatura corporal: ");
    Serial.print(bodytemperature);
    Serial.println("°C");
    
    Serial.println("*********************************");
    Serial.println();
 
    tsLastReport = millis();
  }
  
}
 
void handle_OnConnect() {
  server.send(200, "text/html", SendHTML(temperature, humidity, BPM, SpO2, bodytemperature)); 
}
 
void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}
 
  String SendHTML(float temperature,float humidity,float BPM,float SpO2, float bodytemperature){
  String ptr = "<!DOCTYPE html>";
  ptr +="<html>";
  ptr +="<head>";
  ptr +="<title>Monitoramento da saúde do paciente ESP32</title>";
  ptr +="<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
  ptr +="<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600' rel='stylesheet'>";
  ptr +="<style>";
  ptr +="html { font-family: 'Open Sans', sans-serif; display: block; margin: 0px auto; text-align: center;color: #444444;}";
  ptr +="body{margin: 0px;} ";
  ptr +="h1 {margin: 50px auto 30px;} ";
  ptr +=".side-by-side{display: table-cell;vertical-align: middle;position: relative;}";
  ptr +=".text{font-weight: 600;font-size: 19px;width: 200px;}";
  ptr +=".reading{font-weight: 300;font-size: 50px;padding-right: 25px;}";
  ptr +=".temperature .reading{color: #F29C1F;}";
  ptr +=".humidity .reading{color: #3B97D3;}";
  ptr +=".BPM .reading{color: #FF0000;}";
  ptr +=".SpO2 .reading{color: #955BA5;}";
  ptr +=".bodytemperature .reading{color: #F29C1F;}";
  ptr +=".superscript{font-size: 17px;font-weight: 600;position: absolute;top: 10px;}";
  ptr +=".data{padding: 10px;}";
  ptr +=".container{display: table;margin: 0 auto;}";
  ptr +=".icon{width:65px}";
  ptr +="</style>";
  ptr +="</head>";
  ptr +="<body>";
  ptr +="<h1>Monitoramento da saúde do paciente ESP32</h1>";
  ptr +="<h3>www.capsistema.com.br</h3>";
  ptr +="<div class='container'>";
  
  ptr +="<div class='data temperature'>";
  ptr +="<div class='side-by-side icon'>";
  ptr +="<svg enable-background='new 0 0 19.438 54.003'height=54.003px id=Layer_1 version=1.1 viewBox='0 0 19.438 54.003'width=19.438px x=0px xml:space=preserve xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink y=0px><g><path d='M11.976,8.82v-2h4.084V6.063C16.06,2.715,13.345,0,9.996,0H9.313C5.965,0,3.252,2.715,3.252,6.063v30.982";
  ptr +="C1.261,38.825,0,41.403,0,44.286c0,5.367,4.351,9.718,9.719,9.718c5.368,0,9.719-4.351,9.719-9.718";
  ptr +="c0-2.943-1.312-5.574-3.378-7.355V18.436h-3.914v-2h3.914v-2.808h-4.084v-2h4.084V8.82H11.976z M15.302,44.833";
  ptr +="c0,3.083-2.5,5.583-5.583,5.583s-5.583-2.5-5.583-5.583c0-2.279,1.368-4.236,3.326-5.104V24.257C7.462,23.01,8.472,22,9.719,22";
  ptr +="s2.257,1.01,2.257,2.257V39.73C13.934,40.597,15.302,42.554,15.302,44.833z'fill=#F29C21 /></g></svg>";
  ptr +="</div>";
  ptr +="<div class='side-by-side text'>Temperatura do quarto</div>";
  ptr +="<div class='side-by-side reading'>";
  ptr +=(int)temperature;
  ptr +="<span class='superscript'>&deg;C</span></div>";
  ptr +="</div>";
  
  ptr +="<div class='data humidity'>";
  ptr +="<div class='side-by-side icon'>";
  ptr +="<svg enable-background='new 0 0 29.235 40.64'height=40.64px id=Layer_1 version=1.1 viewBox='0 0 29.235 40.64'width=29.235px x=0px xml:space=preserve xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink y=0px><path d='M14.618,0C14.618,0,0,17.95,0,26.022C0,34.096,6.544,40.64,14.618,40.64s14.617-6.544,14.617-14.617";
  ptr +="C29.235,17.95,14.618,0,14.618,0z M13.667,37.135c-5.604,0-10.162-4.56-10.162-10.162c0-0.787,0.638-1.426,1.426-1.426";
  ptr +="c0.787,0,1.425,0.639,1.425,1.426c0,4.031,3.28,7.312,7.311,7.312c0.787,0,1.425,0.638,1.425,1.425";
  ptr +="C15.093,36.497,14.455,37.135,13.667,37.135z'fill=#3C97D3 /></svg>";
  ptr +="</div>";
  ptr +="<div class='side-by-side text'>Umidade do quarto</div>";
  ptr +="<div class='side-by-side reading'>";
  ptr +=(int)humidity;
  ptr +="<span class='superscript'>%</span></div>";
  ptr +="</div>";
  
  ptr +="<div class='data Heart Rate'>";
  ptr +="<div class='side-by-side icon'>";
  ptr +="<svg enable-background='new 0 0 40.542 40.541'height=40.541px id=Layer_1 version=1.1 viewBox='0 0 40.542 40.541'width=40.542px x=0px xml:space=preserve xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink y=0px><g><path d='M34.313,20.271c0-0.552,0.447-1,1-1h5.178c-0.236-4.841-2.163-9.228-5.214-12.593l-3.425,3.424";
  ptr +="c-0.195,0.195-0.451,0.293-0.707,0.293s-0.512-0.098-0.707-0.293c-0.391-0.391-0.391-1.023,0-1.414l3.425-3.424";
  ptr +="c-3.375-3.059-7.776-4.987-12.634-5.215c0.015,0.067,0.041,0.13,0.041,0.202v4.687c0,0.552-0.447,1-1,1s-1-0.448-1-1V0.25";
  ptr +="c0-0.071,0.026-0.134,0.041-0.202C14.39,0.279,9.936,2.256,6.544,5.385l3.576,3.577c0.391,0.391,0.391,1.024,0,1.414";
  ptr +="c-0.195,0.195-0.451,0.293-0.707,0.293s-0.512-0.098-0.707-0.293L5.142,6.812c-2.98,3.348-4.858,7.682-5.092,12.459h4.804";
  ptr +="c0.552,0,1,0.448,1,1s-0.448,1-1,1H0.05c0.525,10.728,9.362,19.271,20.22,19.271c10.857,0,19.696-8.543,20.22-19.271h-5.178";
  ptr +="C34.76,21.271,34.313,20.823,34.313,20.271z M23.084,22.037c-0.559,1.561-2.274,2.372-3.833,1.814";
  ptr +="c-1.561-0.557-2.373-2.272-1.815-3.833c0.372-1.041,1.263-1.737,2.277-1.928L25.2,7.202L22.497,19.05";
  ptr +="C23.196,19.843,23.464,20.973,23.084,22.037z'fill=#26B999 /></g></svg>";
  ptr +="</div>";
  ptr +="<div class='side-by-side text'>Frequência cardíaca</div>";
  ptr +="<div class='side-by-side reading'>";
  ptr +=(int)BPM;
  ptr +="<span class='superscript'>BPM</span></div>";
  ptr +="</div>";
  
  ptr +="<div class='data Blood Oxygen'>";
  ptr +="<div class='side-by-side icon'>";
  ptr +="<svg enable-background='new 0 0 58.422 40.639'height=40.639px id=Layer_1 version=1.1 viewBox='0 0 58.422 40.639'width=58.422px x=0px xml:space=preserve xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink y=0px><g><path d='M58.203,37.754l0.007-0.004L42.09,9.935l-0.001,0.001c-0.356-0.543-0.969-0.902-1.667-0.902";
  ptr +="c-0.655,0-1.231,0.32-1.595,0.808l-0.011-0.007l-0.039,0.067c-0.021,0.03-0.035,0.063-0.054,0.094L22.78,37.692l0.008,0.004";
  ptr +="c-0.149,0.28-0.242,0.594-0.242,0.934c0,1.102,0.894,1.995,1.994,1.995v0.015h31.888c1.101,0,1.994-0.893,1.994-1.994";
  ptr +="C58.422,38.323,58.339,38.024,58.203,37.754z'fill=#955BA5 /><path d='M19.704,38.674l-0.013-0.004l13.544-23.522L25.13,1.156l-0.002,0.001C24.671,0.459,23.885,0,22.985,0";
  ptr +="c-0.84,0-1.582,0.41-2.051,1.038l-0.016-0.01L20.87,1.114c-0.025,0.039-0.046,0.082-0.068,0.124L0.299,36.851l0.013,0.004";
  ptr +="C0.117,37.215,0,37.62,0,38.059c0,1.412,1.147,2.565,2.565,2.565v0.015h16.989c-0.091-0.256-0.149-0.526-0.149-0.813";
  ptr +="C19.405,39.407,19.518,39.019,19.704,38.674z'fill=#955BA5 /></g></svg>";
  ptr +="</div>";
  ptr +="<div class='side-by-side text'>Oxigênio no Sangue</div>";
  ptr +="<div class='side-by-side reading'>";
  ptr +=(int)SpO2;
  ptr +="<span class='superscript'>%</span></div>";
  ptr +="</div>";
 
  ptr +="<div class='data Body Temperature'>";
  ptr +="<div class='side-by-side icon'>";
  ptr +="<svg enable-background='new 0 0 19.438 54.003'height=54.003px id=Layer_1 version=1.1 viewBox='0 0 19.438 54.003'width=19.438px x=0px xml:space=preserve xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink y=0px><g><path d='M11.976,8.82v-2h4.084V6.063C16.06,2.715,13.345,0,9.996,0H9.313C5.965,0,3.252,2.715,3.252,6.063v30.982";
  ptr +="C1.261,38.825,0,41.403,0,44.286c0,5.367,4.351,9.718,9.719,9.718c5.368,0,9.719-4.351,9.719-9.718";
  ptr +="c0-2.943-1.312-5.574-3.378-7.355V18.436h-3.914v-2h3.914v-2.808h-4.084v-2h4.084V8.82H11.976z M15.302,44.833";
  ptr +="c0,3.083-2.5,5.583-5.583,5.583s-5.583-2.5-5.583-5.583c0-2.279,1.368-4.236,3.326-5.104V24.257C7.462,23.01,8.472,22,9.719,22";
  ptr +="s2.257,1.01,2.257,2.257V39.73C13.934,40.597,15.302,42.554,15.302,44.833z'fill=#F29C21 /></g></svg>";
  ptr +="</div>";
  ptr +="<div class='side-by-side text'>Temperatura corporal</div>";
  ptr +="<div class='side-by-side reading'>";
  ptr +=(int)bodytemperature;
  ptr +="<span class='superscript'>&deg;C</span></div>";
  ptr +="</div>";
  
  ptr +="</div>";
  ptr +="</body>";
  ptr +="</html>";
  return ptr;
}

 

Resultados e Trabalho do Projeto

Assim que o código for carregado, você pode abrir o monitor serial. O ESP32 tentará se conectar a uma rede. Uma vez conectado, ele exibirá o endereço IP.

Copie o endereço IP e cole-o em qualquer navegador da Web e pressione Enter. Você verá a temperatura ambiente, umidade ambiente, frequência cardíaca, nível de oxigênio no sangue, temperatura corporal, etc.

Da mesma forma, você também pode visualizar o status de saúde do paciente no telefone celular. Simplesmente copie o endereço IP e cole no navegador do Celular.