Как получить среднее значение 16-битного АЦП?
У меня есть аналогово-цифровой преобразователь Adafruit ADS1115, настроенный в одностороннем режиме. Я хочу усреднить показания трех датчиков, чтобы повысить стабильность показаний.
//инициализируем переменные
int16_t rawData, ambient;
int i=0;
// запускаем цикл
while(i<3) {
rawData = ads.readADC_SingleEnded(0); //читаем из АЦП
// делим показания датчика на три
// (это после суммирования приведет к переполнению)
rawData=rawData/3;
Serial.println(rawData); // распечатываем данные в последовательный порт для отладки (ОК)
ambient+=rawData;
i+=1;
delay(100);
Serial.println("I LIVVVVEEE"); // распечатываем текст в последовательный порт для отладки (ОК)
}
// Сигнал печати (НЕ ОК)
Serial.print("Ambient is ");
Serial.println(ambient);
Необработанные данные правильно печатаются на последовательном мониторе. Однако значение «окружающего воздуха» может быть сумасшедшим: результирующий результат более чем на порядок выше. Почему-то кажется, что суммирование выполняется неправильно.
@plasma, 👍1
Обсуждение2 ответа
Если вы пытаетесь сначала усреднить показания АЦП трех датчиков, вам нужно сохранить и сложить их все, а затем разделить на 3.
int16_t rawData =0;
int32_t avg=0,ambient=0;
int i=0;
while(i<3) {
rawData = ads.readADC_SingleEnded(0); //читаем из АЦП
// делим показания датчика на три
// (это после суммирования приведет к переполнению)
Serial.println(rawData); // распечатываем данные в последовательный порт для отладки (ОК)
avg += rawData;
i++;
delay(100);
Serial.println("I LIVVVVEEE"); // распечатываем текст в последовательный порт для отладки (ОК)
}
abmient = avg /3;
avg = 0;
// Сигнал печати (НЕ ОК)
Serial.print("Ambient is ");
Serial.println(ambient);
Этот подход отлично подходит для небольших чисел. Однако АЦП 16-битный. Добавление трех 16-битных значений может (может) привести к переполнению буфера для «ambient»., @plasma
@plasma, сумма трех 16-битных чисел не исчерпывается 32-битными, @Juraj
@Юрай, ничего такого нет. Я только что внес изменения в его программу., @Vaibhav
оценил...., @Vaibhav
на самом деле вы получите более стабильные показания, если возьмете _медиану_ трех показаний вместо _среднего_. рассмотрите возможность чтения 12,13,5
, когда истинное показание равно 13. с avg вы получите 10
(ошибка = 3), но с медианой вы получите 12
(ошибка = 1). Я использовал этот метод для проекта цифрового мультиметра, и он имел ОГРОМНОЕ отличие по сравнению с моим наивным методом oversample+avg... Вы также можете настроить количество собираемых внутренних выборок AD1115 и за счет времени чтения получить более стабильный набор ценностей с самого начала., @dandavis
@dandavis Не обязательно, чтобы медиана всегда была правильным значением. Это может произойти в вашем случае, но я тестировал это на контроллере ST, где я беру среднее значение из 4 показаний и получаю ожидаемое значение, хотя я рассчитал напряжение с помощью АЦП, полученная ошибка составляет около -0,01 В от фактического напряжения., @Vaibhav
Расчет среднего значения так, как это делает ОП, абсолютно верен. Не имеет значения, делится ли сумма или слагаемые на количество значений. Ваш код может решить проблему, но это потому, что вы явно инициализируете переменные., @Sim Son
Вы забыли инициализировать ambient
равным нулю, поэтому он получил все, что находилось в том месте памяти, когда он был создан. Какие-то непредсказуемые, на первый взгляд случайные данные.
вы говорите, что int16_tambient; Serial.println(ambient, DEC);
может показать что-то кроме 0
?, @dandavis
@dandavis: Да, абсолютно. Значение слова «окружающий» здесь неопределенно. В некоторых случаях использование такого значения может даже привести к [неопределённому поведению](https://stackoverflow.com/questions/11962457/why-is-using-an-uninitialized-variable-undefined-behavior)., @Edgar Bonet
- Отправка и получение различных типов данных через I2C в Arduino
- Как работают функции вне цикла void?
- Как отображать переменные на 0,96-дюймовом OLED-дисплее с библиотекой u8glib?
- Разные и самые быстрые способы вычисления синусов и косинусов в Arduino
- OVF в последовательном мониторе вместо данных
- ЖК-дисплей I2C отображает странные символы
- Соединение I2C зависает Ведущий если ведомый отключается
- Экран LCD 16*02 I2C показывает только первый напечатанный символ
это не в среднем 3 чтения. это сумма 1/3 показаний, @Juraj