0

I have a function that takes as parameter some doubles and does a subtraction operation on it. However I'm getting a result of 0 when one of the parameter is 0 for some reason.

int calcPID(double current, double desired, double k){
  double diff;
  diff = desired - current;
  Serial.print("desired = ");
  Serial.print(desired);
  Serial.print(", current = ");
  Serial.print(current);
  Serial.print(", diff = ");
  Serial.println(diff);
  int r = (int)diff;
  return r;
}

Output

desired = 250.00, current = 1.69, diff = 248.31
desired = 250.00, current = 0.00, diff = 0.00

When the current is 0.00 the result (diff) is also 0.00, when it should be 250. Can someone tell me what's going on?

1

I can't reproduce that.

int calcPID(double current, double desired, double k) {
  double diff;
  diff = desired - current;
  Serial.print("desired = ");
  Serial.print(desired);
  Serial.print(", current = ");
  Serial.print(current);
  Serial.print(", diff = ");
  Serial.println(diff);
  int r = (int)diff;
  return r;
}

void setup ()
{
  Serial.begin (115200);
  Serial.println ();
  calcPID (1.69, 250, 42);
  calcPID (0, 250, 42);
}  // end of setup

void loop ()
{
}  // end of loop

That gives expected output of:

desired = 250.00, current = 1.69, diff = 248.31
desired = 250.00, current = 0.00, diff = 250.00

I strongly suspect you are passing NaN (not a number) or Inf (infinity) instead of zero. If you add another test line like this:

 calcPID (1.0 / 0, 250, 42);

Then you get the result:

desired = 250.00, current = inf, diff = inf

Now I know you reported getting zero, but earlier versions of the IDE printed 0 for NaN or Inf. I suggested a change to the way the libraries handle that which has been implemented in more recent versions.

Here, for example.


If this doesn't answer your question, please post a Minimal, Complete, and Verifiable example - like I did above.

  • I think NaN is probably it because when I compare current > 1 and current <= 1 both came out to false. – bakalolo Jan 28 '17 at 3:01
  • dang it i was such a poopoohead before now i get it thnx – bakalolo Mar 17 '17 at 1:48
1

You are not providing the input values in the correct type:

calcPID(0.00, 250, 0.0);

will return 0, while

calcPID(0.00, 250.0, 0.0);

will return 250

UPDATE

Here you can get a working test case: it's running on a different processor, so don't expect to behave exactly as the 8bit MCU at Arduino's core.

  • 1
    Is this based on a test, or a source-code reading, or what? What's the name of the library .cpp and .h files you looked at? How do you account for implicit type conversion not occurring? – James Waldby - jwpat7 Jan 26 '17 at 2:46
  • @jwpat7 I didn't look at any library, I just looked at the above code and the only viable option I was able to find is if the OP is expecting type conversion to occur in C as if it was Java. When I posted my answer there was only the calcPID function reported, but now, looking at the updated example I'm more convinced about my answer, so much I updated it with a test. – Roberto Lo Giacco Jan 26 '17 at 16:57
1

@Roberto Lo Giacco The difference is, that on Arduino (IDE) are headers for *.ino done before standard C++ compilation

#include <stdio.h> // on *.ino it is done in IDE hidden way
int calcPID(double current, double desired, double k) ; // forward definition, for *.ino it is done in Arduino IDE hidden way
int main()
{
    calcPID (1.69, 250, 42);
    calcPID (0, 250, 42);
    calcPID (0.0, 250.0, 42);
    return 0;
}

int calcPID(double current, double desired, double k) {
  double diff;
  diff = desired - current;
  printf("desired = %5.2f, current = %5.2f, diff = %5.2f, true = %i\n", desired, current, diff, diff > 0);
  int r = (int)diff;
  printf("desired = %5.2f, current = %5.2f, diff = %i, true = %i\n", desired, current, r, r > 0);
  return r;
}

This compiles and executes on your machine well a gives correct result same as @Nick Gammon have.

Without the definition int calcPID(double current, double desired, double k) ; standard C assumes definition with ints and makes different conversions, which leads to your "incorrect" result. So the result depends on forward definition, which Arduino does behind scene. But for *.cpp and *.h it may be different, so it would be interesting, how bakalolo organized his code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.