Я согласен с ошибкой peek()
-> count()
, указанной vhallac.Но я также укажу, что вам следует рассмотреть усреднение по степеням 2, если нет веских оснований для иного решения.
Причина в том, что на микроконтроллерах деление происходит медленно.Усредняя по степени 2 (2,4,8,16 и т. Д.), Вы можете просто вычислить сумму, а затем сдвинуть ее в битах.
Для вычисления среднего значения 2: (v1 + v2) >> 1
Чтобы вычислить среднее значение 4: (v1 + v2 + v3 + v4) >> 2
Чтобы вычислить среднее значение n значений (где n - степень 2), просто сдвиньте бит вправо вправо на [log2 (n)].
Пока тип данных для вашей переменной sum достаточно велик и не переполняется, это намного проще и намного быстрее.
Примечание : это не будет работать дляплавает в общем.На самом деле, микроконтроллеры не оптимизированы для поплавков.Вам следует подумать о преобразовании из int (что, как я полагаю, вы читаете АЦП) в значение с плавающей точкой в конце после усреднения , а не до этого.
Путем преобразования из int в число с плавающей точкой изатем при усреднении чисел с плавающей точкой вы теряете больше точности, чем при усреднении целых чисел, чем при преобразовании целого числа в число с плавающей точкой.
Other:
Вы используете оператор +=
без инициализациипеременные (qu1
, qu2
и т. д.) - рекомендуется инициализировать их, если вы собираетесь использовать +=
, но похоже, что =
будет работать нормально.
Для чисел с плавающей запятой я написал бы функцию average
как:
float average(QueueList<float> & q, int n)
{
float sum = 0;
for(int i=0; i<n; i++)
{
sum += q.pop();
}
return (sum / (float) n);
}
И назвал бы ее: average(queuea, 5);
Вы можете использовать это, чтобы усреднить любое число показаний датчика и позжеиспользуйте тот же код для последующего усреднения чисел в совершенно другом QueueList.Передача количества показаний для усреднения в качестве параметра действительно пригодится в случае, если вам нужно настроить его.
TL; DR:
Вот как я бы это сделал:
#include <QueueList.h>
const int ANALOG_SHARP=0; // set pin data from sharp
const int AvgPower = 2; // 1 for 2 readings, 2 for 4 readings, 3 for 8, etc.
const int AvgCount = pow(2,AvgPow);
QueueList <int> SensorReadings;
void setup(){
Serial.begin(9600);
}
void loop()
{
int reading = analogRead(ANALOG_SHARP);
SensorReadings.push(reading);
if(SensorReadings.count() > AvgCount)
{
int avg = average2(SensorReadings, AvgPower);
Serial.println(gpd12_to_cm(avg));
}
}
float gp2d12_to_cm(int reading)
{
if(reading <= 3){ return -1; }
return((6787.0 /((float)reading - 3.0)) - 4.0);
}
int average2(QueueList<int> & q, int AvgPower)
{
int AvgCount = pow(2, AvgPower);
long sum = 0;
for(int i=0; i<AvgCount; i++)
{
sum += q.pop();
}
return (sum >> AvgPower);
}