数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 10436|回复: 23

[Arduino] esp8266 + ILI9341 +DHT11 显示图片教程

[复制链接]
发表于 2019-9-20 14:54:04 | 显示全部楼层 |阅读模式
本帖最后由 wei27311 于 2019-9-23 21:23 编辑

接线:
VCC -> 3.3V
GND -> GND
CS -> D8
RESET -> D2
DC/RS -> D1
SDI/MOSI -> D7
SCK -> D5
LED -> 3.3V或PWM控制亮度


我用的是SPI接口的ILI9341彩色LCD
这个屏幕需要在上电的时候复位一次才能显示否则直接白屏
很多的Arduino驱动库是不包含这一步的
例如现在用的Adafruit_GFX库
所以一定要注意这一点
具体的做法就是在reset引脚先给低电平
然后再给高电平
屏幕运行期间reset引脚需要一直给高电平
否则就白屏了


Adafruit_GFX库可以理解为是一个接口它提供了通用的方法
需要搭配具体的屏幕驱动库一起使用
在这里需要搭配Adafruit_ILI9341
关于Adafruit_GFX这个库的详细介绍可以登陆下面连接查看
https://electropeak.com/learn/absolute-beginners-guide-to-tft-lcd-displays-by-arduino/

显示图片的原理其实就是把一张图片通过软件
把每一个像素点变成十六位的RGB数值
然后存入一个数组里面传输到LCD显示
我们常用的图片是RGB888 24位的颜色 一个像素点要3个字节
但是一般这种LCD用的是RGB565 是16位的颜色 一个像素点只需要2个字节
所以要用转换软件
这里推荐用picture2hex


第一步:

用AI设计好仪表盘的背景图


第二部:
导出成RGB565的BMP文件


第三部:
picture2hex软件转换成数组
注意要选好分辨率生成好的数组在picture2hex软件根目录的work文件夹里面


第四部:

在arduino 项目文件夹里新建一个 h文件
picture2hex生成的数组放入
const uint16_t bg[] PROGMEM = { //code };


第五步:
编译并上传到esp8266.


由于esp8266图形处理能力不高
在这个温湿度计中只有指针和温度值是实时画出来的
其他都是一张图片
底图只加载一次
每次刷新画出指针以及打印出温度值
延时一定时间后用背景色清除掉
另外这个屏幕只有65k色彩
色域很窄过渡不够自然
底图不适合用渐变效果
色差与电脑屏幕相差非常大


  1. #include "bg.h"
  2. #include <dht11.h>
  3. #define DHT11PIN D6
  4. dht11 DHT11;
  5. #include <Adafruit_ILI9341.h>
  6. #define lcdreset D2
  7. #define TFT_DC D1
  8. #define TFT_CS D8
  9. Adafruit_ILI9341 ucg = Adafruit_ILI9341(TFT_CS, TFT_DC);
  10. #define bgcolor ucg.color565(102,102,102)
  11. #define WHITE ucg.color565(255,255,255)

  12. int chk;
  13. int tem;
  14. int hum;   
  15. int tem2 = 0;
  16. int hum2 = 0;

  17. void Clear1(int value)
  18. {
  19.   int cx = 160;  //圆心x
  20.   int cy = 120;  //圆心y
  21.   int cr = 118;  //外圆半径r  

  22.   //清除湿度指针
  23.   for(int i=0;i<=15;i++)
  24.   {
  25.     int v = 300 + value * 9;  
  26.     int v2 = (300 + value * 9) - i;
  27.     int v3 = (300 + value * 9) + i;
  28.     int line1_x0 = floor(cx + (cr - 135) * cos(2 * PI / 1200 * v2));
  29.     int line1_y0 = floor(cy + (cr - 135) * sin(2 * PI / 1200 * v2));  
  30.     int line1_x1 = floor(cx + (cr - 40) * cos(2 * PI / 1200 * v));
  31.     int line1_y1 = floor(cy + (cr - 40) * sin(2 * PI / 1200 * v));  
  32.     int line2_x0 = floor(cx + (cr - 135) * cos(2 * PI / 1200 * v3));
  33.     int line2_y0 = floor(cy + (cr - 135) * sin(2 * PI / 1200 * v3));  
  34.     int line2_x1 = floor(cx + (cr - 40) * cos(2 * PI / 1200 * v));
  35.     int line2_y1 = floor(cy + (cr - 40) * sin(2 * PI / 1200 * v));
  36.     ucg.drawLine(line1_x0,line1_y0,line1_x1,line1_y1,bgcolor);
  37.     ucg.drawLine(line2_x0,line2_y0,line2_x1,line2_y1,bgcolor);
  38.   }  
  39. }

  40. void draw1(int value)
  41. {
  42.   int cx = 160;  //圆心x
  43.   int cy = 120;  //圆心y
  44.   int cr = 118;  //外圆半径r

  45.   //湿度中心圆
  46.   ucg.drawCircle(cx,cy,10,CYAN);
  47.   
  48.   //湿度指针
  49.   for(int i=0;i<=15;i++)
  50.   {
  51.     int v = 300 + value * 9;  
  52.     int v2 = (300 + value * 9) - i;
  53.     int v3 = (300 + value * 9) + i;
  54.     int line1_x0 = floor(cx + (cr - 135) * cos(2 * PI / 1200 * v2));
  55.     int line1_y0 = floor(cy + (cr - 135) * sin(2 * PI / 1200 * v2));  
  56.     int line1_x1 = floor(cx + (cr - 40) * cos(2 * PI / 1200 * v));
  57.     int line1_y1 = floor(cy + (cr - 40) * sin(2 * PI / 1200 * v));  
  58.     int line2_x0 = floor(cx + (cr - 135) * cos(2 * PI / 1200 * v3));
  59.     int line2_y0 = floor(cy + (cr - 135) * sin(2 * PI / 1200 * v3));  
  60.     int line2_x1 = floor(cx + (cr - 40) * cos(2 * PI / 1200 * v));
  61.     int line2_y1 = floor(cy + (cr - 40) * sin(2 * PI / 1200 * v));
  62.     ucg.drawLine(line1_x0,line1_y0,line1_x1,line1_y1,WHITE);
  63.     ucg.drawLine(line2_x0,line2_y0,line2_x1,line2_y1,WHITE);
  64.   }  
  65. }

  66. void Clear2()
  67. {
  68.   int cx = 160;  //圆心x
  69.   int cy = 120;  //圆心y

  70.   //清除内圆数值
  71.   ucg.fillRect((cx + 18),(cy + 45),35,30,bgcolor);  
  72. }

  73. void draw2(int value2)
  74. {
  75.   int cx = 160;  //圆心x
  76.   int cy = 120;  //圆心y
  77.   
  78.   //内圆显示数值
  79.   ucg.setTextSize(3);
  80.   ucg.setTextColor(WHITE);
  81.   ucg.setCursor((cx + 18),(cy + 37));
  82.   ucg.print(value2);   
  83. }

  84. void setup()
  85. {
  86.   pinMode(DHT11PIN,OUTPUT);
  87.   pinMode(lcdreset,OUTPUT);
  88.   digitalWrite(lcdreset,LOW);
  89.   delay(10);
  90.   digitalWrite(lcdreset,HIGH);   
  91.   ucg.begin();
  92.   ucg.setRotation(1); //屏幕旋转90度
  93.   ucg.drawRGBBitmap(0,0,bg,320,240);
  94.   delay(100);
  95.   draw1(hum2);
  96.   draw2(tem2);
  97. }

  98. void loop()
  99. {
  100.   chk = DHT11.read(DHT11PIN); //将读取到的值赋给chk
  101.   tem=(float)DHT11.temperature; //将温度值赋值给tem
  102.   hum=(float)DHT11.humidity;   //将湿度值赋值给hum

  103.   if(hum2 != hum)
  104.   {
  105.     Clear1(hum2);
  106.     hum2 = hum;
  107.     draw1(hum2);
  108.   }
  109.   else
  110.   {
  111.    
  112.   }

  113.   if(tem2 != tem)
  114.   {
  115.     Clear2(tem2);
  116.     tem2 = tem;
  117.     draw2(tem2);
  118.   }
  119.   else
  120.   {
  121.    
  122.   }
  123. }
复制代码









本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x

打赏

参与人数 4家元 +120 收起 理由
wenxueroom + 20 優秀文章
钟义亭 + 4 優秀文章
家睦 + 80
飞向狙沙 + 16 謝謝分享

查看全部打赏

 楼主| 发表于 2019-9-21 23:06:06 | 显示全部楼层
本帖最后由 wei27311 于 2019-9-23 17:13 编辑

这个压缩包包含了AI源文件以及Arduino源代码
电脑上设计的时候感觉还行
LCD显示效果大打折扣手机拍出来的效果更差



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
回复 支持 反对

使用道具 举报

发表于 2019-9-20 15:21:06 | 显示全部楼层
这个不错,感谢分享!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-20 15:35:57 来自手机浏览器 | 显示全部楼层
jmx1124 发表于 2019-9-20 15:21
这个不错,感谢分享!

感谢支持
回复 支持 反对

使用道具 举报

发表于 2019-9-21 07:11:37 | 显示全部楼层
确实很漂亮.

不过非IPS的TFT屏幕效果确实不够好,

我没细玩ES8226,
不过我 的 STM32F401@72MHz刷 320*240 (8位总线16位色)已经有 20+ 帧了,
ESP8226 主频不是有200M 吗, 刷新率应该可以吧...
还是SPI速率被限制了?
回复 支持 反对

使用道具 举报

发表于 2019-9-21 07:52:56 | 显示全部楼层
很好看,学习了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-21 11:51:31 来自手机浏览器 | 显示全部楼层
junyee 发表于 2019-9-21 07:11
确实很漂亮.

不过非IPS的TFT屏幕效果确实不够好,

全图刷新20帧吗?
我现在只刷新指针和数值
刷新的时候能明显看到闪烁
所以改为1秒刷新一次
回复 支持 反对

使用道具 举报

发表于 2019-9-21 13:27:43 | 显示全部楼层
wei27311 发表于 2019-9-21 11:51
全图刷新20帧吗?
我现在只刷新指针和数值
刷新的时候能明显看到闪烁

当然是 全屏刷新..


论坛不能传视频..
链接: https://pan.baidu.com/s/1aHA2_K3W4RBHL4iwT7ce8g 提取码: mtcr

回复 支持 反对

使用道具 举报

发表于 2019-9-21 13:31:54 来自手机浏览器 | 显示全部楼层
还可以这样生成图片,学习了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-21 13:37:45 来自手机浏览器 | 显示全部楼层
junyee 发表于 2019-9-21 13:27
当然是 全屏刷新..



你那个很流畅
我这个如果每次都全图刷新会死机
延时1秒刷新都不行
esp8266估计性能还是比不过stm32吧
不过与驱动库也有关系
我之前用ucglib 那库刷新更慢
回复 支持 反对

使用道具 举报

发表于 2019-9-21 17:36:35 | 显示全部楼层
wei27311 发表于 2019-9-21 13:37
你那个很流畅
我这个如果每次都全图刷新会死机
延时1秒刷新都不行

esp8266   比 stm32 M3/M4 可能要强吧,
你这个刷新慢有可能是底层的拖累...
回复 支持 反对

使用道具 举报

发表于 2019-9-22 09:41:12 来自手机浏览器 | 显示全部楼层
既然有8226了还要dht11干嘛?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-22 13:39:14 来自手机浏览器 | 显示全部楼层
触景情伤 发表于 2019-9-22 09:41
既然有8226了还要dht11干嘛?

这是一个温湿度计啊
当然需要温湿度传感器
图片只是一张背景图
关键在于根据传感器的数值画出指针啊
回复 支持 反对

使用道具 举报

发表于 2019-9-22 15:09:55 来自手机浏览器 | 显示全部楼层
wei27311 发表于 2019-9-22 13:39
这是一个温湿度计啊
当然需要温湿度传感器
图片只是一张背景图

8226不是可以从网上爬出来这些数据吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-22 16:06:09 来自手机浏览器 | 显示全部楼层
触景情伤 发表于 2019-9-22 15:09
8226不是可以从网上爬出来这些数据吗?

网上的数据跟传感器的数据没可比性
传感器能很灵敏的显示当前环境的数值
就像同样是30度
之前湿度达到80以上就会觉得很闷热
这几天湿度只有不到40
吹风扇都觉得有点凉了
其实在一个季节当中温度相当固定
湿度在不同时刻不同情况下会有大幅度的改变
这就是为什么我把湿度做成指针仪表
而温度直接显示出来的原因
回复 支持 反对

使用道具 举报

发表于 2019-9-22 16:22:07 来自手机浏览器 | 显示全部楼层
wei27311 发表于 2019-9-22 16:06
网上的数据跟传感器的数据没可比性
传感器能很灵敏的显示当前环境的数值
就像同样是30度

dht11有负温度显示吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-9-22 16:53:00 来自手机浏览器 | 显示全部楼层
触景情伤 发表于 2019-9-22 16:22
dht11有负温度显示吗?

没有
DHT11温度量程是0-50
测负温度要用DHT12
那个量程是-20 - 60
回复 支持 反对

使用道具 举报

发表于 2019-9-28 06:59:41 | 显示全部楼层
wei27311 发表于 2019-9-22 16:53
没有
DHT11温度量程是0-50
测负温度要用DHT12

这块屏没有见过,真不错
回复 支持 反对

使用道具 举报

发表于 2019-11-24 18:33:22 | 显示全部楼层
高分辨率彩屏不适合SPI,也不适合这样效率低的方式驱动。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-10-24 04:44 , Processed in 0.156000 second(s), 14 queries , Gzip On, Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表