Simple assignment operator not working! [SOLVED]

I wonder if heading becomes NaN at some point?

Here is the narrowed down code of what exactly is the problem. I print the before and after, of simply adding two variables together, and its not working. I removed all other print() lines from the program

    Serial.print("angleinc1:");Serial.print(angleinc,8);Serial.println();
    Serial.print("Heading1 :");Serial.print(heading,8);Serial.println();
  heading = heading + angleinc;
    Serial.print("angleinc2:");Serial.print(angleinc,8);Serial.println();
    Serial.print("Heading2 :");Serial.print(heading,8);Serial.println();

And this is some sampling of the return prints.

angleinc1:0.03511390
Heading1 :0.00000000
angleinc2:0.03511390
Heading2 :0.00000000
angleinc1:0.01723574
Heading1 :0.00000000
angleinc2:0.01723574
Heading2 :0.00000000
angleinc1:0.03404021
Heading1 :0.00000000
angleinc2:0.03404021
Heading2 :0.00000000

I am completely baffled. I wrote a small program containing my problem code 'heading = heading + angleinc', and it worked there. I am currently slowly adding chucks at a time of my main program to narrow down the problem.

I was going to say post a whole sketch that shows the problem, with irrelevent code removed. But you've already said that doesn't show the problem. So it must be something other than these five lines of code causing it.

How are these variables declared?

I haven't an UNO at hand now, but...

float angleInc;
float heading = 0.0;

void setup() {
    Serial.begin(9600);
}

void loop() {
    // insert here a way to set angleinc
    // even a simple assignment will do...
    angleinc = ...

    Serial.print("angleinc=");
    Serial.println(angleinc, 8);

    Serial.print("Heading=");
    Serial.println(heading, 8);

    heading = heading + angleinc;

    Serial.print("heading + angleinc=");
    Serial.println(heading, 8);

    delay(1000);
}

HTH

This code:

float angleInc = 0.03511390;
float heading = 0.0;

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    Serial.print("angleInc=");
    Serial.println(angleInc, 8);

    Serial.print("heading=");
    Serial.println(heading, 8);

    heading = heading + angleInc;

    Serial.print("heading + angleInc=");
    Serial.println(heading, 8);

    delay(1000);
}

Produces this output:

angleInc=0.03511390
heading=0.00000000
heading + angleInc=0.03511390
angleInc=0.03511390
heading=0.03511390
heading + angleInc=0.07022780
angleInc=0.03511390
heading=0.07022780
heading + angleInc=0.10534170
angleInc=0.03511390
heading=0.10534170
heading + angleInc=0.14045560
angleInc=0.03511390
heading=0.14045560
heading + angleInc=0.17556951
angleInc=0.03511390
heading=0.17556951
heading + angleInc=0.21068339
...

Which is just as you'd expect, and just as Xenophage described.

I assume all the variables were declared as floats in the sketch showing the problem.

Perhaps when Xenophage has added back enough code to reproduce the problem we'll get another clue, but at the moment the only explanation I can guess at is that the runtime library is running out of memory during the floating point addition and coming up with a garbage answer. Which doesn't seem very likely, but is all I've got at the moment.

You know, I think Nick had a point there. :stuck_out_tongue:

This reproduces your problem:

void setup ()
{
  Serial.begin (115200);
  
  float a = sqrt (-1);
  float b = 0.03511390;
  
  Serial.print ("a1 = ");
  Serial.println (a, 8);
  Serial.print ("b = ");
  Serial.println (b, 8);

  a = a + b;
  
  Serial.print ("a2 = ");
  Serial.println (a, 8); 
}

void loop () {}

Output:

a1 = 0.00000000
b = 0.03511390
a2 = 0.00000000

Ohno! We added something to zero and got zero! But we didn't do that. We added to NaN (not a number). Arithmetic on NaN is not defined.

I spotted a whole lot of sqrt() calls in your code. I bet they are responsible.

Wouldn't it be nice if NaN printed as "NaN"?

It would be nice. And you could change it. In Print.cpp change:

size_t Print::printFloat(double number, uint8_t digits) 
{ 
  size_t n = 0;
  
  // Handle negative numbers
  if (number < 0.0)
  {
     n += print('-');
     number = -number;
  }

... by adding two lines to make it look like this:

size_t Print::printFloat(double number, uint8_t digits) 
{ 
  size_t n = 0;
  
  if (isnan (number))
    return print ("NaN");
    
  // Handle negative numbers
  if (number < 0.0)
  {
     n += print('-');
     number = -number;
  }

Nick++ :slight_smile:

Xenophage:
However something very strange happens when i take the //comment from the line '//heading = heading + temp4'. 'heading' seems to become a null variable or something, and the 'if' comparisons that check the heading against the RC angle stop working entirely.

Yeah, it's like it's Not A Number any more.

I can't believe it's Not A Number tm :stuck_out_tongue_closed_eyes:

Somebody's feeling his oats.

SOLVED!!! Step by step I backed through my math, setting variables as simple numbers, until I came across the TRUE trouble code. 'enctickL' becomes 0 when the robot isn't moving, and i was doing 1/0 which becomes NaN! I didn't think anything of it at first because it was reporting regular numbers. This was then filtering down through the math and eventually showing itself at 'heading = heading + angleinc'. I added two if statements to change them from 0 to 999999 to my main code and it worked! Thank you guys so much for the help! I'm feeling much better about bringing my robot in to class today!

enctickL = pulseIn(encpinL, HIGH, 40000);
enctickR = pulseIn(encpinR, HIGH, 40000);

temp1 = 1.0 / (float)enctickL;//temp1 = ticks per millisecond
temp2 = 1.0 / (float)enctickR;

If you feel the problem is solved, please consider adding [SOLVED] to the topic title. :slight_smile:

Now fixed in the next release:

http://code.google.com/p/arduino/issues/detail?id=946

No F?

  if (isnan (number))
    return print ( F( "nan" ) );

They may not want the overhead of the progmem library, if a sketch was not otherwise using it.

But you could always comment on the Google Code board.

What about this, a few lines down:

 // Print the decimal point, but only if there are digits beyond
  if (digits > 0) {
    n += print(".");

That could be:

 // Print the decimal point, but only if there are digits beyond
  if (digits > 0) {
    n += print(F("."));

Or perhaps better:

 // Print the decimal point, but only if there are digits beyond
  if (digits > 0) {
    n += print('.');

Naw. Seems like rather low hanging fruit (especially the print(".") in your post) and was curious.