В среднем 10 показаний, неверно
Я читаю из ячейки загрузки и вычисляю среднее значение последних 10 показаний. Но когда тензодатчик считывает что-то большее, чем 3800 г, среднее значение становится отрицательным, как? Масса, которую я читаю, не является отрицательными числами. Я пытался найти свою ошибку, но не смог. Какая-нибудь помощь?
#include "HX711.h"
const int numReadings = 10;
const int LOADCELL_DOUT_PIN = 8;
const int LOADCELL_SCK_PIN = 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 mass =0;
long reading = 0;
HX711 scale;
float a = 0.0088;
float b = 2009.7;
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;
}
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
}
void loop() {
if (scale.is_ready()) {
// read from the sensor:
reading = scale.read();
// convert to mass
mass = int((a*reading)-b);
// subtract the last reading:
total = total - readings[readIndex];
Serial.print(int((a*reading)-b));
readings[readIndex] = mass;
// 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.print(" ");
Serial.print(average);
Serial.println("");
delay(1000); // delay in between reads for stability
}
else{
Serial.print("loadcell not found!");
}
}
@animos_be, 👍3
Обсуждение2 ответа
Как уже прокомментировал Майенко, проблема в целочисленном охвате. Одним из решений было бы избавиться от этой общей
переменной и вычислять каждое новое среднее значение на основе предыдущего среднего и массы, которую вы заменяете в массиве, используя эту формулу:
new_average = old_average + (mass - readings[readIndex]) / numReadings
Таким образом, ваш код будет выглядеть следующим образом:
if (scale.is_ready()) {
// считывание с датчика:
reading = scale.read();
// преобразовать в массу
mass = int((a*reading)-b);
// вычислите новое среднее значение:
new_average = average + (mass - readings[readIndex]) / numReadings;
Serial.print(int((a*reading)-b));
readings[readIndex] = mass;
// переход на следующую позицию в массиве:
readIndex = readIndex + 1;
// если мы находимся в конце массива...
if (readIndex >= numReadings) {
// ...оборачиваемся к началу:
readIndex = 0;
}
// установите среднее значение:
average = new_average;
// отправьте его на компьютер в виде цифр ASCII
Serial.print(" ");
Serial.print(average);
Serial.println("");
delay(1000); // задержка между считываниями для обеспечения стабильности
}
Просто не забудьте добавить объявление для new_average
в начало вашего кода.
Другим вариантом было бы использовать "длинный" в качестве типа переменной для total. В зависимости от вашего приложения вы также можете изучить экспоненциально взвешенную скользящую среднюю (EWMA); она может уменьшить акцент на более старых точках данных, если это проблема.
- Какова работа pulseIn?
- Сколько датчиков может поддерживать один модуль Arduino?
- Получение BPM из данного кода
- DS18B20 дает высокие показания. Как заставить его вернуть правильную температуру?
- Какой тип разъема использует система GROVE?
- Улавливают ли ультразвуковые датчики прозрачные материалы?
- Как подключить более 10 датчиков к Arduino uno r3
- В чем разница между акселерометром, гироскопом и датчиком магнитометра?
Это называется "целочисленная оболочка" - " int " может содержать только от -32768 до +32767 на 8-разрядном Arduino., @Majenko
Боже, большое вам спасибо за помощь. Я боролся с этим, @animos_be
совет, если вы знаете, что он должен содержать только положительные числа, объявите его целым числом без знака., @Swedgin