thelastoutpostworkshop / animated_gif_sdcard_spiffs

Animated GIF stored in SD Card and played from SPIFFS on a Round Display (GC9A01) with the ESP32
https://youtu.be/mqSe_uMpxIs
MIT License
19 stars 1 forks source link

cant read from sd card #1

Closed rivelta closed 1 month ago

rivelta commented 3 months ago

hi im curently testing project to read data from sdcard module and i have 4GB of micro sd

`


#include "FS.h"
#include "SD.h"
#include "SPI.h"

#include <SPIFFS.h>
#include <TFT_eSPI.h>      // Install this library with the Arduino Library Manager
                           // Don't forget to configure the driver for the display!

#include <AnimatedGIF.h>   // Install this library with the Arduino Library Manager

#define SD_CS_PIN 5 // Chip Select Pin (CS) for SD card Reader

AnimatedGIF gif;
File gifFile;              // Global File object for the GIF file
TFT_eSPI tft = TFT_eSPI(); 

const char *filename = "/x_wing.gif";   // Change to load other gif files in images/GIF
void setup()
{
  Serial.begin(115200);

 if (!SD.begin(SD_CS_PIN)) {
    Serial.println("Card Mount Failed");
    return;
  }
  Serial.println("Card initialized.");

  // List files in root directory
  //listFiles("/");

  tft.begin();
  tft.setRotation(2); // Adjust Rotation of your screen (0-3)
  tft.fillScreen(TFT_BLACK);

  // Initialize SD card
 // Serial.println("SD card initialization...");
 // SD.begin(SD_CS_PIN);

  // Initialize SPIFFS
  Serial.println("Initialize SPIFFS...");
  if (!SPIFFS.begin(true))
  {
    Serial.println("SPIFFS initialization failed!");
  }

  // Reformmating the SPIFFS to have space if a large GIF is loaded
  // You could run out of SPIFFS storage space if you load more than one image or a large GIF
  // You can also increase the SPIFFS storage space by changing the partition of the ESP32
  //
  Serial.println("Formatting SPIFFS...");
  SPIFFS.format(); // This will erase all the files, change as needed, SPIFFs is non-volatile memory
  Serial.println("SPIFFS formatted successfully.");

  // Open GIF file from SD card
  Serial.println("Openning GIF file from SD card...");
 // File sdFile = SD.open(filename);

File sdFile = SD.open(filename);

  // Create a file in SPIFFS to store the GIF
  File spiffsFile = SPIFFS.open(filename, FILE_WRITE, true);
  if (!spiffsFile)
  {
    Serial.println("Failed to copy GIF in SPIFFS!");
    return;
  }

  // Read the GIF from SD card and write to SPIFFS
  Serial.println("Copy GIF in SPIFFS...");
  byte buffer[512];
  while (sdFile.available())
  {
    int bytesRead = sdFile.read(buffer, sizeof(buffer));
    spiffsFile.write(buffer, bytesRead);
  }

  spiffsFile.close();
  sdFile.close();

  // Initialize the GIF
  Serial.println("Starting animation...");
  gif.begin(BIG_ENDIAN_PIXELS);
}

void loop()
{

}

// Callbacks for file operations for the Animated GIF Lobrary
void *fileOpen(const char *filename, int32_t *pFileSize)
{
  gifFile = SPIFFS.open(filename, FILE_READ);
  *pFileSize = gifFile.size();
  if (!gifFile)
  {
    Serial.println("Failed to open GIF file from SPIFFS!");
  }
  return &gifFile;
}

void fileClose(void *pHandle)
{
  gifFile.close();
}

int32_t fileRead(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
{
  int32_t iBytesRead;
  iBytesRead = iLen;
  if ((pFile->iSize - pFile->iPos) < iLen)
    iBytesRead = pFile->iSize - pFile->iPos;
  if (iBytesRead <= 0)
    return 0;

  gifFile.seek(pFile->iPos);
  int32_t bytesRead = gifFile.read(pBuf, iLen);
  pFile->iPos += iBytesRead;

  return bytesRead;
}

int32_t fileSeek(GIFFILE *pFile, int32_t iPosition)
{
  if (iPosition < 0)
    iPosition = 0;
  else if (iPosition >= pFile->iSize)
    iPosition = pFile->iSize - 1;
  pFile->iPos = iPosition;
  gifFile.seek(pFile->iPos);
  return iPosition;
}

void listFiles(String dirname) {
  Serial.println("Listing files in directory: " + dirname);

  File root = SD.open(dirname);
  if (!root) {
    Serial.println("Failed to open directory");
    return;
  }
  if (!root.isDirectory()) {
    Serial.println("Not a directory");
    return;
  }

  File file = root.openNextFile();
  while (file) {
    if (file.isDirectory()) {
      Serial.print("  DIR : ");
      Serial.println(file.name());
    } else {
      Serial.print("  FILE: ");
      Serial.print(file.name());
      Serial.print("  SIZE: ");
      Serial.println(file.size());
    }
    file = root.openNextFile();
  }
}
`

and the questions is why the log shows

16:53:01.813 -> Openning GIF file from SD card... 16:53:02.304 -> [ 9200][W][sd_diskio.cpp:109] sdWait(): Wait Failed 16:53:02.351 -> [ 9204][E][sd_diskio.cpp:128] sdSelectCard(): Select Failed 16:53:02.351 -> [ 9210][E][sd_diskio.cpp:595] ff_sd_status(): Check status failed 16:53:02.825 -> [ 9716][W][sd_diskio.cpp:109] sdWait(): Wait Failed 16:53:02.825 -> [ 9720][E][sd_diskio.cpp:128] sdSelectCard(): Select Failed 16:53:03.329 -> [ 10226][W][sd_diskio.cpp:109] sdWait(): Wait Failed 16:53:03.371 -> [ 10230][E][sd_diskio.cpp:128] sdSelectCard(): Select Failed

16:53:03.371 -> [ 10236][E][vfs_api.cpp:99] open(): /sd/x_wing.gif does not exist, no permits for creation

otherways i described to read " const char *filename = "/x_wing.gif"; "

and the log monitor shows "/sd/x_wing.gif "

and im already place file x_wing.gif already on root of my sdcard

thelastoutpostworkshop commented 3 months ago

Is the SD card connected to the same SPI bus as the screen (it should be) ? Does the screen works ? Which version of the TFT_eSPI library you are using ? Please provide the content of the config file for you screen.

rivelta commented 3 months ago

im use esp32 devkit v1 and here is diagram of my board

im connected cs to pin 5 / gpio 5 --> For sd card module use 4GB of micro Sd's

and tft espi is working normaly cs pin on pin 21 / 22

and for my tft espi config pin is based on default libs Setup46_GC9A01_ESP32

where contains

`// See SetupX_Template.h for all options available

define USER_SETUP_ID 46

define GC9A01_DRIVER

//#define TFT_MISO 19

define TFT_MOSI 23

define TFT_SCLK 18

define TFT1_CS 21 // Chip select control pin

define TFT_DC 2 // Data Command control pin

define TFT_RST 4 // Reset pin (could connect to RST pin)

//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST

define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH

define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters

define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters

define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm

define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.

define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.

define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts

define SMOOTH_FONT

define SPI_FREQUENCY 40000000

define SPI_READ_FREQUENCY 20000000

define SPI_TOUCH_FREQUENCY 2500000

// #define SUPPORT_TRANSACTIONS`

but when i try test with simple code to read file on micro sd's its working nice

im really like your works and for internal memory version its working without problem. nice

thelastoutpostworkshop commented 3 months ago

if the test example works with the SD card, without the display, something is happening on the SPI bus. Try lowering the #define SPI_FREQUENCY 40000000 to #define SPI_FREQUENCY 20000000

rivelta commented 3 months ago

im added

#include "FS.h"
#include "SD.h"
#include "SPI.h"

#include <SPIFFS.h>
#include <TFT_eSPI.h>      // Install this library with the Arduino Library Manager
                           // Don't forget to configure the driver for the display!

#include <AnimatedGIF.h>   // Install this library with the Arduino Library Manager
#define SPI_FREQUENCY 20000000
#define SD_CS_PIN 5 // Chip Select Pin (CS) for SD card Reader

here the full serial monitor since started clean boot

09:25:51.516 -> ho 8 tail 4 room 4
09:25:51.516 -> load:0x40080404,len:3048
09:25:51.516 -> entry 0x40080590
09:25:51.691 -> Card initialized.
09:25:51.691 -> [    22][E][esp32-hal-cpu.c:121] addApbChangeCallback(): duplicate func=0x400d9d1c arg=0x3ffbdbf4
09:25:52.035 -> Initialize SPIFFS...
09:25:52.135 -> Formatting SPIFFS...
09:25:52.402 -> E (1310) task_wdt: esp_task_wdt_reset(763): task not found
09:25:52.402 -> E (1311) task_wdt: esp_task_wdt_reset(763): task not found
.
.
.
continue with this log
.
.
09:26:00.421 -> E (9316) task_wdt: esp_task_wdt_reset(763): task not found
09:26:00.421 -> SPIFFS formatted successfully.
09:26:00.421 -> Openning GIF file from SD card...
09:26:00.907 -> [  9247][W][sd_diskio.cpp:109] sdWait(): Wait Failed
09:26:00.942 -> [  9251][E][sd_diskio.cpp:128] sdSelectCard(): Select Failed
09:26:00.942 -> [  9257][E][sd_diskio.cpp:595] ff_sd_status(): Check status failed
09:26:01.453 -> [  9763][W][sd_diskio.cpp:109] sdWait(): Wait Failed
09:26:01.453 -> [  9767][E][sd_diskio.cpp:128] sdSelectCard(): Select Failed
09:26:01.941 -> [ 10283][E][vfs_api.cpp:99] open(): /sd/x_wing.gif does not exist, no permits for creation

my questions is why the log shows wrong path ---> /sd/x_wing.gif but on filename its defined root of sd card

const char *filename = "/x_wing.gif";

rivelta commented 3 months ago

my provided code im adding additional for debugging list of file on micro sd by calling

listFiles("/");

and serial monitor shows

09:34:11.644 -> Card initialized. 09:34:11.644 -> Listing files in directory: / 09:34:11.644 -> DIR : System Volume Information 09:34:11.677 -> FILE: darthvader.gif SIZE: 113053 09:34:11.677 -> FILE: hud_1.gif SIZE: 914956 09:34:11.677 -> FILE: hud_2.gif SIZE: 720790 09:34:11.677 -> FILE: hud_5.gif SIZE: 965585 09:34:11.677 -> FILE: hud_6.gif SIZE: 310036 09:34:11.677 -> FILE: hud_7.gif SIZE: 882873 09:34:11.677 -> FILE: hyperspace.gif SIZE: 244827 09:34:11.677 -> FILE: nostromo.gif SIZE: 368538 09:34:11.677 -> FILE: shr2.h SIZE: 3782885 09:34:11.709 -> FILE: x_wing.gif SIZE: 431760 09:34:11.709 -> FILE: test.txt SIZE: 1048576 09:34:11.709 -> FILE: foo.txt SIZE: 13 09:34:11.709 -> DIR : sd

rivelta commented 3 months ago

i found the problem , its tft screen im moving code

tft.begin(); tft.setRotation(2); // Adjust Rotation of your screen (0-3) tft.fillScreen(TFT_BLACK);

to end of void setup before

spiffsFile.close(); sdFile.close();

and here is result

09:48:48.830 -> Card initialized. 09:48:48.830 -> Listing files in directory: / 09:48:48.830 -> DIR : System Volume Information 09:48:48.830 -> FILE: darthvader.gif SIZE: 113053 09:48:48.830 -> FILE: hud_1.gif SIZE: 914956 09:48:48.830 -> FILE: hud_2.gif SIZE: 720790 09:48:48.830 -> FILE: hud_5.gif SIZE: 965585 09:48:48.830 -> FILE: hud_6.gif SIZE: 310036 09:48:48.865 -> FILE: hud_7.gif SIZE: 882873 09:48:48.865 -> FILE: hyperspace.gif SIZE: 244827 09:48:48.865 -> FILE: nostromo.gif SIZE: 368538 09:48:48.865 -> FILE: shr2.h SIZE: 3782885 09:48:48.865 -> FILE: x_wing.gif SIZE: 431760 09:48:48.865 -> FILE: test.txt SIZE: 1048576 09:48:48.900 -> FILE: foo.txt SIZE: 13 09:48:48.900 -> DIR : sd 09:48:48.900 -> [ 87][E][esp32-hal-cpu.c:121] addApbChangeCallback(): duplicate func=0x400da0a8 arg=0x3ffbdbf4 09:48:49.242 -> Initialize SPIFFS... 09:48:49.347 -> Formatting SPIFFS... 09:48:49.347 -> E (1183) task_wdt: esp_task_wdt_reset(763): task not found 09:48:49.347 -> E (1184) task_wdt: esp_task_wdt_reset(763): task not found 09:48:49.347 -> E (1191) task_wdt: esp_task_wdt_reset(763): task not found . . . 09:56:36.728 -> E (8821) task_wdt: esp_task_wdt_reset(763): task not found 09:56:36.728 -> SPIFFS formatted successfully. 09:56:36.728 -> Openning GIF file from SD card... 09:56:36.898 -> x_wing.gif 09:56:36.898 -> Copy GIF in SPIFFS... 09:56:39.981 -> Starting animation...

its there something conflict?

thelastoutpostworkshop commented 3 months ago

I am not sure about this log, it comes from the sd library : 09:26:01.941 -> [ 10283][E][vfs_api.cpp:99] open(): /sd/x_wing.gif does not exist, no permits for creation.

So everything works except the x_wing.gif ?

rivelta commented 3 months ago

no one its works , im stil searching what is main problem

thelastoutpostworkshop commented 3 months ago

Post a picture of your wiring setup and your full code

rivelta commented 3 months ago

tft espi pin :

SCL - D18 SDA - D23 DC - D2 CS - D23 RST - D4 VCC - 3V3 GND - GND

MICRO SD PIN WIRE:

CS - D25 SCK - D18 MOSI D23 MISO - D19 VCC - 5V GND - GND

and the problem is when this code

tft.begin(); tft.setRotation(2); // Adjust Rotation of your screen (0-3) tft.fillScreen(TFT_BLACK);

i placed before

spiffsFile.close(); sdFile.close(); }

its work without problem its seems problem confilct between tft and sd card module. how i fix it?

full code

include

include

include

include

include // Install this library with the Arduino Library Manager

                       // Don't forget to configure the driver for the display!

include // Install this library with the Arduino Library Manager

define SD_CS_PIN 25 // Chip Select Pin (CS) for SD card Reader

AnimatedGIF gif; File gifFile; // Global File object for the GIF file TFT_eSPI tft = TFT_eSPI();

const char *filename = "/x_wing.gif"; // Change to load other gif files in images/GIF void setup() { Serial.begin(115200);

// Initialize SD card Serial.println("SD card initialization..."); if (!SD.begin(SD_CS_PIN)) { Serial.println("SD card initialization failed!"); return; }

// Initialize SPIFFS Serial.println("Initialize SPIFFS..."); if (!SPIFFS.begin(true)) { Serial.println("SPIFFS initialization failed!"); }

// Reformmating the SPIFFS to have space if a large GIF is loaded // You could run out of SPIFFS storage space if you load more than one image or a large GIF // You can also increase the SPIFFS storage space by changing the partition of the ESP32 // Serial.println("Formatting SPIFFS..."); SPIFFS.format(); // This will erase all the files, change as needed, SPIFFs is non-volatile memory Serial.println("SPIFFS formatted successfully.");

// Open GIF file from SD card Serial.println("Openning GIF file from SD card..."); File sdFile = SD.open(filename); if (!sdFile) { Serial.println("Failed to open GIF file from SD card!"); return; }

// Create a file in SPIFFS to store the GIF File spiffsFile = SPIFFS.open(filename, FILE_WRITE, true); if (!spiffsFile) { Serial.println("Failed to copy GIF in SPIFFS!"); return; }

// Read the GIF from SD card and write to SPIFFS Serial.println("Copy GIF in SPIFFS..."); byte buffer[512]; while (sdFile.available()) { int bytesRead = sdFile.read(buffer, sizeof(buffer)); spiffsFile.write(buffer, bytesRead); } tft.begin(); tft.setRotation(2); // Adjust Rotation of your screen (0-3) tft.fillScreen(TFT_BLACK);

spiffsFile.close(); sdFile.close();

// Initialize the GIF Serial.println("Starting animation..."); gif.begin(BIG_ENDIAN_PIXELS); }

void loop() { if (gif.open(filename, fileOpen, fileClose, fileRead, fileSeek, GIFDraw)) { tft.startWrite(); // The TFT chip slect is locked low while (gif.playFrame(true, NULL)) { } gif.close(); tft.endWrite(); // Release TFT chip select for the SD Card Reader } }

// Callbacks for file operations for the Animated GIF Lobrary void fileOpen(const char filename, int32_t pFileSize) { gifFile = SPIFFS.open(filename, FILE_READ); pFileSize = gifFile.size(); if (!gifFile) { Serial.println("Failed to open GIF file from SPIFFS!"); } return &gifFile; }

void fileClose(void *pHandle) { gifFile.close(); }

int32_t fileRead(GIFFILE pFile, uint8_t pBuf, int32_t iLen) { int32_t iBytesRead; iBytesRead = iLen; if ((pFile->iSize - pFile->iPos) < iLen) iBytesRead = pFile->iSize - pFile->iPos; if (iBytesRead <= 0) return 0;

gifFile.seek(pFile->iPos); int32_t bytesRead = gifFile.read(pBuf, iLen); pFile->iPos += iBytesRead;

return bytesRead; }

int32_t fileSeek(GIFFILE *pFile, int32_t iPosition) { if (iPosition < 0) iPosition = 0; else if (iPosition >= pFile->iSize) iPosition = pFile->iSize - 1; pFile->iPos = iPosition; gifFile.seek(pFile->iPos); return iPosition; }

thelastoutpostworkshop commented 3 months ago

It's hard for me to help you since I cannot reproduce the problem, it maybe the wiring or a bad SD module. You could try having the SD module on a separate SPI bus.