9 years, 1 month ago.

Converting float array to a single string line

Hey guys,

I am using NUCLEO ST F410RE MCU and I am trying to convert an array of float values which I read from ADC to a single line of string. I don't need whole float values just the first 8 or 6 digits. I written this code, it should work, but it doesn't fill the whole string up and I end up with the values I need and gibberish code inside the string, I tried increasing the size of the array to fill the string completely, but then the program stops, any suggestions on how to fix this?

Code here:

data.h

#include "mbed.h"
#include "Timer.h"
#include "dac.h" 
#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
              
 /*
  * initialize: a function to set up Op amp Gain status and the amount with which the input data will be raised by. 
  * Arguments: 
  * int MSG[12] - amount to raise the input data.
  * Returns: 
  * Nothing.
  */
  
void initialize(int MSG[12]){
    DAC(MSG);               // DAC sends a message to the OpAmp to set up the level of input
   
    G2.write(1);            // Setting Op amp Gain status with G2 G1 G0 pins
    G1.write(1);
    G0.write(1);
}

/*
 * get_channel_data - reads values from analog channels A and B.
 * Arguments:
 * CHA - single measurment from point A.
 * CHB - single measurment from point B.
 * Returns:
 * Both measurment points. 
 */
 
void get_channel_data(float & CHA, float & CHB){
    
    CHA = A.read();                 // Measuring value A
    CHB = B.read();                 // Measuring value B
}
 
/*
 * get_data - 
 * Arguments:
 * CHC - single measurment point.
 * t - time when the measurment was taken.
 * Returns:
 * A single measurment. 
 * Time when measurment was taken.
 */ 

void get_data(float (&CHC)[16], int (&t)[16]){
    float   CHA, CHB;                       // Input channels                             
      
    timer.start();
        for(int i = 0; i < 16; i++){
            get_channel_data(CHA,CHB);      // Read data from A and B channels.
            t[i] = timer.read_us();            // Measuring the time when A and B was taken
            CHC[i] = (CHA-CHB);                // Producing the real measurment
        }
    timer.stop();
}

/*
 * convert - converts float array into a string 
 * Arguments: 
 * float a[32] - float array of 32 values which will be conveted into a string
 * char text[256] - conversion result 
 * Returns:
 * Converted 
 */
 
void convert(float a[16], char (&text)[256]){
    int     i;                              // Loop index
    char    tmp[100];                       // Conversion buffer
    
    a[0] = 0;                               // getting rid of random symbols
    for (i = 0; i < 16; i++){ 
        snprintf(tmp, 8, "%f ", a[i]);    
        strcat(text, tmp);
    }
}

/*
 * pack - packs measurment data packet and time packet into strings
 * Arguments:
 * text_float[256] - measurment string
 * text_time[256] - time string
 * Returns:
 * Measurment string
 * Time string
 */
 
void pack(char (&text_float)[256], char (&text_time)[256]){
    float   data[16];                       // Measurment data packet
    float   time[16];                       // Time packet as floats
    int     time_int[16];                   // Time packet as interges                    
    int     i;                              // Loop index    
    
    get_data(data,time_int);
        
    for(i=0; i<16; i++)
        time[i] = float(time_int[i]);
    
    convert(data,text_float);
    convert(time,text_time);    
}

dac.h - includes initialization function. Ignore the initialization it has nothing to do with converting from float to string.

1 Answer

9 years, 1 month ago.

Are your text strings initialized anywhere in the code that's not shown? In the convert function strcat will look for the first null in the output text and add the data after that. If the text string is never initialized then it'll start at a random point in the string based on what happens to be at that memory location. Adding text[0]=0; at the start of that function should fix the problem.

Also you truncate the output string for each number to 8 characters no matter how long the number is, if a number is more than 7 digits long the space between values will get lost. If what you see is a long string of digits with no spaces then that's why.

Alternatively you could skip the whole strcat stage and speed things up by adding each value directly to the correct point in the output buffer:

int convert(float a[16], char (&text)[256]){
    int     i;                              // Loop index
    int     length = 0;             // output length
    
    a[0] = 0;    // throw away the first value but still print a 0? weird but OK.

    for (i = 0; i < 16; i++){ 
        length += snprintf(text+length , 256-length, "%7f ", a[i]);    // add current value to string, increase length counter.
    }
  return length;
}

Note this also returns the length of the final string, probably not needed but it's effectively free and could potentially save a strlen operation in the future.

Accepted Answer