johnreq
September 21, 2022, 1:57am
1
Description
What MCU/Processor/Board and compiler are you using?
ESP 32 Devkit on Arduino IDE
What LVGL version are you using?
8.3
What do you want to achieve?
Setup File system to be able to use an image on an SD Card for LVGL widgets
What have you tried so far?
Code to reproduce
/*Initialize your Storage device and File system.*/
static void fs_init(void)
{
// E.g. for FatFS initialize the SD card and FatFS itself
// SD Card Initialization
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);
Serial.println( "Setup done" );
}
static void * sd_fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
{
File *fp = (File *)lv_mem_alloc(sizeof(File));
if (fp == NULL)
return NULL;
File mySDfile = *fp;
// Make the path relative to the current directory (the projects root folder)
char buf[256];
sprintf(buf, "/%s", path);
if (mode == LV_FS_MODE_WR)
{
// Open a file for write
mySDfile = SD.open(buf, FILE_WRITE);
}
else if (mode == LV_FS_MODE_RD)
{
// Open a file for read
mySDfile = SD.open(buf, FILE_READ);
}
else if (mode == (LV_FS_MODE_WR | LV_FS_MODE_RD))
{
// Open a file for read and write
mySDfile = SD.open(buf, FILE_WRITE);
}
mySDfile = SD.open(buf);
//make sure at the beginning
mySDfile.seek(0);
*fp = mySDfile;
return fp;
}
static lv_fs_res_t sd_fs_close(lv_fs_drv_t *drv, void *file_p)
{
File *fp = (File *)file_p;
fp->close();
delete (fp); // when close
return LV_FS_RES_OK;
}
static lv_fs_res_t sd_fs_read(lv_fs_drv_t *drv, void *file_p, void *fileBuf, uint32_t btr, uint32_t *br)
{
lv_fs_res_t res = LV_FS_RES_NOT_IMP;
return res;
}
static lv_fs_res_t sd_fs_seek(lv_fs_drv_t *drv, void *file_p, uint32_t pos, lv_fs_whence_t whence)
{
lv_fs_res_t res = LV_FS_RES_OK;
File *fp = (File *) file_p;
// commented out because it is throwing an error
/* if (whence == LV_FS_SEEK_SET)
{
fp->seek(pos, 0);
}
if (whence == LV_FS_SEEK_CUR)
{
fp->seek(pos, 1);
}
if (whence == LV_FS_SEEK_END)
{
fp->seek(pos, 2);
} */
fp->seek(pos);
return res;
}
static lv_fs_res_t sd_fs_tell(lv_fs_drv_t *drv, void *file_p, uint32_t *pos_p)
{
File *fp = (File *)file_p;
*pos_p = fp->position();
return LV_FS_RES_OK;
}
void sd_fs_init(void)
{
fs_init();
/*Add a simple drive to open images*/
static lv_fs_drv_t fs_drv;
lv_fs_drv_init(&fs_drv);
/*Set up fields...
To use files in image widgets the following callbacks are required:
- open
- close
- read
- seek
- tell
*/
fs_drv.letter = 'S';
fs_drv.open_cb = sd_fs_open;
fs_drv.close_cb = sd_fs_close;
fs_drv.read_cb = sd_fs_read;
fs_drv.seek_cb = sd_fs_seek;
fs_drv.tell_cb = sd_fs_tell;
fs_drv.write_cb = NULL;
fs_drv.dir_close_cb = NULL;
fs_drv.dir_open_cb = NULL;
fs_drv.dir_read_cb = NULL;
lv_fs_drv_register(&fs_drv);
Serial.println("drv registered!");
}
void setup()
{
...
sd_fs_init();
lv_obj_t * img_bin = lv_img_create(lv_scr_act());
lv_img_set_src(img_bin, "S:Baboon40.bin");
lv_obj_align(img_bin, LV_ALIGN_CENTER, 0, 0);
...
}
Screenshot and/or video
This compiles with no errors but when uploaded to my ESP32, it goes into a boot loop with this logs:
SD Card Type: SDHC
SD Card Size: 14910MB
Setup done
drv registered!
Guru Meditation Error: Core 1 panic'ed (InstrFetchProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x00000000 PS : 0x00060230 A0 : 0x800ef870 A1 : 0x3ffb26e0
A2 : 0x3ffc1348 A3 : 0x3ffc5044 A4 : 0x3ffb2788 A5 : 0x00000004
A6 : 0x3ffb26f8 A7 : 0xff000000 A8 : 0x800d18cc A9 : 0x3ffb26b0
A10 : 0x3ffc5044 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x3f400e94
A14 : 0x00000000 A15 : 0x3ffc4e48 SAR : 0x0000001c EXCCAUSE: 0x00000014
EXCVADDR: 0x00000000 LBEG : 0x40086518 LEND : 0x40086523 LCOUNT : 0xffffffff
Backtrace:0xfffffffd:0x3ffb26e00x400ef86d:0x3ffb2700 0x400ddb17:0x3ffb2720 0x400de102:0x3ffb2750 0x400f513f:0x3ffb2770 0x400d1af1:0x3ffb27b0 0x400fee3a:0x3ffb2820
ELF file SHA256: 0000000000000000
Rebooting...
Most of my references seem to be using older versions of lvgl and I’m having trouble making odds and ends of them.
Thank you!
johnreq
September 21, 2022, 3:21am
2
PS: I’ve checked that the SD card works using the SD.h library example together with this tutorial:
and
I had to add a jumper to make it work (see 2nd video)
I forgot to mention that I am using an ST7796 TFT Screen
First of all install backtrace Plugin to IDE: https://github.com/me-no-dev/EspExceptionDecoder and you will see Error place.
Next: try to add check for successful file open in sd_fs_open()
:
mySDfile = SD.open(buf);
+ if (!mySDfile) {
+ lv_mem_free(fp);
+ return NULL;
+ }
//make sure at the beginning
mySDfile.seek(0);
may be you file is not opened?
johnreq
September 21, 2022, 6:45am
4
I tried using the ExceptionDecoder and here’s what it returned:
PC: 0x00000000
EXCVADDR: 0x00000000
Decoding stack results
0x400ef7e5: lv_fs_close at C:\Users\User\Documents\Arduino\libraries\lvgl\src\misc\lv_fs.c line 115
0x400dda8f: lv_img_decoder_built_in_info at C:\Users\User\Documents\Arduino\libraries\lvgl\src\draw\lv_img_decoder.c line 295
0x400de07a: lv_img_decoder_get_info at C:\Users\User\Documents\Arduino\libraries\lvgl\src\draw\lv_img_decoder.c line 99
0x400f50b7: lv_img_set_src at C:\Users\User\Documents\Arduino\libraries\lvgl\src\widgets\lv_img.c line 107
0x400d1afd: setup() at D:\clinikapps\repositories\tft_test/tft_test.ino line 271
0x400fe762: loopTask(void*) at C:\Users\User\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.4\cores\esp32\main.cpp line 42
may be you file is not opened?
How do I check this?
Does you apply my last diff?
Did you opening lv_fs.c at 115 line to chek what it doing?
I’ve decided to abandon the code I wrote and try out the “prepared drivers.”
So now I’m trying out POSIX, changed LV_USE_FS_POSIX
to 1
, LV_FS_POSIX_LETTER
to 'S'
, and LV_FS_POSIX_PATH
to "/"
.
I then ran the code, but the image is still not showing up. It’s not showing any errors though.
lv_obj_t * img_bin = lv_img_create(lv_scr_act());
lv_img_set_src(img_bin, "S:/Baboon40.bin");
lv_obj_align(img_bin, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(img_bin, 320,480);
100ask
October 17, 2022, 10:41am
7
johnreq
October 17, 2022, 12:33pm
8
Hello!
Thank you so much for sharing your code!
I do have questions:
I was reading your project’s README fileWhy do you have different pins for your MISO, MOSI and SCK/CK for your TFT and SD Card reader? Is it ok to have them share or do I need to separate them? Here’s what my circuit looks like:
Do I do this:
lv_img_set_src(img_bin, "S:/root/arduino.png");
or this:
lv_img_set_src(img_bin, "S:/arduino.png");
Once more, thank you so much for helping me out, I am a complete noob when it comes to hardware!
EDIT:
The error I’m getting now is a kernel panic, I think this is progress!
ets Jun 8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13864
load:0x40080400,len:3608
entry 0x400805f0
Hello Arduino! V8.3.1
I am LVGL_Arduino
initializing sd fs init...
SD Card Type: SDHC
SD Card Size: 14910MB
Total space: 14902MB
Used space: 2MB
sd fs init done...
assert failed: xQueueSemaphoreTake queue.c:1549 (pxQueue->uxItemSize == 0)
Backtrace:0x40083595:0x3ffb1f000x400894a5:0x3ffb1f20 0x4008e215:0x3ffb1f40 0x4008a1f9:0x3ffb2070 0x400fd4e9:0x3ffb20b0 0x400d2d34:0x3ffb20d0 0x400d30a1:0x3ffb20f0 0x400d3111:0x3ffb2110 0x400d33ed:0x3ffb2130 0x400d341d:0x3ffb2150 0x4010a766:0x3ffb2170 0x4010a979:0x3ffb2190 0x4010c87b:0x3ffb21d0 0x4010ea2b:0x3ffb2440 0x40107b7a:0x3ffb25b0 0x40116a75:0x3ffb25d0 0x400d2857:0x3ffb25f0 0x400d2141:0x3ffb2670 0x400d1e5b:0x3ffb26a0 0x400efb31:0x3ffb26e0 0x400e7b87:0x3ffb2700 0x400de346:0x3ffb2750 0x400f51db:0x3ffb2770 0x400d1c3f:0x3ffb27b0 0x400fe92a:0x3ffb2820
ELF file SHA256: 0000000000000000
Rebooting...
John
100ask
October 18, 2022, 2:29am
9
I wrote these examples for teaching. At present, our smallest board is not convenient to connect bread board, so we adopted this wiring method.
You can first test whether the file system interface works normally, such as: https://gitee.com/weidongshan/lvgl_100ask_course_materials/blob/master/02_%E7%A8%8B%E5%BA%8F%E6%BA%90%E7%A0%81/01_%E8%AF%BE%E5%A0%82%E4%BB%A3%E7%A0%81/lv_100ask_teach_demos/src/lv_100ask_demo_course_6_1_1/lv_100ask_demo_course_6_1_1.c
Key source code in the link:
// 要打开的文件
#define FILE_NAME "D:/100ask/tmp/lv_fs_test.txt"
// 要读取的目录
#define DIR_PATH "D:/100ask/tmp/"
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/* 通过LVGL文件系统接口统一不同的文件系统并读取文件 */
static void lv_fs_read_dir(char * fn);
/* 通过LVGL文件系统接口统一不同的文件系统并读取目录内容 */
static void lv_fs_read_file(char * path);
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_100ask_demo_course_6_1_1(void)
{
#if 1
// 读取文件
lv_fs_read_file(FILE_NAME);
#else
// 读取目录内容
lv_fs_read_dir(DIR_PATH);
#endif
}
/**********************
* STATIC FUNCTIONS
**********************/
/* 通过LVGL文件系统接口统一不同的文件系统并读取文件 */
static void lv_fs_read_file(char * fn)
{
lv_fs_file_t f;
lv_fs_res_t res;
// 打开文件有两个模式: LV_FS_MODE_RD(只读) 和 LV_FS_MODE_WR(写)
res = lv_fs_open(&f, fn, LV_FS_MODE_RD);
// 如果一切正常会返回 LV_FS_RES_OK ,其他错误代码请看 lv_fs.h 中的 lv_fs_res_t 定义
if(res != LV_FS_RES_OK) {
LV_LOG_USER("Open error! Error code: %d", res);
return;
}
/* 每次实际读取到的数据大小(byte) */
uint32_t read_num;
/* 数据缓冲区 */
uint8_t buf[8];
/* 读取整个文件并打印内容 */
while (1) {
res = lv_fs_read(&f, buf, 8, &read_num);
if(res != LV_FS_RES_OK) {
LV_LOG_USER("Read error! Error code: %d", res);
break;
}
/* 将读取到数据打印出来 */
printf("%s", buf);
if (read_num != 8) break;
}
lv_fs_close(&f);
}
/* 通过LVGL文件系统接口统一不同的文件系统并读取目录内容 */
static void lv_fs_read_dir(char * path)
{
lv_fs_dir_t dir;
lv_fs_res_t res;
res = lv_fs_dir_open(&dir, path);
if(res != LV_FS_RES_OK){
LV_LOG_USER("Open DIR error! Error code: %d", res);
return;
}
char fn[256]; // 缓冲区
while(1) {
res = lv_fs_dir_read(&dir, fn);
if(res != LV_FS_RES_OK) {
LV_LOG_USER("Read DIR error! Error code: %d", res);
break;
}
/* 如果没有更多文件可以读取时 fn 就为空 */
if(strlen(fn) == 0) {
LV_LOG_USER("Fn is empty, if not more files to read.");
break;
}
printf("%s\n", fn);
}
lv_fs_dir_close(&dir);
}
johnreq
November 7, 2022, 2:11pm
10
Hello! Just a bit of an update, I needed to uncomment #define SUPPORT_TRANSACTIONS
and seems like that made this work!!! Thank you so much!
Now I just need to find a way to get rid of these lines.
1 Like
johnreq
November 8, 2022, 9:06am
11
One thing I noticed is that it works for .bin
files but if it’s .png
files, they are outputted as NO DATA
.
100ask
November 17, 2022, 2:26am
12
Cheers!
This seems to be a screen driver problem. You should check the screen driver code.
100ask
November 17, 2022, 2:31am
13
When NO DATA.
is displayed, check the output information of the console.
johnreq
November 17, 2022, 2:40pm
14
I was using TFT_eSPI for this, tried LovyanGFX and it still has the same problem with the lines. Strange…
100ask
November 28, 2022, 6:46am
15
Have you tested the screen and screen driver? For example, the full screen is brushed to a certain color.
johnreq
November 28, 2022, 7:13am
16
Not yet, what do you mean by “brushed to a certain color”?
[SOLVED] The solution was found, I should enable LV_USE_FS_FATFS , inside my lv_conf.h
the _lv_indev_read warning was because of the touch input, which I am not using, and I have registered a dummy one, so removing the input device declaration solves the problem as well.