Сглаживание Arduino не работает должным образом

Я использую стандартный пример сглаживания:

/*
Сглаживание

Многократно считывает с аналогового входа, вычисляя скользящее среднее значение и
распечатать на комп. Хранит десять показаний в массиве и постоянно
усредняет их.

Схема:
- аналоговый датчик (подойдет потенциометр), подключенный к аналоговому входу 0

создано 22 апреля 2007 г.
Дэвид А. Меллис <[email protected]>
изменено 9 апреля 2012 г.
Том Айгоу

Этот пример кода находится в общественном достоянии.

http://www.arduino.cc/en/Tutorial/Сглаживание
*/

// Определяем количество отсчетов для отслеживания. Чем выше число, тем
// чем больше будут сглаживаться показания, но тем медленнее будет реагировать вывод на
// ввод. Использование константы вместо обычной переменной позволяет нам использовать это
// значение для определения размера массива показаний.
const int numReadings = 10;

int readings[numReadings];      // показания с аналогового входа
int readIndex = 0;              // индекс текущего показания
int total = 0;                  // промежуточный итог
int average = 0;                // среднее

int inputPin = A0;

void setup() {
  // инициализируем последовательную связь с компьютером:
  Serial.begin(9600);
  // инициализируем все показания равными 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }
}

void loop() {
  // вычесть последнее чтение:
  total = total - readings[readIndex];
  // чтение с датчика:
  readings[readIndex] = analogRead(inputPin);
  // добавляем показания к сумме:
  total = total + readings[readIndex];
  // переход на следующую позицию в массиве:
  readIndex = readIndex + 1;

  // если мы в конце массива...
  if (readIndex >= numReadings) {
    // ...переход в начало:
    readIndex = 0;
  }

  // вычисляем среднее:
  average = total / numReadings;
  // отправляем его на компьютер в виде цифр ASCII
  Serial.println(average);
  delay(1);        // задержка между чтениями для стабильности
}

для расчета энергопотребления нагрузки, которая часто меняет свое значение (иногда останавливается и потребление снижается до пары ватт).

Моя единственная модификация приведенного выше кода заключается в передаче ему расчетного значения мощности (V*I) вместо аналогаRead(inputPin);. Входное значение для расчета мощности работает нормально, потому что без этого кода я получаю точные правильные значения мощности. Я также увеличил числовые показания с 10 до > 100, и, вероятно, их нужно будет увеличить намного больше, так как мне нужно среднее значение за 1 минуту.

С этим кодом связаны две основные проблемы:

1. Когда подключена постоянная нагрузка, которая, скажем, потребляет 500 Вт, значение, сгенерированное кодом, колеблется в пределах 312 Вт и никогда не достигает 500.

2, когда нагрузка отключена и текущая потребляемая мощность составляет 1-2 Вт в режиме ожидания, этот код переходит на -312 Вт. Я мог бы сначала привести его к целому числу без знака, но это не очень хорошее решение.

Кто-нибудь знает, как это исправить?

Спасибо

, 👍0

Обсуждение

Учитывайте размер вашего массива, размер оперативной памяти Arduino и количество элементов, которые вам понадобятся в массиве, если вы хотите использовать это для получения среднего значения за минуту или более. Все подойдет?, @JRE

Ваши показания мощности точные или плавающие?, @JRE

Десять значений analogRead, суммированные вместе, могут легко переполнить int total., @AnT

@AnT, как вы поняли, что сумма десяти AnalogReads может переполнить целое число? Даже если бы они были максимальными (1023), они наверняка легко вписались бы в целое число, даже если бы это было 16-битное целое число. Я немного озадачен вашим комментарием.., @GMc

@GMc: Честно говоря, я понятия не имею, почему я это сказал. Сумма десяти должна вписываться в 16-битное целое число., @AnT

нет проблем, по крайней мере, теперь это прояснилось :), @GMc


1 ответ


1

Да, измените тип переменной на такой, который может содержать большие числа, потому что теперь добавление 100 измерений приведет к переполнению вашей переменной.

,