使用数组获取传感器平均值?

时间:2016-06-08 17:35:13

标签: c++ arduino

首先,让我说清楚:我是一个完全的菜鸟,我的编程经验接近零,我知道我已经离开了我的联盟,但我想学习和理解。 这是问题所在。以下代码用于控制加热垫,使用4个继电器关闭/打开,具体取决于4 lm35温度传感器拾取的温度。因为这些传感器有时会跳动,我想从50个读数中得到平均温度,并使代码检查THAT数据而不是原始温度读数。 我有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.

1 个答案:

答案 0 :(得分:0)

备注:其他人已经指出了代码无法在您的问题的评论中编译的原因。

更详细的说明,声明 readIndex 数组,有一个错误 readIntex 而非 readIndex 44 行)和两个缺少的半列(行 41 42 )。

然而,在仔细阅读您的代码后,我认为即使应用这些语法修复程序,您也无法获得满足您需要的代码。

因此,我将根据您的问题描述和您的尝试,在此提供所需源代码的解释

我可以验证它是否已编译,但 - 因为我缺少硬件 - 我无法测试它。

  

免责声明:我非常生锈 Arduino &#39; 风格指南所以   我提前为采用个人代码样式而道歉。)

#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
}

注意:我保留 word 类型的总计读数,以避免<的典型障碍< em>浮点操作。

附加说明

  1. 有一个 50 读数的平滑窗口对我来说听起来很可疑,根据我的经验,最后3-5个读数应该足够了,可能有更大的延迟在两者之间。

  2. 因为您还在学习,我建议您不时在https://codereview.stackexchange.com/分享您的工作(小)项目,以便获得一些< em>非常好的反馈。 (: