String to unsigned long

Hello, im recieving an error that I can't convert a string to an unsigned long.

Ive been looking for a solution for a while now but I haven't found any.

Here's the code im using

unsigned long value = 0;
String woord = "";
String last = "";

void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
 
  if (Serial.available() > 0) {    // is a character available?
    
    woord = Serial.readString();// get the character
    if (woord.startsWith("TIJD"))
    {
      woord.replace("TIJD","");
      woord.trim();
      Serial.println(woord);
      value = woord;
    }

    if (woord.startsWith("zonlicht="))
    {
      woord.replace("zonlicht=","");
      woord.trim();
      Serial.println(woord);
      value = woord;
    }
 
  
}

It gives me this error : cannot convert 'String' to 'long unsigned int' in assignment

It gives me this error : cannot convert 'String' to 'long unsigned int' in assignment

value is an unsigned long
woord is a String

As usual, the compiler does not lie

If you used strings (lowercase s) rather than Strings, then you could use the strtol() function

UKHeliBob:
value is an unsigned long
woord is a String

As usual, the compiler does not lie

If you used strings (lowercase s) rather than Strings, then you could use the strtol() function

Is there a difference between "string" and "String"?
"string" does not have a variable type. How do I use the strtol() function? Ive never heard of it before.

Is there a difference between “string” and “String”?

A String (uppercase S) is an object created by the String library
A string (lowercase s) is an array of chars terminated by a zero

It is generally not recommended to use Strings in the small memory footprint of many microcontrollers although there are some who disagree

Take a look at Serial input basics - updated for some examples of how to use and parse strings

UKHeliBob:
A String (uppercase S) is an object created by the String library
A string (lowercase s) is an array of chars terminated by a zero

It is generally not recommended to use Strings in the small memory footprint of many microcontrollers although there are some who disagree

Take a look at Serial input basics - updated for some examples of how to use and parse strings

I'll just stick with the String because I have enough memory for it but I understand why you would use a string instead.
Ive taken a look at the strtol() function but when I try to use it and fill in the variables (String woord) and (Unsigned long value) it says "end" is not declared. Am i supposed to add a library or something because I can't find what end is supposed to be.

strtol() will not work with Strings so stop trying

Try this

void setup()
{
  Serial.begin(115200);
  String theString = "12345";
  unsigned long theLong = strtol(theString.c_str(), NULL, 10);
  Serial.println(theLong);
}

void loop()
{
}

you could simply use toInt() for now, which returns a 'long'

Im gonna post a new message under here because I messed up with the coding brackets that vanished now…

You can safely continue to use Strings (cap S).
Check out my Taming Arduino Strings tutorial for the details

Deva_Rishi:
you could simply use toInt() for now, which returns a 'long'

So like this you mean? (I will test it later because I don't have my arduino with me right now)

unsigned long value = 0;
String woord = "";
String last = "";

void setup()
{
  Serial.begin(9600);
}

void loop()
{
 
  if (Serial.available() > 0) {    // is a character available?
   
    woord = Serial.readString();// get the character
    if (woord.startsWith("TIJD"))
    {
      woord.replace("TIJD","");
      woord.trim();
      Serial.println(woord);
      value = woord;
    }

    if (woord.startsWith("zonlicht="))
    {
      woord.replace("zonlicht=","");
      woord.trim();
      Serial.println(woord);
      woord.toInt(value);
    }
}

drmpf:
You can safely continue to use Strings (cap S).
Check out my Taming Arduino Strings tutorial for the details

I'll defenitely check that out thank you!

So like this you mean?

If you look at the link to the arduino reference properly you will see that the proper usage is :value = woord.toInt();
Keep in mind that toInt() returns '0' if no valid value is found, and from the reference

Converts a valid String to an integer. The input String should start with an integer number. If the String contains non-integer numbers, the function will stop performing the conversion.

Deva_Rishi:
If you look at the link to the arduino reference properly you will see that the proper usage is :

value = woord.toInt();

Keep in mind that toInt() returns '0' if no valid value is found, and from the reference

Oh okay,

"

Converts a valid String to an integer. The input String should start with an integer number. If the String contains non-integer numbers, the function will stop performing the conversion.

Does this also applies when the string gets filtered?

Try this code. It avoids the readString() which blocks the loop waiting for end of input. And fixes some compile errors.
Also adds a check for the not very reliable toInt() to see that the String really is a number

BUT, this code expects the input to end with NL (or CR NL) so set the IDE monitor accordingly.
You can add a timeout as well, but that is more code.
You can add checks for missing NL, but that is more code also.

unsigned long value = 0;
String woord = "";
String last = "";

void setup()
{
  Serial.begin(9600);
  for (int i = 10; i > 0; i--) {
    Serial.print(i); Serial.print(' ');
    delay(500);
  }
  Serial.println();
}

// stopC is the char to stop at
// returns true when get stopC and input contains the input up to then
// else return false
bool readStrUntil(char stopC, String& input) {
  while (Serial.available()) {
    char c = Serial.read();
    if (c == stopC) {
      return true;
    }
    // else
    input += c; // good for >1000 char lines on UNO
  }
  return false;
}

void processLine(String& line) {
  line.trim();
  Serial.println(line);
  if (line.startsWith("TIJD"))
  {
    line.replace("TIJD", "");
    line.trim();
    Serial.println(line);
    //value = woord; // need to use toInt to convert String to number
  }

  if (line.startsWith("zonlicht="))
  {
    line.replace("zonlicht=", "");
    line.trim();
    Serial.println(line);
    value = line.toInt();
    if (String(value) != line) { // check toInt conversion
      // for very long numbers, will return garbage, non numbers returns 0
      Serial.print(F("not a long: ")); Serial.println(line);
    }
  }
}

void loop()
{
  if (readStrUntil('\n', woord)) { // does not block loop
    // have word
    processLine(woord);
    woord = ""; // clear for next line
  }
}

Does this also applies when the string gets filtered?

Yes toInt() is not very robust. The low level strtol is better but requires more code
My SafeString library has a very robust toLong( ) method that wraps up strtol and includes the extra code.
But the code in my last post works as well.

@OP

1. Upload the following sketch onto UNO.

unsigned long value = 0;
String woord = "";
String last = "";

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available() > 0)
  { // is a character available?

    woord = Serial.readString();// get the character
    if (woord.startsWith("TIJD"))
    {
      woord.replace("TIJD", "");  //replace TIJD by 0x00s
      woord.trim();   //remove all leading and trailing spaces
      Serial.println(woord);  //show the received string
      value = woord.toInt();//convert numeral string into interger  value (0 to 4294967295)
      Serial.println(value, DEC); //show the integer value
    }

    if (woord.startsWith("zonlicht="))
    {
      woord.replace("zonlicht=", "");
      woord.trim();
      Serial.println(woord);
      value = woord.toInt();
      Serial.println(value, DEC);
    }
  }
}

2. Open the Serial Monitor.
3. In the InputBox of the Serial Monitor (Fig-1) enter the following string and then click on the Send button. Select "No line ending" option for the "Line ending tab'.

TIJD 4294967295


Figure-1: Layout of Serial Monitor

4. Check that the following message has appeared on the OutputBox of the Serial Monitor.
4294967295 //Shows in response to: Serial.println(woord);
4294967295 //shows in response to Serial.prinln(value, DEC);

Oh okay,

The main thing to keep in mind is that when '0' is a valid input, '0' may also indicate that there has been an invalid input. Eventually one most assume that the (end) user may not always do what you expect, but as long as you are the end user, you don't have to worry. The question is "Would '0' be a valid input ?"

It is not just zero you need to ‘worry’ about. -ve and large strings are a problem also
My code above handled most of that but the method below method handles all of it
replace
line.toInt()
with

  if (!strToUnsignedLong(line,value)) {
      Serial.print(F("number not an unsigned long: ")); Serial.println(line);      
  }

Typical output

zonlicht=3434k3kj34lj34
3434k3kj34lj34
number not an unsigned long: 3434k3kj34lj34
zonlicht=-33
-33
number not an unsigned long: -33
zonlicht=5678901234567890
5678901234567890
number not an unsigned long: 5678901234567890
 // a valid input
zonlicht=45366
45366
bool strToUnsignedLong(String& data, unsigned long& result) {
  data.trim();
  long tempResult = data.toInt();
  if (String(tempResult) != data) { // check toInt conversion
    // for very long numbers, will return garbage, non numbers returns 0
   // Serial.print(F("not a long: ")); Serial.println(data);
    return false;
  } else if (tempResult < 0) { //  OK check sign
   // Serial.print(F("not an unsigned long: ")); Serial.println(data);
    return false;
  } //else
  result = tempResult;
  return true;
}

GolamMostafa:
@OP

1. Upload the following sketch onto UNO.

unsigned long value = 0;

String woord = "";
String last = "";

void setup()
{
 Serial.begin(9600);
}

void loop()
{
 if (Serial.available() > 0)
 { // is a character available?

woord = Serial.readString();// get the character
   if (woord.startsWith("TIJD"))
   {
     woord.replace("TIJD", "");  //replace TIJD by 0x00s
     woord.trim();   //remove all leading and trailing spaces
     Serial.println(woord);  //show the received string
     value = woord.toInt();//convert numeral string into interger  value (0 to 4294967295)
     Serial.println(value, DEC); //show the integer value
   }

if (woord.startsWith("zonlicht="))
   {
     woord.replace("zonlicht=", "");
     woord.trim();
     Serial.println(woord);
     value = woord.toInt();
     Serial.println(value, DEC);
   }
 }
}



**2.** Open the Serial Monitor.
**3.** In the InputBox of the Serial Monitor (Fig-1) enter the following string and then click on the Send button. Select "No line ending" option for the "Line ending tab'.

TIJD 4294967295

![SerialMonitorX.png|746x474](upload://ekt4vqUAiGFuKMULT7uTZHW7sHg.png)
Figure-1: Layout of Serial Monitor

**4.** Check that the following message has appeared on the OutputBox of the Serial Monitor.
4294967295 //Shows in response to: Serial.println(woord);
4294967295 //shows in response to Serial.prinln(value, DEC);

Ok, i'll try that tomorrow!

For comparison here is the output of toInt()

zonlicht=3434k3kj34lj34
3434

zonlicht=-33
4294967263

zonlicht=5678901234567890
986516178

lots of bad input gets through so not a good choice.

lots of bad input gets through so not a good choice.

My suggestion would be, that if toInt() is not sufficient for the purpose you want it for, you can write your own function. Creating a conversion function is highly educative, and you can make it so it exactly does what you want. Of course someone else has already done this and you can use that function just as well. (keep in mind that when using safestrings, you can only expect support from 1 person)