Решение уравнения

pupesk
Offline
Зарегистрирован: 28.06.2014

Подскажите  пожалуйста как мне в ардуине решить уравнение: 

37-(37-A)/(0,68-0,0014*B+0,5681)-0,29*A*(1-BR/100)
при A=28.10, B=45,50

Разложил по порядку. В комментариях после строки решение для точности в // 4 цифры | 2 цифры
    

        temp1 = 37 - A; // 8,9 | 8,9
        temp2 = 0,0014 * B; // 0,0637 | 0
        temp3 = 0,68 - temp2; // 0,6163 | 0,68
        temp4 = temp3 + 0,5681; // 1,1844 | 1,24
        temp5 = B / 100; // 0,455 | 0,45
        temp6 = 1 - temp5; // 0,545 | 0,55
        temp7 = temp1 / temp4;// 7,5143 | 7,17
        temp8 = 0,29 * A; // 8,149 | 8,14
        temp9 = temp8 * temp6; // 4,4412 | 4,48
        temp10 = 37 - temp7; // 29,4857 | 29.83
        temp11 = temp10 - temp9; // 25,0445 | 25,35

На выходе у меня всегда ошибки inf. Ардуино выдает в temp7, temp10 и temp11 результат inf. Что я делаю не так?

 

vvadim
Offline
Зарегистрирован: 23.05.2012

весь код покажите

kalapanga
Offline
Зарегистрирован: 23.10.2016

pupesk пишет:

Подскажите  пожалуйста как мне в ардуине решить уравнение: 

37-(37-A)/(0,68-0,0014*B+0,5681)-0,29*A*(1-BR/100)
при A=28.10, B=45,50

Здесь нет уравнения.

pupesk пишет:

На выходе у меня всегда ошибки inf. Ардуино выдает в temp7, temp10 и temp11 результат inf.

Что такое "inf"? И что с ним за ошибки?

А по сути, выведите результаты всех этих Ваших "разложений", возможно всё станет понятнее.

 

pupesk
Offline
Зарегистрирован: 28.06.2014

это и есть весь код, только сверху ещё double tempX = 0;

В общем-то пока просматривал код, решил поменять , на . и все заработало.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

pupesk пишет:

поменять , на . и все заработало.

Феерично!

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Да "классика", чего уж там. Оператор запятая мать его .. :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

kalapanga пишет:

Что такое "inf"? И что с ним за ошибки?

Бесконечное значение. Обычно - результат деления на 0 или подобной ошибки.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

kalapanga пишет:

Что такое "inf"?

Одно из конечного множества значений, которое может принимать переменная с плавающей точкой.

kalapanga
Offline
Зарегистрирован: 23.10.2016

За "inf" спасибо, буду знать. 

pupesk
Offline
Зарегистрирован: 28.06.2014
// Без ветра: 37 - (37 - T) / (0,68 - 0,0014 R + 1 / (1,76)) - 0,29 T (1 – R / 100)

#include "DHT.h"
#define DHTPIN 7
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

int RED = 6;
int GREEN = 10;
int BLUE = 9;
int i = 0;
float eeti = 0;
double temp1 = 0;
double temp2 = 0;
double temp3 = 0;
double temp4 = 0;
double temp5 = 0;
double temp6 = 0;
double temp7 = 0;
double temp8 = 0;
double temp9 = 0;
double temp10 = 0;

void sel_col_eet()
{
  if (eeti >= 30.1) 
    {analogWrite(RED, 0);
    analogWrite(GREEN, 255);
    analogWrite(BLUE, 255);
                Serial.println("> 30 ]");}
  
  else if (eeti >= 24.1 && eeti <= 30.0)
    {analogWrite(RED, 0);
    analogWrite(GREEN, 127);
    analogWrite(BLUE, 255);
                Serial.println("24.1 30 ]");}
  
  else if (eeti >= 18.1 && eeti <= 24.0)
    {analogWrite(RED, 127);
    analogWrite(GREEN, 0);
    analogWrite(BLUE, 0);
                Serial.println("18.1 24 ]");}
  
  else if (eeti >= 12.1 && eeti <= 18.0)
    {analogWrite(RED, 255);
    analogWrite(GREEN, 0);
    analogWrite(BLUE, 200);
                Serial.println("12.1 18 ]");}
  
  else if (eeti >= 6.1 && eeti <= 12.0)
    {analogWrite(RED, 255);
    analogWrite(GREEN, 0);
    analogWrite(BLUE, 255);
                Serial.println("6.1 12 ]");}
  
  else if (eeti >= 0.1 && eeti <= 6.0)
    {analogWrite(RED, 255);
    analogWrite(GREEN, 0);
    analogWrite(BLUE, 127);
                Serial.println("0.1 6 ]");}
    
  else if (eeti >= -6.0 && eeti <= 0.0)
    {analogWrite(RED, 127);
    analogWrite(GREEN, 127);
    analogWrite(BLUE, 0);
                Serial.println("-6 0 ]");}

  else if (eeti <= -6.1 && eeti >= -12.0)
    {analogWrite(RED, 255);
    analogWrite(GREEN, 127);
    analogWrite(BLUE, 0);
                Serial.println("-6.1 -12 ]");}

  else if (eeti <= -12.1 && eeti >= -18.0)
    {analogWrite(RED, 255);
    analogWrite(GREEN, 200);
    analogWrite(BLUE, 0);
                Serial.println("-12.1 -18 ]");}

  else if (eeti <= -18.1 && eeti >= -24.0)
    {analogWrite(RED, 255);
    analogWrite(GREEN, 255);
    analogWrite(BLUE, 0);
                Serial.println("-18.1 -24 ]");}

  else if (eeti < -24.1)
    {analogWrite(RED, 255);
    analogWrite(GREEN, 255);
    analogWrite(BLUE, 0);
                Serial.println("< 24.1 ]");}

  else {init_rgb();};
}

void init_rgb()
{
  Serial.println("RED");
    analogWrite(RED, 0);
    analogWrite(GREEN, 255);
    analogWrite(BLUE, 255);
delay(1500);
  Serial.println("GREEN");
    analogWrite(RED, 255);
    analogWrite(GREEN, 0);
    analogWrite(BLUE, 255);
delay(1500);
  Serial.println("BLUE");
    analogWrite(RED, 255);
    analogWrite(GREEN, 255);
    analogWrite(BLUE, 0);
delay(1500);
}

void eet() 
{
  int R = dht.readHumidity();
  int T = dht.readTemperature();
  //eeti=37-(37-T)/(0,68-0,0014*R+0,5681)-0,29*T*(1-R/100);
        temp1 = 37 - T; //1 skobka 9 
        Serial.print("temp1=");
        Serial.print(temp1);
        Serial.print(" | ");
        temp2 = 0.0014 * R; //2 skobka 0,0644
        Serial.print("temp2=");
        Serial.print(temp2);
        Serial.print(" | ");
        temp3 = 0.68 - temp2; //2 skobka
        Serial.print("temp3=");
        Serial.print(temp3);
        Serial.print(" | ");
        temp4 = temp3 + 0.5681; //2 skobka
        Serial.print("temp4=");
        Serial.print(temp4);
        Serial.print(" | ");
        temp5 = R / 100; //3 skobka
        Serial.print("temp5=");
        Serial.print(temp5);
        Serial.print(" | ");
        temp6 = 1 - temp5; //3 skobka
        Serial.print("temp6=");
        Serial.print(temp6);
        Serial.print(" | ");
        temp7 = temp1 / temp4;
        Serial.print("temp7=");
        Serial.print(temp7);
        Serial.print(" | ");
        temp8 = 0.29 * T;
        Serial.print("temp8=");
        Serial.print(temp8);
        Serial.print(" | ");
        temp9 = temp8 * temp6;
        Serial.print("temp9=");
        Serial.print(temp9);
        Serial.print(" | ");
        temp10 = 37 - temp7;
        Serial.print("temp10=");
        Serial.println(temp10);
        eeti = temp10 - temp9;

  //eeti=37-(37-T)/(0,68-0,0014*R+0,5681)-0,29*T*(1-R/100);
        Serial.print("[ Temp: ");
        Serial.print(T);
        Serial.print(" ][ Humidity: ");
        Serial.print(R);
        Serial.println(" ]");
        Serial.print("[ eeti=");
        Serial.print(eeti);
        Serial.print(" ] [ ");
}

void setup()
{
  Serial.begin(115200);
  init_rgb();
  dht.begin();
}

void loop()
{
  eet();
  sel_col_eet();
  delay(5000);
  Serial.println("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
}

Погорячился. Оно конечно считает, но совсем не то, что ожидается. Табличку ожиданий могу приложить завтра, делал в экселе по этой же форуле. Т.е. при T=30 H=99 должен получить уже 28.8 а ардуина пишет только 23. Никак не пойму.

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

накапливаются ошибки округления.  например, при R/100 не всегда получается то, что ты ажыдал.  Правильнее писать R/100.0

pupesk
Offline
Зарегистрирован: 28.06.2014

Везде где были целые числа, дописал ".00", стало лучше но не совсем:

Temp: 23.40 \ Humidity: 39.00 : eeti=21.47 | Должно быть: ~18
Temp: 25.10 \ Humidity: 57.60 : eeti=23.72 | Должно быть: ~21
Temp: 25.30 \ Humidity: 50.00 : eeti=23.40 | Должно быть: ~20
Temp: 25.70 \ Humidity: 96.80 : eeti=26.60 | Должно быть: ~24
Temp: 28.90 \ Humidity: 99.90 : eeti=29.68 | Должно быть: ~28
Temp: 30.30 \ Humidity: 99.90 : eeti=30.95 | Должно быть: ~29

Т.е. местами врет значительно, с учетом необходимых пределов.

Вот тут excel-файлик с этой же формулой - ориентируюсь на него округляя до ближайшего значения. Может как-то можно повысить правильность? Вообще не понимаю в каком месте ардуина ошибается :(

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

pupesk пишет:

Вообще не понимаю в каком месте ардуина ошибается :(

Плак.... Ошибается автор кода, а не ардуина =) это вам по секрету

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

pupesk пишет:
при T=30 H=99 должен получить уже 28.8 а ардуина пишет только 23. Никак не пойму.

Вы в показаниях путаетсь. Сначала у Вас будо A и B, в скетче T и R, а здесь уже T и H.

Давайте Вы напишете точно формулу, которую считаете и скажете, что и при каких параметрах у Вас получается.

И приведите текущий код, а то Бог его знает, что Вы там куда дописали.

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

116, 117 почему int а не float? 

pupesk
Offline
Зарегистрирован: 28.06.2014

nik182

Сменил int на float, результат изменился практически незаметно.

ЕвгенийП

Здесь последний код. abtrth облегчал жизнь себе, в итоге всё и вся запутал.

ToRcH2565

Не отрицаю, с 6 класса с математикой не дружу, но проще все свалить на ардуину :)

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

pupesk. вам всего-то одну формулу надо подсчитать? Что мешает написать ее как есть. в одну строку?

eeti=37-(37-T)/(0,68-0,0014*R+0,5681)-0,29*T*(1-R/100);

Нафига вам эта фигова куча промежуточных переменных?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

pupesk пишет:

Здесь последний код. abtrth облегчал жизнь себе, в итоге всё и вся запутал.

Если это последний код, то смотрим на строку №135. Где обещанная Вами замена всех целых на "с .0 на конце".

Эта строка гадит Вам конкртено. Результат деления двух целых - всегда целое с отбрасыванием остатка, каким бы он ни был. Например 2000 / 1999 - результат - ровно 1

Проверяйте также всё остальное. Целочисленного деления (когда оба операнда - целые) быть не должно.

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

ЕвгенийП пишет:

Например 2000 / 1999 - результат - ровно 1

Самый неудачный пример из возможных =) потому что погрешность всего то 0.0005 =) ибо 2000.00 / 1999.00 = 1.0005...

2000 / 1001 = 1 при том что 2000.00 / 1001.00 = 1.998....

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Таки да. Чёт переклинило. Собирался на самом деле оба привести, чтобы разница видна была :)))

pupesk
Offline
Зарегистрирован: 28.06.2014

А как-то можно вместо двух цифр после точки, сделать 4? Что double, что float - всегда 2

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

pupesk пишет:

А как-то можно вместо двух цифр после точки, сделать 4? Что double, что float - всегда 2

Их там не 2, просто Вы печатаете 2. Печатайте больше, сколько Вам нужно. Только, больше 6 знаков после запятой особого смысла не имеет - это приблизительно предел точности этого типа.