Convert float to a Char value?[SOLVED]

I have a Digital level where the incoming data is a Char value in this format and I send this out using an NRF24L01, This is all working perfectly at sending and receiving the data.

Now what I would like to do is have 1 receiver and 2 transmitters(not both transmitters working at the same time). Rather than have 2 receiver’s I would just like the one, Now I know that the data format that is been sent out as to be the same setup on all modules.

Transmitter 1 will be the digital level.
Transmitter 2, Will a multimeter type thing.
This is the Data format that comes in from the digital level:
XXX.XX
examples:
-32.70
+4.32

This is the working code of the multi-meter code(minus the NRF24L01 code, As I need to convert the float to a char first):

#include <Wire.h>
#include <MCP342x.h>
#include <LiquidCrystal.h>// Highlight out when ready to use mian display
LiquidCrystal lcd(2, 4, 5, 3, 7, 8);
MCP342x adcCh1 = MCP342x(0x68);  // Ch1 MCP3424 I2C address

//###############################################################
//# Variables for the input voltage set up in differential mode #
//###############################################################
#define ECHO_TO_SERIAL 1 //change to zero = no serial output
float Volts_disp_Ch1 = 0;
float res1a = 100; // Resistor value of R1
float res2a = 1; // Resistor value of R2
float res3a = 100;// Resistor value of R3
float res4a = 1;// Resistor value of R4
float volts2a = 0 ; // volage 1 input =0 to give potsive reading
float stored1; // Holds the stored value of Resistor network
float stored2; // Holds value of voltage to be transmitted to rx unit
long Volts_fb_Ch1 = 0;
float res2 = 2700.00;
float Batt_R1;
float V_out;
float Volt_scale = 1.02263 ; //Change this if the incoming reading with nothing connected on the input terminals
float Volts_Cal = 9975.1;
const byte numChars = 9; //Number of bits to get
char receivedChars[numChars];//store the value of imcoming data
boolean newData = false;
unsigned long NO_Data_in = 0;
int Lost_data = 0;
typedef struct Data_struct {
  int PRO3600_Disconnected = 10;
  boolean No_data ;
  char receivedChars[numChars];   // an array to store the received data
} Data_struct;
Data_struct myData;
void printRecord(Print* pr, char sep = ',') {
  pr->print(myData.receivedChars[0]); // Print btye 0
  // pr->print(sep);
  pr->print(myData.receivedChars[1]); // Print btye 1
  //  pr->print(sep);
  pr->print(myData.receivedChars[2] ); // Print btye 2
  // pr->print(sep);
  pr->print(myData.receivedChars[3]); // Print btye 3
  //  pr->print(sep);
  pr->print(myData.receivedChars[4]); // Print btye 4
  //  pr->print(sep);
  pr->print(myData.receivedChars[5]); // Print btye 5
  // pr->print(sep);
  pr->print(myData.receivedChars[6] ); // Print btye 6
  // pr->print(sep);
  pr->print(myData.receivedChars[7]); // Print btye 7
  //  pr->print(sep);
  pr->print(myData.receivedChars[8]); // Print btye 7
  pr->print(sep);
  pr->print(myData.PRO3600_Disconnected); // Print btye 7
  pr->print(sep);
  pr->print(myData.No_data);
  pr->println();
}
void setup() {
  Serial.begin(9600);
  lcd.begin(8, 2);
  lcd.clear();
  Wire.begin();
  TWBR = 12;  // Set 142.8kHz I2C clock. Keypad doesn't work at anything faster (freq = clock / (16 + (2 * TWBR * prescaler))
  // ADC - external
  MCP342x::generalCallReset(); // Reset all ADC devices
  delay(1);                    // MC342x needs 300us to settle, wait 1ms
}
//####################################################
//#  Main Loop,runs Timed_actions                    #
//####################################################
void loop() {
  TimerService01();
  TimerService02();
  /*
  #if ECHO_TO_SERIAL
    printRecord(&Serial);
#endif //ECHO_TO_SERIAL
*/
}
//####################################################
//#   TimedAction - Timer Interrupt                  #
//####################################################
void TimerService01() {// Read the external ADC MCP3426
  MCP342x::Config status;
  adcCh1.convertAndRead(MCP342x::channel1, MCP342x::oneShot, MCP342x::resolution16, MCP342x::gain1, 1000000, Volts_fb_Ch1, status);  // Ch.1 (3) 16bit
  Volts_disp_Ch1 = Volts_fb_Ch1 * 2.048 / 32767; // convert to voltage reading// Adjust here for display
  V_out = Volt_scale - Volts_disp_Ch1; // 2.500V referance voltage - incoming voltage
  stored1 = (((1 + (res2a / res1a)) / (1 + (res3a / res4a))) * volts2a) - ((res2a / res3a) * V_out);
  stored2 = stored1 * Volts_Cal;
  // dtostrf(stored2, 9, 2, myData.receivedChars[numChars]); // WHEN I UNHIGHLIGHT THIS NOTHING GETS DIDPSALED ON LCD

}
// ********************** Timed Action 02 ***********************
void TimerService02() {// Displat the data
  /*
     // NOT USED YET NEED TO GET WORKING
    lcd.setCursor(0, 0);
    lcd.print(myData.receivedChars[0]);//show signle receivedChars
    lcd.print(myData.receivedChars[1]);//show signle receivedChars
    // display.setCursor(5, 20);
    lcd.print(myData.receivedChars[2]);//show signle receivedChars
    lcd.print(myData.receivedChars[3]);//show signle receivedChars
    lcd.print(myData.receivedChars[4]);//show signle receivedChars
    lcd.print(myData.receivedChars[5]);//show signle receivedChars
    lcd.print(myData.receivedChars[6]);//show signle receivedChars
    lcd.print(myData.receivedChars[7]);//show signle receivedChars
  */
  lcd.setCursor(0, 1);
  lcd.print(stored2, 2);
  lcd.print(" v ");
}

The meter code works and displays the values on an LCD, Now what I would like to do is is convert the final float volt value of Stored2 into a Char value/format as follows:
positive float value 12.36
negative float value -12.36
Data format out char value
-12.36
XXX.XX (Char value)

I’ve tried this

dtostrf(stored2, 9, 2, myData.receivedChars[numChars]); // WHEN I UNHIGHLIGHT THIS NOTHING GETS DIDPSALED ON LCD

But this stops everything working or the LCD remains blank, At the moment the serial data is not been sent out for debugging at the moment until I can convert the float to a char.

c-string methods like dtostrf() are very prone to crashing your sketch if you don’t get all the sizes correct.

A very safe way to do that is to use my SafeString library,

#include "SafeString.h" // from library manager

 lcd.setCursor(0, 1);
 cSF(sfVolts, 15);   // create a SafeString that can hold 15 chars (+'\0') no chance of buffer overflow if is stored2 is too large
 sfVolts.print(stored2,2); // just like Serial.print but result is in the char[] inside sfVolts
 lcd.print(sfVolts.c_str());  // access the underlying char[] to pass as char* to lcd.print
 lcd.print(" v ");
...

1 Like

Thanks drmpf,
This works and now displays the data on the LCD. Now the next thing is would it be possible to store this value in my struct so that I can send the same data format out to the RX unit ?

typedef struct Data_struct {
  int PRO3600_Disconnected = 10;
  boolean No_data ;
  char receivedChars[numChars];   // an array to store the received data
} Data_struct;
Data_struct myData;

I will go trough your examples and learn this new function.

Thanks
Steve

You could use dtostrf correctly.

Sure, there is an example in the tutorial, but you just ‘wrap’ your struct’s char in a SafeString

cSFA(sfVolts, myData.receivedChars); // wraps receivedChars and picks up its length automatically
sfVolts.print(stored2,2);
lcd.print(sfVolts.c_str());

Now receivedChars has the text version of stored2.
NOTE carefully if numChars is too small SafeString will not store any thing at all (just an empty null terminate string);

Add

SafeString::setOutput(Serial);

in the setup() to see the error messages, if any.

1 Like

SafeString is safer and has better error message. Well actually any error message would be better than what dtostrf gives when it not used ‘correctly’

1 Like

I don’t want error messages, I want working code

drmpf Thanks very much for all your help and useful comments/information, This will get me started and has pointed me in the right direction. nice to learn new functions.

You are fortunate, I find most of my code does not work first time so I really need the error messages.

1 Like

drmpf Which example will I need to look at so that I can get a better understanding how the functions works as there is loads and not quite sure which one to look at. Has I’m not quite getting it.
The first bit of code you posted works and displays the data on the LCD and changes .
I’ve tried to add the second part and nothing gets displayed on the LCD again.

#include <Wire.h>
#include <MCP342x.h>
#include <LiquidCrystal.h>// Highlight out when ready to use mian display
#include "SafeString.h" // from library manager
LiquidCrystal lcd(2, 4, 5, 3, 7, 8);
MCP342x adcCh1 = MCP342x(0x68);  // Ch1 MCP3424 I2C address

//###############################################################
//# Variables for the input voltage set up in differential mode #
//###############################################################
#define ECHO_TO_SERIAL 1 //change to zero = no serial output
float Volts_disp_Ch1 = 0;
float res1a = 100; // Resistor value of R1
float res2a = 1; // Resistor value of R2
float res3a = 100;// Resistor value of R3
float res4a = 1;// Resistor value of R4
float volts2a = 0 ; // volage 1 input =0 to give potsive reading
float stored1; // Holds the stored value of Resistor network
float stored2; // Holds value of voltage to be transmitted to rx unit
long Volts_fb_Ch1 = 0;
float res2 = 2700.00;
float Batt_R1;
float V_out;
float Volt_scale = 1.02263 ; //Change this if the incoming reading with nothing connected on the input terminals
float Volts_Cal = 9975.1;
const byte numChars = 9; //Number of bits to get
char receivedChars[numChars];//store the value of imcoming data
boolean newData = false;
unsigned long NO_Data_in = 0;
int Lost_data = 0;
typedef struct Data_struct {
  int PRO3600_Disconnected = 10;
  boolean No_data ;
  char receivedChars[numChars];   // an array to store the received data
} Data_struct;
Data_struct myData;
void printRecord(Print* pr, char sep = ',') {
  pr->print(myData.receivedChars[0]); // Print btye 0
  // pr->print(sep);
  pr->print(myData.receivedChars[1]); // Print btye 1
  //  pr->print(sep);
  pr->print(myData.receivedChars[2] ); // Print btye 2
  // pr->print(sep);
  pr->print(myData.receivedChars[3]); // Print btye 3
  //  pr->print(sep);
  pr->print(myData.receivedChars[4]); // Print btye 4
  //  pr->print(sep);
  pr->print(myData.receivedChars[5]); // Print btye 5
  // pr->print(sep);
  pr->print(myData.receivedChars[6] ); // Print btye 6
  // pr->print(sep);
  pr->print(myData.receivedChars[7]); // Print btye 7
  //  pr->print(sep);
  pr->print(myData.receivedChars[8]); // Print btye 7
  pr->print(sep);
  pr->print(myData.PRO3600_Disconnected); // Print btye 7
  pr->print(sep);
  pr->print(myData.No_data);
  pr->println();
}
void setup() {
  Serial.begin(9600);
  lcd.begin(8, 2);
  lcd.clear();
  Wire.begin();
  TWBR = 12;  // Set 142.8kHz I2C clock. Keypad doesn't work at anything faster (freq = clock / (16 + (2 * TWBR * prescaler))
  // ADC - external
  MCP342x::generalCallReset(); // Reset all ADC devices
  delay(1);                    // MC342x needs 300us to settle, wait 1ms
  SafeString::setOutput(Serial);
}
//####################################################
//#  Main Loop,runs Timed_actions                    #
//####################################################
void loop() {

  TimerService01();
  TimerService02();

  /*
      #if ECHO_TO_SERIAL
      printRecord(&Serial);
      #endif //ECHO_TO_SERIAL
  */
}
//####################################################
//#   TimedAction - Timer Interrupt                  #
//####################################################
void TimerService01() {// Read the external ADC MCP3426
  MCP342x::Config status;
  adcCh1.convertAndRead(MCP342x::channel1, MCP342x::oneShot, MCP342x::resolution16, MCP342x::gain1, 1000000, Volts_fb_Ch1, status);  // Ch.1 (3) 16bit
  Volts_disp_Ch1 = Volts_fb_Ch1 * 2.048 / 32767; // convert to voltage reading// Adjust here for display
  V_out = Volt_scale - Volts_disp_Ch1; // 2.500V referance voltage - incoming voltage
  stored1 = (((1 + (res2a / res1a)) / (1 + (res3a / res4a))) * volts2a) - ((res2a / res3a) * V_out);
  stored2 = stored1 * Volts_Cal;
  // dtostrf(stored2, 6, 2, myData.receivedChars[numChars]); // WHEN I UNHIGHLIGHT THIS NOTHING GETS DIDPSALED ON LCD

}
// ********************** Timed Action 02 ***********************
void TimerService02() {// Displat the data
  /*
     // NOT USED YET NEED TO GET WORKING
    lcd.setCursor(0, 0);
    lcd.print(myData.receivedChars[0]);//show signle receivedChars
    lcd.print(myData.receivedChars[1]);//show signle receivedChars
    // display.setCursor(5, 20);
    lcd.print(myData.receivedChars[2]);//show signle receivedChars
    lcd.print(myData.receivedChars[3]);//show signle receivedChars
    lcd.print(myData.receivedChars[4]);//show signle receivedChars
    lcd.print(myData.receivedChars[5]);//show signle receivedChars
    lcd.print(myData.receivedChars[6]);//show signle receivedChars
    lcd.print(myData.receivedChars[7]);//show signle receivedChars
  */
  /// This works displaying the lcd but myData.receivedChars does not get update with value
  lcd.setCursor(0, 1);
  cSF(sfVolts, 15);   // create a SafeString that can hold 15 chars (+'\0') no chance of buffer overflow if is stored2 is too large
  sfVolts.print(stored2, 2); // just like Serial.print but result is in the char[] inside sfVolts
  lcd.print(sfVolts.c_str());  // access the underlying char[] to pass as char* to lcd.print
  lcd.print(" v ");
  /*
    // This does not not work display remains blank
    lcd.setCursor(0, 1);
    cSFA(sfVolts, myData.receivedChars); // wraps receivedChars and picks up its length automatically
    sfVolts.print(stored2,2);
    lcd.print(sfVolts.c_str());
  */

}

Just to get back to the original code and explaining the original problem

For 9 characters, you will need 10 bytes. And you should not use [numChars]in the call;

dtostrf(stored2, 9, 2, myData.receivedChars);

Yes, using SafeStrings you will get a precise error message telling you just that and the name of the variable that too small and how big it needs to be.
like this if you use cSF(sfVolts, 8); instead on cSF(sfVolts, 15);

Error: sfVolts.print() needs capacity of 9
         Input arg was '-10414.08'
         sfVolts cap:8 len:0 ''

You need to look at the error messages
Using the code below the output is

Error: sf_myDataVolts.print() needs capacity of 9
        Input arg was '-10414.08'
        sf_myDataVolts cap:8 len:0 ''

The problem as noted by sterretje is that numChars = 9 is not large enough. You need a myData.char receivedChars[…] that can hold 9 char + ‘\0’
so increase numChars to at least 10;
Since SafeString cannot put the entire result in the char it does not store anything (just the ‘\0’)
SafeString functions are all on nothing so errors show up quickly as missing stuff.

See the Wrapping existing char arrays in a SafeString part of the tutorial and the library example sketch SafeStringfromCharArray.ino in the File->Examples->SafeString->SafeString_Test

void TimerService01() {// Read the external ADC MCP3426
 // MCP342x::Config status;
 // adcCh1.convertAndRead(MCP342x::channel1, MCP342x::oneShot, MCP342x::resolution16, MCP342x::gain1, 1000000, Volts_fb_Ch1, status);  // Ch.1 (3) 16bit
 Volts_fb_Ch1 = -1654000;
  Volts_disp_Ch1 = Volts_fb_Ch1 * 2.048 / 32767; // convert to voltage reading// Adjust here for display
  V_out = Volt_scale - Volts_disp_Ch1; // 2.500V referance voltage - incoming voltage
  stored1 = (((1 + (res2a / res1a)) / (1 + (res3a / res4a))) * volts2a) - ((res2a / res3a) * V_out);
  stored2 = stored1 * Volts_Cal;
  createSafeStringFromCharArray(sf_myDataVolts, myData.receivedChars); // or cSFA(sf_myDataVolts, myData.receivedChars) for short
  sf_myDataVolts.print(stored2,2);
  Serial.println(myData.receivedChars);
  // dtostrf(stored2, 6, 2, myData.receivedChars[numChars]); // WHEN I UNHIGHLIGHT THIS NOTHING GETS DIDPSALED ON LCD

}

OK, back home now and opened up my trusty X61S, and I don’t have to navigate the forum on my phone - let’s start with Debugging 101.

Start with the problem you identified

// dtostrf(stored2, 9, 2, myData.receivedChars[numChars]); // WHEN I UNHIGHLIGHT THIS NOTHING GETS DIDPSALED ON LCD

So, a function, and a couple of variables; we’ll isolate them in a simple, throwaway sketch.

float stored2; // Holds value of voltage to be transmitted to rx unit

const byte numChars = 9; //Number of bits to get

typedef struct Data_struct {
  int PRO3600_Disconnected = 10;
  boolean No_data ;
  char receivedChars[numChars];   // an array to store the received data
} Data_struct;
Data_struct myData;

void setup() 
{
 dtostrf(stored2, 9, 2, myData.receivedChars[numChars]); // WHEN I UNHIGHLIGHT THIS NOTHING GETS DIDPSALED ON LCD
}

void loop() {}

And when I compile this, I get the following

/home/TMFKAA/Arduino/CloudStation/FooWayBar/FooWayBar.ino: In function 'void setup()':
/home/TMFKAA/Arduino/CloudStation/FooWayBar/FooWayBar.ino:16:54: warning: invalid conversion from 'char' to 'char*' [-fpermissive]
  dtostrf(stored2, 9, 2, myData.receivedChars[numChars]); // WHEN I UNHIGHLIGHT THIS NOTHING GETS DIDPSALED ON LCD
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
In file included from /home/TMFKAA/arduino-1.8.12-linux64/arduino-1.8.12/hardware/arduino/avr/cores/arduino/Arduino.h:23:0,
                 from /tmp/arduino_build_98305/sketch/FooWayBar.ino.cpp:1:
/home/TMFKAA/arduino-1.8.12-linux64/arduino-1.8.12/hardware/tools/avr/avr/include/stdlib.h:666:14: note:   initializing argument 4 of 'char* dtostrf(double, signed char, unsigned char, char*)'
 extern char *dtostrf(double __val, signed char __width,
              ^~~~~~~

So now, it’s fairly clear I’m not using “dtostrf” correctly - I don’t expect to see warnings if I’m using an official library function correctly.

We Google “dtostrf”, and find the following

char* dtostrf 	( 	double  	__val,
		signed char  	__width,
		unsigned char  	__prec,
		char *  	__s 
	) 	
The dtostrf() function converts the double value passed in val into an ASCII representationthat will be stored under s. The caller is responsible for providing sufficient storage in s.

Conversion is done in the format "[-]d.ddd". The minimum field width of the output string (including the possible '.' and the possible sign for negative values) is given in width, and prec determines the number of digits after the decimal sign. width is signed value, negative for left adjustment.

The dtostrf() function returns the pointer to the converted string s.

Now, the warning about the char pointer becomes clear, and hopefully, a little further thought will clear up the problem of the buffer size.

(I’m really, really not happy with this new forum)

1 Like

I’m getting more confused (old age) or I’m looking at it completely different.
The example title say’s SafeStringFromCharArray but it’s a float value that I’m trying to convert into a char array
This what’s been output on the serial monitor with no input voltage

Error: sf_myDataVolts.print() needs capacity of 21
        Input arg was '0.02'
        sf_myDataVolts cap:17 len:17 '-0.000.010.010.02'
-0.000.010.010.02

This what’s been output on the serial monitor with 2.51 input voltage

Error: sf_myDataVolts.print() needs capacity of 21
        Input arg was '2.51'
        sf_myDataVolts cap:17 len:17 '-0.000.010.010.02'
-0.000.010.010.02

So I adjust const byte numChars = 21 to 21 uplload and run it again it now says

Error: sf_myDataVolts.print() needs capacity of 24
        Input arg was '7.51'
        sf_myDataVolts cap:20 len:20 '0.020.020.020.020.02'
0.020.020.020.020.02

I must be missing something ?.
I think I need to study more the link you mentioned I keep reading it and it’s not sinking in, May need a little break as mu brain is overloaded
Once again thanks everyone for the help and time

You’re missing the fact that you’re a hair’s breadth away from using dtostrf correctly, as set out above

1 Like

Two things:

  1. This new Forum layout sucks and, in my mind, might look “prettier” to some, but is much less useful.
  2. Solving the dtostrf() call by substituting a new function seems rather stupid to me, There are probably a bazillion lines of code out in the Open Source world that use this function. Seems to me the OP needs to learn how to use the widely-used version of code for conversion rather than using a less well-known set of library routines.
1 Like

I’m trying and made a little progress, I can get the LCD to keep displaying the data and changing, But the serial data is now garbage.
Here is my latest code:

#include <Wire.h>
#include <MCP342x.h>
#include <LiquidCrystal.h>// Highlight out when ready to use mian display
LiquidCrystal lcd(2, 4, 5, 3, 7, 8);
MCP342x adcCh1 = MCP342x(0x68);  // Ch1 MCP3424 I2C address

//###############################################################
//# Variables for the input voltage set up in differential mode #
//###############################################################
#define ECHO_TO_SERIAL 1 //change to zero = no serial output
float Volts_disp_Ch1 = 0;
float res1a = 100; // Resistor value of R1
float res2a = 1; // Resistor value of R2
float res3a = 100;// Resistor value of R3
float res4a = 1;// Resistor value of R4
float volts2a = 0 ; // volage 1 input =0 to give potsive reading
float stored1; // Holds the stored value of Resistor network
float stored2; // Holds value of voltage to be transmitted to rx unit
long Volts_fb_Ch1 = 0;
float res2 = 2700.00;
float Batt_R1;
float V_out;
float Volt_scale = 1.02263 ; //Change this if the incoming reading with nothing connected on the input terminals
float Volts_Cal = 9975.1;
const byte numChars = 10; //Number of bits to get
//char receivedChars[numChars];//store the value of imcoming data
boolean newData = false;
unsigned long NO_Data_in = 0;
int Lost_data = 0;
char str_i[10];
typedef struct Data_struct {
  int PRO3600_Disconnected = 10;
  boolean No_data ;
  char receivedChars[numChars];   // an array to store the received data
} Data_struct;
Data_struct myData;
void printRecord(Print* pr, char sep = ',') {
  pr->print(myData.receivedChars[0]); // Print btye 0
  // pr->print(sep);
  pr->print(myData.receivedChars[1]); // Print btye 1
  //  pr->print(sep);
  pr->print(myData.receivedChars[2] ); // Print btye 2
  // pr->print(sep);
  pr->print(myData.receivedChars[3]); // Print btye 3
  //  pr->print(sep);
  pr->print(myData.receivedChars[4]); // Print btye 4
  //  pr->print(sep);
  pr->print(myData.receivedChars[5]); // Print btye 5
  // pr->print(sep);
  pr->print(myData.receivedChars[6] ); // Print btye 6
  // pr->print(sep);
  pr->print(myData.receivedChars[7]); // Print btye 7
  //  pr->print(sep);
  pr->print(myData.receivedChars[8]); // Print btye 7
  pr->print(sep);
  pr->print(myData.PRO3600_Disconnected); // Print btye 7
  pr->print(sep);
  pr->print(myData.No_data);
  pr->println();
}
void setup() {
  Serial.begin(9600);
  lcd.begin(8, 2);
  lcd.clear();
  Wire.begin();
  TWBR = 12;  // Set 142.8kHz I2C clock. Keypad doesn't work at anything faster (freq = clock / (16 + (2 * TWBR * prescaler))
  // ADC - external
  MCP342x::generalCallReset(); // Reset all ADC devices
  delay(1);                    // MC342x needs 300us to settle, wait 1ms

}
//####################################################
//#  Main Loop,runs Timed_actions                    #
//####################################################
void loop() {

  TimerService01();
  TimerService02();
  /*

        #if ECHO_TO_SERIAL
        printRecord(&Serial);
        #endif //ECHO_TO_SERIAL
  */
}
//####################################################
//#   TimedAction - Timer Interrupt                  #
//####################################################
void TimerService01() {// Read the external ADC MCP3426
  MCP342x::Config status;
  adcCh1.convertAndRead(MCP342x::channel1, MCP342x::oneShot, MCP342x::resolution16, MCP342x::gain1, 1000000, Volts_fb_Ch1, status);  // Ch.1 (3) 16bit
  Volts_disp_Ch1 = Volts_fb_Ch1 * 2.048 / 32767; // convert to voltage reading// Adjust here for display
  V_out = Volt_scale - Volts_disp_Ch1; // 2.500V referance voltage - incoming voltage
  stored1 = (((1 + (res2a / res1a)) / (1 + (res3a / res4a))) * volts2a) - ((res2a / res3a) * V_out);
  stored2 = stored1 * Volts_Cal;
  dtostrf(stored2, 9, 2, myData.receivedChars);  //4 is mininum width, 4 is precision; float value is copied onto buff
  //display character array
  Serial.print("charVal: ");
  for (int i = 1; i < sizeof(myData.receivedChars); i++)
  {
    Serial.print(myData.receivedChars[i]);
  }
  Serial.println();
  // dtostrf(stored2, 10, 2, myData.receivedChars); // IF I change this to 10 stored2 value goes to -101.01 and does not change
  delay(20);

  Serial.print("dtstore: ");
  Serial.print(myData.receivedChars[0]); //display string
  Serial.print(myData.receivedChars[1]); //display string
  Serial.print(myData.receivedChars[2]); //display string
  Serial.print(myData.receivedChars[3]); //display string
  Serial.print(myData.receivedChars[4]); //display string
  Serial.print(myData.receivedChars[5]); //display string
  Serial.print(myData.receivedChars[6]); //display string

}
// ********************** Timed Action 02 ***********************
void TimerService02() {// Displat the data

  /*
      // NOT USED YET NEED TO GET WORKING
     lcd.setCursor(0, 0);
     lcd.print(myData.receivedChars[0]);//show signle receivedChars
     lcd.print(myData.receivedChars[1]);//show signle receivedChars
     // display.setCursor(5, 20);
     lcd.print(myData.receivedChars[2]);//show signle receivedChars
     lcd.print(myData.receivedChars[3]);//show signle receivedChars
     lcd.print(myData.receivedChars[4]);//show signle receivedChars
     lcd.print(myData.receivedChars[5]);//show signle receivedChars
     lcd.print(myData.receivedChars[6]);//show signle receivedChars
     lcd.print(myData.receivedChars[7]);//show signle receivedChars
  */

  lcd.setCursor(0, 1);
  lcd.print(stored2, 2);
  lcd.print(" v ");

}

for (int i = 1; i < sizeof(myData.receivedChars)

Why from 1?

Don’t bother to give us examples; we love guessing games