Problems converting a string to float received by serial


#1

Hello guys,

I got problems when converting a string, received by serial, to float. The best case I get is with the code below, is alternating between the float value and 0.00 on thinger dashboard. If someone could help would be really helpful. Thanks

// changing interval sample on thingers sometimes gives readings

//#define _DEBUG_
#include <ESP8266WiFi.h>
#include <ThingerESP8266.h>

#define USERNAME "username" //Username from thinger.io
#define DEVICE_ID "TESTNODE" //Device you create on thinger.io
#define DEVICE_CREDENTIAL "credentials" //Credentials from thinger.io


#define SSID "dlink-C961"
#define SSID_PASSWORD "password"
String inString = "";    // string to hold input
const char separator = ';';
float current_temperature = 0;
//float current_temperature =  // siguiente inString.toFloat en out=

ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

void setup() {
  Serial.begin(9600);
  thing.add_wifi(SSID, SSID_PASSWORD);

  // digital pin control example (i.e. turning on/off a light, a relay, configuring a parameter, etc)
  //thing["led"] << invertedDigitalPin(LED_BUILTIN);

  // resource output example (i.e. reading a sensor value)
  //thing["millis"] >> outputValue(millis());

 // thing["Temperature"] >> [](pson& out){  //  xc 
   // sensors.requestTemperatures();
     // out["valor"] = sensors.getTempCByIndex(0); //on email {{valor}}
     thing["temperature"] >> [](pson& out){
      out = current_temperature;
      
};}


void loop() {
  //delay500+
inString = "";
delay (10);
while (Serial.available()) // 
   {
      char incomingChar = Serial.read();
      
      if (incomingChar == separator)
      {
        break;  
      }
      else if (incomingChar == '\n')
      {
  break;  
      }
  inString += incomingChar;
   }
  current_temperature = inString.toFloat();
  delay (2000); //without this delay always is 0
  
 
    thing.handle(); }
//delay (10);
// 


#2

You need to be sure that the code that contains toFloat instruction runs just one time after the whole value (be careful with this) is received by serial port, because as the code is, when it is not received anything by serial port, the micro is resetting the variable “inString” to nothing and after that is doing the conversion as many times it can.

Another advice, I recommend you to avoid the use of delay() function with thinger, it provoques abnormal behavior, use another method to control time at microcontroller.

Hope it helps


#3

Hi ega,

thanks for yoour help.

It’s ok how I am trying now to do toFloat just once on the loop?

//#define _DEBUG_
#include <ESP8266WiFi.h>
#include <ThingerESP8266.h>

#define USERNAME "ieiot" //Username from thinger.io
#define DEVICE_ID "TESTNODE" //Device you create on thinger.io
#define DEVICE_CREDENTIAL "D$HE&D0AOZAT" //Credentials from thinger.io
#define SSID "dlink-C961"
#define SSID_PASSWORD "mgtke78360"

String inString = "";    // string to hold input
const char separator = ';';
float current_temperature = 0;

ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

void setup() {
  Serial.begin(9600);
  thing.add_wifi(SSID, SSID_PASSWORD);

  // digital pin control example (i.e. turning on/off a light, a relay, configuring a parameter, etc)
  //thing["led"] << invertedDigitalPin(LED_BUILTIN);

  // resource output example (i.e. reading a sensor value)
  //thing["millis"] >> outputValue(millis());

 // thing["Temperature"] >> [](pson& out){  //  xc 
   // sensors.requestTemperatures();
     // out["valor"] = sensors.getTempCByIndex(0); //on email {{valor}}
     thing["temperature"] >> [](pson& out){
      out = current_temperature;
      
};}
int endpointUpperFlag=1;

void loop() {
  
  inString = ""; //

while (Serial.available() && endpointUpperFlag) // 
   {
    
      char incomingChar = Serial.read();
      
      if (incomingChar == separator)
      {
        break;  
      }
      else if (incomingChar == '\n')
      {
  break;  
      }
  inString += incomingChar;
   } 
   
  endpointUpperFlag=0;
  current_temperature = inString.toFloat();
  
 // delay (2000); //without this delay always is 0
  
 
    thing.handle(); 
    //inString = "";
    endpointUpperFlag=1;
    }

#4

I’m going to give you some advices to have your process working, you need a flag that will give you the state of the serial variable, when is received complete it is set (for example) to 1, and after a code like this

if (flag==1)
{
current_temperature = inString.toFloat();
flag=0;
}

But it is so important that you set this flag only when you have received the whole variable by serial port, because you can be converting digit by digit, destroying previous and having just the last digit until next convertion, I can’t determ how to or where to do it, because I don’t know the nature of the variable that you are working with.

Last recomendation, get used to do “cold runs” it means to interpret line by line, tracking variables, what is the microcontroller doing, so you can understand better where are the issue in logic and code when it does something that is not supossed to do.