如何将脉冲传感器的ANALOG值转换为BPM?



首先我要为我的英语说得不好而道歉。

我的问题如下:我有一个arduino传感器(iDuino SE049)。我需要将模拟值转换为BPM值。因此,首先我必须消除传感器可能遇到的漂移(滑动,(我不知道确切的词))。要做到这一点,我建议:

处理一个X值的数组计算平均值从每个值中减去平均值

之后,我需要在Arduino IDE(我在1.8.19版本上工作)上用曲线找到X的最佳值。(我的老师告诉我,数组的大小从X = 50开始)

一旦我有了这个平均值,我需要使系统对光线变化具有鲁棒性。问题:振幅变化,所以我们不能使用固定的阈值。心率隐藏在时间信息中。你只需要能够测量特征时间。解决方案:我可以用一个总是最大振幅为1的曲线,然后找到一个理想的阈值。

消除漂移后对X值表进行处理。寻找最大值所有值除以这个最大值按阈值拆分

然后我要做研究找到阈值

我试着做一个不能很好地处理漂移/滑动和信号平均值的代码。但是它并没有很好地工作,因为我无法在我的循环之外得到平均值,将其减去传感器读取的模拟值。

我想在20毫秒的时间内获得传感器读取的所有值,这就是为什么我使用函数millis()。所有这些值都需要存储在我的数组中

#include <Arduino.h>

int Sensor = 0;
//#define start_read 0
float tab[20]={0};
float sum = 0;
int i;

void setup() {
Serial.begin(9600);
}

void loop ()
{
unsigned long currentTime=0;
while (millis() - currentTime > 20)
{
tab[i] = analogRead(Sensor);
i++;
sum += tab[i];
float average = sum/20;
Serial.println(average);
}
currentTime = millis();
i = 0;
}

我有另一段代码要测试,我应该工作,但它不是,我不知道为什么:变量名是法语的,但你可以复制它,并改变它的名字,如果它更清楚,我会理解的变化。

#include <Arduino.h>
int sensor=A0, comp=1, var=0;
float bpm=0;
double temps;
const int nbr=50;
float tab[nbr]={0}, moyenne=0, maximum=0;
void setup() {
Serial.begin(9600);
pinMode(sensor, INPUT);
}
void loop() {
maximum=0;
moyenne=0;
for (int i = 0; i < nbr; i++)
{
tab[i]=analogRead(sensor);
moyenne=moyenne+tab[i];
delay(40);
}

moyenne=moyenne/nbr;

for (int i = 0; i < nbr; i++)
{
tab[i]=tab[i]-moyenne;
}
maximum=tab[0];
for (int i = 0; i < nbr; i++)
{
if (tab[i]>maximum)
{
maximum=tab[i];
}

}

for (int i = 0; i < nbr; i++)
{
tab[i]=tab[i]/maximum;
}

for (int i = 0; i < nbr; i++)
{
if (tab[i]>(0.950))
{
bpm++;
}

}

temps=(millis()/1000);
var=15*comp;
if (temps/(var)>=1)
{
bpm=bpm*4;
//Serial.setCursor(0,10);
Serial.print("BPM : ");
Serial.print(bpm);
Serial.println("♥️");
//Serial.display();
//Serial.clearDisplay();
comp=comp+1;
bpm=0;
}

}

我无法获得循环外的平均值

average在循环内声明,因此当迭代结束时,它将超出作用域。你应该在while循环之外声明它。

我想获得传感器在20毫秒的时间内读取的所有值

你可能想要得到像每毫秒1个值的东西,因为在20毫秒内读取的所有值不是20,你也可能无法知道值的确切数量,因为它取决于传感器的采样率等。

如果你需要这些值来获得一个固定的阈值(即使用代码来研究某些行为并获得将在第二个代码中使用的const),请将代码放在void setup()而不是void loop()中,否则它将永远循环。

void loop ()
{
unsigned long currentTime=0;
while (millis() - currentTime > 20)
{
tab[i] = analogRead(Sensor);
i++;
sum += tab[i];
float average = sum/20;
Serial.println(average);
}
currentTime = millis();
i = 0;
}

这里有一些问题。每次void loop()结束并再次执行currentTime时,它将被删除并再次声明为值0。这使得while循环执行无限长的时间,导致itab的长度上递增,从而导致内存错误。

analogRead()也不返回浮点数(返回0到1023之间的整数)。

这就是我对第一个代码的发现,但关于第二个代码,我不明白是什么问题。是编译错误吗?您在串行监视器中没有得到预期的输出?如果是最后一个,输出是什么?

相关内容

  • 没有找到相关文章

最新更新