Rilevare frequenza cardiaca e ossigenazione del sangue con il biosensore MAX30102
Il MAX30102 è un biosensore dotato di cardiofrequenzimetro e ossimetro, includendo LED interni, foto rivelatori, elementi ottici ed elettronica a basso rumore con rifiuto della luce ambientale. Il MAX30102 è realizzato per facilitare il processo di progettazione per dispositivi mobili e indossabili. La programmazione è facilitata anche dall’utilizzo dell’interfaccia I2C.
Specifiche
Alimentabile con una tensione di 3,3V o 5V, il MAX30102 funziona con una tensione di lavoro da 1,8 V, mentre possiede una tensione dedicata da 3,3 V per i LED interni. La comunicazione avviene tramite interfaccia I2C a frequenze di clock fino a 400kHz. Ogni parola trasmessa al MAX30102 è lunga 8 bit ed è seguita da un impulso di clock di riconoscimento. Il modulo può essere spento tramite software, portandolo in modalità di standby, consentendo alle linee di alimentazione di rimanere sempre alimentate.
Troviamo 8 pin: il Vin e GND per l’alimentazione, SDA e SCL per l’interfaccia I2C, INT per interrupt a cui collegare un’alimentazione esterna con resistore in pullup, RD il terminale di messa a terra del LED RED e IRD il terminale di messa a terra del LED INFRARED (solitamente RD e IRD non vanno connessi).
Acquistalo su Amazon: https://amzn.to/2S0Iuke
Acquistalo su Aliexpress: https://s.click.aliexpress.com/e/_ADZ78B
Collegamenti
Il sensore MAX30102 richiede solo la semplice connessione tramite interfaccia I2C, quindi SDA e SCL del sensore vanno connessi a SDA e SCL di Arduino, mentre il Vin ai 5V o ai 3,3V, mentre il GND al GND di Arduino.
Codice
Per funzionare il sensore MAX30102 necessita di un’apposita libreria che possiamo scaricare direttamente dalla IDE di Arduino: muoviamoci sulla barra dei menu ->Sketch->#include libreria->Gestione libreria. Dal Gestore librerie cerchiamo nella casella di ricerca “MAX30102” e scarichiamo la libreria SparkFun MAX3010x Pulse and Proximity Sensor Library.
Andremo a vedere due esempi proposti dalla libreria. Nel primo (Exampl5_HeartRate), oltre alla libreria da adoperare, verrà anche adoperata una funzione che contiene l’algoritmo per il calcolo della frequenza cardiaca (heartRate.h).
#include <Wire.h> #include "MAX30105.h" #include "heartRate.h"
Nel VOID SETUP avviamo il sensore e poi lo configuriamo, attivando il led rosso integrato nel sensore.
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) { Serial.println("MAX30105 was not found. Please check wiring/power. "); while (1); } Serial.println("Place your index finger on the sensor with steady pressure."); particleSensor.setup(); particleSensor.setPulseAmplitudeRed(0x0A);
Nel VOID LOOP verifichiamo che il led Infrarosso sia attivo e se il valore è superiore a 50000, vengono calcolati e stampati i valori cardiaci rilevati, altrimenti viene avvisato l’utente che va poggiato il dito sul sensore per effettuare le misurazioni.
long irValue = particleSensor.getIR(); if (checkForBeat(irValue) == true) { //We sensed a beat! long delta = millis() - lastBeat; lastBeat = millis(); beatsPerMinute = 60 / (delta / 1000.0); if (beatsPerMinute < 255 && beatsPerMinute > 20) { rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array rateSpot %= RATE_SIZE; //Wrap variable //Take average of readings beatAvg = 0; for (byte x = 0 ; x < RATE_SIZE ; x++) beatAvg += rates[x]; beatAvg /= RATE_SIZE; } } Serial.print("IR="); Serial.print(irValue); Serial.print(", BPM="); Serial.print(beatsPerMinute); Serial.print(", Avg BPM="); Serial.print(beatAvg); if (irValue < 50000) Serial.print(" No finger?"); Serial.println();
Nel secondo esempio, chiamato Exampl8_SPO2, troviamo il codice per effettuare la misurazione dei livelli di ossigeno nel sangue. Come prima, pariamo inserendo l’apposita libreria e un algoritmo per il calcolo dei livelli di ossigeno.
#include <Wire.h> #include "MAX30105.h" #include "spo2_algorithm.h"
Nel VOID SETUP, avviamo il sensore e lo configuriamo con una serie di impostazioni, come ad esempio la frequenza del campionamento, la media del campione e la larghezza dell’impulso. Nell’esempio troviamo anche i valori che possiamo settare.
byte ledBrightness = 60; //Options: 0=Off to 255=50mA byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32 byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green byte sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200 int pulseWidth = 411; //Options: 69, 118, 215, 411 int adcRange = 4096; //Options: 2048, 4096, 8192, 16384 particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings
Possiamo anche cancellare le righe. In questo modo,possiamo evitare di avviare la lettura del sensore digitando un qualsiasi tasto su monitor seriale::
Serial.println(F("Attach sensor to finger with rubber band. Press any key to start conversion")); while (Serial.available() == 0) ; //wait until user presses a key Serial.read();
Nel VOID LOOP, come prima, andiamo a estrapolare e stampare i valori. Questa operazione richiede qualche secondo di attesa prima che i valori siano correttamente calcolati.
while (particleSensor.available() == false) //do we have new data? particleSensor.check(); //Check the sensor for new data digitalWrite(readLED, !digitalRead(readLED)); //Blink onboard LED with every data read redBuffer[i] = particleSensor.getRed(); irBuffer[i] = particleSensor.getIR(); particleSensor.nextSample(); //We're finished with this sample so move to next sample //send samples and calculation result to terminal program through UART Serial.print(F("red=")); Serial.print(redBuffer[i], DEC); Serial.print(F(", ir=")); Serial.print(irBuffer[i], DEC); Serial.print(F(", HR=")); Serial.print(heartRate, DEC); Serial.print(F(", HRvalid=")); Serial.print(validHeartRate, DEC); Serial.print(F(", SPO2=")); Serial.print(spo2, DEC); Serial.print(F(", SPO2Valid=")); Serial.println(validSPO2, DEC);