Hi all,
Im trying to figure out how to get more than 3 decimal places to be inputted into a formula and return a more accurate result too.
i have tried making the variables a float and a double.
i want to be able to input this value "44.64978683" without having to go down too "44.65".
When i put the whole value in i get the image below;
Thanks
double level;
double myValue;
String msg1 = "Enter Frequency (type 0 to exit): ";
String msg2 = "Your Frequency is: ";
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print(msg1);
while (Serial.available() == 0);
{
}
myValue = Serial.parseFloat();
if (myValue == 0.0)
{
Serial.end();
}
else
{
freqConversion();
}
}
void freqConversion()
{
level = (myValue-44.712)/-0.0285493333;
Serial.println(myValue);
Serial.print(msg2);
Serial.println(level);
}
gcjr
December 4, 2020, 10:23am
2
seems there's a problem reading your input.
44.64978683 is entered, but the code reports 1.70
dtostrf() can be used to format FP values
By default print() only displays two decimal places, you can specify the number of decimal places:
Serial.println(level, 4); //will print level with 4 decimal places.
Note that in most arduino's double is implemented as float, and float is limited to 6 to 7 significant digits.
david_2018:
By default print() only displays two decimal places, you can specify the number of decimal places:
Serial.println(level, 4); //will print level with 4 decimal places.
Note that in most arduino's double is implemented as float, and float is limited to 6 to 7 significant digits.
I had tested (level,8), and it had outputted "1.70011425" when i had written "44.62352548"
gcjr:
seems there's a problem reading your input.
44.64978683 is entered, but the code reports 1.70
dtostrf() can be used to format FP values
Does this have to be specific?
e.g. could i use dtostrf(myValue,9,7,outValue) and i would of only inputted a number with 7 decimal places?
gcjr:
yes
Error Message
Arduino: 1.8.10 (Windows 10), Board: "Arduino/Genuino Uno"
C:\Users\jacklythgoe\Documents\Training\Arduino Projects\WORK\ArduinoFreqProject\ArduinoFreqProject.ino: In function 'void setup()':
ArduinoFreqProject:9:31: error: cannot convert 'float' to 'char*' for argument '4' to 'char* dtostrf(double, signed char, unsigned char, char*)'
dtostrf(myValue,9,7,outValue);
^
exit status 1
cannot convert 'float' to 'char*' for argument '4' to 'char* dtostrf(double, signed char, unsigned char, char*)'
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
float level;
float myValue;
float outValue;
String msg1 = "Enter Frequency (type 0 to exit): ";
String msg2 = "Your Frequency is: ";
void setup()
{
dtostrf(myValue,9,7,outValue);
Serial.begin(9600);
}
void loop()
{
Serial.print(msg1);
while (Serial.available() == 0);
{
}
myValue = Serial.parseFloat();
if (myValue == 0.0)
{
Serial.end();
}
else
{
freqConversion();
}
}
void freqConversion()
{
level = (myValue-44.712)/-0.0285493333;
Serial.println(myValue,8);
Serial.print(msg2);
Serial.println(level,8);
}
gcjr
December 4, 2020, 10:53am
8
dtostrf formats the value into a c string. it doesn't configure the value with a specific # of digits
you need to define and use a char array, and do a conversion for each new value
char s [20]
dtostrf (myValue, 9, 7, s);
Serial.println (s);
gcjr:
dtostrf formats the value into a c string. it doesn't configure the value with a specific # of digits
you need to define and use a char array, and do a conversion for each new value
char s [20]
dtostrf (myValue, 9, 7, s);
Serial.println (s);
Would you be able to implement this into my code? im not really understanding how this is formatted.
gcjr
December 4, 2020, 11:05am
10
Enter Frequency (type 0 to exit): 1.1737840
Your Frequency is: 1525.02
Enter Frequency (type 0 to exit):
void freqConversion()
{
char s [20];
dtostrf (myValue, 9, 7, s);
Serial.println(s);
level = (myValue-44.712)/-0.0285493333;
Serial.print(msg2);
Serial.println(level);
}
hammy
December 4, 2020, 11:28am
11
You need to think carefully about precision here .
All those significant figures may well be meaningless in the accuracy of the result .
If the input resolution is to say 4 significant figures then there maybe no point having higher resolution in any of the multiplying/dividing factors . You need to test this out , rather than using up all that computing effort. An integer for example may suffice for your input and all following maths .
For example : “ level = (myValue-44.712)/-0.0285493333”
Chopping off the 3333 from the denominator does not affect the accuracy of the result as your numerator is to less significant figures .
Are you having a problem with the input value being incorrect, or only with the result of the calculation? It may be that Serial.parseFloat() cannot handle the excessively long input number.
Which arduino are you using? There is no double on most models, so 44.62352548 will always get shorted to around 4 decimal places.
david_2018:
Are you having a problem with the input value being incorrect, or only with the result of the calculation? It may be that Serial.parseFloat() cannot handle the excessively long input number.
Which arduino are you using? There is no double on most models, so 44.62352548 will always get shorted to around 4 decimal places.
The input value is wrong, which then makes the result wrong. Do you know anyway i could help the parseFloat? as that may be the problem.
I am using the Arduino Elegoo Uno R3.
gcjr
December 4, 2020, 1:14pm
14
jacklythgoee:
The input value is wrong, which then makes the result wrong. Do you know anyway i could help the parseFloat? as that may be the problem.
arduino uses many techniques not common in standard C++
String msg1 = "Enter Frequency (type 0 to exit): ";
String msg2 = "Your Frequency is: ";
char inpBuf [80];
int inpIdx = 0;
void setup()
{
Serial.begin(9600);
Serial.print(msg1);
}
void loop()
{
while (Serial.available()) {
if ('\n' == (inpBuf [inpIdx++] = Serial.read())) {
float freq = atof (inpBuf);
freqConversion (freq);
inpIdx = 0;
Serial.print(msg1);
}
}
}
void freqConversion(
float freq )
{
char s [20];
dtostrf (freq, 10, 7, s);
Serial.println(s);
double level = (freq -44.712)/-0.0285493333;
Serial.print(msg2);
Serial.println(level);
}
gcjr:
arduino uses many techniques not common in standard C++
String msg1 = "Enter Frequency (type 0 to exit): ";
String msg2 = "Your Frequency is: ";
char inpBuf [80];
int inpIdx = 0;
void setup()
{
Serial.begin(9600);
Serial.print(msg1);
}
void loop()
{
while (Serial.available()) {
if ('\n' == (inpBuf [inpIdx++] = Serial.read())) {
float freq = atof (inpBuf);
freqConversion (freq);
inpIdx = 0;
Serial.print(msg1);
}
}
}
void freqConversion(
float freq )
{
char s [20];
dtostrf (freq, 10, 7, s);
Serial.println(s);
double level = (freq -44.712)/-0.0285493333;
Serial.print(msg2);
Serial.println(level);
}
i go to run this code and first message gets displayed, when i go to input a value, nothing is returned to me
gcjr
December 4, 2020, 1:33pm
16
i should have said that you need to configure your serial monitor to return Newline. it's the box at the bottom to the left of the bitrate (baud)
gcjr:
i should have said that you need to configure your serial monitor to return Newline. it's the box at the bottom to the left of the bitrate (baud)
I have this code functioning now, thank you very much for that. However is there a way to make the input value exact? the output doesnt have to have any decimal places so i can change that to an int im pretty sure.
String msg1 = "Enter Frequency (type 0 to exit): ";
String msg2 = "Your Frequency is: ";
A great way to waste nearly 70 bytes of precious RAM. Needs more F() macro.
arduino uses many techniques not common in standard C++
:o
gcjr:
try it and find out
changed level to an int and it had worked. Thanks