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);



