Indice
Descrizione
Vuoi misurare la tua frequenza cardiaca con Arduino? In questo video scoprirai come usare un sensore di battito cardiaco per ottenere dati in tempo reale. Ti guiderò passo dopo passo nel collegamento del sensore e nella lettura dei valori.
Vedrai come scrivere il codice necessario per elaborare i segnali e visualizzare i dati in modo chiaro e preciso. Bastano pochi componenti e alcune righe di codice per trasformare Arduino in un semplice strumento di monitoraggio biometrico.
Alla fine sarai in grado di leggere la frequenza cardiaca direttamente su un display OLED.
#define SENSOR_PIN A0
#define ALPHA 0.75
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(readSensor());
delay(20);
}
float readSensor() {
static float last = 0;
float sum = 0;
for (int i = 0; i < 20; i++) {
sum += analogRead(SENSOR_PIN);
delay(1);
};
last = ALPHA * (sum / 20) + (1 - ALPHA) * last;
return last;
}
#define SENSOR_PIN A0
#define ALPHA 0.75
#define LED_PIN 9
#define BEAT_BUFFER_SIZE 7
#define THRESHOLD 3
#define MIN_VALUE 100
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
float value = readSensor();
if (detectBeat(value)) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
}
bool detectBeat(float currentValue) {
static float buffer[BEAT_BUFFER_SIZE] = { 0 };
static int index = 0;
static int counter = 0;
static bool isRising = false;
bool detected = false;
if (currentValue < MIN_VALUE) {
return false;
}
buffer[index] = currentValue;
index = (index + 1) % BEAT_BUFFER_SIZE;
int half = BEAT_BUFFER_SIZE / 2;
float olderSum = 0;
float newerSum = 0;
int olderStart = index;
int newerStart = olderStart + BEAT_BUFFER_SIZE - half;
for (int i = 0; i < half; i++) {
olderSum += buffer[(olderStart + i) % BEAT_BUFFER_SIZE];
newerSum += buffer[(newerStart + i) % BEAT_BUFFER_SIZE];
}
counter += newerSum > olderSum ? 1 : -1;
if (abs(counter) > THRESHOLD) {
detected = counter > 0 && !isRising;
isRising = counter > 0;
counter = 0;
}
return detected;
}
float readSensor() {
static float last = 0;
float sum = 0;
for (int i = 0; i < 20; i++) {
sum += analogRead(SENSOR_PIN);
delay(1);
};
last = ALPHA * (sum / 20) + (1 - ALPHA) * last;
return last;
}
#include <Adafruit_SSD1306.h>
#include "images.h"
#define SENSOR_PIN A0
#define ALPHA 0.75
#define LED_PIN 9
#define BEAT_BUFFER_SIZE 7
#define THRESHOLD 3
#define MIN_VALUE 100
#define TIMEOUT 3000
#define INTERVALS_SIZE 7
#define OLED_I2C_ADDRESS 0x3C
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
unsigned long lastTime = 0;
float intervals[INTERVALS_SIZE] = { 0 };
int intervalIndex = 0;
int numBeats = 0;
Adafruit_SSD1306 oled(OLED_WIDTH, OLED_HEIGHT);
void setup() {
pinMode(LED_PIN, OUTPUT);
if (!oled.begin(SSD1306_SWITCHCAPVCC, OLED_I2C_ADDRESS)) {
while (true);
}
oled.clearDisplay();
showHeader();
showBPM(-1);
oled.display();
}
void loop() {
float value = readSensor();
unsigned long currentTime = millis();
if (detectBeat(value)) {
digitalWrite(LED_PIN, HIGH);
numBeats++;
if (numBeats > 1) {
intervals[intervalIndex] = currentTime - lastTime;
intervalIndex = (intervalIndex + 1) % INTERVALS_SIZE;
}
if (numBeats > INTERVALS_SIZE) {
showBPM(getBPM());
oled.display();
}
lastTime = currentTime;
} else {
digitalWrite(LED_PIN, LOW);
}
if (currentTime - lastTime > TIMEOUT) {
numBeats = 0;
showBPM(-1);
oled.display();
lastTime = currentTime;
}
}
float getBPM() {
float sum = 0;
for (int i = 0; i < INTERVALS_SIZE; i++) {
sum += intervals[i];
}
return INTERVALS_SIZE * 60000.0 / sum;
}
bool detectBeat(float currentValue) {
static float buffer[BEAT_BUFFER_SIZE] = { 0 };
static int index = 0;
static int counter = 0;
static bool isRising = false;
bool detected = false;
if (currentValue < MIN_VALUE) {
return false;
}
buffer[index] = currentValue;
index = (index + 1) % BEAT_BUFFER_SIZE;
int half = BEAT_BUFFER_SIZE / 2;
float olderSum = 0;
float newerSum = 0;
int olderStart = index;
int newerStart = olderStart + BEAT_BUFFER_SIZE - half;
for (int i = 0; i < half; i++) {
olderSum += buffer[(olderStart + i) % BEAT_BUFFER_SIZE];
newerSum += buffer[(newerStart + i) % BEAT_BUFFER_SIZE];
}
counter += newerSum > olderSum ? 1 : -1;
if (abs(counter) > THRESHOLD) {
detected = counter > 0 && !isRising;
isRising = counter > 0;
counter = 0;
}
return detected;
}
float readSensor() {
static float last = 0;
float sum = 0;
for (int i = 0; i < 20; i++) {
sum += analogRead(SENSOR_PIN);
delay(1);
};
last = ALPHA * (sum / 20) + (1 - ALPHA) * last;
return last;
}
void showHeader() {
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(16, 4);
oled.print("Battiti cardiaci");
oled.drawLine(0, 15, 128, 15, WHITE);
}
void showBPM(float bpm) {
int offset = 0;
String content = String((int) bpm);
if (bpm < 0) {
content = "---";
} else if (bpm < 100) {
offset = 24;
}
oled.fillRect(0, 16, 128, 63, BLACK);
oled.setTextColor(WHITE);
oled.setTextSize(4);
oled.setCursor(10 + offset, 26);
oled.print(content);
oled.setTextSize(1);
oled.setCursor(95, 47);
oled.print("BPM");
oled.drawBitmap(92, 21, heartbeat, 24, 24, WHITE);
}
// 'heartbeat', 48x48px
const unsigned char heartbeat [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
0xe7, 0xc0, 0x07, 0xff, 0xe0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xf3, 0xf0, 0x0f, 0xe3,
0xf0, 0x00, 0x08, 0x00, 0x07, 0xfc, 0xe0, 0x03, 0xfd, 0xc0, 0x01, 0xff, 0x80, 0x00, 0xff, 0x00,
0x00, 0x7e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
In qualità di Affiliato Amazon riceviamo un guadagno dagli acquisti idonei