SD.exists

Hi!

I am having problems applying SD.exists to one of my projects, so I decided to try it with the very basics:

#include <SD.h>
#include <SPI.h>

#define SDssPin 4

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

void loop() {
  if (SD.exists("1.bmp")) {
    Serial.println("exists");
  }
}

This piece of code doesnt work. I am expecting to read “exists” in the serial monitor and I get nothing.

I know that the sd card is well connected and working and that the file 1.bmp exists, and I am certain about it after checking it with the “Cardinfo” example, from the sd library.

somebody knows about this?

This piece of code doesnt work. I am expecting to read "exists" in the serial monitor and I get nothing.

Why do you expect that? Have you any proof that the file exists?

Why is there no else clause?

I know that the sd card is well connected and working and that the file 1.bmp exists, and I am certain about it after checking it with the "Cardinfo" example, from the sd library.

The file exists in what directory? What directory is SD.exists() looking for it in?

camilozk:
Hi!

I am having problems applying SD.exists to one of my projects, so I decided to try it with the very basics:

#include <SD.h>

#include <SPI.h>

#define SDssPin 4

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

void loop() {
 if (SD.exists(“1.bmp”)) {
   Serial.println(“exists”);
 }
}




This piece of code doesnt work. I am expecting to read "exists" in the serial monitor and I get nothing.


I know that the sd card is well connected and working and that the file 1.bmp exists, and I am certain about it after checking it with the "Cardinfo" example, from the sd library.

somebody knows about this?

You forgot to initialize the SD card using the SD.begin() function in setup(), didn’t you?

Perhaps look up some simple SD example programs how to use SD card with Arduinos SD library!

You forgot to initialize the SD card using the SD.begin() function in setup(), didn’t you?

I did. thanks for noticing. it does work

You forgot to initialize the SD card using the SD.begin() function in setup(), didn’t you?

I am. thanks for your advice

I am working on a project in which I cannot make sense of whats wrong.

camilozk:
very weird…

this works:

  if (SD.exists(stringOne += stringTwo)) {

Serial.println(“exists”);
 }




this also works:



SendFile(stringOne += stringTwo);
 }




but this doesnt work:



if (SD.exists(stringOne += stringTwo)) {
   SendFile(stringOne += stringTwo);
 }

I suspect that it's this line

stringOne += stringTwo

Why is there an equal sign in there?

You replace stringOne by a concatenation of the stringOne and stringTwo. And you do that a second time.

If you're clever, you use some Serial.println statement.

Serial.println("before if");
Serial.print("stringOne: "); Serial.println(stringOne);
Serial.print("stringTwo: "); Serial.println(stringTwo);
if (SD.exists(stringOne += stringTwo)) {
  Serial.println("Before SendFile");
  Serial.print("stringOne: "); Serial.println(stringOne);
  Serial.print("stringTwo: "); Serial.println(stringTwo);

  SendFile(stringOne += stringTwo);


  Serial.println("after SendFile");
  Serial.print("stringOne: "); Serial.println(stringOne);
  Serial.print("stringTwo: "); Serial.println(stringTwo);
}

Oh, and get rid of String (with capital S) before it's too late and you run into unexplainable behaviour of your code.

Why is there an equal sign in there?

Well because I am an ignorant and I copied this piece of code from somewhere else and it ruined my sunday.
That was my problem. Now it runs ok. thanks for spoting it!

get rid of String (with capital S) before it’s too late and you run into unexplainable behaviour of your code.

If I do, the compilation fails and return “‘string’ does not name a type”

If I do, the compilation fails and return "'string' does not name a type"

A string is a NULL terminated array of chars.

so I have this loop:

void loop() {
  int buttonstate = digitalRead(buttonPin);

  stringOne = String(numberFile);
  stringTwo = String(".bmp");

  if (buttonstate == HIGH) {
    numberFile++;
    delay (1000);
  }

  if (SD.exists(stringOne + stringTwo)) {
    Serial.println(stringOne + stringTwo);
    SendFile(stringOne + stringTwo);
  }
  
  else {
    SendFile("1.bmp");
    int numberFile = 1;
  }
}

the idea is to increase one by one numberFile, so sendFile sends 1.bmp, 2.bmp, 3.bmp, etc, and when it doesnt find a file, goess back to 1.bmp. but it is not working. I have 4 files in the sd card, so when numberFile gets to 5, 1.bmp is being sent, but numberFile is not being set back to 1

I copy here the whole code:

#include <Adafruit_NeoPixel.h>
#include <SD.h>
#include <SPI.h>

#define SDssPin 4     //arduino nano
//#define SDssPin 53    //arduino mega

int NPPin = 6;        //arduino nano
//int NPPin = 23;       //arduino mega

//int ColorSeq = NEO_RGB;
int ColorSeq = NEO_GRB;

int BitstreamFreq = NEO_KHZ800;     //ws2812b
//int BitstreamFreq = NEO_KHZ400;     //ws2811

int g = 0;
int b = 0;
int r = 0;

#define STRIP_LENGTH 3

int frameDelay = 10;
int brightness = 100;

byte x;

int buttonPin = 2;
int numberFile = 1;
String stringOne, stringTwo;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(STRIP_LENGTH, NPPin, ColorSeq + BitstreamFreq);

File dataFile;


void setup() {
  Serial.begin(9600);
  strip.begin();
  strip.show();
  setupSDcard();
  pinMode(buttonPin, INPUT);
}


void loop() {
  int buttonstate = digitalRead(buttonPin);

  stringOne = String(numberFile);
  stringTwo = String(".bmp");

  if (buttonstate == HIGH) {
    numberFile++;
    delay (1000);
  }

  if (SD.exists(stringOne + stringTwo)) {
    Serial.println(stringOne + stringTwo);
    SendFile(stringOne + stringTwo);
  }
  
  else {
    SendFile("1.bmp");
    int numberFile = 1;
  }
}


void setupSDcard() {
  pinMode(SDssPin, OUTPUT);
  while (!SD.begin(SDssPin)) {
  }
}


void SendFile(String Filename) {
  char temp[14];
  Filename.toCharArray(temp, 14);

  dataFile = SD.open(temp);

  if (dataFile) {
    ReadTheFile();
    dataFile.close();
  }
  else {
    delay(1000);
    setupSDcard();
    return;
  }
}


/*
  void ClearStrip(int duration) {
  int x;
  for (x = 0; x < STRIP_LENGTH; x++) {
    strip.setPixelColor(x, 0);
  }
  strip.show();
  }
*/


uint32_t readLong() {
  uint32_t retValue;
  byte incomingbyte;

  incomingbyte = readByte();
  retValue = (uint32_t)((byte)incomingbyte);

  incomingbyte = readByte();
  retValue += (uint32_t)((byte)incomingbyte) << 8;

  incomingbyte = readByte();
  retValue += (uint32_t)((byte)incomingbyte) << 16;

  incomingbyte = readByte();
  retValue += (uint32_t)((byte)incomingbyte) << 24;

  return retValue;
}


uint16_t readInt() {
  byte incomingbyte;
  uint16_t retValue;

  incomingbyte = readByte();
  retValue += (uint16_t)((byte)incomingbyte);

  incomingbyte = readByte();
  retValue += (uint16_t)((byte)incomingbyte) << 8;

  return retValue;
}


int readByte() {
  int retbyte = -1;
  while (retbyte < 0) retbyte = dataFile.read();
  return retbyte;
}


void getRGBwithGamma() {
  g = gamma(readByte()) / (101 - brightness);
  b = gamma(readByte()) / (101 - brightness);
  r = gamma(readByte()) / (101 - brightness);
}


void ReadTheFile() {
#define MYBMP_BF_TYPE           0x4D42
#define MYBMP_BF_OFF_BITS       54
#define MYBMP_BI_SIZE           40
#define MYBMP_BI_RGB            0L
#define MYBMP_BI_RLE8           1L
#define MYBMP_BI_RLE4           2L
#define MYBMP_BI_BITFIELDS      3L

  uint16_t bmpType = readInt();
  uint32_t bmpSize = readLong();
  uint16_t bmpReserved1 = readInt();
  uint16_t bmpReserved2 = readInt();
  uint32_t bmpOffBits = readLong();
  bmpOffBits = 54;

  /* Check file header */
  if (bmpType != MYBMP_BF_TYPE || bmpOffBits != MYBMP_BF_OFF_BITS) {
    delay(1000);
    return;
  }

  /* Read info header */
  uint32_t imgSize = readLong();
  uint32_t imgWidth = readLong();
  uint32_t imgHeight = readLong();
  uint16_t imgPlanes = readInt();
  uint16_t imgBitCount = readInt();
  uint32_t imgCompression = readLong();
  uint32_t imgSizeImage = readLong();
  uint32_t imgXPelsPerMeter = readLong();
  uint32_t imgYPelsPerMeter = readLong();
  uint32_t imgClrUsed = readLong();
  uint32_t imgClrImportant = readLong();

  /* Check info header */
  if ( imgSize != MYBMP_BI_SIZE || imgWidth <= 0 ||
       imgHeight <= 0 || imgPlanes != 1 ||
       imgBitCount != 24 || imgCompression != MYBMP_BI_RGB ||
       imgSizeImage == 0 )
  {
    delay(1000);
    return;
  }

  int displayWidth = imgWidth;
  if (imgWidth > STRIP_LENGTH) {
    displayWidth = STRIP_LENGTH;
  }


  /* compute the line length */
  uint32_t lineLength = imgWidth * 3;
  if ((lineLength % 4) != 0)
    lineLength = (lineLength / 4 + 1) * 4;


  // Note:
  // The x,r,b,g sequence below might need to be changed if your strip is displaying
  // incorrect colors.  Some strips use an x,r,b,g sequence and some use x,r,g,b
  // Change the order if needed to make the colors correct.

  for (int y = imgHeight; y > 0; y--) {
    int bufpos = 0;
    for (int x = 0; x < displayWidth; x++) {
      uint32_t offset = (MYBMP_BF_OFF_BITS + (((y - 1) * lineLength) + (x * 3))) ;
      dataFile.seek(offset);

      getRGBwithGamma();

      strip.setPixelColor(x, r, b, g);

    }
    strip.show();
    delay(frameDelay);
  }
}


PROGMEM const char gammaTable[]  = {
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,
  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,
  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,
  4,  4,  4,  4,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  7,  7,
  7,  7,  7,  8,  8,  8,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11,
  11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16,
  16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22,
  23, 23, 24, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30,
  30, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 39,
  40, 40, 41, 41, 42, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 50,
  50, 51, 52, 52, 53, 54, 55, 55, 56, 57, 58, 58, 59, 60, 61, 62,
  62, 63, 64, 65, 66, 67, 67, 68, 69, 70, 71, 72, 73, 74, 74, 75,
  76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
  92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 104, 105, 106, 107, 108,
  109, 110, 111, 113, 114, 115, 116, 117, 118, 120, 121, 122, 123, 125, 126, 127
};


inline byte gamma(byte x) {
  return pgm_read_byte(&gammaTable[x]);
}

Well, your still ignorant :D

  else {
    SendFile("1.bmp");
    int numberFile = 1;
  }

You use a different variable having the same name 'numberFile' ;)

  else {
    SendFile("1.bmp");
    numberFile = 1;
  }

Should do the trick

To get rid of String (just the idea)

  // space for 8.3 filename an nul character
  // your responsibility to make sure that the fname will not be larger than 12 + 1 characters
  char fname[13];

  sprintf(fname, "%d.bmp", numberFile);

  if (SD.exists(fname)) {
    Serial.println(fname);
    SendFile(fname);
  }
  
  else {
    SendFile("1.bmp");
    int numberFile = 1;
  }

Not tested.

thanks!

so this is the loop now:

void loop() {
  int buttonstate = digitalRead(buttonPin);

  stringOne = String(numberFile);
  stringTwo = String(".bmp");

  if (buttonstate == HIGH) {
    numberFile++;
    delay (1000);
  }

  if (SD.exists(stringOne + stringTwo)) {
    Serial.println(numberFile);
    SendFile(stringOne + stringTwo);
  }
  
  else {
    SendFile("1.bmp");
    numberFile = 1;
  }
}

with it, I am able to play the files if they are numberer, from 1 on, and without interruptions. 1 2 3 4 5 6 7 8 9 would work 1 2 3 4 6 7 8 9 would reproduce until 4 and then go back to one

What if I want to play the files that are available in the sd card without having to number them? just play what is there and in order, regardless of their name? would openNextFile() do this job?