Pages: 1 [2]   Go Down
Author Topic: reading text from an sd card  (Read 1677 times)
0 Members and 1 Guest are viewing this topic.
Germany
Offline Offline
Faraday Member
**
Karma: 57
Posts: 3005
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Where do you think the bottleneck is?
Is this a trick question ? smiley-wink

SD card speed depends. I read that it gets slower when you delete / create many files often on a card, without re-formatting the card.

What's your result ?

BTW, I would not use String for the filenames, but
Code:
static char filename[] = "fr0#.txt";
 
 for (int tens = '0'; tens< '3'; tens++) {
   for (int ones = '0'; ones <='9'; ones++) {
      filename[3] = ones;
      // open the file for reading:
      myFile = SD.open(filename);
      // etc.
   }
   filename[2]++;
 }

There might be enough space for 30 dynamic Strings besides the 512 byte data, but in a "run forever" scenario it's a bad idea...

And check that your byteCount does not exceed the limit (512) with a bad file
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 124
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is this a trick question ?

Do you mean 'How the * should I know?'. Was just hoping there might be an obvious way, different to my approach, to speed up the reading of each file on the card

It's currently taking 54ms to open,read, then close each (1024byte) file.  This equates to a maximum of 18fps before any further time spent processing.

I came across http://code.google.com/p/fat16lib/ which is an optimised sd library but it only supports fat16 standard sd cards and I don't have one to test. Any idea if this would speed up file opening and reading times?


Using hex instead of csv takes 2/3 of the time, but if there is no delimiter, how do I read in values less than 0xF? ie where there is only one digit...  Can I just write 00 rather than 0 in the text file?


Thanks for your optimised filename code. I wasn't sure how to do it with chars. It's way better!


edit- also, how do I convert a char[] with a value of (for example) 'FF' into an int with a value of 255?
« Last Edit: June 07, 2012, 02:27:32 pm by mrboni » Logged

Germany
Offline Offline
Faraday Member
**
Karma: 57
Posts: 3005
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Using hex instead of csv takes 2/3 of the time, but if there is no delimiter, how do I read in values less than 0xF? ie where there is only one digit...  Can I just write 00 rather than 0 in the text file?
That would have been my approach: Always two chars to one byte.
Quote
how do I convert a char[] with a value of (for example) 'FF' into an int with a value of 255?
Code:
byte b = bin(c[0])<<4+bin(c[1]);

byte bin(char c)
{
  if (c >='A') return c-'A'+10;
  else return c-'0';
}

This method bin() only works for '0' ...'9' , 'A' ... 'F' . Every other character, including spaces or 'a' ... 'f' produces garbage.

BTW: If it's for absolute speed optimization, my first approach (file size does not matter) might be wrong: You might prefer binary files over human readable files.
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 124
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Michael

I've actually got it working using ascii codes, running at 25 fps for a 512byte (and 512 value) file

Attached code shows it controlling a string of ws2801 led driver chips

Seems to be a memory leak though as it stops running after a few seconds.  So close smiley

Code:
#include <SD.h>
#include "SPI.h"
#include "Adafruit_WS2801.h"


int dataPin  = 2;    // Yellow wire on Adafruit Pixels
int clockPin = 3;    // Green wire on Adafruit Pixels

Adafruit_WS2801 strip = Adafruit_WS2801(170, dataPin, clockPin);



File myFile;

unsigned long millisPre;
unsigned long millisPost;
int testLoopCount;

void setup()
{
  strip.begin();
  // Update LED contents, to start they are all 'off'
  strip.show();
 
 
  Serial.begin(57600);
  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output
  // or the SD library functions will not work.
   pinMode(53, OUTPUT);
   
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
 

   
  unsigned char testBuff[513];
  int testBuffInt[512];
 
  Serial.println("beginning read");
  millisPre = millis();
  //Serial.println(millisPre);
   
 
 
  testLoopCount = 30;
 
  for(int cycles = 0; cycles < testLoopCount; cycles++)
  {
   
    static char filename[] = "fr0#.txt";
 
   for (int tens = '0'; tens< '3'; tens++)
   {
     for (int ones = '0'; ones <='9'; ones++)
     {
        filename[3] = ones;
        // open the file for reading:
        myFile = SD.open(filename);
        if (myFile)
        {
          //Serial.println(filename);
         
          // read from the file until there's nothing else in it:
          int byteCount = 0;
          while (myFile.available())
          {
            testBuff[byteCount] = myFile.read();
            //testBuffInt[byteCount] =(int)testBuff[byteCount];
            byteCount++;
          }
          testBuff[byteCount] = NULL;
         
         
          //set ws2801 pixels
          for(int i=0;i<512;i++)//channel position
          {
            strip.setPixelColor(i,(int)testBuff[i*3],(int)testBuff[i*3+1],(int)testBuff[i*3+2]);
          }
          strip.show();
         
         
          // close the file:
          myFile.close();
        }
        else
        {
          // if the file didn't open, print an error:
          Serial.print("error opening ");
          Serial.print(filename);
          Serial.println(" test.txt");
        }
      }
        filename[2]++;
    }
   
    filename[2] = '0';
    filename[3] = '#';

   
  }
   Serial.println();
   millisPost = millis();
   //Serial.println(millisPost);
   Serial.println((millisPost-millisPre)/testLoopCount);
   

   
   
}



void loop()
{
// nothing happens after setup
}

Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your two testBuffs use 3/4 of your available SRAM. Probably the SD library has some buffer too, so I'm not surprised you ran out of memory. As far as I saw in a quick overview testBuffInt is not used but consumes half of your memory.

BTW: why storing the read values in an array and not directly putting them into the strip?
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 124
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Pylon, that's a good point about the array.

Turns out it's not freezing though (yet)  - I'd set it to only loop 30 times as a test. Duh
Logged

Pages: 1 [2]   Go Up
Jump to: