Hello,
my code has a modified version of the listDir function provided with SD.h. Instead of printing the contents to the serial monitor, it writes them to a char* array. Immediately after writing the, I have it printing the contents of one of them to the serial monitor and it is correct:
At end of the "listmake" function, fileArray1 is /Octopus.c
Later, the file is accessed by a modified version of the readfile function (also from SD.h). However, it fails to read. To troubleshoot this, I decided to check the value of array again just before the read function. Now I get this:
Just before readfile, filearray1 is ⸮?⸮⸮@?⸮⸮⸮'⸮?@
that's pretty different!
Here is my full code:
// The SD card is using VSPI, the display is using HSPI
/* Includes ------------------------------------------------------------------*/
#include "DEV_Config.h"
#include "EPD.h"
#include "GUI_Paint.h"
#include "imagedata.h"
#include <stdio.h>
#include <stdlib.h>
#include "FS.h" //for SD card
#include "SD.h" //for SD card
#include "SPI.h" //for SD card
//#include "DigiFrame_Functions.h"
/* Declares -------------------------------------------------------------------*/
//Create a new image cache
UBYTE *BlackImage;
/* you have to edit the startup_stm32fxxx.s file and set a big enough heap size */
UWORD Imagesize = ((EPD_4IN2_WIDTH % 8 == 0) ? (EPD_4IN2_WIDTH / 8 ) : (EPD_4IN2_WIDTH / 8 + 1)) * EPD_4IN2_HEIGHT;
byte image[30000];
char buffer[20];
char *ptr;
int SDerror = 0;
char c;
char *fileArray[40];
char loadfile[50];
/* Entry point ----------------------------------------------------------------*/
// Initialize SD card
void initSDCard() {
if (!SD.begin()) {
Serial.println("Card Mount Failed");
return;
}
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
Serial.println("No SD card attached");
return;
}
Serial.print("SD Card Type: ");
if (cardType == CARD_MMC) {
Serial.println("MMC");
} else if (cardType == CARD_SD) {
Serial.println("SDSC");
} else if (cardType == CARD_SDHC) {
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\n", cardSize);
}
//Modified SD Card read function
void readFile(fs::FS &fs, char * path) {//was const char
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if (!file) {
Serial.println("Failed to open file for reading");
SDerror = 1;
return;
}
int index = 0;
Serial.print("Read from file: ");
while (file.available() && file.read() != '\n') {}; // IGNORE FIRST LINE OF FILE
while (file.available()) {
int count = file.readBytesUntil(',', buffer, 20 );
buffer[count] = '\0'; // Add null terminator
image[index++] = strtoul(buffer, &ptr, 0); // Convert hex constant to binary
}
file.close();
}
//Modified listDir. Now for making arrays of picture array file names
void listMake(fs::FS &fs, const char * dirname, uint8_t levels) {
Serial.printf("Listing directory: %s\n", dirname);
File root = fs.open(dirname);
if (!root) {
Serial.println("Failed to open directory");
return;
}
if (!root.isDirectory()) {
Serial.println("Not a directory");
return;
}
String fname;
int flen;
String ext;
int Ccount = 0;
char fnamebuf[50];
File file = root.openNextFile();
while (file) {
if (file.isDirectory()) {
Serial.print(" DIR : ");
Serial.println(file.name());
if (levels) {
listMake(fs, file.path(), levels - 1);
}
} else {
fname = file.name();
flen = fname.length();
ext = fname.substring(flen - 2);
if (ext == ".c") {
// Serial.print(" FILE: ");
// Serial.print(file.name());
// Serial.print(" EXTENSION: ");
// Serial.print(ext);
// Serial.print(" SIZE: ");
// Serial.println(file.size());
fname = "/" + fname + '\0';
fname.toCharArray(fnamebuf, 50);
fileArray[Ccount] = fnamebuf;
Ccount++;
}
}
file = root.openNextFile();
}
Serial.print("At end of listmake function, fileArray1 is ");
Serial.println(fileArray[1]);
}
void setup()
{
Serial.begin(115200);
initSDCard();
listMake(SD, "/", 0);
printf("EPD_4IN2_test Demo\r\n");
DEV_Module_Init();
printf("e-Paper Init and Clear...\r\n");
EPD_4IN2_Init();
EPD_4IN2_Clear();
DEV_Delay_ms(500);
if ((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) {
printf("Failed to apply for black memory...\r\n");
while (1);
}
printf("Paint_NewImage\r\n");
Paint_NewImage(BlackImage, EPD_4IN2_WIDTH, EPD_4IN2_HEIGHT, 0, WHITE);
Paint_SetScale(4); //I don&t understand this but seems to be necessary
#if 1 //Welcome Screen
Paint_Clear(WHITE);
Paint_DrawString_EN(32, 140, "DIGIFRAME", &Font20, WHITE, BLACK);//Font 20 each char 14 pxl wide 24char = 336
Paint_DrawString_EN(116, 170, "(Name Subject to Change)", &Font12, WHITE, BLACK);//Font 12 each char 7 pxl wide 24char = 168
EPD_4IN2_4GrayDisplay(BlackImage);
DEV_Delay_ms(8000);
#endif
}
/* The main loop -------------------------------------------------------------*/
void loop()
{
#if 1 //read file with array number 1
Serial.print("Just before readfile, filearray1 is ");
Serial.println(fileArray[1]);
readFile(SD, fileArray[1]);
Paint_Clear(WHITE);
if (SDerror == 0) {
Paint_DrawImage(image, 16, 0, 768, 300);
}
else {
Paint_DrawImage(gImage_SD_Card_Error, 16, 0, 768, 300);
SDerror = 0;
}
EPD_4IN2_4GrayDisplay(BlackImage);
DEV_Delay_ms(10000);
#endif
#if 1 //CutDown
Paint_Clear(WHITE);
Paint_DrawImage(gImage_cutdown, 16, 0, 768, 300);
EPD_4IN2_4GrayDisplay(BlackImage);
DEV_Delay_ms(10000);
#endif
}
I was considering using malloc to prevent memory problems, but didn't have much luck with that, and while googling for answers, saw a lot of comments advising against the use of malloc at all...
Incidentally, I'd also be curious as to if what I'm doing on this line or not is okay
readFile(SD, fileArray[1]);
the readFile function is expecting a char where I'm putting fileArray[1]. I was considering doing a strcpy() to pull the contents of fileArray[1 etc.] into a normal char[] string.
Any and all help greatly appreciated. Thanks.