Xiao ESP32S3 Sense read MicroSD
Exercise run on Xiao ESP32S3 Sense
in Arduino framework, read SD Card. Base on the exercise "240x240 ST7789V2 SPI IPS with FT6236 cap touch on XIAO ESP32S3 using GFX
Library for Arduino", display ST7789 LCD.
XiaoS3_ST7789_SD.ino, read and display SD info and hello.txt content.
XiaoS3_ST7789_SD_listDir.ino, list files in SD /images_240 directory.
List files in SD images_240 directory on LVGL list:
XiaoS3_ST7789_SD_listFiles_in_lvgl.ino
Next:
~ ESP32S3 (Arduino framework) decode jpg and display on ST7789 SPI Display.
XiaoS3_ST7789_SD.ino, read and display SD info and hello.txt content.
/*******************************************************************************
Xiao ESP32S3 Sense exercise
******************************************************************************/
/*******************************************************************************
* Start of Arduino_GFX setting
******************************************************************************/
#include <Arduino_GFX_Library.h>
//=== Custom to match my connection ===========================================
#define PIN_BLK 4
#define PIN_CS 3
#define PIN_DC 2
#define PIN_RES 1
#define PIN_SDA 9
#define PIN_SCL 7
#define GFX_BL PIN_BLK
#define CTP_INT 43
#define CTP_RST 44
#define FT6236_ADDR 0x38
#define DISP_WIDTH 240
#define DISP_HEIGHT 240
Arduino_DataBus *bus = new Arduino_HWSPI(PIN_DC, PIN_CS);
Arduino_GFX *gfx = new Arduino_ST7789(bus, PIN_RES, 0 /* rotation */, true /* IPS */, DISP_WIDTH, DISP_HEIGHT);
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
// SD
#include <SD.h>
#define SD_CS 21
void readFile(fs::FS &fs, const char *path) {
Serial.printf("Reading file: %s\n", path);
gfx->printf("Reading file: %s\n", path);
File file = fs.open(path);
if (!file) {
Serial.println("Failed to open file for reading");
gfx->println("Failed to open file for reading");
return;
}
Serial.print("Read from file: ");
while (file.available()) {
char c = file.read();
Serial.write(c);
gfx->write(c);
}
file.close();
}
void setup()
{
delay(1000);
Serial.begin(115200);
delay(1000);
Serial.println("Xiao ESP32S3 Sense exercise");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
gfx->setTextSize(2);
gfx->println(F("Xiao ESP32S3 Sense exercise"));
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
if (!SD.begin(SD_CS))
{
Serial.println(F("ERROR: File System Mount Failed!"));
gfx->println(F("ERROR: File System Mount Failed!"));
for(;;); // Fatal error, do not continue
}
else
{
Serial.println(F("File System Mount Successful!"));
gfx->println(F("File System Mount Successful!"));
}
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE){
Serial.println("No SD card attached");
gfx->println(F("No SD card attached"));
return;
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\r\n", cardSize);
gfx->printf("SD Card Size: %lluMB\r\n", cardSize);
uint64_t totalBytes = SD.totalBytes();
uint64_t usedBytes = SD.usedBytes();
Serial.printf("SD.totalBytes = %lld \r\n", totalBytes);
gfx->printf("SD.totalBytes = %lld \r\n", totalBytes);
Serial.printf("SD.usedBytes = %lld \r\n", usedBytes);
gfx->printf("SD.usedBytes = %lld \r\n", usedBytes);
delay(2000);
// Read and display /hello.txt on SD
Serial.println();
gfx->println();
readFile(SD, "/hello.txt");
}
void loop() {
}
XiaoS3_ST7789_SD_listDir.ino, list files in SD /images_240 directory.
/*******************************************************************************
Xiao ESP32S3 Sense exercise
List files in SD /images_240 directory.
******************************************************************************/
/*******************************************************************************
* Start of Arduino_GFX setting
******************************************************************************/
#include <Arduino_GFX_Library.h>
//=== Custom to match my connection ===========================================
#define PIN_BLK 4
#define PIN_CS 3
#define PIN_DC 2
#define PIN_RES 1
#define PIN_SDA 9
#define PIN_SCL 7
#define GFX_BL PIN_BLK
#define CTP_INT 43
#define CTP_RST 44
#define FT6236_ADDR 0x38
#define DISP_WIDTH 240
#define DISP_HEIGHT 240
Arduino_DataBus *bus = new Arduino_HWSPI(PIN_DC, PIN_CS);
Arduino_GFX *gfx = new Arduino_ST7789(bus, PIN_RES, 0 /* rotation */, true /* IPS */, DISP_WIDTH, DISP_HEIGHT);
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
// SD
#include <SD.h>
#define SD_CS 21
void readFile(fs::FS &fs, const char *path) {
Serial.printf("Reading file: %s\n", path);
gfx->printf("Reading file: %s\n", path);
File file = fs.open(path);
if (!file) {
Serial.println("Failed to open file for reading");
gfx->println("Failed to open file for reading");
return;
}
Serial.print("Read from file: ");
while (file.available()) {
char c = file.read();
Serial.write(c);
gfx->write(c);
}
file.close();
}
void listDir(fs::FS &fs, const char * dirname){
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;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory()){
Serial.print(" DIR : ");
Serial.println(file.name());
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
gfx->println(file.name());
Serial.print(" SIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
void setup()
{
delay(1000);
Serial.begin(115200);
delay(1000);
Serial.println("Xiao ESP32S3 Sense exercise");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
gfx->setTextSize(2);
gfx->println(F("Xiao ESP32S3 Sense exercise"));
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
if (!SD.begin(SD_CS))
{
Serial.println(F("ERROR: File System Mount Failed!"));
gfx->println(F("ERROR: File System Mount Failed!"));
for(;;); // Fatal error, do not continue
}
else
{
Serial.println(F("File System Mount Successful!"));
gfx->println(F("File System Mount Successful!"));
}
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE){
Serial.println("No SD card attached");
gfx->println(F("No SD card attached"));
return;
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\r\n", cardSize);
gfx->printf("SD Card Size: %lluMB\r\n", cardSize);
uint64_t totalBytes = SD.totalBytes();
uint64_t usedBytes = SD.usedBytes();
Serial.printf("SD.totalBytes = %lld \r\n", totalBytes);
gfx->printf("SD.totalBytes = %lld \r\n", totalBytes);
Serial.printf("SD.usedBytes = %lld \r\n", usedBytes);
gfx->printf("SD.usedBytes = %lld \r\n", usedBytes);
delay(2000);
Serial.println();
gfx->fillScreen(RGB565_BLACK);
gfx->setCursor(0, 0);
listDir(SD, "/images_240");
}
void loop() {
}
List files in SD images_240 directory on LVGL list:
XiaoS3_ST7789_SD_listFiles_in_lvgl.ino
/*******************************************************************************
Xiao ESP32S3 Sense exercise
List files in SD /images_240 directory.
******************************************************************************/
/*******************************************************************************
* Start of Arduino_GFX setting
******************************************************************************/
#include <Arduino_GFX_Library.h>
//=== Custom to match my connection ===========================================
#define PIN_BLK 4
#define PIN_CS 3
#define PIN_DC 2
#define PIN_RES 1
#define PIN_SDA 9
#define PIN_SCL 7
#define GFX_BL PIN_BLK
#define CTP_INT 43
#define CTP_RST 44
#define FT6236_ADDR 0x38
#define DISP_WIDTH 240
#define DISP_HEIGHT 240
Arduino_DataBus *bus = new Arduino_HWSPI(PIN_DC, PIN_CS);
Arduino_GFX *gfx = new Arduino_ST7789(bus, PIN_RES, 0 /* rotation */, true /* IPS */, DISP_WIDTH, DISP_HEIGHT);
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
// SD
#include <SD.h>
#define SD_CS 21
const char *images_path = "/images_240";
//==============================================================
// LVGL
#include <lvgl.h>
// for FT6236 cap touch
#include <Wire.h>
uint32_t screenWidth;
uint32_t screenHeight;
uint32_t bufSize;
lv_display_t *disp;
lv_color_t *disp_draw_buf;
static lv_obj_t * list1;
uint32_t millis_cb(void)
{
return millis();
}
/* LVGL calls it when a rendered image needs to copied to the display*/
void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map)
{
#ifndef DIRECT_RENDER_MODE
uint32_t w = lv_area_get_width(area);
uint32_t h = lv_area_get_height(area);
gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)px_map, w, h);
#endif // #ifndef DIRECT_RENDER_MODE
/*Call it to tell LVGL you are ready*/
lv_disp_flush_ready(disp);
}
/*Read the touchpad*/
void my_touchpad_read( lv_indev_t * indev, lv_indev_data_t * data )
{
if (get_touch_count()>0){
data->state = LV_INDEV_STATE_PRESSED;
int x, y;
Wire.beginTransmission(FT6236_ADDR);
Wire.write(0x03);
Wire.endTransmission();
Wire.requestFrom(FT6236_ADDR, 2);
x = (Wire.read() & 0x0f) << 8 | Wire.read();
x = DISP_WIDTH - x;
Wire.beginTransmission(FT6236_ADDR);
Wire.write(0x05);
Wire.endTransmission();
Wire.requestFrom(FT6236_ADDR, 2);
y = (Wire.read() & 0x0f) << 8 | Wire.read();
y = DISP_HEIGHT - y;
data->point.x = x;
data->point.y = y;
}else{
data->state = LV_INDEV_STATE_RELEASED;
}
}
int get_touch_count(){
// Register 0x02;
// Touch count, max 2
Wire.beginTransmission(FT6236_ADDR);
Wire.write(0x02);
Wire.endTransmission();
Wire.requestFrom(FT6236_ADDR, 1);
return(Wire.read());
}
//==============================================================
void readFile(fs::FS &fs, const char *path) {
Serial.printf("Reading file: %s\n", path);
File file = fs.open(path);
if (!file) {
Serial.println("Failed to open file for reading");
return;
}
Serial.print("Read from file: ");
while (file.available()) {
char c = file.read();
Serial.write(c);
gfx->write(c);
}
file.close();
}
void listDir(fs::FS &fs, const char * dirname){
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;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory()){
Serial.print(" DIR : ");
Serial.println(file.name());
} else {
Serial.print(" FILE: ");
Serial.print(file.name());
lv_list_add_text(list1, file.name());
Serial.print(" SIZE: ");
Serial.println(file.size());
}
file = root.openNextFile();
}
}
void setup()
{
delay(1000);
Serial.begin(115200);
delay(1000);
Serial.println("Xiao ESP32S3 Sense exercise");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
// Init I2C for FT6236 and CTR_RST
Wire.begin(); // I2C
delay(100);
pinMode(CTP_RST, OUTPUT);
digitalWrite(CTP_RST, HIGH);
delay(100);
digitalWrite(CTP_RST, LOW);
delay(100);
digitalWrite(CTP_RST, HIGH);
delay(100);
//====================================================================
// init LVGL
lv_init();
/*Set a tick source so that LVGL will know how much time elapsed. */
lv_tick_set_cb(millis_cb);
screenWidth = gfx->width();
screenHeight = gfx->height();
#ifdef DIRECT_RENDER_MODE
bufSize = screenWidth * screenHeight;
#else
bufSize = screenWidth * 40;
#endif
#if defined(DIRECT_RENDER_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
disp_draw_buf = (lv_color_t *)gfx->getFramebuffer();
#else // !(defined(DIRECT_RENDER_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)))
disp_draw_buf = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (!disp_draw_buf)
{
// remove MALLOC_CAP_INTERNAL flag try again
disp_draw_buf = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_8BIT);
}
#endif // !(defined(DIRECT_RENDER_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)))
if (!disp_draw_buf)
{
Serial.println("LVGL disp_draw_buf allocate failed!");
}
else
{
disp = lv_display_create(screenWidth, screenHeight);
lv_display_set_flush_cb(disp, my_disp_flush);
#ifdef DIRECT_RENDER_MODE
lv_display_set_buffers(disp, disp_draw_buf, NULL, bufSize * 2, LV_DISPLAY_RENDER_MODE_DIRECT);
#else
lv_display_set_buffers(disp, disp_draw_buf, NULL, bufSize * 2, LV_DISPLAY_RENDER_MODE_PARTIAL);
#endif
/*Initialize the (dummy) input device driver*/
lv_indev_t *indev = lv_indev_create();
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); /*Touchpad should have POINTER type*/
lv_indev_set_read_cb(indev, my_touchpad_read);
}
//====================================================================
// Create LVGL content
lv_obj_t *label_top = lv_label_create(lv_screen_active());
lv_label_set_text(label_top, images_path);
lv_obj_align(label_top, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_t *label_bottom = lv_label_create(lv_screen_active());
lv_label_set_text(label_bottom, "coXXect.blogspot.com");
lv_obj_align(label_bottom, LV_ALIGN_BOTTOM_MID, 0, 0);
/*Create a list*/
list1 = lv_list_create(lv_screen_active());
lv_obj_set_size(list1, 200, 200);
lv_obj_center(list1);
//====================================================================
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
if (!SD.begin(SD_CS))
{
Serial.println(F("ERROR: File System Mount Failed!"));
for(;;); // Fatal error, do not continue
}
else
{
Serial.println(F("File System Mount Successful!"));
}
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE){
Serial.println("No SD card attached");
return;
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\r\n", cardSize);
uint64_t totalBytes = SD.totalBytes();
uint64_t usedBytes = SD.usedBytes();
Serial.printf("SD.totalBytes = %lld \r\n", totalBytes);
Serial.printf("SD.usedBytes = %lld \r\n", usedBytes);
listDir(SD, images_path);
}
void loop() {
lv_task_handler(); /* let the GUI do its work */
#ifdef DIRECT_RENDER_MODE
#if defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)
gfx->flush();
#else // !(defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
gfx->draw16bitRGBBitmap(0, 0, (uint16_t *)disp_draw_buf, screenWidth, screenHeight);
#endif // !(defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
#else // !DIRECT_RENDER_MODE
#ifdef CANVAS
gfx->flush();
#endif
#endif // !DIRECT_RENDER_MODE
delay(5);
}
Next:
~ ESP32S3 (Arduino framework) decode jpg and display on ST7789 SPI Display.
Comments
Post a Comment