Усреднение значений с потенциометра

b707
Offline
Зарегистрирован: 26.05.2017

-NMi- пишет:

Дык давай сделаем, чо?  Алгоритм есть? Формулы?

Ну, скажем так - алгоритм там правильный и реализация без ошибок. Нужно только учитывать ограничения метода.

Этот код оценивает тренд упрощенным методом МНК для уравнения без второго члена:

y = a* x

Понятно, что одни наборы данных описываются этим уравнением хорошо, а другие хуже. Поэтому тренд, который найден по этой формуле - может сильно расходится с оценкой по классическому линейному уравнению:

y = a*x + b

зато метод очень быстрый, легко приводится к целочисленному виду и требует раза в 4 меньше вычислений, чем классический МНК

-NMi-
Offline
Зарегистрирован: 20.08.2018

А если взять массив "первый вошёл последний вылетел" , поделить его на пополам и брать среднее от двух половин - не проще ли так будет???

Degalo
Offline
Зарегистрирован: 26.01.2020
const byte averageFactor = 30;
byte Pressure_pin = 0

void loop(void) {

  int oldpressure_tonn = pressure_tonn;
  pressure_tonn = analogRead(Pressure_pin);
   if (averageFactor > 0)        // усреднение показаний для устранения "скачков"
  {     
    pressure_tonn = (long)((oldpressure_tonn * (averageFactor - 1) + pressure_tonn))/ averageFactor; 
    // <новое среднее> = (<старое среднее>*19 + <текущее значение>) / 20

Добрый день! Подскажите почему не работает усреднение? В чем ошибка?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Degalo пишет:

const byte averageFactor = 30;
byte Pressure_pin = 0

void loop(void) {

  int oldpressure_tonn = pressure_tonn;
  pressure_tonn = analogRead(Pressure_pin);
   if (averageFactor > 0)        // усреднение показаний для устранения "скачков"
  {     
    pressure_tonn = (long)((oldpressure_tonn * (averageFactor - 1) + pressure_tonn))/ averageFactor; 
    // <новое среднее> = (<старое среднее>*19 + <текущее значение>) / 20

Добрый день! Подскажите почему не работает усреднение? В чем ошибка?

не увидел объявление -

pressure_tonn

 

b707
Offline
Зарегистрирован: 26.05.2017

Degalo пишет:

Подскажите почему не работает усреднение? В чем ошибка?

потому что этот код -  не усреднение, а взвешенное среднее. В этой формуле averageFactor должен быть меньше единицы, например 0.1. Чем меньше averageFactor - тем плавнее будет менятся величина, но тем медленее она будет реагировать на изменение измеряемого сигнала

b707
Offline
Зарегистрирован: 26.05.2017

поправка - нет, все верно, в этом коде фактор больше единицы - не заметил деления, у меня на экране строчка 10 перенеслась на следующую

Код верный, только повторяю, что это не устреднение.

Если пишете "не работает" - напишите конкретнее, в чем это заключается. Добавьте в код вывод в сериал измеряемых и вычисляемых значений (строчки 7 и 10) и прогоните серию из 30-50 измерений

Degalo
Offline
Зарегистрирован: 26.01.2020

Благодарю всех за ответы! Нашел ошибку

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

Пример: 

Данные у чистом виде/Усредненные данные

238/238.00

235/238.00 и т.д. 

Заранее прошу извинения за тупые вопросы

b707
Offline
Зарегистрирован: 26.05.2017

вы так и не сказали, как описано

pressure_tonn

 

Degalo
Offline
Зарегистрирован: 26.01.2020
const byte averageFactor = 30;
byte Pressure_pin = 0

void loop(void) {

  int oldpressure_tonn = pressure_tonn;
  pressure_tonn = analogRead(Pressure_pin);
   if (averageFactor > 0)        // усреднение показаний для устранения "скачков"
  {     
    pressure_tonn = (long)((oldpressure_tonn * (averageFactor - 1) + pressure_tonn))/ averageFactor; 
    // <новое среднее> = (<старое среднее>*19 + <текущее значение>) / 20

pressure_tonn_f = (pressure_tonn)*22,5454/1000;//усредненные показания, перевод в тонны
Serial.println(pressure_tonn_f);// вывод показаний

Не смог отредактировать свое сообщение, высылаю код с добавлением вывода на монитор

 

b707
Offline
Зарегистрирован: 26.05.2017

Degalo - вы русский язык хорошо понимаете?

Вас спрашивали как описано pressure_tonn ? - вместо того чтоб описать переменную, вы добавили еще одну - pressure_tonn_f - опять без описания. Этот код не будет компилироваться

   

 

Degalo
Offline
Зарегистрирован: 26.01.2020
byte Pressure_pin = 0; 
float pressure_tonn = 0;

 

Degalo
Offline
Зарегистрирован: 26.01.2020

Я не понимаю вашего вопроса. Сформулируйте его иначе

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а нахрена ты читаешь целое в цикле и присваиваешь его float?  Усредняй тоже в целых, а потом присваивай

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017
int16_t result = 0;
for (uint8_t i=0; i<16; ++i) result+=analogRead(pin);
pressure = (result>>4);

 

Degalo
Offline
Зарегистрирован: 26.01.2020

Ребята, оказываете ли вы платные консультации? Я готов заплатить. А то вижу, что мои вопросы заставляют нервничать, возможно финансовая компенсация поможет сгладить ситуацию и перевести разговор в конструктивное  русло

b707
Offline
Зарегистрирован: 26.05.2017

Да ладно, вы просто делайте что говорят. А два нулика после запятой у вас появляются, потому переменная типа флоат. Поэтому от вас и добивались, как она описана. Среднее вы считаете не вполне верно, не надо смешивать целые и флоаты. Подробнее не буду, с телефона много набивать

nik182
Offline
Зарегистрирован: 04.05.2015

Degalo пишет:

const byte averageFactor = 30;
byte Pressure_pin = 0

void loop(void) {

  int oldpressure_tonn = pressure_tonn;
  pressure_tonn = analogRead(Pressure_pin);
   if (averageFactor > 0)        // усреднение показаний для устранения "скачков"
  {     
    pressure_tonn = (long)((oldpressure_tonn * (averageFactor - 1) + pressure_tonn))/ averageFactor; 
    // <новое среднее> = (<старое среднее>*19 + <текущее значение>) / 20

Добрый день! Подскажите почему не работает усреднение? В чем ошибка?


Данный вид усреднения работает только на действительных числах. Попытка применить его на целых не даст необходимого результата. Только приближение.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Degalo пишет:

Ребята, оказываете ли вы платные консультации? Я готов заплатить. А то вижу, что мои вопросы заставляют нервничать, возможно финансовая компенсация поможет сгладить ситуацию и перевести разговор в конструктивное  русло

ещё бы не оказывать...

rkit
Offline
Зарегистрирован: 23.11.2016

nik182 пишет:

Данный вид усреднения работает только на действительных числах.

Во как. Уже до действительных добрались, фантастика.

Degalo
Offline
Зарегистрирован: 26.01.2020

Мне нужно было убрать скачки, сейчас все работает, только приходится ждать время пока данные начнет показывать, есть эффект накопления, приходится выжидать время и потом все показывает нормально. 

Можно ли этот период накопления не выводить на дисплей? например сделать так чтобы сначала производились вычисления и только спустя определенное количество измерений результат начинал попадать на дисплей?

И еще один вопрос, как можно ограничить количество символов после запятой простым способом?

Нужно чтобы было 1 число после запятой, сейчас от 2 до 3 символов.

nik182
Offline
Зарегистрирован: 04.05.2015

rkit пишет:

nik182 пишет:

Данный вид усреднения работает только на действительных числах.

Во как. Уже до действительных добрались, фантастика.


Извини что потревожил твою психику использовав термин из области математики а не программирования. Предлагаю тебе читать вместо термина действительные числа термин тип float. Может быть тогда не будет фантастики?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Degalo пишет:

Мне нужно было убрать скачки, сейчас все работает, только приходится ждать время пока данные начнет показывать, есть эффект накопления, приходится выжидать время и потом все показывает нормально. 

Можно ли этот период накопления не выводить на дисплей? например сделать так чтобы сначала производились вычисления и только спустя определенное количество измерений результат начинал попадать на дисплей?

И еще один вопрос, как можно ограничить количество символов после запятой простым способом?

Нужно чтобы было 1 число после запятой, сейчас от 2 до 3 символов.

это уже платно...

Pyotr
Offline
Зарегистрирован: 12.03.2014

Вот пример скользящего среднего на целых числах. В своих проектах так делаю. 

word  prevMillis, intervalMs = 50;
int avgAdc, errorVal,  averageFactor = 8;
    
void setup() { 
  Serial.begin(115200);
  avgAdc = analogRead(A0);    
}
void loop() {  
  if((word)millis() - prevMillis >= intervalMs){
    prevMillis += intervalMs;      
    int valAdc = analogRead(A0); 
    int delta = valAdc - avgAdc;
    int sum = errorVal + delta;
    avgAdc += sum / averageFactor;
    errorVal = sum % averageFactor;//накапливаем погрешность
    Serial.print(valAdc); Serial.print('\t');
    Serial.print(errorVal); Serial.print('\t');
    Serial.println(avgAdc);  
  }    
}

 

Degalo
Offline
Зарегистрирован: 26.01.2020

Можете позвонить мне или написать 

b707
Offline
Зарегистрирован: 26.05.2017

Degalo пишет:

Можете позвонить мне или написать 

Куда? Нужно вычислить тебя по IP ? :)

Degalo
Offline
Зарегистрирован: 26.01.2020

ICQ 642168784

Degalo
Offline
Зарегистрирован: 26.01.2020

И что вы все пропали? Мне уже мошенники несколько раз позвонили, а вы ни разу.

b707
Offline
Зарегистрирован: 26.05.2017

Degalo пишет:

И что вы все пропали? Мне уже мошенники несколько раз позвонили, а вы ни разу.

Про других не скажу, а я не вполне понял, зачем вам звонить? - потому и не звоню

Если вы хотите заказать разработку - создайте тему в разделе "Ищу исполнителя"