Shop OBEX P1 Docs P2 Docs Learn Events
SD Card help on reading text lines from a file — Parallax Forums

SD Card help on reading text lines from a file

Mike_GTNMike_GTN Posts: 106
edited 2011-03-03 15:05 in Propeller 1
Hi Everyone,

I have a project that would like to use an SD memory card to open a file called Label.txt that will contain
8 lines of text as in: -

One
Two
Three
etc

I do not need to process these lines, above using each one seperately to represent information to a user via LCD on the selection of input 1 to 8. Thus far have tested that my hardware can correctly detect an SD memory card. Really looking for a few pointers on how to accomplish this instead of fully completed code from the forum.

Thank-you for any insight offered.

Mike.

Comments

  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-03-03 14:31
    I reckon Kye's sd driver might be able to do that. http://obex.parallax.com/objects/619/

    There is a fair bit of code in there that you won't need - eg the demo does all sorts of things like play wav files. So it might be a matter of removing bits.

    The 'main' program is the SD3FATDemo and just check that for startup syntax and opening and closing files.

    The routine that does the part you need is in the FATEngine and this is the code
    PUB readString(stringPointer, maximumStringLength) '' 37 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Reads a string from the file that is currently open and advances the file position by the string length.
    '' //
    '' // Returns the next string to read from the file. Reads nothing when at the end of a file.
    '' //
    '' // This function will do nothing if a file is not currently open for reading or writing.
    '' //
    '' // If an error occurs this function will abort and return a pointer to a string describing that error.
    '' //
    '' // This function will stop reading when line feed (ASCII 10) is found - it will be included within the string.
    '' //
    '' // This function will stop reading when carriage return (ASCII 13) is found - it will be included within the string.
    '' //
    '' // StringPointer - A pointer to a string to read to from the file.
    '' // MaximumStringLength - The maximum read string length. Including the null terminating character.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      if(stringPointer and (maximumStringLength > 0))
        result := stringPointer
    
        bytefill(stringPointer--, 0, maximumStringLength--)
        repeat while(maximumStringLength--)
          ifnot( readData(++stringPointer, 1) and byte[stringPointer] and {
               } (byte[stringPointer] <> 10) and (byte[stringPointer] <> 13) )
            quit
    

    One small thing there is that this reads a line and ends with either 13 or 10. If you are reading a line of text, you might want to delete one of those and it will depend on which order they are saved, eg if you file saves 13,10, then you might finish on 10 so you might modify that code to ignore the 13. Or you might use that code as it is, and it reads the line of text, and then maybe the alternate lines return a 10. Perhaps test this as it is very close to what you want. If you can read your text file with a binary reader program (I use hexedit and simply rename .txt files as .bin files) then you can see which order the 13 and 10 are stored.

    There are a lot of things you won't need in Kye's code. The real time clock is optional (it is used for date stamping but works fine without this). You might find the string object useful if you want to process the strings of text.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-03-03 15:05
    Here's a bit of code I used in a test.
    check := \sdcard.popen(@testfile, "r")                        ' attempt to open
      if (check == 0)
        bytefill(@sbuf, 0, BUF_SIZE)                                ' clear buffer
        readln(@sbuf)                                               ' read line from file
        term.str(@sbuf)                                             ' write to terminal  
    
      else
        term.str(string("-- failed to open test file", CR))
    
    
    pub readln(pntr) | c, idx
    
    '' reads line of text from open file
    '' -- terminated by CR or EOF
    
      repeat
        c := sdcard.pgetc                                           ' get a character
        if (c == CR) or (c < 0)                                     ' if CR or EOF we're done
          quit
        else
          byte[pntr++] := c                                         ' else move c to buffer
    
      byte[pntr] := 0                                               ' terminate end of line
    
Sign In or Register to comment.