mathworks / thingspeak-arduino

ThingSpeak Communication Library for Arduino, ESP8266 and ESP32
https://thingspeak.com
431 stars 231 forks source link

Ongoing issues passing floats in the setField command #60

Closed cjmckay closed 3 years ago

cjmckay commented 4 years ago

I note that there appears to be many issues associated with sending floats as part of the sendmultiple fields workflow. I have experienced this myself recently working for the Arudino/ESP8266 example however attempting to setFields with float values.

A quick look at line 1647 of ThingSpeak.h suggests that there may be an error in function convertFloatToChar (can someone with better knowledge than I please check this?) as follows:

Line 1647 of ThingSpeak.h reads: dtostrf(value,1,5,valueString);

however reference to https://www.microchip.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1ga060c998e77fb5fc0d3168b3ce8771d42.html and others suggest that the 2nd parameter (currently coded as '1') should be the "minimum field width of the output string including possible negative signs and possible decimal point" with the third value '5' predetermining that the precision (i.e. number of digits after the decimal sign) will be 5. Given the test is for 19+1 (defined in line 350 of the same code) I would have thought the second field should also be 19 (instead of 1).

I'm hoping this gets a whole bunch of people out of trouble moving forward. Given the 'strange behaviour' and the number of reported issues around this, perhaps an example can be included in the documentation (or the existing example modified to show correct casting or alternate methods required).

addyvenkat commented 3 years ago

As you mentioned, the 2nd parameter is the minimum width of the output string, so it need not be 19. Considering the case for 19, it would just add whitespace in front of the value so as to make it 19 characters.

You can try reproducing the same way I did:

do uncomment #define PRINT_DEBUG_MESSAGES in line 15 of ThingSpeak.h file to get the messages in the Serial Monitor Output.

with dtostrf(value,1,5,valueString); -

float val = 255.24;
ThingSpeak.setField(fieldNumber, val);
int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
  if(x == 200){
    Serial.println("Channel update successful.");
  }
  else{
    Serial.println("Problem updating channel. HTTP error code " + String(x));
  }

Output:

Screen Shot 2020-08-20 at 11 18 26 AM

with dtostrf(value,19,5,valueString); -

float val = 255.24;
ThingSpeak.setField(fieldNumber, val);
int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
  if(x == 200){
    Serial.println("Channel update successful.");
  }
  else{
    Serial.println("Problem updating channel. HTTP error code " + String(x));
  }

Output:

Screen Shot 2020-08-20 at 11 30 34 AM

So as per my observation, having the 2nd argument as 1 is not leading to an error.