Nan's on RPi3 with working C

Hello,

I’ve been consistently getting Nan’s on a straightforward approach to accessing floats stored a char array. I’m using the Raspberry Pi 3 device with apt-get update / upgrade performed recently, and also updated (or installed) the latest particle-agent with a recent update from this forum.

This is the sketch:

    #define N_FLOATS 10

    const int bufLen=40;
    char buf[40]; // floats are 4 bytes on Arduino
    float *myFloat;
    unsigned long cnt=0;

    void setup() {
        Serial.begin(250000);
        memset(buf,0,bufLen); // zero-out buf array
        myFloat = (float*) &buf[0]; // assign float pointer to beginning of char array
    }


    void loop() {
        cnt++;
        Serial.print("cnt=");
        Serial.print(cnt);
        Serial.print(", buf=[");
        for (int i=0; i<N_FLOATS; i++){
            myFloat[i] = (float) i + (float) cnt/10.0;
            Serial.print( myFloat[i] );
            Serial.print(", ");
        }
        Serial.println("]");
        delay(1000);
    }

This code works exactly as-is on the Arduino Uno R3. Copy-pasting directly from the Arduino IDE into particle web-IDE generates this output:

    cnt=1, buf=[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, ]
    cnt=2, buf=[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, ]
    cnt=3, buf=[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, ]
    cnt=4, buf=[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, ]
    .
    .
    .

The exact same sketch on Arduino generates the expected result:

    cnt=1, buf=[0.10, 1.10, 2.10, 3.10, 4.10, 5.10, 6.10, 7.10, 8.10, 9.10, ]
    cnt=2, buf=[0.20, 1.20, 2.20, 3.20, 4.20, 5.20, 6.20, 7.20, 8.20, 9.20, ]
    cnt=3, buf=[0.30, 1.30, 2.30, 3.30, 4.30, 5.30, 6.30, 7.30, 8.30, 9.30, ]
    cnt=4, buf=[0.40, 1.40, 2.40, 3.40, 4.40, 5.40, 6.40, 7.40, 8.40, 9.40, ]
    .
    .
    .

This looks like a bug somewhere in the raspberrry pi particle binary. Perhaps it’s a compiler option.

Not sure. But this is standard C and should work.

Why no workee???

Marc

You also need to consider the endianness of your respective platforms.
The daft thing is, that the endianness of floats on a platform does not have to align to the integer endianness of the system.

Although your 40byte buffer should be fine I’d still suggest to let the compiler decide on the buffer size.

const int bufLen = N_FLOATS * sizeof(float);
1 Like

This is a thoughtful reply and the code-clip is helpful.

Endianness is certainly important but accessing and retrieving within the same sketch means the code will always be compiled on the same machine. So, Endianness is likely not the culprit here.

Also, a mismatch in endianness doesn’t generate nan’s, but rather, weird numbers.

Nan’s are a strange result. Almost as if the address is attempting to access memory that is not available.

Running ‘particle-agent serial’ as root does not change the result.

top confirms firmware.bin is being executed as root.

it’s like a compile-time or linked library on the particle.io back-end is different from the runtime library on the pi

gcc --version
gcc (Raspbian 4.9.2-10) 4.9.2

ld --version
GNU ld (GNU Binutils for Raspbian) 2.25

ldconfig --version
ldconfig (Debian GLIBC 2.19-18+deb8u7) 2.19

True for the first part, I had written that before I read the full code, when I read the comment // floats are 4 bytes on Arduino I guessed you were transfering floats from an Arduino to RPi via a byte array :blush:
But I decided to leave it there for completeness.

But for the second part I wouldn’t agree, since not all byte combinations do render valid floats and hence there will be floats in one endianness that won’t give you valid floats in another one.

Hello,

I need floats and doubles and am getting unusual results. This code should generate very simple, predictable results:

void setup() {
    
    Serial.begin(9600);
    
    int myInt = 3;
    float myFloat = 10.1;

    Serial.print("myInt = ");
    Serial.println( myInt );
    
    Serial.print("myFloat = ");
    Serial.println( myFloat );

}

void loop() {
}

The correct result should provide:
myInt = 3 myFloat = 10.10

But ‘particle-agent serial’ is generating:
myInt = 3 myFloat = nan

Floats and doubles are broken.

I’ve installed particle.io on a Raspberry Pi 3 and really enjoy it so far. The installation went without a glitch and the device is showing up on the particle console nicely. I’ve run apt-get update and upgrade.

The webIDE works great and ‘particle-agent serial’ is very handy.

I suspect a runtime library mis-match.

gcc --version
gcc (Raspbian 4.9.2-10) 4.9.2

ld --version
GNU ld (GNU Binutils for Raspbian) 2.25

ldconfig --version
ldconfig (Debian GLIBC 2.19-18+deb8u7) 2.19

How do I correct this? I definitely need floats and doubles.

Marc

Hi @comperem

I moved your separate topic here since this was a double post.

I think you are running into issues on RPi due to the Arduino print code not understanding the float format on RPi.

Can you try a work-around like this:

void setup() {
    
    Serial.begin(9600);
    
    int myInt = 3;
    float myFloat = 10.1;

    Serial.print("myInt = ");
    Serial.println( myInt );
    
    Serial.print("myFloat = ");
    char str[64];
    snprintf(str,64,"%f",myFloat);
    Serial.println( str );

}

void loop() {
}
1 Like

Hello @bko,

Yes, indeed, this works. Thank you for the work-around. It’s an unusual result.

I tried adding the ‘DEC’ argument to Serial.print and it worked but generated waaay to many decimal placed on output.

Then I tried the order of the Serial.print commands and found that once the variable was formatted and snprint()'ed, the Serial.print() command seemed to work just fine, even with a different variable.

void setup() {
    
    Serial.begin(9600);
    
    int myInt = 3;
    float myFloat = 10.1;
    float myOtherFloat = 12.2;

    Serial.print("myInt = ");
    Serial.println( myInt );
    
    Serial.print("1: myFloat = ");
    Serial.println( myFloat );

    Serial.print("2: myFloat = ");
    char str[64];
    snprintf(str,64,"%f",myFloat);
    Serial.println( str );
    
    Serial.print("3: myFloat = ");
    Serial.println( myFloat );
    
    Serial.print("myOtherFloat = ");
    Serial.println( myOtherFloat );
}

void loop() {
}

Output from ‘particle-agent serial’:
myInt = 3 1: myFloat = nan 2: myFloat = 10.100000 3: myFloat = 10.10 myOtherFloat = 12.20

It’s a curious result. The 1st and 3rd instances of the myFloat are identical and yet produce dissimilar results. Something isn’t quite right but you’ve been very helpful for providing this work-around. I’ll use it and can keep cruising.

I’m receiving a number of doubles from a python script that reads serial on the Pi and sends to localhost. The particle.io process reads these udp packets and will post some data to the cloud.

It appears the floats and doubles were, indeed, working and it was the Serial.print() function that was behaving unusually.

Thanks again.