Home > front end >  Arduino String.toInt() function wrongly converts to uint32_t
Arduino String.toInt() function wrongly converts to uint32_t

Time:12-13

I have a webserver running on an ESP32-Wrover_E. A user's session id is stored in cookie format. This session ID is coming from esp_random() function which returns an uint32_t type integer. It is being set on log in. When a user goes to any page or reloads it, the http route will check the session ID from the cookie. Sometimes it is matching, other times not.

I have created a wokwi sketch to represent the problem. toInt() function often times does not convert a String to uint32_t properly.

#include <Arduino.h>

void setup() {
  Serial.begin(115200);

  String user_session = "2227761735"; // <-- This number comes from esp_random();
  uint32_t sessionID = user_session.toInt();
  Serial.printf("String session: %s, uint32_t session: %lu\n",user_session,sessionID);
}

void loop() {
  vTaskDelay(1);
}

Here is a link to wokwi where you can see it yourself: https://wokwi.com/projects/342242993672028755

Here is the esp_random() function documentation: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/random.html

How can i convert a String to uint32_t?

EDIT:

If you run this code at wokwi you can see that there are errors in the conversion:

void setup() {
  Serial.begin(115200);

  String user_session = "2227761735";
  uint32_t sessionID = user_session.toInt();
  Serial.printf("String session: %s, uint32_t session: %lu\n", user_session, sessionID);
}


boolean isConvertSuccess(uint32_t originalInteger, uint32_t convertedInteger) {
  if ( originalInteger == convertedInteger ) {
    return true;
  }
  return false;
}

long lastTestMS = 0;
void testSessionStringToInt() {
  if ( millis() - lastTestMS >= 2000 ) {
    lastTestMS = millis();

    uint32_t newSessionID = esp_random();
    Serial.println("\n**********");
    Serial.printf("newSessionID: %lu\n", newSessionID);
    String sessionComingFromA_Cookie = String(newSessionID);
    Serial.printf("sessionComingFromA_Cookie: %s\n", sessionComingFromA_Cookie);
    uint32_t convertedIntFromCookieString = sessionComingFromA_Cookie.toInt();
    Serial.printf("convertedIntFromCookieString: %lu\n", convertedIntFromCookieString);

    Serial.printf(
      "Conversion was: %s\n",
      isConvertSuccess(newSessionID, convertedIntFromCookieString) ? "success" : "failed"
    );

    Serial.println("**********");
  }
}

void loop() {
  delay(10);
  testSessionStringToInt();
}

CodePudding user response:

Thanks to @hcheung i just had to convert the uint32_t esp_random() to long and use long everywhere. Here is a link to the corrected wokwi ( where every uint32_t became a long, including the printf("%lu") to printf("%ld") since its not an unsigned ): https://wokwi.com/projects/342242993672028755

And here is the corrected code:

void setup() {
  Serial.begin(115200);

  String user_session = "2227761735";
  long sessionID = (long)user_session.toInt();
  Serial.printf("String session: %s, uint32_t session: %ld\n", user_session, sessionID);
}


boolean isConvertSuccess(long originalInteger, long convertedInteger) {
  if ( originalInteger == convertedInteger ) {
    return true;
  }
  return false;
}

long lastTestMS = 0;
void testSessionStringToInt() {
  if ( millis() - lastTestMS >= 2000 ) {
    lastTestMS = millis();

    long newSessionID = (long)esp_random();
    Serial.println("\n**********");
    Serial.printf("newSessionID: %ld\n", newSessionID);
    String sessionComingFromA_Cookie = String(newSessionID);
    Serial.printf("sessionComingFromA_Cookie: %s\n", sessionComingFromA_Cookie);
    long convertedIntFromCookieString = sessionComingFromA_Cookie.toInt();
    Serial.printf("convertedIntFromCookieString: %ld\n", convertedIntFromCookieString);

    Serial.printf(
      "Conversion was: %s\n",
      isConvertSuccess(newSessionID, convertedIntFromCookieString) ? "success" : "failed"
    );

    Serial.println("**********");
  }
}

void loop() {
  delay(10);
  testSessionStringToInt();
}
  • Related