Convert float to a Char value?[SOLVED]

I was trying other ways I did change that to 0 but still the same.
This is what is coming out the serial port.

8⸮⸮!⸮
8⸮⸮!⸮
8⸮⸮!⸮
8⸮⸮!⸮
8⸮⸮!⸮
8⸮⸮!⸮
8⸮⸮!⸮

The baud rate is set to 9600 on the serial monitor,

Now this is a strange thing I tried this code below with the ADC routine removed and to make things more simpler.


#include <LiquidCrystal.h>// Highlight out when ready to use mian display
LiquidCrystal lcd(2, 4, 5, 3, 7, 8);
const byte numChars = 10; //Number of bits to get
float resistance = 12.36;
double floatVal = 23.01;
String stringVal = "";     //data on buff is copied to this string
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()
{
  Serial.begin(9600);
  lcd.begin(8, 2);
  lcd.clear();

  resistance = resistance - 40.36;
  dtostrf(floatVal, 10, 2, myData.receivedChars);  //4 is mininum width, 4 is precision; float value is copied onto buff
  Serial.print("charVal: ");
  for (int i = 0; i < sizeof(myData.receivedChars); i++)
  {
    Serial.print(myData.receivedChars[i]);
  }
  Serial.println();


  dtostrf(resistance, 6, 2, myData.receivedChars); // L
  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

}
void loop()
{
  lcd.setCursor(0, 0);
  lcd.print(resistance);
  lcd.setCursor(0, 1);
  lcd.print(myData.receivedChars[0]); //display string
  lcd.print( myData.receivedChars[1]); //display string
  lcd.print( myData.receivedChars[2]); //display string
  lcd.print( myData.receivedChars[3]); //display string
  lcd.print( myData.receivedChars[4]); //display string
  lcd.print( myData.receivedChars[5]); //display string
  lcd.print( myData.receivedChars[6]); //display string
}

This is what I get on the Serial monitor

charVal:      23.01
dtstore: -28.00

Not sure why it does or will not work when I just add this to the code in post 17.
I've just added this to the code from post 17 and get the same results.

dtostrf(stored2, 6, 2, myData.receivedChars); // L
  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
⸮!⸮
⸮!⸮
⸮!⸮
⸮!⸮
⸮!⸮
⸮!⸮

You haven't really got the concept of reducing the code to its simplest, have you?

Looks like I haven't.
This code now below I've added some code to count up and count down (one at a time) and this seems to be working and displaying on the LCD and serial monitor even when the values go below 0


#include <LiquidCrystal.h>// Highlight out when ready to use mian display
LiquidCrystal lcd(2, 4, 5, 3, 7, 8);
const byte numChars = 10; //Number of bits to get
float resistance = 12.36;
double floatVal = 23.01;
String stringVal = "";     //data on buff is copied to this string
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 1000;           // interval at which to blink (milliseconds)

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()
{
  Serial.begin(9600);
  lcd.begin(8, 2);
  lcd.clear();
  //resistance = resistance - 40.36;


}
void loop()
{
  /*
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    resistance = resistance +0.01;
    }
  */
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    resistance = resistance - 1.00;
  }
  dtostrf(resistance, 6, 2, myData.receivedChars); // L
  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.println( myData.receivedChars[6]); //display string
  lcd.setCursor(0, 0);
  lcd.print(resistance);
  lcd.setCursor(0, 1);
  lcd.print(myData.receivedChars[0]); //display string
  lcd.print( myData.receivedChars[1]); //display string
  lcd.print( myData.receivedChars[2]); //display string
  lcd.print( myData.receivedChars[3]); //display string
  lcd.print( myData.receivedChars[4]); //display string
  lcd.print( myData.receivedChars[5]); //display string
  lcd.print( myData.receivedChars[6]); //display string
}

That tells you that your char[ ] that the SafeString is wrapping ALREADY contains data that you are trying to print( ) to the end of and running out of space.
try clearing it first

createSafeStringFromCharArray(sf_myDataVolts, myData.receivedChars); // or cSFA(sf_myDataVolts, myData.receivedChars) for short
  sf_myDataVolts = ""; // clear any existing text  
  sf_myDataVolts.print(stored2,2);
  Serial.println(myData.receivedChars);

Try this

#include "SafeString.h"

//#include <LiquidCrystal.h>// Highlight out when ready to use mian display
//LiquidCrystal lcd(2, 4, 5, 3, 7, 8);
// to print the lcd data without an lcd
#define lcd Serial

const byte numChars = 10; //Number of bits to get
float resistance = 12.36;
double floatVal = 23.01;
String stringVal = "";     //data on buff is copied to this string
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 1000;           // interval at which to blink (milliseconds)

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()
{
  Serial.begin(9600);
  for (int i = 10; i > 0; i--) {
    Serial.print(' '); Serial.print(i);
    delay(500);
  }
  Serial.println();
  //  lcd.begin(8, 2);
  //  lcd.clear();
  //resistance = resistance - 40.36;
  SafeString::setOutput(Serial); // for error msgs
}

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    resistance = resistance - 1.00;
  }
  createSafeStringFromCharArray(sfResistance, myData.receivedChars); // wraps in a SafeString and  keeps the current text if any
  sfResistance = ""; // clear it  OR you could use myData.receivedChars[0] ='\0';
  sfResistance.print(resistance, 2);
  // dtostrf(resistance, 6, 2, myData.receivedChars); // L
  Serial.print("dtstore: ");
  Serial.println(myData.receivedChars);  // just print it  SafeString leaves the char[] correctly terminated even if there are errors

  // lcd.setCursor(0, 0);
  lcd.print(resistance);
  // lcd.setCursor(0, 1);
  lcd.print(myData.receivedChars);
  lcd.println();
}

Thanks drmpf
I've now got to the bottom of it and kicking myself with my size nine boot's and completely my own fault and making. Because I uploaded some code to another arduino mini which was running at 3.3V 8MHz when I opened a new window the setting was for the last board and the board I was trying to upload the new code to was set to 3.3V 8MHz

I'v now changed to suit and everything works perfectly.
I feel so stupid and apologize for waiting everyones time, But I would like to say a massive thank you to all for the help. learnt so much today

dtostf() looks difficult to use safely.
Can you tell me how to calculate the minimum size of the result char[..] so that it will not be overflowed?

The maximum precision for a true double data type is usually 16 characters or less. Because you need the sentinel null character at the end, a char array of 17 char's would likely cover the largest (meaningful) string you could use. With a float data type, 8 digits of precision with one more for the null, or 9 total. The compiler can generate more digits than these suggestions, but they should be taken with a block of salt since they are a "guess" at best.

I cannot tell you a way to prevent overflow, since C does not do runtime checks for overflow on its own. A runtime check for overflow would require modifying the standard dtostrf() library routine. Some languages do have runtime checks on overflow (e.g., Java), but that, to me, seems to be like C with training wheels....not a fan.

econjack Thanks for that.
I like training wheels because my code keeps falling over :frowning:

What are you using to teach yourself C? That will stop as you gain more experience with C. Hang in there...

I have been trying to avoid the pit falls of C code since the 1980's
I once gave a course on C programming that consisted entirely of example code that compiled but did not run :frowning:

I find that avoiding c-string methods and char[..] helps my code reliability a lot which is why I use either Arduino Strings or my SafeString library.

Of course both of these are written using char[..] and c-string methods, but they only need to be debug once, not every project.

p.s. the dtostrf functionality looked useful so added a
print(double, prec, width);
method to SafeString. It prints to the current SafeString, concats the formatted double.

However being SafeString you are protected from buffer overflows. Also in my method the width param is the fixed width the result is padded to. This is in addition to preventing buffer overflow in the SafeString accepting the result.
Here is a comparison with dtostrf

Formatting -1.23
 using dtostrf(d,width,6,dtos); | -1.234560| text following field
 using sfStr.print(d,6,width)   | -1.234560| text following field
 Formatting -12.35
 using dtostrf(d,width,6,dtos); |-12.345600| text following field
 using sfStr.print(d,6,width)   |-12.345600| text following field
 Formatting -123.46
 using dtostrf(d,width,6,dtos); |-123.456000| text following field
 using sfStr.print(d,6,width)   |-123.45600| text following field
 Formatting -1234.56
 using dtostrf(d,width,6,dtos); |-1234.560100| text following field
 using sfStr.print(d,6,width)   |-1234.5601| text following field
 Formatting -12345.60
 using dtostrf(d,width,6,dtos); |-12345.601000| text following field
 using sfStr.print(d,6,width)   |-12345.601| text following field
 Formatting -123456.01
 using dtostrf(d,width,6,dtos); |-123456.010000| text following field
 using sfStr.print(d,6,width)   |-123456.01| text following field
 Formatting -1234560.12
 using dtostrf(d,width,6,dtos); |-1234560.100000| text following field
 using sfStr.print(d,6,width)   |-1234560.1| text following field
 Formatting -12345601.00
 using dtostrf(d,width,6,dtos); |-12345601.000000| text following field
 using sfStr.print(d,6,width)   | -12345601| text following field
 Formatting -123456008.00
 using dtostrf(d,width,6,dtos); |-123456010.000000| text following field
 using sfStr.print(d,6,width)   |-123456010| text following field
 Formatting -1234560128.00
 using dtostrf(d,width,6,dtos); |-1234560100.000000| text following field
 using sfStr.print(d,6,width)   |          | text following field

 SafeString Error detected! d:-1234560128.00 too large to display in field width:10

Sounds like we've both been at it a while. I wrote my first C book in 1982 and taught various programming languages over the years, but C remains my favorite. I retired from Purdue University's College of Technology in 2009, but continue to write...just started book #21, also using C, but co-authored with another ham developing an SDT (Software Defined Transceiver). I don't know what the best language is, but C is way out in front of whatever's in second place.

TIOBE Index for May 2021 shows C as No1 so you are not alone in your choice of favorite.

When working with text I prefer to use libraries/classes that protect me from buffer overruns, null pointers, missing '\0' terminators etc. As you say C expects you to 'ride' perfectly. I am not a perfect programmer and those libaries/class keep me from falling of my Cycle when processing text.

I found Ch2 and Ch5 of Secure Coding in C and C++, 2nd Edition informative on the problems of using C correctly.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.