单片机/MCUwilliam hill官网
直播中

sipower

4年用户 26经验值
擅长:嵌入式技术
私信 关注

【FireBeetle 2 ESP32-S3开发板体验】003:增加屏幕和SD卡组件

本帖最后由 sipower 于 2023-8-13 20:25 编辑


上一帖介绍搭建MicroPython开发环境,并在此基础上设计一个天气时钟。这一贴介绍增加屏幕和SD卡组件,并通过Arduino编写基础程序模块,为后面实验做准备。本次实验要实现的功能:
焊接屏幕组件;调试显示和触摸;调试SD卡;SD卡上的大分辨率图片缩小显示。

这次测评只提供了FireBeetle 2ESP32-S3这个实验板,没有配套屏幕,DFRobot官网倒是可以买到他们GDI专用接口的屏幕,如下图所示,但是太贵了,买这个有点肉疼,所以我只好换个思路,从淘宝找个便宜的替代品。

001.png
图1、DFRobot官网GDI接口的屏幕
淘宝这个屏幕带的是电阻触摸屏,尺寸和分辨率和DFRobot官网一样,同样也预留SD卡接口,完全能满足我这次设计需求。屏幕模组图片如下。
002.jpg
图2、淘宝屏幕模组
这个屏幕资料还是挺全面的,用起来很方便,资料链接如下。
http://www.lcdwiki.com/zh/3.5inch_SPI_Module_ILI9488_SKU:MSP3520
目前网上搜索涉及到ESP32-S3接摄像头的操作,大部分是基于ESP-IDF或者Arduino平台的,ESP-IDF的难度系数有点高,暂时玩不转,因此后面所有实验均是基于Arduino平台的。
第一个任务,焊接屏幕组件。由于买来的屏幕模组只有DIP插针接口,要想和FireBeetle 2开发板连起来,需要焊接10根线。其中SPI和电源是显示、触摸、SD卡共用的,背光、片选都是独立线。如下图所示。
003.png
图3、屏幕模组接口
焊接这个线还是挺有挑战的,但是想到能省点有限的预算,咬咬牙还是得上。为了让屏幕和实验板能重复使用,我是先安装了插母,然后在插母上焊接导线,这样以后想接别的外设,可以很方便的拆下。经过两个晚上的努力,成果如下,而且一次成功。
004.jpg
图4、模组焊接完成
第二个任务,调试显示和触摸。在Arduino平台点屏,那肯定首选《TFT_eSPI》这个库了。使用这个库,首先就是要安装这个库文件,其他帖子介绍的比较多,此处不再赘述。然后最主要的一项工作就是配置屏幕参数头文件。我参照其他用ILI9488这个芯片的屏幕头文件改造了一下,并命名为《Setup208_ESP32_T_ILI9488_S3.h》,然后在《User_Setup_Select.h》这个头文件里面调用。在ArduinoIDE中打开《Animated_Eyes_1》这个例程,什么不用改直接运行,就可以成功显示了,如下图。
005.jpg
图5、显示调试成功
调试触摸屏的时候出现一点小插曲,下载测试程序后,触摸屏不好用,我反复检查焊接都没有发现问题,最后检查程序,才发现原来在改引用的头文件时,由于原来那个屏幕没有触摸,其中SPI输入引脚设置为:
#defineTFT_MISO -1
是没有使用的,我这个漏改了,我改正后触摸屏就好用。测试效果如下图。
006.jpg
图6、触摸调试成功
第三个任务,调试SD卡。使用SD卡,最重要的是片选要设置好,在SD.begin(GDI_SDCS)语句中设置,我看到好多新手发帖子说SD卡不好使,大部分就是这个没设置。我使用SD卡的目的是存储和显示JPEG图片,因此选用的是《ESP32_SDcard_jpeg》这个例程。其中为了实现JPEG解码,还需要安装《JPEGDecoder》库文件。将例程中的图片拷贝到SD卡上,然后运行程序,显示结果如下。
007.jpg
图7、SD调试成功。
第四个任务,SD卡上的大分辨率图片缩小显示。我预期的功能是用摄像头拍照并显示到屏幕上,摄像头拍摄照片分辨率是1600*1200,屏幕分辨率是是480*320,直接显示的话,只能看到一个角。我PS了一张1600*1200的图片放到卡上显示,原图和屏幕直接显示效果如下图。
008.JPG
图8、原图和屏幕显示效果
由上图可见,基本上就看不出来要显示的是什么内容了。要想全幅显示出来,就要缩小图片,但当前的解码程序不支持缩小分辨率的功能。经过群友提醒,有些JPEG的库是支持缩放的,我就搜索Scale这个关键词,最终还真被我找到了,就是《TFT_eSPI》这个库的作者Bodmer,在GitHub上回复一个话题说他新做了一个库《TJpg_Decoder》,是支持缩小分辨率的,采用的是抽点方式,虽然不如色块平均法效果好,但是在32位MCU上运行效率还是非常不错的。
有了大神的基础工作,我想实现的功能就简单了。然后就是迅速下载《TJpg_Decoder》库,上例程开始调试。关于GitHub下载文件,这有个小窍门,当GitHub网站打不开时,可以在域名前面加个K,就是KGitHub,然后就可以打开国内镜像网站了,速度还是很不错的。
经过我的一通改造,终于实现了放在SD卡上的图片使用《TJpg_Decoder》库缩小后显示到屏幕上,下面是代码和视频。

整体代码如下。
  1. // Example for library:
  2. // https://github.com/Bodmer/TJpg_Decoder
  3. // This example if for an ESP8266 or ESP32, it renders a Jpeg file
  4. // that is stored in a SD card file. The test image is in the sketch
  5. // "data" folder (press Ctrl+K to see it). You must save the image
  6. // to the SD card using you PC.
  7. // Include the jpeg decoder library
  8. #include
  9. // Include SD
  10. #define FS_NO_GLOBALS
  11. #include
  12. #ifdef ESP32
  13.   #include "SPIFFS.h" // ESP32 only
  14. #endif
  15. #define SD_CS   4
  16. // Include the TFT library https://github.com/Bodmer/TFT_eSPI
  17. #include "SPI.h"
  18. #include               // Hardware-specific library
  19. TFT_eSPI tft = TFT_eSPI();         // Invoke custom library
  20. // This next function will be called during decoding of the jpeg file to
  21. // render each block to the TFT.  If you use a different TFT library
  22. // you will need to adapt this function to suit.
  23. bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap)
  24. {
  25.    // Stop further decoding as image is running off bottom of screen
  26.   if ( y >= tft.height() ) return 0;
  27.   // This function will clip the image block rendering automatically at the TFT boundaries
  28.   tft.pushImage(x, y, w, h, bitmap);
  29.   // This might work instead if you adapt the sketch to use the Adafruit_GFX library
  30.   // tft.drawRGBBitmap(x, y, bitmap, w, h);
  31.   // Return 1 to decode next block
  32.   return 1;
  33. }
  34. void setup()
  35. {
  36.   Serial.begin(115200);
  37.   Serial.println("\n\n Testing TJpg_Decoder library");
  38.   // Set all chip selects high to avoid bus contention during initialisation of each peripheral
  39.   pinMode(GDI_CS, OUTPUT);
  40.   pinMode(GDI_TCS, OUTPUT);
  41.   pinMode(GDI_SDCS, OUTPUT);
  42.   digitalWrite(GDI_TCS, HIGH); // Touch controller chip select (if used)
  43.   digitalWrite(GDI_CS, HIGH); // TFT screen chip select
  44.   digitalWrite(GDI_SDCS, HIGH); // SD card chips select, must use GPIO 5 (ESP32 SS)
  45.   // Initialise SD before TFT
  46.   if (!SD.begin(GDI_SDCS)) {
  47.     Serial.println(F("SD.begin failed!"));
  48.     while (1) delay(0);
  49.   }
  50.   Serial.println("\r\nInitialisation done.");
  51.   // Initialise the TFT
  52.   tft.begin();
  53.   tft.setTextColor(0xFFFF, 0x0000);
  54.   tft.fillScreen(TFT_BLACK);
  55.   tft.setSwapBytes(true); // We need to swap the colour bytes (endianess)
  56.   // The jpeg image can be scaled by a factor of 1, 2, 4, or 8
  57.   TJpgDec.setJpgScale(1);
  58.   // The decoder must be given the exact name of the rendering function above
  59.   TJpgDec.setCallback(tft_output);
  60. }
  61. void loop()
  62. {
  63.   tft.fillScreen(TFT_RED);
  64.   // Time recorded for test purposes
  65.   uint32_t t = millis();
  66.   // Get the width and height in pixels of the jpeg if you wish
  67.   uint16_t w = 0, h = 0;
  68.   TJpgDec.getSdJpgSize(&w, &h, "/panda.jpg");
  69.   Serial.print("Width = "); Serial.print(w); Serial.print(", height = "); Serial.println(h);
  70.   // Draw the image, top left at 0,0
  71.   TJpgDec.drawSdJpg(0, 0, "/panda.jpg");
  72.   // How much time did rendering take
  73.   t = millis() - t;
  74.   Serial.print(t); Serial.println(" ms");
  75.   // Wait before drawing again
  76.   delay(2000);
  77.   //////////////////////////////////////////////////////////////////////////////////////////////////////////
  78.   tft.setRotation(1);  // portrait
  79.   //////////////////////////////////////////////////////////////////////////////////////////////////////////
  80.   tft.fillScreen(TFT_RED);
  81.   t = millis();
  82.   TJpgDec.setJpgScale(1);
  83.   // Get the width and height in pixels of the jpeg if you wish
  84.   TJpgDec.getSdJpgSize(&w, &h, "/3.jpg");
  85.   Serial.print("Width = "); Serial.print(w); Serial.print(", height = "); Serial.println(h);
  86.   // Draw the image, top left at 0,0
  87.   TJpgDec.drawSdJpg(0, 0, "/3.jpg");
  88.   // How much time did rendering take
  89.   t = millis() - t;
  90.   Serial.print(t); Serial.println(" ms");
  91.   // Wait before drawing again
  92.   delay(2000);
  93.   //////////////////////////////////////////////////////////////////////////////////////////////////////////
  94.   tft.fillScreen(TFT_RED);
  95.   t = millis();
  96.   TJpgDec.setJpgScale(2);
  97.   // Get the width and height in pixels of the jpeg if you wish
  98.   TJpgDec.getSdJpgSize(&w, &h, "/3.jpg");
  99.   Serial.print("Width = "); Serial.print(w); Serial.print(", height = "); Serial.println(h);
  100.   // Draw the image, top left at 0,0
  101.   TJpgDec.drawSdJpg(0, 0, "/3.jpg");
  102.   // How much time did rendering take
  103.   t = millis() - t;
  104.   Serial.print(t); Serial.println(" ms");
  105.   // Wait before drawing again
  106.   delay(2000);
  107.   //////////////////////////////////////////////////////////////////////////////////////////////////////////
  108.   tft.fillScreen(TFT_RED);
  109.   t = millis();
  110.   TJpgDec.setJpgScale(4);
  111.   // Get the width and height in pixels of the jpeg if you wish
  112.   TJpgDec.getSdJpgSize(&w, &h, "/3.jpg");
  113.   Serial.print("Width = "); Serial.print(w); Serial.print(", height = "); Serial.println(h);
  114.   // Draw the image, top left at 0,0
  115.   TJpgDec.drawSdJpg(0, 0, "/3.jpg");
  116.   // How much time did rendering take
  117.   t = millis() - t;
  118.   Serial.print(t); Serial.println(" ms");
  119.   // Wait before drawing again
  120.   delay(2000);
  121.   Serial.println("finished!");
  122.   while (1);
  123. }

展示视频如下。

缩小图片

回帖(1)

sipower

2023-8-12 23:12:57
本帖最后由 sipower 于 2023-8-13 20:27 编辑

附件是代码打包,《Setup208_ESP32_T_ILI9488_S3.h》为屏幕设置
《SD_Jpg.ino》为主程序


code.zip (2.03 KB)
(下载次数: 1, 2023-8-13 20:27 上传)


举报

更多回帖

发帖
×
20
完善资料,
赚取积分