string.toDouble() returns zero after the first string converted right

I’m working on a project where I am sending some data from mobile app in the form of String via BLE (CC41-A) to Arduino Uno. In arduino the string is divided into small strings and the small strings are then converted to double for some mathematical calculation. The original string is in the format (Ex: 23.54, 108.67; 56.85, 45.75; … so on). And the smaller strings are created inside loop as follows:

the string segment before comma (,) is converted to double and stored in variable x &
the string segment before semi colon (:wink: is converted to double and stored in variable y

For double conversion I’m using string.toDouble(). But the first ‘x’ value shows right (in this ex: x=23.54) using that function and gives 0.00 on subsequent conversions for ‘x’. The ‘y’ value always returns right.

I’ve attached the code. I can’t figure out why only the ‘x’ value is printed wrong. Pls help…

XY_Plotternew.ino (2.34 KB)

Please post your code, in code tags.

I would suggest reading your data into an array and using string tokenizer strtok to split it into tokens https://www.tutorialspoint.com/c_standard_library/c_function_strtok.htm e.g.

  char str[] ="Ex: 23.54, 108.67; 56.85, 45.75; ";
  char * pch;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str,":,;");
  while (pch != NULL)
  {
    float x=999;
    printf ("string found %s\n",pch);
    if(sscanf(pch,"%f",&x) == 1) printf("float value decoded %f\n",x);
    else                         printf("%s not a float \n", pch);
     pch = strtok (NULL, ":,;");
  }

gives

Splitting string "Ex: 23.54, 108.67; 56.85, 45.75; " into tokens:
string found Ex
Ex not a float
string found  23.54
float value decoded 23.540001
string found  108.67
float value decoded 108.669998
string found  56.85
float value decoded 56.849998
string found  45.75
float value decoded 45.750000
string found
  not a float

Thank you for your suggestion @horace… I’ll try that…

Here is the original code…

#include <Servo.h>
#include <math.h>
#include <SoftwareSerial.h>

SoftwareSerial BTSerial(4, 5);
Servo servo1;  // create servo object to control a servo
Servo servo2;
// twelve servo objects can be created on most boards

double L = 61;
int pos1 = 0;    // variable to store the servo position
int pos2 = 0;
double x;
double y;
double X = 0;
double Y = 0;
double pi = 3.142;

String inputString = ""; // a String to hold incoming data
String inputStr = "";  
String inpStr = "";  
boolean stringComplete = false; 
int i, j;

void setup() {
  Serial.begin(9600);
  BTSerial.begin(9600);
  servo1.attach(9);
  servo2.attach(6);  // attaches the servo on pin 9 & 6 to the servo object
}

void loop() {
  while (BTSerial.available()) {
    char inChar = BTSerial.read();
    if (inChar == '

) {
      Serial.println(inputString);
      CalcAngle();
    }
    else {
      inputString += inChar;
    }
  }
}

void CalcAngle() {
  for(i = 0; i <= inputString.length(); i++) {
    char c = inputString.charAt(i);
    if (c == ‘;’) {
      i +=1;
      inputStr += c;
      for(j = 0; j <= inputStr.length(); j++) {
        char d = inputStr.charAt(j);
        if (d == ‘,’) {
          x = inpStr.toDouble();
          Serial.println(x);
          inpStr = “”;
          d = ’ ';
        }
        else if (d == ‘;’) {
          y = inpStr.toDouble();
          Serial.println(y);
          inpStr = “”;
          d = ’ ';
        }
        else{
          inpStr += d;
        }
      }
      X = (x/315.00)86.30;
      Y = (y/275.00)86.23;
     
   
      double inv_cos = acos(sqrt(square(X)+square(Y))/(2
L));
      //Serial.println(inv_cos);
      double ang1 = atan2(Y, X) + inv_cos;
      double ang2 = 2
inv_cos;
      //Serial.println(ang1);
      //Serial.println(ang2);
      pos1 = (int)round(ang1180/pi);
      pos2 = (int)round(ang2
180/pi);
      Serial.println(pos1);
      Serial.println(pos2);
      if (pos1 >= 0 && pos1 <=135 && pos2 >= 0 && pos2 <=180) {
        servo1.write(pos1*0.9);              // tell servo to go to position in variable ‘pos’
        //delay(50);
        servo2.write(180-pos2);
        //delay(50);                      // waits 50ms for the servo to reach the position
      }
      else {
        Serial.println(“Angle outbound”);
      }
      c = ’ ';
      inputStr = “”;
    }
    else{
      inputStr += c;
    }
    //return x, y;
  }
}

I tested the fragment of you code which parses the input with

#include <iostream>
#include <string>

using namespace std;

int main(void) {
string inpStr,inputStr, inputString="23.54, 108.67; 56.85, 45.75; ";
int i,j;
double x, y, X, Y;
  for(i = 0; i <= inputString.length(); i++) {
    char c = inputString[i];
    if (c == ';') {
      i +=1;
      inputStr += c;
      for(j = 0; j <= inputStr.length(); j++) {
        char d = inputStr[j];
        if (d == ',') {
          cout << " x " << inpStr << endl;
         // x = inpStr.toDouble();
         // cout << (x) << endl;;
          inpStr = "";
          d = ' ';
        }
        else if (d == ';') {
                cout << " y " << inpStr << endl;
          //y = inpStr.toDouble();
          //cout << y << endl;
          inpStr = "";
          d = ' ';
        }
        else{
          inpStr += d;
        }
      }
      X = (x/315.00)*86.30;
      Y = (y/275.00)*86.23;


      c = ' ';
      inputStr = "";
    }
    else{
      inputStr += c;
    }
    //return x, y;
  }
}

a run gives

 x 23.54
 y  108.67
 x  56.85
 y  45.75

which appears to be correct
could you have some none printable characters in the received data ?
try printing inpStr as in the above code

this stringSplit() function may useful
it takes a char and using strtok() returns an array of floats

/* stringSplit function using strtok */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main (void)
{
  char str[] ="Ex: 23.54, 108.67; 56.85, 45.75; ";
  int i,j;
  float result[100];
  printf ("Splitting string \"%s\" into tokens:\n",str);
  i=stringSplit(str, ":,;", result);
  for(j=0; j<i;j++)
    printf("result[%d] = %f\n",j, result[j]);
}

// split string str into float values  using delimiters
// this version uses atof() and does not return tokens with value 0.0f
// return function result number of floats converted
// return converted values in data[]
int stringSplit(char *str, char *delim, float data[])
{
  int i=0;
  char *pch = strtok (str,delim);       // get first token
  while (pch != NULL)
  {
    float x=999;
    printf ("string found %s\n",pch);
    // check if token is a float
    if((data[i]=atof(pch)) != 0.0f) printf("float value decoded %f\n",data[i++]);
    else                            printf("%s not a float \n", pch);
    pch = strtok (NULL, delim);   // parse next token
  }
  return i;
}

a run gives

Splitting string "Ex: 23.54, 108.67; 56.85, 45.75; " into tokens:
string found Ex
Ex not a float
string found  23.54
float value decoded 23.540001
string found  108.67
float value decoded 108.669998
string found  56.85
float value decoded 56.849998
string found  45.75
float value decoded 45.750000
string found
  not a float
result[0] = 23.540001
result[1] = 108.669998
result[2] = 56.849998
result[3] = 45.750000