Странное поведение, когда компилятор преобразует из float в double

У меня есть массив:

float foo[3];

В ino файле я должен отправить один из них в PID в качестве входного.

double output;
PID myPID(&input, &output, &target, 1, 0.0, 1.1, DIRECT);
...
void loop(){
  input =foo[2];   
  myPID.Compute();
  Serial.print(output); //output: "nan"
...
}

ПИД-код выглядит следующим образом:

PID::PID(double* Input, double* Output, double* Setpoint,
        double Kp, double Ki, double Kd, int ControllerDirection)

Он компилируется, но вывод выходного значения PID - nan.

Однако, если я устанавливаю ввод в -1.2, тогда он работает.

void loop(){
      input =foo[2];  
      input = -1.2;
      myPID.Compute();
      Serial.print(output); //output: "1200"
    ...
    }

Как я могу это исправить? Компилятор должен автоматически преобразовать double float. Как в Mega 2560. Я также пробовал: input =double(foo[2]); без каких-либо успехов.


EDIT:

  Serial.print(foo[2]);  //Prints -9.2
  foo[2] = -9.2;         // I manually set foo[2] to -9.2  
  xAngle = foo[2];
  xPID.Compute();        //Computes perfectly.

Мне нужно добавить, что foo находится в пользовательской библиотеке. Это так странно. Кто-нибудь понял это?

Ответ 1

  • Прежде всего, все дубликаты AVR - это float как описанные здесь или здесь. Это делает удвоения такими же, как float на Arduino Mega 2560. Вы можете проверить это, сравнив sizeof(double); и sizeof(float);, оба возвратятся 4.
  • Во-вторых, если вы хотите использовать один тип для другого, синтаксис (targetType)sourceType, поэтому, если вы делаете что-то подобное, ваше назначение должно выглядеть так:

    input =(double)foo[2];
    

или

    input =(double)(foo[2]);

Однако в этом случае это не имеет значения, так как двойники и поплавки идентичны.

Я думаю, что, скорее всего, проблема связана с тем, что ваш ПИД-регулятор не любит любое значение, которое у вас есть в foo[2] с учетом установленных вами параметров. Вы пробовали foo[2]=-1.2 перед назначением input = foo[2];?