Read unsigned long from SDcard

Hi,

I'm working on a counting project with some backup functions to SDCard. I do the counting with a unsigned long. (must count from 0 to 1.000.000). Writh the long to a SDCard is no problem but read them and reload is a problem when my counts are above 65.535. The problem is to convert my data from SDCard to unsigned long. I know there must be a wat with strtoul() but than my data must be in a char array. but mine is in string after i got all data. Can someone help me?

Board: Mega 2560
Shield: Ethernet v3

Below here is a part of my code where i need to do this.

unsigned long counter1 = 0;
void sdcard_loadbackup(){
    File teller1_file;
    String teller1_read = "";

    if(SD.exists("teller1.txt")){
        Serial.println("backup counter found.. loading");
        teller1_file = SD.open("teller1.txt");
        while(teller1_file.available()){
            char chRead = teller1_file.read();
            if(chRead != '\n'){
                teller1_read += chRead;
            }
        }
        if(teller1_read.length() > 7){
            Serial.println("1000000 is the max i want to count so if it's bigger than load 0 count");
            sdcard_createNew(1);
        }
        else{
            // Here i must convert [String teller1_read] to unsigned long
            counter1 = teller1_read.toInt(); // int - must be long
        }
    }
}

Read it as a char* and then use strtoul() (STRing TO Unsigned Long)

NAME
       strtoul - convert a string to an unsigned long integer

SYNOPSIS
       unsigned long int strtoul(const char *nptr, char **endptr, int base);

DESCRIPTION
       The  strtoul()  function  converts  the  initial  part of the string in nptr to an unsigned long int value
       according to the given base, which must be between 2 and 36 inclusive, or be the special value 0.

       The string may begin with an arbitrary amount of white space (as determined by isspace(3)) followed  by  a
       single  optional  '+'  or '-' sign.  If base is zero or 16, the string may then include a "0x" prefix, and
       the number will be read in base 16; otherwise, a zero base is taken as 10 (decimal) unless the next  char‐
       acter is '0', in which case it is taken as 8 (octal).

       The  remainder of the string is converted to an unsigned long int value in the obvious manner, stopping at
       the first character which is not a valid digit in the given base.  (In bases above 10, the letter  'A'  in
       either upper or lower case represents 10, 'B' represents 11, and so forth, with 'Z' representing 35.)

       If  endptr  is not NULL, strtoul() stores the address of the first invalid character in *endptr.  If there
       were no digits at all, strtoul() stores the original value of nptr in *endptr (and returns 0).  In partic‐
       ular, if *nptr is not '\0' but **endptr is '\0' on return, the entire string is valid.

but than my data must be in a char array. but mine is in string after i got all data.

No, it isn't. It's in a String, which is nowhere near the same thing as a string.

And, it needn't be in a String. You know how many characters are in the value. You know how big the NULL-terminated char array would need to be. So, ditch the String class and learn to use c-strings.

Can someone help me?

What is your problem? The toInt() method of the String class is piss-poorly named, like a lot of things about the String class. It really returns a long.

majenko:
Read it as a char* and then use strtoul() (STRing TO Unsigned Long)

Yes i know i must read the SDCard .txt as a char* but how? I know how to read 1 char from it but how do i put read the next char withoud losing my first char. I only know a way to do that to put all chars 1 by 1 in a string like i do on line 11 to 13. Can someone help me with that part?

PaulS:

but than my data must be in a char array. but mine is in string after i got all data.

No, it isn't. It's in a String, which is nowhere near the same thing as a string.

  • Sorry i'm i was thinking string is the same as String. I meant String.

PaulS:
And, it needn't be in a String. You know how many characters are in the value. You know how big the NULL-terminated char array would need to be. So, ditch the String class and learn to use c-strings.

Sorry, i don't know how many chars there are in my sdcard.
when there are 100 counts there is a backup with 3 chars.
When there are 4000 counts there is a backup with 4 chars.
I have only a max of 7 chars because 1.000.000 is the max of my counter.

PaulS:

Can someone help me?

What is your problem? The toInt() method of the String class is piss-poorly named, like a lot of things about the String class. It really returns a long.

My problem is that i wanted to use the strtoul() because i was thinking that my toInt() has a max of 65.535 because thats the max of an unsigned integer on the arduino. Just tested this and yes it works on my script, but still i like to know how to read and keep the data as a char instead of a String like i do now.

But thanks for advice you both.

By placing each character, as you read it, into a character array.

You know the MAXIMUM number of characters you can have (7), so you can size your array to fit that number of characters, plus a NULL character.

Then you can read each character and place them in order into the array until you either reach 7 characters or run out of characters. Then you have it as a string (character array) that you can use strtoul() with.

And don't forget the terminating NULL character (simplest way is to zero the array out first).

You can store your data on the SDcard as either text or as actual binary numbers. You can do either. But you must write it and then read it in the same way.