使用阵列获取传感器平均值
Getting Sensor Average using Arrays?
首先,让我明确一点:我是一个彻头彻尾的傻瓜,我几乎没有编程经验,我知道我不在我的行列中,但我想学习和理解。问题来了。以下代码用于使用4个继电器控制加热垫,这些继电器根据4个lm35温度传感器检测到的温度而关闭/打开。因为这些传感器有时会跳动,我想从50个读数中获得平均温度,并让代码检查数据,而不是原始温度读数。我有arduino的代码(我写了一些代码,其他论坛上的人把它修改了,使它更短(这有点让我迷失了方向,但代码有效)然后我搜索了平滑数据,得到了一段代码,它完全符合我的要求:制作一个数组,计算平均温度,并不断删除和添加新数据。
我试着把这两个代码连接在一起,结果出现了各种各样的错误,哈哈我来了。
没有平均数据的代码是这样的:
const byte tempPin[] = {A1, A2, A3, A4};
const byte relayPin[] = {6, 7, 8, 9};
// hysteresis = upperLimit - lowerLimit
const byte lowerLimit = 24;
const byte upperLimit = 31;
float tempC[4];
word reading[4];
word printInterval = 1000; // 1 second
unsigned long printCheck = 0, lastPrintTime = 0;
void setup()
{
analogReference(INTERNAL);
Serial.begin(115200);
for (int i = 0; i < 4; i++) {
pinMode(relayPin[i], INPUT_PULLUP);
pinMode(relayPin[i], OUTPUT); // defaults HIGH, relay OFF
}
}
void loop()
{
// readings and control
for (int i = 0; i < 4; i++) {
reading[i] = analogRead(tempPin[i]);
tempC[i] = reading[i] / 9.31;
if (tempC[i] < lowerLimit) {
digitalWrite(relayPin[i], LOW); //relay OFF
}
else if (tempC[i] > upperLimit) {
digitalWrite(relayPin[i], HIGH); // relay ON
}
}
printCheck = millis() - lastPrintTime;
if (printCheck >= printInterval) {
for (int i = 0; i < 4; i++) {
Serial.print("tempC");
Serial.print(i + 1);
Serial.print(" ");
Serial.println(tempC[i]);
}
Serial.println();
lastPrintTime = millis(); // reset print timer
}
}
我从Arduino学习中心得到的平均代码是这样的:
/*
Smoothing
Reads repeatedly from an analog input, calculating a running average
and printing it to the computer. Keeps ten readings in an array and
continually averages them.
The circuit:
* Analog sensor (potentiometer will do) attached to analog input 0
Created 22 April 2007
By David A. Mellis <dam@mellis.org>
modified 9 Apr 2012
by Tom Igoe
http://www.arduino.cc/en/Tutorial/Smoothing
This example code is in the public domain.
*/
// Define the number of samples to keep track of. The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input. Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
const int numReadings = 10;
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int inputPin = A0;
void setup() {
// initialize serial communication with computer:
Serial.begin(9600);
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
}
void loop() {
// subtract the last reading:
total = total - readings[readIndex];
// read from the sensor:
readings[readIndex] = analogRead(inputPin);
// add the reading to the total:
total = total + readings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;
// if we're at the end of the array...
if (readIndex >= numReadings) {
// ...wrap around to the beginning:
readIndex = 0;
}
// calculate the average:
average = total / numReadings;
// send it to the computer as ASCII digits
Serial.println(average);
delay(1); // delay in between reads for stability
}
我创建的加入两个代码的怪物是这样的:
const byte tempPin[] = {A1, A2, A3, A4};
const byte relayPin[] = {6, 7, 8, 9};
// hysteresis = upperLimit - lowerLimit
const byte lowerLimit = 24;
const byte upperLimit = 31;
float tempC[4];
word reading[4];
const int numReadings = 50;
int readings[numReadings];
int readIndex = 0;
int total = 0;
float average[4];
word printInterval = 1000; // 1 second
unsigned long printCheck = 0, lastPrintTime = 0;
void setup()
{
analogReference(INTERNAL);
Serial.begin(115200);
for (int i = 0; i < 4; i++) {
pinMode(relayPin[i], INPUT_PULLUP);
pinMode(relayPin[i], OUTPUT); // defaults HIGH, relay OFF
}
for (int thisReading = 0; thisReading < numReadings; thisReading++){
readings[thisReading] = 0;
}
}
void loop()
{
// readings and control
for (int i = 0; i < 4; i++) {
reading[i] = analogRead(tempPin[i]);
tempC[i] = reading[i] / 9.31;
total[i] = total[i] - readings[readIndex];
readings[readIndex] = tempC[i]
total[i] = total[i] + readings[readIndex]
readIndex[i] = readIndex[i] + 1 ;
if (readIntex[i] >= numReadings) {
readIndex = 0;
}
average[i] = total[i] / numReadings;
if (average[i] < lowerLimit) {
digitalWrite(relayPin[i], LOW); //relay OFF
}
else if (average[i] > upperLimit) {
digitalWrite(relayPin[i], HIGH); // relay ON
}
}
printCheck = millis() - lastPrintTime;
if (printCheck >= printInterval) {
for (int i = 0; i < 4; i++) {
Serial.print("tempC");
Serial.print(i + 1);
Serial.print(" ");
Serial.println(tempC[i]);
}
Serial.println();
lastPrintTime = millis(); // reset print timer
}
}
这些是我得到的错误:
Arduino: 1.6.8 (Windows 7), Board: "Arduino/Genuino Uno"
temprelayfinal2.ino: In function 'void loop()':
temprelayfinal2:40: error: invalid types 'int[int]' for array subscript
total[i] = total[i] - readings[readIndex];
^
temprelayfinal2:40: error: invalid types 'int[int]' for array subscript
total[i] = total[i] - readings[readIndex];
^
temprelayfinal2:42: error: expected ';' before 'total'
total[i] = total[i] + readings[readIndex]
^
temprelayfinal2:44: error: 'readIntex' was not declared in this scope
if (readIntex[i] >= numReadings) {
^
temprelayfinal2:47: error: invalid types 'int[int]' for array subscript
average[i] = total[i] / numReadings;
^
exit status 1
invalid types 'int[int]' for array subscript
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
注释:其他人已经在问题的注释中指出了您的代码没有编译的原因。
更详细地说,您声明无论是total还是readIndex都不是数组,在44行有一个打字错误(readIntex而不是readIndex)和两个missing半列。
但是,在仔细阅读您的代码后,我认为即使应用这些语法修复,您也无法获得一段符合您要求的代码。
因此,我将在这里根据您的问题和尝试的描述,提供我对所需源代码的解释。
我可以验证它是否编译,但是-因为我缺少硬件-我无法测试它。
(免责声明:我对Arduino的风格指南很反感所以我提前为采用个人代码样式道歉。)
#include<Arduino.h>
#define NUM_SENSORS 4
#define NUM_READINGS 5
#define LOWER_LIMIT 24
#define UPPER_LIMIT 31
#define PRINT_PERIOD 1000
#define TEMPERATURE_FACTOR 9.31
/* global variables */
const byte tempPin[] = {A1, A2, A3, A4};
const byte relayPin[] = {6, 7, 8, 9};
word readings[NUM_SENSORS][NUM_READINGS] = {};
word totals[NUM_SENSORS] = {};
float averages[NUM_SENSORS] = {};
unsigned long time_elapsed = 0;
word num_readings = 0;
word j = 0;
/* setup */
void setup()
{
analogReference(INTERNAL);
Serial.begin(115200);
for (int i = 0; i < 4; i++)
{
pinMode(relayPin[i], INPUT_PULLUP);
pinMode(relayPin[i], OUTPUT); // defaults HIGH, relay OFF
}
}
/* main loop */
void loop()
{
// keep track of actual readings:
// (prevents under-estimation of initial values
// due to a too large smoothing window)
if (num_readings < NUM_READINGS)
{
num_readings++;
}
for (int i = 0; i < NUM_SENSORS; i++)
{
// subtract the last reading:
totals[i] = totals[i] - readings[i][j];
// read from the sensor:
readings[i][j] = analogRead(tempPin[i]);
// add the reading to the total:
totals[i] = totals[i] + readings[i][j];
// update average
averages[i] = ((float) totals[i] / TEMPERATURE_FACTOR) / (float) num_readings;
// uncomment to optionally delay action on relays
// up until when the smooth window has been filled up
// if (num_readings == NUM_READINGS) {
if (averages[i] < LOWER_LIMIT)
{
digitalWrite(relayPin[i], LOW); // relay OFF
} else if (averages[i] > UPPER_LIMIT) {
digitalWrite(relayPin[i], HIGH); // relay ON
}
// }
}
// advance the reading index:
j = (j + 1) % NUM_READINGS;
unsigned long curr_time = millis();
static unsigned long start_time = curr_time; // initialized only once
if ((curr_time - start_time) >= PRINT_PERIOD)
{
for (int i = 0; i < 4; i++)
{
Serial.print("tempC");
Serial.print(i + 1);
Serial.print(" ");
Serial.println(averages[i]);
}
Serial.println();
start_time = curr_time; // not really best solution, but
// i don't want to bloat the code
}
delay(1); // waste some time
}
注意:我保留了单词类型的总计和读数,以避免浮点操作的典型障碍。
附加说明:
有一个50读数的平滑窗口对我来说听起来非常可疑,根据我的经验,最后3-5个读数应该足够了,也许其间有更大的延迟。
既然你还在学习,我建议你在上分享你的工作(小)项目https://codereview.stackexchange.com/以便获得一些非常好的反馈。(:
- 计算数组c++的平均值
- Android NDK传感器向事件队列报告奇怪的间隔
- 扩展光电二极管探测器以支持多个传感器
- 传感器值的阈值
- 计算平均值,不包括上次得分
- 无法获取webot::PositionSensor对象中位置传感器的值
- 彩色图像的卤化物处理平均值
- 如何创建一个函数来计算并返回平均值、最大值和最小值
- 按平均值替换数组中的元素
- 如何返回多个矢量对象的平均值?C++
- 将随机生成的数字添加到数组 + 对这些数组求平均值
- 查找数组中第一个最小值和最后一个最大值元素之间的算术平均值
- 制作具有平均值的随机数生成器
- C++ 函数,用于查找传入的 N 个数字的平均值、总和、最小值和最大值
- 如何使用对象制作分数列表并获得平均值
- 浮点格式数组的平均值
- 在二叉搜索树C++中计算平均值
- 同步两个具有不同帧速率的传感器
- 使用阵列获取传感器平均值
- Arduino HC-SR04 传感器,平均值数据