计算传感器数据的平均值(电容式传感器)
Calculating the average of Sensor Data (Capacitive Sensor)
所以我开始摆弄电容式传感器,这一切都是因为它是一些非常酷的东西。
我在网上学习了一些关于如何设置和使用 Arduino 的 CapSense 库的教程,我只是对我在此处编写的这段代码提出了一个快速问题,以获取该数据的平均值。
void loop() {
long AvrNum;
int counter = 0;
AvrNum += cs_4_2.capacitiveSensor(30);
counter++;
if (counter = 10) {
long AvrCap = AvrNum/10;
Serial.println(AvrCap);
counter = 0;
}
}
这是我的循环语句,在 Serial 中它似乎有效,但数字对我来说看起来低得可疑。我正在使用一个 10M 的电阻器(棕色、黑色、黑色、绿色、棕色)并触摸发送和接收引脚都连接到的箔片(电工胶带)并且得到大约 650 的数字,给予或接受30.
基本上我是在问这段代码是否正确以及这些数字是否有意义...?
您的行 if (counter = 10)
无效。应该是if (counter == 10)
第一个将计数器设置为 10,并且(当然)将计算为真。
第二次测试计数器是否等于 10,并且在计数器确实等于 10 之前不会评估为真。
另外,kaylum提到了另一个问题,没有初始化AvrNum
Arduino 环境中使用的语言实际上只是 C++ 的一个非强制子集,main()
函数隐藏在 IDE 提供的框架代码中。您的代码是一个将被编译并链接到框架的模块。当框架启动 运行 时,它首先初始化自身,然后通过调用函数 setup()
初始化您的模块。初始化后,框架进入无限循环,在每次迭代时调用模块函数 loop()
。
您的代码在 loop()
中使用了局部变量,并期望它们在每次调用中保持它们的值。虽然这在实践中可能会发生(并且很可能会发生,因为框架的 main()
的那部分可能只是 while(1) loop();
),但这是在调用未定义行为的恶魔。 C++ 不对未初始化变量的值做出任何承诺,即使读取它也可能导致任何事情发生。甚至显然在工作。
要解决此问题,累加器 AvrNum
和 counter
必须存储在 loop()
堆栈以外的其他位置。它们可以被声明为 static
,或者被移动到模块之外。外面更好恕我直言,尤其是在受限的 Arduino 环境中。
您还需要在完成平均后清空累加器。这是平均滤波器的最简单形式,您可以在其中对 N 个样本的固定长度块求和,然后对每个第 N 个样本使用该平均值。
我相信这个片段(未经测试)对你有用:
long AvrNum;
int counter;
void setup() {
AvrNum = 0;
counter = 0;
}
void loop() {
AvrNum += cs_4_2.capacitiveSensor(30);
counter++;
if (counter == 10) {
long AvrCap = AvrNum/10;
Serial.println(AvrCap);
counter = 0;
AvrNum = 0;
}
}
我提供了一个setup()
,尽管它与C++语言保证全局变量开始生命初始化为0是多余的。
这就是我花了更多时间后得出的结论。经过一些手动计算后,它获得了所有数据。
long AvrArray [9];
for(int x = 0; x <= 10; x++){
if(x == 10){
long AvrMes = (AvrArray[0] + AvrArray[1] + AvrArray[2] + AvrArray[3] + AvrArray[4] + AvrArray[5] + AvrArray[6] + AvrArray[7] + AvrArray[8] + AvrArray[9]);
long AvrCap = AvrMes/x;
Serial.print("\t");
Serial.println(AvrCap);
x = 0;
}
AvrArray[x] = cs_4_2.capacitiveSensor(30);
Serial.println(AvrArray[x]);
delay(500);
所以我开始摆弄电容式传感器,这一切都是因为它是一些非常酷的东西。
我在网上学习了一些关于如何设置和使用 Arduino 的 CapSense 库的教程,我只是对我在此处编写的这段代码提出了一个快速问题,以获取该数据的平均值。
void loop() {
long AvrNum;
int counter = 0;
AvrNum += cs_4_2.capacitiveSensor(30);
counter++;
if (counter = 10) {
long AvrCap = AvrNum/10;
Serial.println(AvrCap);
counter = 0;
}
}
这是我的循环语句,在 Serial 中它似乎有效,但数字对我来说看起来低得可疑。我正在使用一个 10M 的电阻器(棕色、黑色、黑色、绿色、棕色)并触摸发送和接收引脚都连接到的箔片(电工胶带)并且得到大约 650 的数字,给予或接受30.
基本上我是在问这段代码是否正确以及这些数字是否有意义...?
您的行 if (counter = 10)
无效。应该是if (counter == 10)
第一个将计数器设置为 10,并且(当然)将计算为真。
第二次测试计数器是否等于 10,并且在计数器确实等于 10 之前不会评估为真。
另外,kaylum提到了另一个问题,没有初始化AvrNum
Arduino 环境中使用的语言实际上只是 C++ 的一个非强制子集,main()
函数隐藏在 IDE 提供的框架代码中。您的代码是一个将被编译并链接到框架的模块。当框架启动 运行 时,它首先初始化自身,然后通过调用函数 setup()
初始化您的模块。初始化后,框架进入无限循环,在每次迭代时调用模块函数 loop()
。
您的代码在 loop()
中使用了局部变量,并期望它们在每次调用中保持它们的值。虽然这在实践中可能会发生(并且很可能会发生,因为框架的 main()
的那部分可能只是 while(1) loop();
),但这是在调用未定义行为的恶魔。 C++ 不对未初始化变量的值做出任何承诺,即使读取它也可能导致任何事情发生。甚至显然在工作。
要解决此问题,累加器 AvrNum
和 counter
必须存储在 loop()
堆栈以外的其他位置。它们可以被声明为 static
,或者被移动到模块之外。外面更好恕我直言,尤其是在受限的 Arduino 环境中。
您还需要在完成平均后清空累加器。这是平均滤波器的最简单形式,您可以在其中对 N 个样本的固定长度块求和,然后对每个第 N 个样本使用该平均值。
我相信这个片段(未经测试)对你有用:
long AvrNum;
int counter;
void setup() {
AvrNum = 0;
counter = 0;
}
void loop() {
AvrNum += cs_4_2.capacitiveSensor(30);
counter++;
if (counter == 10) {
long AvrCap = AvrNum/10;
Serial.println(AvrCap);
counter = 0;
AvrNum = 0;
}
}
我提供了一个setup()
,尽管它与C++语言保证全局变量开始生命初始化为0是多余的。
这就是我花了更多时间后得出的结论。经过一些手动计算后,它获得了所有数据。
long AvrArray [9];
for(int x = 0; x <= 10; x++){
if(x == 10){
long AvrMes = (AvrArray[0] + AvrArray[1] + AvrArray[2] + AvrArray[3] + AvrArray[4] + AvrArray[5] + AvrArray[6] + AvrArray[7] + AvrArray[8] + AvrArray[9]);
long AvrCap = AvrMes/x;
Serial.print("\t");
Serial.println(AvrCap);
x = 0;
}
AvrArray[x] = cs_4_2.capacitiveSensor(30);
Serial.println(AvrArray[x]);
delay(500);