Search code examples
c++cazurearduino-esp8266

c++ function in Arduino esp8266 modifies a float generated in a c file, gibberish seen in the c file after the c++ function exits


I am writing code for the Azure IoT Hub, which requires the use of c-functions in the Arduino loop(). The issue that I'm having is that if I pass a pointer to a float created in the c-file to a c++ file and modify the value, what is seen in the c-file after the c++ function returns is gibberish.

Here's a psuedocode example, and a working example is included below:

loop() in ino file:
runs runInLoop(), defined in the c-file RunTest.c

runInLoop() in RunTest.c:
create a float
pass the address to modifyFloat(float *address) defined in FloatTest.cpp
print the value of the float after modifyFloat() returns.

modifyFloat(float *address) in FloatTest.cpp:
assign a vale to *address
print the value
return

I've executed this pseudocode in the working example below and the result in the serial monitor is:

Value assigned in modifyFloat: 22.55
The value that was returned is: 1077316812

I'm using an Adafruit Huzzah Feather, configured exactly as they indicate in their documentation.

Here is a working example:

azure_troubleshoot.ino

#include "RunTest.h"

void setup()
{
    initSerial();
}

void loop()
{
    Serial.println("Starting main loop!\r\n");
    runInLoop();
}

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

RunTest.c

#include "FloatTest.h"

void runInLoop(void)
{
    while(1)
    {
        float testValue;
        modifyFloat(&testValue);
        (void)printf("The value that was returned is: %d\r\n", testValue);
        delay(1000);
    }

}

RunTest.h

#ifndef RUNTEST_H
#define RUNTEST_H

#ifdef __cplusplus
extern "C" {
#endif

void runInLoop(void);

#ifdef __cplusplus
}
#endif

#endif // RUNTEST_H

FloatTest.cpp

#include <Arduino.h>
#include "FloatTest.h"

void modifyFloat(float *address)
{
    *address = 22.55;
    Serial.print("Value assigned in modifyFloat: ");
    Serial.println(*address);
}

FloatTest.h

#ifndef FLOATTEST_H
#define FLOATTEST_H

#ifdef __cplusplus
extern "C" {
#endif

void modifyFloat(float* address);

#ifdef __cplusplus
}
#endif

#endif // FLOATTEST_H

Solution

  • The issue was the use of the %d in the printf string in RunTest.c. Updating the code to that shown below fixes the issue and makes the output:

    Value seen in modifyFloat: 22.55
    The value that was returned is: 22.55
    

    RunTest.c

    #include "FloatTest.h"
    
    void runInLoop(void)
    {
        while(1)
        {
            float testValue;
            modifyFloat(&testValue);
            char str_tmp[6];
            dtostrf(testValue, 4, 2, str_tmp);
            (void)printf("The value that was returned is: %s\r\n", str_tmp);
            delay(1000);
        }
    
    }