首先我要为我的英语说得不好而道歉。
我的问题如下:我有一个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循环执行无限长的时间,导致i
在tab
的长度上递增,从而导致内存错误。
analogRead()
也不返回浮点数(返回0到1023之间的整数)。
这就是我对第一个代码的发现,但关于第二个代码,我不明白是什么问题。是编译错误吗?您在串行监视器中没有得到预期的输出?如果是最后一个,输出是什么?