This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

when 0.000030517578125 multiplied with any number getting result as Zero

Hi

I am reading the sensor data (Irms and Vrms) via I2C protocol and multiplying the read data with 0.000030517578125 to get correct result but i am getting the result as zero

Vrms = ((m_sample[1] << 8) | m_sample[0]);
Irms = ((m_sample[3] << 8) | m_sample[2]);

float Vrms_acc = ((float)Vrms) * (0.000030517578125);
float Irms_acc = ((float)Irms) * (0.00006103515625);


NRF_LOG_INFO("-------------------\r\n");
NRF_LOG_INFO(" Recevied Data.\r\n");
NRF_LOG_INFO(" Vrms = " NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(Vrms_acc));
NRF_LOG_INFO(" Irms = " NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(Irms_acc));
NRF_LOG_INFO("-------------------\r\n");

---------------------------------------------------------------------------------------------------------------------------

OUTPUT

ENERGY_METER:INFO:-------------------
ENERGY_METER:INFO: Recevied Data.
ENERGY_METER:INFO: Vrms = 0.000000000000000
ENERGY_METER:INFO: Irms = 0.000000000000000
ENERGY_METER:INFO:-------------------

Thanks in advance 

  • Hi,

    If you open definition of macros NRF_LOG_FLOAT, then you see:  

    /**
     * @brief Macro to be used in a formatted string to a pass float number to the log.
     *
     * Use this macro in a formatted string instead of the %f specifier together with
     * @ref NRF_LOG_FLOAT macro.
     * Example: NRF_LOG_INFO("My float number" NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(f)))
     */
    #define NRF_LOG_FLOAT_MARKER "%s%d.%02d"
    
    /**
     * @brief Macro for dissecting a float number into two numbers (integer and residuum).
     */
    #define NRF_LOG_FLOAT(val) (uint32_t)(((val) < 0 && (val) > -1.0) ? "-" : ""),   \
                               (int32_t)(val),                                       \
                               (int32_t)((((val) > 0) ? (val) - (int32_t)(val)       \
                                                    : (int32_t)(val) - (val))*100)

    This means that any numbers will be displayed with an accuracy of two decimal places.
    Change these definitions, for example like this and you will see 6 decimal places:

    /**
     * @brief Macro to be used in a formatted string to a pass float number to the log.
     *
     * Use this macro in a formatted string instead of the %f specifier together with
     * @ref NRF_LOG_FLOAT macro.
     * Example: NRF_LOG_INFO("My float number" NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(f)))
     */
    #define NRF_LOG_FLOAT_MARKER "%s%d.%06d"
    
    /**
     * @brief Macro for dissecting a float number into two numbers (integer and residuum).
     */
    #define NRF_LOG_FLOAT(val) (uint32_t)(((val) < 0 && (val) > -1.0) ? "-" : ""),   \
                               (int32_t)(val),                                       \
                               (int32_t)((((val) > 0) ? (val) - (int32_t)(val)       \
                                                    : (int32_t)(val) - (val))*1000000)

  • NRF_LOG_FLOAT_XXX does not support small numbers, since there is no scientific (exponential) display modeand only a limited amount of digits.

    That means numers between 0 and 1e-3 (? Not sure where the limit is exactly) are rounded down to zero.

    You might want to print the (integer?) values for Vrms and Irms directly for debugging.

    Also note that ((float)Vrms) * (0.000030517578125) is a double multiplication (IMHO, the constant is a double number) which must be done in software instead of the Cortex-M4 FPU.

  • Thank you  now i am able to get the correct values.
    Thank you for the information

  • You're welcome.

    For segger, there is another solution that, in principle, works correctly.
    1. In the settings (project options -> code -> Printf/Scanf),  set the permission to output numbers with double precision through the printf function: 

    Printf Floating Point Supported = double

    Wide Characters Supported = Yes

    Note: be prepared for a slight increase in the consumption of flash and RAM memory.


    2. add header file: #include <debugio.h>

    3. use one of the following output:

    debug_printf("test: %.9f \n", 100.123456789);
    

  • Thank you 

    Another problem i am facing is when i multiply Vrms and Irms with overall full scale of voltage path (i.e 230v) And

    overall full scale of current path (i.e 90 A) respectively i am getting worng result.

    float Vrms_acc = ((float)Vrms) * ((0.00003051757) * 230);
    float Irms_acc = ((float)Irms) * ((0.00006103515) * 90);

    result:

    Vrms = 0.-02088566784
    Irms = 0.-00202559488

     i am not getting why that - sign is coming.

    Thanks in advance

Related