亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

在 TFT LCD Shield 上显示来自 SD 卡的 BMP 图片

组件和用品

Arduino UNO
× 1

关于这个项目

您好,本教程是关于 2.4" TFT LCD Shield with Arduino UNO 的其他 2 个教程的后续,所以第一个是关于接口和修复触摸功能问题也倒轴,然后第二个是关于使用简单功能绘制不同的形状以及如何创建触摸按钮以激活某些功能......

Arduino TFT 2.4″ LCD shield 接口与修复触控问题

TFT LCD 2.4″触摸屏屏蔽教程

但是今天我们是关于从 SD 卡读取图像并将它们显示在屏幕上,首先不要忘记将您的 SD 卡插入您的计算机并将其格式化为 FAT32 然后传输您的图像不要忘记它们应该是“BMP”格式,位图 24 !!要获得正确的图像,分辨率应为 240*320,几乎没有解释:

这是屏幕的正常方向,您可以显示240*320的图像,这是默认的旋转方向,即setRotation(0);

如果你 setRotation(1),这是屏幕的方向;现在可以显示320*240的图片了。

所以你可以选择适合你的任何东西,在你的电脑上改变屏幕旋转或图像旋转......然后记住或复制图像名称,就是这样,将你的 SD 卡插入盾牌。

这些是我在 SD 卡上的 bmp 24 位图像的名称,例如“Img1”,我们在代码中使用“Img1.bmp”调用它。

图书馆:

这是对我有用的库:如果您使用此库,请在此处下载,但在尝试使用示例代码时,它会向您显示白屏,您一定要寻找适合您的库。

代码:

这是我在.ino格式的视频中使用的代码,不要忘记更改您正在使用的文件的名称。如果您需要帮助,请不要忘记查看教程。

  • 代码 1
  • 代码 2

代码

  • TFT_Shield_SD_1.ino
  • TFT_Shield_SD_2.ino
TFT_Shield_SD_1.inoArduino
/*此代码用于 2.4" TFT LCD 触摸屏屏蔽,它读取存储在 SD 卡上的 bmp 图像*并将它们显示在屏幕上*更多详细信息请参阅 SurtrTech.com */#include  // 核心图形库#include  // 硬件特定库#include #include #define LCD_CS A3 // 片选进入模拟3#define LCD_CD A2 // 命令/数据进入模拟 2#define LCD_WR A1 // LCD 写入进入模拟 1#define LCD_RD A0 // LCD 读取进入模拟 0#define SD_CS 10 //屏蔽上的 SD 卡引脚Adafruit_TFTLCD tft(LCD_CS, LCD_CD , LCD_WR, LCD_RD, A4);void setup(){ Serial.begin(9600); tft.reset(); uint16_t identifier =tft.readID(); pinMode(10, OUTPUT); digitalWrite(10, HIGH); tft .begin(identifier); if (!SD.begin(SD_CS)) { progmemPrintln(PSTR("failed!")); return; } }void loop(){ bmpDraw("Logo.bmp", 0, 0); //调用bmpDraw函数("Name_of_your_image.bmp",x,y) (x,y)是图片drawi的起始位置ng延迟(2000); bmpDraw("Img2.bmp", 0, 0);延迟(2000); bmpDraw("Img3.bmp", 0, 0); delay(2000);}#define BUFFPIXEL 20 //绘图速度,20是最好的,但你可以使用60虽然它需要很多uno的RAM //绘图功能,从SD卡读取文件并执行//转换和绘图,它还会在出现问题时在串行监视器上显示消息//对此函数没有影响:Dvoid bmpDraw(char *filename, int x, int y) { File bmpFile; int bmpWidth, bmpHeight; // W+H 以像素为单位 uint8_t bmpDepth; // 位深(目前必须是 24) uint32_t bmpImageoffset; // 文件开始图像数据 uint32_t rowSize; // 并非总是 =bmpWidth;可能有填充 uint8_t sdbuffer[3*BUFFPIXEL]; // 缓冲区中的像素(每像素 R+G+B) uint16_t lcdbuffer[BUFFPIXEL]; // 像素输出缓冲区(每像素 16 位) uint8_t buffidx =sizeof(sdbuffer); // 当前位置在 sdbuffer boolean goodBmp =false; // 在有效的标头解析上设置为 true boolean flip =true; // BMP 自下而上存储 int w, h, row, col; uint8_t r, g, b; uint32_t pos =0,startTime =毫秒(); uint8_t lcdidx =0;布尔值第一 =真; if((x>=tft.width()) || (y>=tft.height())) 返回; Serial.println(); progmemPrint(PSTR("加载图像'")); Serial.print(文件名); Serial.println('\''); // 打开 SD 卡上请求的文件 if ((bmpFile =SD.open(filename)) ==NULL) { progmemPrintln(PSTR("File not found"));返回; } // 解析 BMP 头 if(read16(bmpFile) ==0x4D42) { // BMP 签名 progmemPrint(PSTR("File size:")); Serial.println(read32(bmpFile)); (无效)read32(bmpFile); // 读取并忽略创建者字节 bmpImageoffset =read32(bmpFile); // 开始图像数据 progmemPrint(PSTR("Image Offset:")); Serial.println(bmpImageoffset, DEC); // 读取 DIB 头 progmemPrint(PSTR("Header size:")); Serial.println(read32(bmpFile)); bmpWidth =read32(bmpFile); bmpHeight =read32(bmpFile); if(read16(bmpFile) ==1) { // # 平面 -- 必须是 '1' bmpDepth =read16(bmpFile); // 每像素位数 progmemPrint(PSTR("Bit Depth:")); Serial.println(bmpDepth); if((bmpDepth ==24) &&(read32(bmpFile) ==0)) { // 0 =未压缩的 goodBmp =true; // 支持的 BMP 格式——继续! progmemPrint(PSTR("图片尺寸:")); Serial.print(bmpWidth); Serial.print('x'); Serial.println(bmpHeight); // BMP 行被填充(如果需要)到 4 字节边界 rowSize =(bmpWidth * 3 + 3) &~3; // 如果 bmpHeight 为负,则图像为自上而下的顺序。 // 这不是经典,而是在野外观察到的。 if(bmpHeight <0) { bmpHeight =-bmpHeight;翻转 =假; } // 要加载的裁剪区域 w =bmpWidth; h =bmpHeight; if((x+w-1)>=tft.width()) w =tft.width() - x; if((y+h-1)>=tft.height()) h =tft.height() - y; // 将 TFT 地址窗口设置为裁剪图像边界 tft.setAddrWindow(x, y, x+w-1, y+h-1); for (row=0; row=sizeof(sdbuffer)) { // 确实 // 先将 LCD 缓冲区推送到显示器 if(lcdidx> 0) { tft.pushColors(lcdbuffer, lcdidx, first); lcdidx =0;第一个 =假; bmpFile.read(sdbuffer, sizeof(sdbuffer)); buffidx =0; // 将索引设置为开始 } // 将像素从 BMP 转换为 TFT 格式 b =sdbuffer[buffidx++]; g =sdbuffer[buffidx++]; r =sdbuffer[buffidx++]; lcdbuffer[lcdidx++] =tft.color565(r,g,b); } // 结束像素 } // 结束扫描线 // 将任何剩余数据写入 LCD if(lcdidx> 0) { tft.pushColors(lcdbuffer, lcdidx, first); } progmemPrint(PSTR("载入")); Serial.print(millis() - startTime); Serial.println("毫秒"); } // 结束goodBmp } } bmpFile.close(); if(!goodBmp) progmemPrintln(PSTR("BMP 格式无法识别。"));}// 这些从 SD 卡文件中读取 16 位和 32 位类型。// BMP 数据是小端存储的,Arduino 是小端-endian 也是。// 如果移植到别处,可能需要颠倒下标顺序。uint16_t read16(File f) { uint16_t result; ((uint8_t *)&result)[0] =f.read(); // LSB ((uint8_t *)&result)[1] =f.read(); // MSB 返回结果;}uint32_t read32(File f) { uint32_t result; ((uint8_t *)&result)[0] =f.read(); // LSB ((uint8_t *)&result)[1] =f.read(); ((uint8_t *)&result)[2] =f.read(); ((uint8_t *)&result)[3] =f.read(); // MSB 返回结果;}// 将字符串从闪存复制到串行端口// 源字符串必须在 PSTR() 声明中!void progmemPrint(const char *str) { char c; while(c =pgm_read_byte(str++)) Serial.print(c);}// 同上,尾随 newlinevoid progmemPrintln(const char *str) { progmemPrint(str); Serial.println();}
TFT_Shield_SD_2.inoArduino
/*此代码适用于带有 UNO 板的 2.4" TFT LCD 触摸屏护罩 * 它创建了一个小的图像幻灯片,根据您在屏幕上按下的位置而变化 * 图像是从 SD 卡读取的 * 请参阅到 SurtrTech.com 获取更多详细信息 */#include  // 核心图形库#include  // 硬件特定库#include #include  #include  //触摸屏函数库#if defined(__SAM3X8E__) #undef __FlashStringHelper::F(string_literal) #define F(string_literal) string_literal#endif//下面的参数取决于你的屏蔽,所以确保引脚是正确#define YP A3 // 必须是模拟引脚,使用“An”符号!#define XM A2 // 必须是模拟引脚,使用“An”符号!#define YM 9 // 可以是数字引脚#define XP 8 // 可以是数字引脚//不要忘记如果您的触摸功能不起作用,请检查上面的值可能是 (A1 A2 7 6) resp // 校准您可能使用的值ant 首先运行校准代码并设置这些点#define TS_MINX 176#define TS_MINY 159#define TS_MAXX 921#define TS_MAXY 884#define MINPRESSURE 10#define MAXPRESSURE 1000TouchScreen ts =TouchScreen(XP, YP, XM, YM); #define LCD_CS A3 // 片选进入模拟 3#define LCD_CD A2 // 命令/数据进入模拟 2#define LCD_WR A1 // LCD 写入进入模拟 1#define LCD_RD A0 // LCD 读取进入模拟 0#定义 SD_CS 10 // 将片选线设置为您使用的任何内容 Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, A4);char x[]="x1.bmp";/*在这段代码中,我将名称声明为数组 * 所以如果我想滚动,我可以做修改 * 确保你的图像有一个像“1”这样的数字,这样你就可以增加或减少 * 转到下一个图像 */void setup(){ Serial.begin( 9600); tft.reset(); uint16_t 标识符 =tft.readID(); pinMode(10,输出);数字写入(10,高); tft.begin(标识符); if (!SD.begin(SD_CS)) { progmemPrintln(PSTR("failed!"));返回; } tft.setRotation(1); //将屏幕旋转90° bmpDraw(x, 0, 0); //我们绘制第一个图像,即 x -> "x1.bmp" 正如我们所声明的}void loop(){if(x[1]<49) //所以我们不会去这里添加一些奇怪的值值 x[1]=49 的重置; //如果我们已经在第一张图片中,我们就留在那里,lastif(x[1]>52) 也是如此 //字符中的“1”是“49”,“4”是“52”我把它们写在这种格式,所以我可以操纵他们x[1]=52; TSPoint p =ts.getPoint(); //检查用户是否触摸了屏幕 pinMode(XM, OUTPUT); pinMode(YP,输出); if (pz> MINPRESSURE &&pz  0 &&py <100 ){ Serial.println("左"); //我这样做是为了在串行监视器上显示我按下了左 x[1]=x[1]-1; //这里我们改变我们要读取的文件名 x[]="x1.bmp" 并且 x[1] 是名称中的 1 而 x[0] 是 x bmpDraw(x, 0, 0); //所以我所做的只是增加它使其成为2或减少它使其成为0(请参阅第一个“if”以查看这种情况的解决方案,因为0不存在) delay(300); //然后我绘制的图像现在根据我按下的那一侧具有不同的名称 } //添加一点延迟以便触摸检测不会反弹 else if(py>200 &&py <320){ Serial.println("Right "); x[1]=x[1]+1; bmpDraw(x, 0, 0);延迟(300); } } }#define BUFFPIXEL 20 //打印速度20应该是最好的,你可以到60但是使用太多内存//绘图功能不敏感 :Dvoid bmpDraw(char *filename, int x, int y) {文件 bmpFile; int bmpWidth, bmpHeight; // W+H 以像素为单位 uint8_t bmpDepth; // 位深(目前必须是 24) uint32_t bmpImageoffset; // 文件开始图像数据 uint32_t rowSize; // 并非总是 =bmpWidth;可能有填充 uint8_t sdbuffer[3*BUFFPIXEL]; // 缓冲区中的像素(每像素 R+G+B) uint16_t lcdbuffer[BUFFPIXEL]; // 像素输出缓冲区(每像素 16 位) uint8_t buffidx =sizeof(sdbuffer); // 当前位置在 sdbuffer boolean goodBmp =false; // 在有效的标头解析上设置为 true boolean flip =true; // BMP 自下而上存储 int w, h, row, col; uint8_t r, g, b; uint32_t pos =0,startTime =毫秒(); uint8_t lcdidx =0;布尔值第一 =真; if((x>=tft.width()) || (y>=tft.height())) 返回; Serial.println(); progmemPrint(PSTR("加载图像'")); Serial.print(文件名); Serial.println('\''); // 打开 SD 卡上请求的文件 if ((bmpFile =SD.open(filename)) ==NULL) { progmemPrintln(PSTR("File not found"));返回; } // 解析 BMP 头 if(read16(bmpFile) ==0x4D42) { // BMP 签名 progmemPrint(PSTR("File size:")); Serial.println(read32(bmpFile)); (无效)read32(bmpFile); // 读取并忽略创建者字节 bmpImageoffset =read32(bmpFile); // 开始图像数据 progmemPrint(PSTR("Image Offset:")); Serial.println(bmpImageoffset, DEC); // 读取 DIB 头 progmemPrint(PSTR("Header size:")); Serial.println(read32(bmpFile)); bmpWidth =read32(bmpFile); bmpHeight =read32(bmpFile); if(read16(bmpFile) ==1) { // # 平面 -- 必须是 '1' bmpDepth =read16(bmpFile); // 每像素位数 progmemPrint(PSTR("Bit Depth:")); Serial.println(bmpDepth); if((bmpDepth ==24) &&(read32(bmpFile) ==0)) { // 0 =未压缩的 goodBmp =true; // 支持的 BMP 格式——继续! progmemPrint(PSTR("图片尺寸:")); Serial.print(bmpWidth); Serial.print('x'); Serial.println(bmpHeight); // BMP 行被填充(如果需要)到 4 字节边界 rowSize =(bmpWidth * 3 + 3) &~3; // 如果 bmpHeight 为负,则图像为自上而下的顺序。 // 这不是经典,而是在野外观察到的。 if(bmpHeight <0) { bmpHeight =-bmpHeight;翻转 =假; } // 要加载的裁剪区域 w =bmpWidth; h =bmpHeight; if((x+w-1)>=tft.width()) w =tft.width() - x; if((y+h-1)>=tft.height()) h =tft.height() - y; // 将 TFT 地址窗口设置为裁剪图像边界 tft.setAddrWindow(x, y, x+w-1, y+h-1); for (row=0; row=sizeof(sdbuffer)) { // 确实 // 先将 LCD 缓冲区推送到显示器 if(lcdidx> 0) { tft.pushColors(lcdbuffer, lcdidx, first); lcdidx =0;第一个 =假; bmpFile.read(sdbuffer, sizeof(sdbuffer)); buffidx =0; // 将索引设置为开始 } // 将像素从 BMP 转换为 TFT 格式 b =sdbuffer[buffidx++]; g =sdbuffer[buffidx++]; r =sdbuffer[buffidx++]; lcdbuffer[lcdidx++] =tft.color565(r,g,b); } // 结束像素 } // 结束扫描线 // 将任何剩余数据写入 LCD if(lcdidx> 0) { tft.pushColors(lcdbuffer, lcdidx, first); } progmemPrint(PSTR("载入")); Serial.print(millis() - startTime); Serial.println("毫秒"); } // 结束goodBmp } } bmpFile.close(); if(!goodBmp) progmemPrintln(PSTR("BMP 格式无法识别。"));}// 这些从 SD 卡文件中读取 16 位和 32 位类型。// BMP 数据是小端存储的,Arduino 是小端-endian 也是。// 如果移植到别处,可能需要颠倒下标顺序。uint16_t read16(File f) { uint16_t result; ((uint8_t *)&result)[0] =f.read(); // LSB ((uint8_t *)&result)[1] =f.read(); // MSB 返回结果;}uint32_t read32(File f) { uint32_t result; ((uint8_t *)&result)[0] =f.read(); // LSB ((uint8_t *)&result)[1] =f.read(); ((uint8_t *)&result)[2] =f.read(); ((uint8_t *)&result)[3] =f.read(); // MSB 返回结果;}// 将字符串从闪存复制到串行端口// 源字符串必须在 PSTR() 声明中!void progmemPrint(const char *str) { char c; while(c =pgm_read_byte(str++)) Serial.print(c);}// 同上,尾随 newlinevoid progmemPrintln(const char *str) { progmemPrint(str); Serial.println();}

示意图

这是盾牌 :D

制造工艺

  1. 贺卡
  2. 信用卡
  3. 液晶显示器 (LCD)
  4. 数据模块:23.1 英寸超拉伸 TFT 显示屏,智能控制
  5. Distec:来自 Ortustech 的坚固、阳光下可读的 7 英寸 TFT 显示屏
  6. 同意:GPU-PC 从显卡中获得性能
  7. 展览:原始展示
  8. Kuman TFT 3.5 RetroPie 2018
  9. AI 从简单的基于文本的食谱中生成已完成膳食的图像
  10. ILI9341 TFT 触摸屏显示盾上的位图动画
  11. Arduino Spybot
  12. Dodge The Defs!