arduino - 即使引脚接地,analogRead() 输出也会振荡
问题描述
我正在使用 Arduino Micro 从 5 个柔性传感器中读取数据并将相应的角度显示到串行监视器。我目前对从analogRead() 获得的振荡值有相当多的问题。引脚是否连接到柔性传感器或仅接地似乎无关紧要 - 输出振荡很多。
最初一切都被很好地读取和输出,但我希望有一个精确的 100Hz 采样频率,并尝试使用 Timer Interrupts 播放一下。这就是这种振荡行为开始的时候。我反转了我的原始代码,它只使用了一些延迟(),并简化为仅从两个引脚读取,但似乎无法摆脱振荡。
我想我在尝试实现中断时可能搞砸了 ADC,但我不知道如何检查或修复它。请帮我弄清楚如何解决这个问题!
这是analogRead 的原始输出。当我弯曲弯曲传感器时会发生值下降
这是我的代码最小工作示例:
int fin;
const int input[5] = {A0,A1,A2,A3,A4}; // the analog pins
int flex[5]; // analog signal read
float flexV;
float flexR[5]; // resistance on the 47k resistor
int angle[5]; // joint angles
const float VCC = 4.98; // Measured voltage of Arduino 5V line
// Measured resistance of the 47k resistors R1-R5
const float R[5] = {45900.0,45900.0,45900.0,45900.0,45900.0};
// Calibration values of resistance measured during straight phase and 90 deg bend phase
const float R_STRAIGHT[5] = {37651.0,37651.0,37651.0,37651.0,37651.0};
const float R_BEND[5] = {71783.0,71783.0,71783.0,71783.0,71783.0};
void setup() {
}
void loop() {
for(fin = 0; fin <= 4; fin++) {
flex[fin] = analogRead(input[fin]);
flexV = flex[fin]*VCC/1023.0;
flexR[fin] = R[fin] * (VCC/flexV - 1.0);
angle[fin] = map(flexR[fin],R_STRAIGHT[fin],R_BEND[fin],0,90.0);
delay(1);
}
Serial.print(angle[0]);
Serial.print(" ");
Serial.print(angle[1]);
Serial.print(" ");
Serial.print(angle[2]);
Serial.print(" ");
Serial.print(angle[3]);
Serial.print(" ");
Serial.print(angle[4]);
Serial.print(" ");
Serial.println(millis());
delay(6);
}
解决方案
好的,analogReads 通常确实有一点振荡,这是正常的!它们正在测量电压值,并且根据您使用的传感器,它们会振荡,与使用万用表测量电压的想法相同。如果你想了解更多关于这方面的知识,ADC 的转换器是一个很好的开始。
为了防止这些振荡,您需要做的是开发一个过滤器。这可以在硬件或软件上完成。显然,该软件是最简单的方法。
我给你的建议是平均过滤器!这是一个简单的概念,您将同时获得该传感器的 X 个读数(值会随着变化而上升和下降),并且您会从中获得平均值。
这是一个使用您的代码的简单示例:
int fin;
const int input[5] = {A0,A1,A2,A3,A4}; // the analog pins
int flex[5]; // analog signal read
float flexV;
float flexR[5]; // resistance on the 47k resistor
float average; //Variable to store the sum of measurements
int nSamples = 4; //Number of reading you are going to use
int angle[5]; // joint angles
const float VCC = 4.98; // Measured voltage of Arduino 5V line
// Measured resistance of the 47k resistors R1-R5
const float R[5] = {45900.0,45900.0,45900.0,45900.0,45900.0};
// Calibration values of resistance measured during straight phase and 90 deg bend phase
const float R_STRAIGHT[5] = {37651.0,37651.0,37651.0,37651.0,37651.0};
const float R_BEND[5] = {71783.0,71783.0,71783.0,71783.0,71783.0};
void setup() {
}
void loop() {
for(fin = 0; fin <= 4; fin++) {
/* A new for here to make readings and store them on the average variable */
for(int x = 0; x <= nSamples; x++){
flex[fin] = analogRead(input[fin]);
average = average + flex[fin];
}
/*Do de avarage and clear the value on this variable*/
flex[fin] = average/nSamples;
avarage = 0;
flexV = flex[fin]*VCC/1023.0;
flexR[fin] = R[fin] * (VCC/flexV - 1.0);
angle[fin] = map(flexR[fin],R_STRAIGHT[fin],R_BEND[fin],0,90.0);
delay(1);
}
Serial.print(angle[0]);
Serial.print(" ");
Serial.print(angle[1]);
Serial.print(" ");
Serial.print(angle[2]);
Serial.print(" ");
Serial.print(angle[3]);
Serial.print(" ");
Serial.print(angle[4]);
Serial.print(" ");
Serial.println(millis());
delay(6);
}
这里的想法很简单,通过进行平均来平滑值,从而产生更一致的值。显然,更多的样本会改善结果。
这是简单的数学运算,如果您得到 4 个值,例如:45、50、55、50,您的平均值将为 50 (45+50+55+50 = 200/nSamples = 50)
推荐阅读
- android - API 26 (Oreo) 中的 Wifi Direct 对等点发现
- tensorflow - 在 gpu 上运行更快的 rcnn - 内存不足
- http - 我应该使用 http 还是 https 来跟踪链接?
- java - Servlet 在 session.getAttribute 的转换上抛出异常
- html - 为什么 CSS/HTML 中的颜色以 # 开头
- html - 第一个 div 坐在我的导航栏中?
- android - Android Studio 无法解决:com.android.support:support-core-ui:27.1.1
- python - Python中带或不带括号的函数?
- python - 使用 Seaborn 创建 for 循环以绘制 DataFrame 的各个列的直方图
- java - 无法访问请求映射spring boot