Problem with Integer Conversion

I'm trying to implement some code I found on the net for doing updates to the Arduino via HTTP. The author advises putting the bin file along with a text file containing the version number in an HTTP accessible folder. The Arduino then downloads the contents of the version file, converts it to an integer, and compares it to the version number of the current firmware, before deciding whether to download the update.

I'm hitting a snag at conversion from string to integer. If I use

String firmwareVersionAvailableString = httpClient.getString();

and

long firmwareVersionAvailable = firmwareVersionAvailableString.toInt();

I get a zero for the integer.

I tried to troubleshoot by checking the string with

Serial.println( firmwareVersionAvailableString );

before conversion and everything looks okay. I also checked the conversion by bypassing the HTTP and manually entering the string with

String firmwareVersionAvailableString = "2020010101";

and the string converts fine in that case.

With those options being eliminated, I'm guessing that there's something in my text file that's goofing up the string in a way I can't see. But I have no idea what it could be. Any help would be appreciated.

The original code is at Self-updating OTA firmware for ESP8266 – OppoverBakke

My version of the code is

void otaUpdateCheck() {
 String firmwareURL = String( SECRET_otaUpdateLocation );
 firmwareURL.concat( unitFirmwareCode );
 String firmwareVersionURL = firmwareURL;
 firmwareVersionURL.concat( ".version" );

 Serial.print( "checking for firmware updates for " );
 Serial.println( unitFirmwareCode );
 Serial.print( "at " );
 Serial.println( firmwareVersionURL );
 Serial.println();

 HTTPClient httpClient;
 httpClient.begin( clientWiFiOTAUpdate, firmwareVersionURL );
 int httpCode = httpClient.GET();
 if( httpCode == 200 ) {
 String firmwareVersionAvailableString = httpClient.getString();
 long firmwareVersionAvailable = firmwareVersionAvailableString.toInt();

 Serial.print( "current firmware version: " );
 Serial.println( firmwareVersionCurrent );
 Serial.print( "available firmware version: " );
 Serial.println( firmwareVersionAvailable );
 Serial.println();

 if( firmwareVersionAvailable > firmwareVersionCurrent ) {
 
 Serial.println( "new version available" );
 Serial.println( "performing update" );

 String firmwareImageURL = firmwareURL;
 firmwareImageURL.concat( ".bin" );
 
 #ifdef ESP8266
 
 t_httpUpdate_return ret = ESPhttpUpdate.update( clientWiFiOTAUpdate, firmwareImageURL );

 switch(ret) {
 
 case HTTP_UPDATE_FAILED:
 Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
 break;

 case HTTP_UPDATE_NO_UPDATES:
 Serial.println("HTTP_UPDATE_NO_UPDATES");
 break;
 
 }
 
 #endif

 #ifdef ESP32
 
 t_httpUpdate_return ret = httpUpdate.update( clientWiFiOTAUpdate, firmwareImageURL );

 switch(ret) {
 
 case HTTP_UPDATE_FAILED:
 Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
 break;

 case HTTP_UPDATE_NO_UPDATES:
 Serial.println("HTTP_UPDATE_NO_UPDATES");
 break;
 
 }
 
 #endif
 
 }
 
 else {
 
 Serial.println( "already latest version" );
 Serial.println( "skipping update" );
 
 }
 
 Serial.println();
 
 }
 
 else {
 
 Serial.println( "firmware version check failed" );
 Serial.print( "HTTP response code " );
 Serial.println( httpCode );
 Serial.println();
 
 }
 
 httpClient.end();
}

What do you see when you print out the String before .toInt()

my code is

Serial.print( "version string: " );
Serial.println( firmwareVersionAvailableString );

and the serial monitor outputs

version string: 2020010101

What arduino are you using? That number maybe too big for a 16-bit int.

Try this:

long firwareVersionAvailable = atol(firwareVersionAvailableString.c_str());

Thanks for the help.

I'm using an LOLIN D32 Pro, but I'm pretty sure it's not an issue of it being too long because A) I am using a long and not a plain integer and B) if I bypassing the httpClient.getString(); and instead create the string manually (see my note in the first post), the conversion works just fine.

I also tried your suggestion, but no luck. :frowning: (And in case anyone's wondering I did catch the typo "firware" > "firmware"

cweinhofer:
Thanks for the help.

I'm using an LOLIN D32 Pro, but I'm pretty sure it's not an issue of it being too long because A) I am using a long and not a plain integer and B) if I bypassing the httpClient.getString(); and instead create the string manually (see my note in the first post), the conversion works just fine.

I also tried your suggestion, but no luck. :frowning: (And in case anyone's wondering I did catch the typo "firware" > "firmware"

Alright, maybe there's a weird character in the beginning of the string. Try this:

Serial.print("Length: ");
Serial.print(firmwareVersionAvailableString.length());
Serial.println( firmwareVersionAvailableString );

Try to count if the length reported is matched.

I jut solved it and it turned out to be something simple. I switched the text file from UTF8 to ANSI and now everything works.

If anyone can explain why UTF8 would have produced a String that looked okay but didn't convert, I'm sure it would be helpful for others in the future.

But otherwise, we can consider this solved. Thank again for your help!

I suspect there may have been characters in your file that don't exist in the "ANSI" character encoding (which is what Microsoft probably means by "Windows-1252"), and when you convert to "ANSI" in your text editor, those characters were either removed or converted to the most similar character.

For example, a non-breaking space (U+00A0), word joiner (U+2060), figure space (U+2007), thin space (U+2009), or narrow no-break space (U+202F) might all either be removed or converted to a normal space (U+0020).

This is all speculation, of course. If you posted the original (UTF-8) file and the converted (ANSI) file, we could inspect it and maybe give you a more definitive answer to that question.

I suspect there is a byte order mark (U+FEFF, UTF-8 sequence EF BB BF) in the beginning of the file.

I hadn't considered that. Some text editors do indeed include a BOM for UTF-8. Some editors like Notepad++ can convert to UTF-8 with or without the BOM. I don't think I've ever used the BOM option.

I think you hit it. Notepad++ is my default editor and for some reason I have UFT-8 with BOM set as the default.

This would explain a few other quirky things I've experienced creating files for Aduino as well... :confused: