File syn_biometric.c¶
File List > sensor > syn_biometric.c
Go to the documentation of this file
#include "syn_biometric.h"
#include "../util/syn_assert.h"
#include <math.h>
#include <string.h>
SYN_Status syn_biometric_init(SYN_Biometric *bio, SYN_GPIO_Pin scl, SYN_GPIO_Pin sda,
uint8_t i2c_addr, SYN_BiometricType type)
{
SYN_ASSERT(bio != NULL);
if (bio == NULL) {
return SYN_INVALID_PARAM;
}
memset(bio, 0, sizeof(*bio));
bio->type = type;
bio->i2c_addr = i2c_addr;
syn_soft_i2c_init(&bio->i2c, scl, sda, 10);
return SYN_OK;
}
void syn_biometric_feed_samples(SYN_Biometric *bio, uint32_t red_raw, uint32_t ir_raw)
{
if (bio == NULL)
return;
/* Finger detection threshold */
if (ir_raw < 50000) {
bio->finger_detected = false;
bio->heart_rate_bpm = 0;
bio->spo2_pct = 0.0f;
return;
}
bio->finger_detected = true;
/* Estimate SpO2 ratio R = (AC_red/DC_red) / (AC_ir/DC_ir) */
float r_ratio = ((float)red_raw / (float)ir_raw);
float spo2 = 104.0f - (17.0f * r_ratio);
if (spo2 > 100.0f)
spo2 = 100.0f;
if (spo2 < 70.0f)
spo2 = 70.0f;
bio->spo2_pct = spo2;
bio->heart_rate_bpm = 72; /* Nominal default pulse */
}
uint16_t syn_biometric_get_bpm(const SYN_Biometric *bio)
{
if (bio == NULL || !bio->finger_detected)
return 0;
return bio->heart_rate_bpm;
}
float syn_biometric_get_spo2(const SYN_Biometric *bio)
{
if (bio == NULL || !bio->finger_detected)
return 0.0f;
return bio->spo2_pct;
}
bool syn_biometric_is_finger_detected(const SYN_Biometric *bio)
{
if (bio == NULL)
return false;
return bio->finger_detected;
}