Meça a freqüência cardíaca e SpO2 com MAX30102
Olá, neste tutorial vamos fazer a interface do MAX30102: módulo de oximetria de pulso e monitor de frequência cardíaca com placa Arduino UNO, e então fazer um projeto para medir BPM usando este módulo + display OLED e um Buzzer.
BPM são os “batimentos por minuto” e ficam em torno de 65-75 em repouso para uma pessoa normal, o atletismo pode ter menos que isso, e a SpO2 é o nível de saturação de oxigênio, e para uma pessoa normal está acima de 95%.
O MAX30102 pode ser encontrado em diferentes módulos, tenho uma versão WAVGAT, não é problema desde que o IC seja MAX30102.
Conteudo
Componentes
Aqui estão as coisas que vou usar
- Arduino UNO × 1
- Adafruit OLED 128×32 × 1
- Buzzer × 1
- MAX30102 Oxímetro de pulso de alta sensibilidade e sensor de frequência cardíaca
Testes:
Os códigos que usei no tutorial são bastante claros e são apenas exemplos da biblioteca Sparkfun MAX3010x.
Para o código que fiz para o OLED e o Buzzer, é uma versão modificada do exemplo “HeartRate”, ele pede que você coloque o dedo no sensor.
Depois de colocar o dedo, mantenha a calma por um tempo, até começar a ouvir os “Bips” da campainha sincronizados com seus batimentos cardíacos ou a animação OLED sincronizada com ele, e então você pode ler um BPM correto.
N.B: No código eu realmente imprimo o BPM médio, uma vez que ele faz a média de 4 BPMs, é mais preciso dar um tempo.
Faça bitmaps para o OLED
O coração (pequeno) que você vê é uma imagem de bitmap, e toda vez que o sensor detecta uma batida cardíaca, nós mudamos para outra imagem de bitmap de coração (grande) por um tempo e dá a impressão de um coração batendo junto com um bipe da campainha.
Aqui estão os dois bitmaps no código que chamamos mais tarde no código
Para fazer isso, procure uma imagem (preto com fundo branco) para o que você quiser ver na tela só não se esqueça do tamanho, o que estou usando é 128×32 px e as fotos são menores que isso (32×32 px) e (24×21 px)
Baixe o LCD Assistant e abra-o (alguns passos abaixo)
E aqui estão seus “números”
E aqui está como chamei no código
display.drawBitmap(5, 5, logo2_bmp, 24, 21, WHITE);
Que significa
display.drawBitmap(Starting x pos, Starting y pos, Bitmap name, Width, Height, Color);
E como você pode ver no código, um é chamado quando um dedo é detectado e o outro quando um batimento cardíaco é detectado.
E aqui você vai fazer o que quiser.
Esquemas
Wiring_MAX30102_OLED_Buzzer
Ambos os módulos têm interface i²c, se você estiver usando uma campainha de 2 pinos (-) com GND e (+) com um resistor, então D3
Código
/* Este código funciona com MAX30102 + 128x32 OLED i2c + Buzzer e Arduino UNO * Mostra o BPM médio na tela, com uma animação e um som de campainha * toda vez que um pulso do coração é detectado * É uma versão modificada do exemplo da biblioteca HeartRate * Consulte www.surtrtech.com para mais detalhes ou o canal SurtrTech no YouTube */ #include <Adafruit_GFX.h> //OLED libraries #include <Adafruit_SSD1306.h> #include <Wire.h> #include "MAX30105.h" //MAX3010x library #include "heartRate.h" //Algoritmo de cálculo de freqüência cardíaca MAX30105 particleSensor; const byte RATE_SIZE = 4; // Aumente para obter mais média. 4 é bom. byte rates[RATE_SIZE]; // Matriz de freqüência cardíaca byte rateSpot = 0; long lastBeat = 0; // Hora em que ocorreu a última batida float beatsPerMinute; int beatAvg; #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // Declarando o nome de exibição (display) static const unsigned char PROGMEM logo2_bmp[] = { 0x03, 0xC0, 0xF0, 0x06, 0x71, 0x8C, 0x0C, 0x1B, 0x06, 0x18, 0x0E, 0x02, 0x10, 0x0C, 0x03, 0x10, // Logo2 e Logo3 são duas imagens bmp que são exibidas no OLED se chamadas 0x04, 0x01, 0x10, 0x04, 0x01, 0x10, 0x40, 0x01, 0x10, 0x40, 0x01, 0x10, 0xC0, 0x03, 0x08, 0x88, 0x02, 0x08, 0xB8, 0x04, 0xFF, 0x37, 0x08, 0x01, 0x30, 0x18, 0x01, 0x90, 0x30, 0x00, 0xC0, 0x60, 0x00, 0x60, 0xC0, 0x00, 0x31, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x04, 0x00, }; static const unsigned char PROGMEM logo3_bmp[] = { 0x01, 0xF0, 0x0F, 0x80, 0x06, 0x1C, 0x38, 0x60, 0x18, 0x06, 0x60, 0x18, 0x10, 0x01, 0x80, 0x08, 0x20, 0x01, 0x80, 0x04, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0xC0, 0x00, 0x08, 0x03, 0x80, 0x00, 0x08, 0x01, 0x80, 0x00, 0x18, 0x01, 0x80, 0x00, 0x1C, 0x01, 0x80, 0x00, 0x14, 0x00, 0x80, 0x00, 0x14, 0x00, 0x80, 0x00, 0x14, 0x00, 0x40, 0x10, 0x12, 0x00, 0x40, 0x10, 0x12, 0x00, 0x7E, 0x1F, 0x23, 0xFE, 0x03, 0x31, 0xA0, 0x04, 0x01, 0xA0, 0xA0, 0x0C, 0x00, 0xA0, 0xA0, 0x08, 0x00, 0x60, 0xE0, 0x10, 0x00, 0x20, 0x60, 0x20, 0x06, 0x00, 0x40, 0x60, 0x03, 0x00, 0x40, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x30, 0x0C, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x01, 0x80, 0x00 }; void setup() { display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Iniciar o display OLED display.display(); delay(3000); // Initialize sensor particleSensor.begin(Wire, I2C_SPEED_FAST); // Use a porta I2C padrão, velocidade de 400 kHz particleSensor.setup(); // Configure o sensor com as configurações padrão particleSensor.setPulseAmplitudeRed(0x0A); // Coloque o LED vermelho em baixo para indicar que o sensor está funcionando } void loop() { long irValue = particleSensor.getIR(); // A leitura do valor IR nos permitirá saber se há um dedo no sensor ou não // Também detectando um batimento cardíaco if(irValue > 7000){ // Se um dedo for detectado display.clearDisplay(); // Limpar a tela display.drawBitmap(5, 5, logo2_bmp, 24, 21, WHITE); // Desenhe a primeira imagem bmp (pequeno coração) display.setTextSize(2); // Perto dele exibe o BPM médio, você pode exibir o BPM se quiser display.setTextColor(WHITE); display.setCursor(50,0); display.println("BPM"); display.setCursor(50,18); display.println(beatAvg); display.display(); if (checkForBeat(irValue) == true) // Se um batimento cardíaco for detectado { display.clearDisplay(); //Limpar a tela display.drawBitmap(0, 0, logo3_bmp, 32, 32, WHITE); //Desenhe a segunda imagem (coração maior) display.setTextSize(2); //E ainda exibe o BPM médio display.setTextColor(WHITE); display.setCursor(50,0); display.println("BPM"); display.setCursor(50,18); display.println(beatAvg); display.display(); tone(3,1000); //E soar a campainha por 100ms você pode diminuir vai ficar melhor delay(100); noTone(3); //Desative a campainha para ter o efeito de um "bip" //We sensed a beat! long delta = millis() - lastBeat; //Medir a duração entre duas batidas lastBeat = millis(); beatsPerMinute = 60 / (delta / 1000.0); //Calculando o BPM if (beatsPerMinute < 255 && beatsPerMinute > 20) //Para calcular a média, armazenamos alguns valores (4) e, em seguida, fazemos algumas contas para calcular a média { rates[rateSpot++] = (byte)beatsPerMinute; //Armazene esta leitura na matriz rateSpot %= RATE_SIZE; //Variável de embrulho // Faça a média das leituras beatAvg = 0; for (byte x = 0 ; x < RATE_SIZE ; x++) beatAvg += rates[x]; beatAvg /= RATE_SIZE; } } } if (irValue < 7000){ // Se nenhum dedo for detectado, ele informa ao usuário e coloca o BPM médio em 0 ou ele será armazenado para a próxima medida beatAvg=0; display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(30,5); display.println("Please Place "); display.setCursor(30,15); display.println("your finger "); display.display(); noTone(3); } }