yellamo 0 Posted April 8, 2015 Share Posted April 8, 2015 Hi Guys, I've posted an issue over on the Ti website but they have suggested posting in an Energia forum too. The issue I am seeing is when concatenating a string and a long number. It either goes one of two ways - the value is zeros, or the numbers following the decimal point are missing. https://e2e.ti.com/support/wireless_connectivity/f/968/t/414222 //This works fine static float diet = tmp006.readDieTempC(); Serial.print("Die Temperature: "); Serial.print(diet); Serial.println("*C"); //This doesnt String pubString = "Temperature " + long(diet); Serial.print(pubString); The following gives zeros: String pubString = "Temperature Test "; pubString += diet; Serial.print(pubString); Thanks Quote Link to post Share on other sites
roadrunner84 466 Posted April 8, 2015 Share Posted April 8, 2015 When you cast a float to a long there is no surprise that the numbers after the decimal separator are missing; you explicitly tell your compiler to add this behaviour. The zeroes are odd, though you must expect String to not work nicely on embedded platforms; concatenating to a string will reallocate memory to expand the required memory to accommodate the new size. Since this will require free space (heap) management, thing get ugly with restricted memory. Do you really need to format your string in your embedded platform, or could a PC user interface do it as well? If you really need to format the string on the embedded platform, do you really need to have it formatted in memory, or is formatted over the serial line fine too (like you're doing in your first example)? If you really must use embedded formatting, you'd better use a c-string (char array) instead of String, since it's much easier to manage the size beforehand and uses lighter functions for the formatting. //This does, but it leaves out the decimal separator String pubString = "Temperature " + long(diet * 1000) + "m*C"; Serial.print(pubString); // This does too, but uses c-string char pubString[] = "Temperature xx.xxx*C"; sprintf(pubString + 12, "%6.3f*C", diet); Serial.print(pubString); Quote Link to post Share on other sites
yellamo 0 Posted April 9, 2015 Author Share Posted April 9, 2015 Hi RoadRunner, Thanks for the helpful reply. Ultimately I want to construct a string of multiple values which can be posted as a JSON value. I have tried both the examples and the second one is very good, but I am having the same issue with this bit of code - it works fine in a new sketch, but once I add this into my sketch with all the code in, it returns zeros! The same goes for another piece of code suggested there too: String pubString7; char buffer1[8]; float diet1 = 40.05; sprintf(buffer1, "%.2f", diet1); pubString7 = "\r\n\Temperature Test : "; pubString7 += buffer1; Serial.println(pubString7); I am just about to reply over there, but it was originally looking like an issue with SPI.h. Here are my imports (which does not make a difference on my main sketch: #ifndef __CC3200R1M1RGC__ #endif #include <WiFi.h> #include <PubSubClient.h> #include <math.h> #include "Adafruit_TMP006.h" #include <Wire.h> #include <stdlib.h> Any help greatly appreciated. Thanks Quote Link to post Share on other sites
abecedarian 330 Posted April 9, 2015 Share Posted April 9, 2015 You probably know this but make sure you're considering variable scope and declaring volatile when appropriate. Quote Link to post Share on other sites
roadrunner84 466 Posted April 9, 2015 Share Posted April 9, 2015 Ultimately I want to construct a string of multiple values which can be posted as a JSON value. Which should work fine if you just format it on the line, instead of in memory. I have tried both the examples and the second one is very good, but I am having the same issue with this bit of code - it works fine in a new sketch, but once I add this into my sketch with all the code in, it returns zeros! The same goes for another piece of code suggested there too: This most probably indicates you're running out of memory. If the code is identical in a separate application as in the integrated one, there must be something that hogs your memory and causes some kind of overflow. String pubString7; char buffer1[8]; float diet1 = 40.05; sprintf(buffer1, "%.2f", diet1); pubString7 = "\r\n\Temperature Test : "; pubString7 += buffer1; Serial.println(pubString7); You're not doing the same as I suggested. The essential difference is that in my example the String is declared with all concatenation in place, no concatenation thereafter. As a result, the compiler does never have to reallocate memory, which in worst case could require up to three times the memory for the resulting string. int color = 123; int styleId = 4; String text = "foobar"; Serial.print("{\"color\":\""); Serial.print(color); Serial.print("\", \"style_id\":\""); Serial.print(styleId); Serial.print("\", \"text\":\""); Serial.print(text); Serial.println("\"}"); // {"color":"123", "style_id":"4", "text":"foobar"} What's wrong with this for formatting JSON? Quote Link to post Share on other sites
yellamo 0 Posted April 9, 2015 Author Share Posted April 9, 2015 Thanks @@roadrunner84, The issue is with the float. I can construct the JSON fine in string, but everything after the decimal point in the float is trimmed. static float diet = tmp006.readDieTempC(); //This Displays fine - from standard TMP006 Example Serial.print("Die Temperature: "); Serial.print(diet); Serial.println("*C"); //This example with "long" will only give a value before decimal, as exptected, but I need the exact value eg. 20.12. String pubString = "{\r\n\"abc\":" + String1 + ",\r\n\"temp\":" + long(diet) + ",\r\n\"def\":" + String2 + "\r\n}"; //What I get {"abc":"123456", "temp":"20", "def":"1234"} //What I Need {"abc":"123456", "temp":"20.24", "def":"1234"} I am trying to get the float value of diet into a string, but all efforts within my sketch make it be "0.00". When I try your examples and those from ti.com, they work fine in a new sketch, but not in mine, even if I do this at the very start of the program.. Thanks Quote Link to post Share on other sites
roadrunner84 466 Posted April 10, 2015 Share Posted April 10, 2015 Look at my signature, it says: Never use floating points in embedded systems. It's a bit if a crude statement, but what it means is, floating point types make your system big and slow. Unless you have a floating point processor (which the msp430 does NOT have), try to avoid them wherever possible. If there is no way to read 100ths or 1000ths of degrees as an integer, move away from floating point as fast as possible. int deg, deg100; char diet[8]; deg100 = modf(tmp006.readDieTempC(), °) * 100; sprintf(diet, "%u.%02u", deg, deg100); String pubString = "{\r\n\"abc\":" + String1 + ",\r\n\"temp\":" + diet + ",\r\n\"def\":" + String2 + "\r\n}"; another approach: int raw = tmp006.readRawDieTemperature(); int deg100 = raw * 3 + (raw >> 3); // at this point, deg100 holds 100ths of degrees deg = raw >> 5; deg100 -= deg * 100; Quote Link to post Share on other sites
yellamo 0 Posted April 24, 2015 Author Share Posted April 24, 2015 Hi @@roadrunner84, Sorry for the delay getting back! Thanks for the pointers about the float. I've tried the code, had to change the ints to double as there was an error, and getting the following output - I've got a digital themomethere here and it is showing 21c. double deg, deg100; char diet[8]; deg100 = modf(tmp006.readDieTempC(), °) * 100; sprintf(diet, "%u.%02u", deg, deg100); Serial.print("\r\n\DIET ");Serial.print(diet); The error with the int was as follows: error: cannot convert 'int*' to 'double*' for argument '2' to 'double modf(double, double*)' Thanks Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.