diff --git a/atom.xml b/atom.xml index 9a23081..b1299a6 100644 --- a/atom.xml +++ b/atom.xml @@ -6,7 +6,7 @@ - 2024-06-01T04:36:43.486Z + 2024-06-26T13:49:12.700Z https://levi52.github.io/ @@ -21,7 +21,7 @@ https://levi52.github.io/posts/df56fc06/ 2024-06-01T03:07:20.000Z - 2024-06-01T04:36:43.486Z + 2024-06-26T13:49:12.700Z ESP32 UV BOX diff --git a/index.html b/index.html index 8839955..c5d4351 100644 --- a/index.html +++ b/index.html @@ -484,9 +484,15 @@

- - + + +

前言

🔗夏日征集令
ESP32-WROOM-32D-N8主控,通过GUVA-S12SD紫外线传感器获取环境紫外线强度;AHT20温湿度传感器获取环境温湿度;BMP280气压传感器获取环境压强;使用拨轮开关切换页面。
以下为制作过程记录

+

功能

+

成本

这里只列出了主要的器件,详情见🔗腾讯文档:BOM_ESP_UV_BOX

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
主要元件价格
ESP32-WROOM-32D(8MB)15
紫外线模块7.05
AHT201.62
BMP2801.04
四脚拨轮开关0.85
CH340K1.4
+

硬件

+

硬件设计见立创开源硬件平台

+
+

原理图

+

存在问题:下载完程序,可以运行,但是板子上电不运行,需要按复位,>去除BOOT0按键的电容<,解决问题
贴片开关的质量也不太行,开关手柄会断🙃
侧边按键质量似乎也不太好,按复位有时也没用🙃

+
+

主控电路

主控

主控选择ESP32-WROOM-32D-N8,外围电路参考官方技术规格书
引出SPI用于控制屏幕,IIC用于控制AHT20和BMP280,ADC用于采集电压值,以及按键控制
image.png

+

自动下载

串口芯片使用CH340K
image.png

+

电源电路

电源切换电路

使用PMOS,当没有外部电源时使用电池供电,有外部电源输入时不使用电池供电
image.png

+

充电电路

电池管理使用TP4056,电路参考TP4056数据手册
image.png
充电电流如下,根据锂电池参数选择合适的电阻

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Rprog(K)Ibat(mA)
1.21000
2.4500
3.0400
4.0300
6.0200
12.0200
+

外设

按键

板载一个RESET和BOOT侧边按键,使用拨轮开关作为控制输入
image.png

+

TFT

使用1.8寸TFT屏幕插接,分辨率128x160,屏幕驱动ST7735,屏幕驱动电路参考屏幕原理图,可以通过BLK引脚控制屏幕亮度
image.png

+

UV

紫外线部分电路参考紫外线模块电路设计

+

image.png
通过采集电压,根据电压范围,得到紫外线强度

+

image.png

+

AHT20 BMP280

这两个器件,用烙铁不好焊,加热台方便些
AHT20可以检测环境温湿度
image.png
BMP280可以检测大气压,温度,以及海拔高度(由压力和温度计算得到)
image.png

+

面板

使用立创EDA设计简单的面板

+

3D外壳

1.8寸版本
本次使用SOLIDWORKS2023建模

+

立创EDA导出模型

image.png

+

image.png

+

SOLIDWORKS

使用SOLIDWORKS打开导出的step格式文件

+

image.png
打开后如下图所示,可以看到电路板模型缺少丝印图案

+

image.png
回到PCB工程,打开PCB的2D视图

+

image.png
导出上下面丝印图
如下图点击PCB上表面,选择外观

+

image.png
选择导出的顶层丝印图

+

image.png

+

image.png
还需要调整丝印的位置和大小,选择映射

+

image.png
根据实际情况,调整以下参数

+

image.png
之后便可以开始外壳的建模,最终效果如下
image.png

+

程序

+

详细代码见levi52@GitHub: ESP32_UV_BOX

+
+

页面结构

在主界面下设四个功能页,之后各级再设功能分页,主要结构如下
image.png

+
+

设计参考:
B站:黑人黑科技的视频DIY万能遥控器
OSHWHub: 黑人黑科技的开源工程ESP32 万能遥控器

+
+

主菜单.png

+

代码

+

开发工具:Visual Studio Code + PlatformIO
图标:iconfont-阿里巴巴
颜色:RGB COLOR PICKER
中文转换:中文转UNICODE
图片转换:FileToCArray

+
+

代码结构主要如下

+
ESP32_UV_BOX
│ clearBuildDir.bat build文件删除
│ default_8MB.csv 存储分区
│ LICENSE 开源协议
│ platformio.ini 开发配置
│ README.md 说明文档
├─assets/ 静态文件
├─include
│ README
├─lib 外部库
│ │ README
│ └─ArduinoZlib
├─src 主要文件
│ │ button.cpp 按键控制
│ │ button.h
│ │ main.cpp 主程序
│ │ network.cpp 网络请求
│ │ network.h
│ │ sensor.cpp 传感器
│ │ sensor.h
│ │ ui.cpp 界面
│ │ ui.h
│ ├─font/ 字体文件
│ └─img/ 图片文件
└─test/ 测试文件

+ +

界面

屏幕尺寸为1.8寸,分辨率是128x160,屏幕驱动是ST7735,使用TFT_eSPI库驱动屏幕,所有界面使用TFT_eSPI绘制

+

使用TFT_eSPI需要修改配置文件User_Setup.h,根据屏幕类型和显示情况修改内容

+
#define ST7735_DRIVER // 屏幕驱动
#define TFT_RGB_ORDER TFT_RGB // 颜色顺序
#define TFT_WIDTH 128 // 屏幕宽度
#define TFT_HEIGHT 160 // 屏幕高度
#define ST7735_GREENTAB2 // 仅ST7735
// #define TFT_INVERSION_ON // 黑白反转
// #define TFT_INVERSION_OFF
#define TFT_BL 17 // 背光引脚
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_CS 5 // Chip select control pin
#define TFT_DC 2 // Data Command control pin
#define TFT_RST 4 // Reset pin (could connect to RST pin)
//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
+ +

使用ledc控制引脚输出PWM调节屏幕背光亮度

+

控制

使用mathertel/OneButton库来实现按键的控制,分别注册短按,双击和长按函数来实现不同的操作

+

上下短按为页面切换,中间短按为进入页面,中间长按为返回上一级

+

传感器

UV

使用S12SD传感器来检测紫外线,然后经过放大,使用ADC采集电压,根据电压范围判断紫外线指数等级

+

下图为紫外线模块
image.png
程序中使用此函数获取紫外线指数

+
uint8_t sensor_uv_data(void)
+ +
+

图中为Arduino对应的数值,详情见DFROBOT: UV Sensor
image.png

+
+

AHT20

使用dvarrel/AHT20库读取AHT20温湿度传感器的数据
主要为如下内容,AHT20数据结构体,初始化函数,以及数据读取函数(返回数据结构体)

+
struct AHT20Data
{
float temperature;
float humidity;
};
void sensor_aht20_init(void);
AHT20Data sensor_aht20_data(void);
+ +

BMP280

使用seeed-studio/Grove - Barometer Sensor BMP280库读取BMP280传感器的数据
主要为如下内容,BMP280数据结构体,初始化函数,以及数据读取函数(返回数据结构体)

+
struct BMP280Data
{
float temperature;
float pressure;
float altitude;
};
void sensor_bmp280_init(void);
BMP280Data sensor_bmp280_data(void);
+ +

在函数bool BMP280::init(void)中注释掉Wire.begin()
在主程序中上面两个传感器初始化前,要先使用Wire.begin(21, 22);来设置IIC引脚

+

网络

配网

初次使用时,会建立如下网络ESP_UV_BOX_WIFI
image.png
连接网络,浏览器打开网址192.168.1.1,会出现如下配网页面

+
+

页面代码参考: CSDN: 请收藏!分享一个ESP32/ESP8266高颜值WIFI配网页面代码-带下拉选择框和中英文版本。文末有arduino配网代码。

+
+

一共四个输入框,分别是WIFI SSID, WIFI PASSWORD, Private KEY, Location ID

+
+

相关链接:和风天气控制台城市 ID

+
+

image.png
点击保存后,芯片会重启连接网络

+

网络配置相关函数如下

+
bool wifi_scan(void);
void wifi_connect(int timeOut_s);
void wifi_disconnect(void);
void ap_init(void);
void server_init(void);
void handleRoot(void);
void handleConfigWifi(void);
void handleNotFound(void);
void doClient(void);
void wifiConfigBySoftAP(void);
+ +

天气时钟

天气等数据使用和风天气API,免费订阅每天可以有1000次请求

+
+

订阅规则

+
+ +
void get_weather_now(void);
void get_weather_future(void);
void get_air(void);
void get_city_id(void);
String urlEncode(const String& text);
+ +

网络相关函数如下

+
void time_init(void);
void get_time(void);
+ +

天气预报

同上,使用和风天气API,屏幕显示未来六天天气状况

+

空气质量

同上,使用和风天气API,屏幕显示颗粒物PM10,颗粒物PM2.5,二氧化氮NO2,二氧化硫SO2,一氧化碳CO,臭氧O3

+

哔哩哔哩

通过如下API接口获得JSON格式的数据,使用ArduinoJson库解析获得关注数和粉丝数

+
https://api.bilibili.com/x/relation/stat?vmid=用户UID
+ +

可以使用官网提供的工具生成解析代码

+
{
"code": 0,
"message": "0",
"ttl": 1,
"data": {
"mid": 378576508,
"following": 318,
"whisper": 0,
"black": 0,
"follower": 56
}
}
+ +

生成的解析代码如下

+
// String input;

JsonDocument doc;

DeserializationError error = deserializeJson(doc, input);

if (error) {
Serial.print("deserializeJson() failed: ");
Serial.println(error.c_str());
return;
}

int code = doc["code"]; // 0
const char* message = doc["message"]; // "0"
int ttl = doc["ttl"]; // 1

JsonObject data = doc["data"];
long data_mid = data["mid"]; // 378576508
int data_following = data["following"]; // 318
int data_whisper = data["whisper"]; // 0
int data_black = data["black"]; // 0
int data_follower = data["follower"]; // 56
+ +

灯光

使用fastled/FastLED库驱动板载的一颗WS2812灯珠,暂时只添加不同颜色灯切换功能

+

实物

PCB

image.png

+

页面

下图为部分页面
image.png
后续会上传B站视频

+

END

最后非常感谢立创🥰提供的机会和各种优惠券,帮助我们实现想法,做出实物,参加征集令活动收获颇多,未来继续努力😄

+

Typing SVG

+
+ + + + + +
]]> + + ESP32 + 开源 - GitHub - icon + ESP32 + PlatformIO + 自制 + 立创 + 开源 + 紫外线 + AHT20 + BMP280 + 1.8寸TFT + 外壳 + 面板 @@ -680,225 +891,15 @@ - ESP32S3N8R8 + Squareline_Studio设计移植 - /posts/b97be97c/ - 说明
-

硬件:立创ESP32S3R8N8开发板 + 2.8寸TFT显示屏(ST7789) + 电容触摸(GT911)
软件:Visual Studio Code + PlatformIO+ Squareline Studio
代码:百度网盘:ESP32S3_SQ(提取码:levi)
代码:百度网盘:ESP32S3_SERVO(提取码:levi)
视频:bilibili: 【ESP32】初试Squareline Studio设计 简单控制屏幕亮度
视频:bilibili: 【ESP32】Squareline Studio新增界面+移植过程 - 简单控制舵机
博客:CSDN: 【ESP32】立创ESP32S3N8R8开发板+2.8寸TFT电容触摸屏+Squareline Studio+PlatformIO

-
-

Squareline Studio

设计UI

image-

-

导出文件

    -
  • 工程设置
    按如下所示设置工程,Project Export RootUI Files Export Path路径可以选择为LVGL工程目录下新建的export文件夹

    -
  • -
  • Export

    -
  • -
-

PlatformIO

文件结构

    -
  • 导出文件
    以下为Squareline Studio导出的文件
    image-

    -
  • -
  • 移植文件
    资源文件复制到src/lvgl_gui
    image-

    -
  • -
-

LVGL

    -
  • 修改lvgl
    修改lvgl_conf.h,如下所示,关闭案例编译
    image-
  • -
-

main

    -
  • 添加头文件

    -
    #include "ui.h"
  • -
  • UI初始化
    删去之前LVGL官方案例的内容,添加如下代码

    -
    ui_init();
    -

    image-

    -
  • -
  • lvgl显示

    -
    void lvgl_task(void *pt)

    {

        while(1)

        {

            lv_timer_handler(); /* let the GUI do its work */

            vTaskDelay(5);

        }

    }
  • -
  • setup()中创建任务

    -
    xTaskCreatePinnedToCore(lvgl_task, "lvgl display", 1024 * 15, NULL, 2, NULL, 1);
  • -
-

编译下载

image-
image-
image-

-

END

2024 Levi5
-]]>
- - ESP32 - 教程 - - - ESP32 - PlatformIO - lvgl - 2.8寸TFT - Squareline Studio - 触摸屏 - 立创 - -
- - ESP32S3N8R8 + lvgl测试官方案例 - /posts/2c4e27ec/ - 说明
-

硬件:立创ESP32S3R8N8开发板 + 2.8寸TFT显示屏(ST7789) + 电容触摸(GT911)
软件:Visual Studio Code + PlatformIO
代码:百度网盘:ESP32S3_GT911TOUCH(提取码:levi)
视频:bilibili: 【ESP32】2.8寸电容触摸屏(ST7789+GT911) lvgl 案例测试
博客:CSDN: 【ESP32】立创ESP32S3R8N8开发板+2.8寸TFT电容触摸屏ST7789+GT911+PlatformIO

-
-

新建工程

    -
  • 点击侧边PlatformIO插件,新建工程

    -
  • -
  • 依次设置工程名,开发板,框架

    -
  • -
-

屏幕测试

添加TFT_eSPI

    -
  • 添加屏幕驱动库TFT_eSPI,按如下图顺序

    -
  • -
  • 添加TFT_eSPI到工程

    -
  • -
  • 打开配置文件,可以看到已成功添加库

    -
  • -
-

修改TFT_eSPI

    -
  • 打开.pio\libdeps\esp32-s3-devkitc-1\TFT_eSPI\User_Setup.h文件

    -
  • -
  • 根据屏幕驱动芯片解注释

    -
  • -
-
// Only define one driver, the other ones must be commented out
// #define ILI9341_DRIVER // Generic driver for common displays
//#define ILI9341_2_DRIVER // Alternative ILI9341 driver, see https://github.com/Bodmer/TFT_eSPI/issues/1172
//#define ST7735_DRIVER // Define additional parameters below for this display
//#define ILI9163_DRIVER // Define additional parameters below for this display
//#define S6D02A1_DRIVER
//#define RPI_ILI9486_DRIVER // 20MHz maximum SPI
//#define HX8357D_DRIVER
//#define ILI9481_DRIVER
//#define ILI9486_DRIVER
//#define ILI9488_DRIVER // WARNING: Do not connect ILI9488 display SDO to MISO if other devices share the SPI bus (TFT SDO does NOT tristate when CS is high)
#define ST7789_DRIVER // Full configuration option, define additional parameters below for this display
//#define ST7789_2_DRIVER // Minimal configuration option, define additional parameters below for this display
//#define R61581_DRIVER
//#define RM68140_DRIVER
//#define ST7796_DRIVER
//#define SSD1351_DRIVER
//#define SSD1963_480_DRIVER
//#define SSD1963_800_DRIVER
//#define SSD1963_800ALT_DRIVER
//#define ILI9225_DRIVER
//#define GC9A01_DRIVER
- -
    -
  • 根据屏幕大小设置宽高
  • -
-
// For ST7789, ST7735, ILI9163 and GC9A01 ONLY, define the pixel width and height in portrait orientation
// #define TFT_WIDTH 80
// #define TFT_WIDTH 128
// #define TFT_WIDTH 172 // ST7789 172 x 320
// #define TFT_WIDTH 170 // ST7789 170 x 320
#define TFT_WIDTH 240 // ST7789 240 x 240 and 240 x 320
// #define TFT_HEIGHT 160
// #define TFT_HEIGHT 128
// #define TFT_HEIGHT 240 // ST7789 240 x 240
#define TFT_HEIGHT 320 // ST7789 240 x 320
// #define TFT_HEIGHT 240 // GC9A01 240 x 240
- -
    -
  • 根据连线设置引脚
  • -
-
// ### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP32 SETUP   ###
// For ESP32 Dev board (only tested with ILI9341 display)
// The hardware SPI can be mapped to any pins
//#define TFT_MISO 19
#define TFT_MOSI 17
#define TFT_SCLK 18
#define TFT_CS 15 // Chip select control pin
#define TFT_DC 16 // Data Command control pin
//#define TFT_RST 4 // Reset pin (could connect to RST pin)
#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
- -

修改main.cpp

在屏幕上从上到下分别显示绿三色,以及白色文字,用来测试屏幕颜色显示是否正常。

-
#include <Arduino.h>
#include <SPI.h>
#include <TFT_eSPI.h> // Hardware-specific library
#define TFT_GREY 0x5AEB
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
void setup() {
tft.init();
tft.setRotation(0);
tft.fillScreen(TFT_GREY);
tft.setTextColor(TFT_WHITE, TFT_GREY); // Adding a background colour erases previous text automatically
tft.fillRect(0,0,240,50,TFT_RED);
tft.fillRect(0,50,240,50,TFT_GREEN);
tft.fillRect(0,100,240,50,TFT_BLUE);
tft.drawCentreString("Time flies",120,260,4);
}
void loop() {
// put your main code here, to run repeatedly:
}
- -

下载调试

    -
  • 编译下载

    -
  • -
  • 根据屏幕显示情况修改User_Setup.h文件

    -
  • -
-

如果颜色反转(白色显示为黑色),如下图所示,则取消下一个注释,尝试两个选项,其中一个选项应该纠正反转。

-
// If colours are inverted (white shows as black) then uncomment one of the next
// 2 lines try both options, one of the options should correct the inversion.
// #define TFT_INVERSION_ON
#define TFT_INVERSION_OFF
-

修改后,如下图所示,白色正常显示,但是RGB顺序存在问题

-

仅对于ST7735, ST7789和ILI9341,如果显示器上的蓝色和红色交换,则定义颜色顺序,一次尝试一个选项来找到显示的正确颜色顺序

-
// For ST7735, ST7789 and ILI9341 ONLY, define the colour order IF the blue and red are swapped on your display
// Try ONE option at a time to find the correct colour order for your display
// #define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
-

修改后,如下图所示,RGB顺序正常

-

LVGL测试

添加LVGL

    -
  • 根据实际情况,选择lvgl版本

    ![](lvglinstall.png” style=”zoom:67%;” >

    -
  • -
  • 添加lvgl到工程
    ![](lvglinstalled.png” style=”zoom:67%;” >

    -
  • -
-

修改LVGL

    -
  • 打开.pio\libdeps\esp32-s3-devkitc-1\lvgl\lv_conf_template.h文件

    -

    将此文件重命名为lv_conf.h

    -
  • -
-

![](lvconf.png” style=”zoom:67%;” >

-
    -
  • 使能lvgl
  • -
-
/* clang-format off */
#if 1 /*Set it to "1" to enable content*/
#ifndef LV_CONF_H
#define LV_CONF_H
- -
    -
  • 设置周期
  • -
-

默认显示刷新周期。LVG将重新绘制改变的区域与这个周期时间
输入设备读取周期毫秒

-
/*Default display refresh period. LVG will redraw changed areas with this period time*/
#define LV_DISP_DEF_REFR_PERIOD 1 /*[ms]*/
/*Input device read period in milliseconds*/
#define LV_INDEV_DEF_READ_PERIOD 1 /*[ms]*/
- -
    -
  • 心跳使能
  • -
-
/*Use a custom tick source that tells the elapsed time in milliseconds.
*It removes the need to manually update the tick with `lv_tick_inc()`)*/
#define LV_TICK_CUSTOM 1
#if LV_TICK_CUSTOM
- -
    -
  • 使能测试案例
  • -
-
/*Show some widget. It might be required to increase `LV_MEM_SIZE` */
#define LV_USE_DEMO_WIDGETS 1
#if LV_USE_DEMO_WIDGETS
#define LV_DEMO_WIDGETS_SLIDESHOW 0
#endif
- -
    -
  • 更改文件路径

    -

    .pio\libdeps\esp32-s3-devkitc-1\lvgl\demos文件夹移动至.pio\libdeps\esp32-s3-devkitc-1\lvgl\src\demos

    -
  • -
  • 修改main.cpp

    -

    .pio\libdeps\esp32-s3-devkitc-1\lvgl\examples\arduino\LVGL_Arduino\LVGL_Arduino.ino文件内容复制

    -
      -
    • 设置头文件
    • -
    -
    #include <Arduino.h>
    #include <SPI.h>
    #include <lvgl.h>
    #include <TFT_eSPI.h> // Hardware-specific library
    #include "demos/lv_demos.h"
    - -
      -
    • 设置宽高
    • -
    -
    static const uint16_t screenWidth  = 320;
    static const uint16_t screenHeight = 240;
    - -
      -
    • 修改类型
    • -
    -

    lv_disp_t修改为lv_disp_drv_t

    -

    lv_indev_t修改为lv_indev_drv_t

    -
      -
    • 注释掉触摸部分
    • -
    -
  • -
-

修改完成

最终main.cpp文件内容如下

-
#include <Arduino.h>
#include <SPI.h>
#include <lvgl.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include "demos/lv_demos.h"
/*Change to your screen resolution*/
static const uint16_t screenWidth = 320;
static const uint16_t screenHeight = 240;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ screenWidth * 10 ];
TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); /* TFT instance */
/* Display flushing */
void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p )
{
uint32_t w = ( area->x2 - area->x1 + 1 );
uint32_t h = ( area->y2 - area->y1 + 1 );
tft.startWrite();
tft.setAddrWindow( area->x1, area->y1, w, h );
tft.pushColors( ( uint16_t * )&color_p->full, w * h, true );
tft.endWrite();
lv_disp_flush_ready( disp );
}
/*Read the touchpad*/
// void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
// {
// uint16_t touchX, touchY;
// bool touched = tft.getTouch( &touchX, &touchY, 600 );
// if( !touched )
// {
// data->state = LV_INDEV_STATE_REL;
// }
// else
// {
// data->state = LV_INDEV_STATE_PR;
// /*Set the coordinates*/
// data->point.x = touchX;
// data->point.y = touchY;
// Serial.print( "Data x " );
// Serial.println( touchX );
// Serial.print( "Data y " );
// Serial.println( touchY );
// }
// }
void setup()
{
Serial.begin( 115200 ); /* prepare for possible serial debug */
String LVGL_Arduino = "Hello Arduino! ";
LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
Serial.println( LVGL_Arduino );
Serial.println( "I am LVGL_Arduino" );
lv_init();
tft.begin(); /* TFT init */
tft.setRotation( 3 ); /* Landscape orientation, flipped */
/*Set the touchscreen calibration data,
the actual data for your display can be acquired using
the Generic -> Touch_calibrate example from the TFT_eSPI library*/
uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
// tft.setTouch( calData );
lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * 10 );
/*Initialize the display*/
static lv_disp_drv_t disp_drv;
lv_disp_drv_init( &disp_drv );
/*Change the following line to your display resolution*/
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register( &disp_drv );
/*Initialize the (dummy) input device driver*/
static lv_indev_drv_t indev_drv;
lv_indev_drv_init( &indev_drv );
indev_drv.type = LV_INDEV_TYPE_POINTER;
// indev_drv.read_cb = my_touchpad_read;
lv_indev_drv_register( &indev_drv );
#if 0
/* Create simple label */
lv_obj_t *label = lv_label_create( lv_scr_act() );
lv_label_set_text( label, LVGL_Arduino.c_str() );
lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
#else
lv_demo_widgets(); // OK
#endif
Serial.println( "Setup done" );
}
void loop()
{
lv_timer_handler(); /* let the GUI do its work */
delay( 5 );
}
-

编译下载

显示效果如下图

-

触摸测试

添加bb_captouch

-

修改main.cpp

    -
  • 添加头文件

    -
    #include <bb_captouch.h>
    -
  • -
  • 设置触摸芯片引脚

    -
    // These defines are for a low cost ESP32 LCD board with the GT911 touch controller
    #define TOUCH_SDA 4
    #define TOUCH_SCL 2
    #define TOUCH_INT 3
    #define TOUCH_RST 1
    -
  • -
  • 设置参数

    -
    BBCapTouch bbct;
    const char *szNames[] = {"Unknown", "FT6x36", "GT911", "CST820"};
    -
  • -
  • 初始化

    -
    bbct.init(TOUCH_SDA, TOUCH_SCL, TOUCH_RST, TOUCH_INT);
    -
  • -
  • 修改my_touchpad_read函数

    -

    这里的x,y坐标需要根据实际情况修改

    -

    -
    /*Read the touchpad*/
    void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
    {
    TOUCHINFO ti;
    if(bbct.getSamples(&ti))
    {
    data->state = LV_INDEV_STATE_PR;
    /*Set the coordinates*/
    data->point.x = screenWidth - ti.y[0];
    data->point.y = ti.x[0];
    Serial.print( "Data x " );
    Serial.println( screenWidth - ti.y[0] );
    Serial.print( "Data y " );
    Serial.println( ti.x[0] );
    }
    else
    {
    data->state = LV_INDEV_STATE_REL;
    }
    }
  • -
-

修改完成

最终main.cpp文件内容如下

-
#include <Arduino.h>
#include <SPI.h>
#include <lvgl.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include "demos/lv_demos.h"
#include <bb_captouch.h>
// These defines are for a low cost ESP32 LCD board with the GT911 touch controller
#define TOUCH_SDA 4
#define TOUCH_SCL 2
#define TOUCH_INT 3
#define TOUCH_RST 1
BBCapTouch bbct;
const char *szNames[] = {"Unknown", "FT6x36", "GT911", "CST820"};
/*Change to your screen resolution*/
static const uint16_t screenWidth = 320;
static const uint16_t screenHeight = 240;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ screenWidth * 10 ];
TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); /* TFT instance */
/* Display flushing */
void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p )
{
uint32_t w = ( area->x2 - area->x1 + 1 );
uint32_t h = ( area->y2 - area->y1 + 1 );
tft.startWrite();
tft.setAddrWindow( area->x1, area->y1, w, h );
tft.pushColors( ( uint16_t * )&color_p->full, w * h, true );
tft.endWrite();
lv_disp_flush_ready( disp );
}
/*Read the touchpad*/
void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
{
// uint16_t touchX, touchY;
TOUCHINFO ti;
if(bbct.getSamples(&ti))
{
data->state = LV_INDEV_STATE_PR;
/*Set the coordinates*/
data->point.x = screenWidth - ti.y[0];
data->point.y = ti.x[0];
Serial.print( "Data x " );
Serial.println( screenWidth - ti.y[0] );
Serial.print( "Data y " );
Serial.println( ti.x[0] );
}
else
{
data->state = LV_INDEV_STATE_REL;
}
}
void setup()
{
Serial.begin( 115200 ); /* prepare for possible serial debug */
String LVGL_Arduino = "Hello Arduino! ";
LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
Serial.println( LVGL_Arduino );
Serial.println( "I am LVGL_Arduino" );
lv_init();
tft.begin(); /* TFT init */
tft.setRotation( 3 ); /* Landscape orientation, flipped */
bbct.init(TOUCH_SDA, TOUCH_SCL, TOUCH_RST, TOUCH_INT);
int iType = bbct.sensorType();
Serial.printf("Sensor type = %s\n", szNames[iType]);
lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * 10 );
/*Initialize the display*/
static lv_disp_drv_t disp_drv;
lv_disp_drv_init( &disp_drv );
/*Change the following line to your display resolution*/
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register( &disp_drv );
/*Initialize the (dummy) input device driver*/
static lv_indev_drv_t indev_drv;
lv_indev_drv_init( &indev_drv );
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touchpad_read;
lv_indev_drv_register( &indev_drv );
#if 0
/* Create simple label */
lv_obj_t *label = lv_label_create( lv_scr_act() );
lv_label_set_text( label, LVGL_Arduino.c_str() );
lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
#else
// uncomment one of these demos
lv_demo_widgets(); // OK
#endif
Serial.println( "Setup done" );
}
void loop()
{
lv_timer_handler(); /* let the GUI do its work */
delay( 5 );
}
- -

编译下载

触摸显示效果如下图所示

-

END

2024 Levi5
+ 预告 + /posts/224bc55d/ + … … … … …

]]>
- ESP32 - 教程 + 预告 - ESP32 - PlatformIO - lvgl - 2.8寸TFT - 触摸屏 - 立创 + 预告
- - Hello World - /posts/4a17b156/ - Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

-

Quick Start

Create a new post

$ hexo new "My New Post"
- -

More info: Writing

-

Run server

$ hexo server
- -

More info: Server

-

Generate static files

$ hexo generate
- -

More info: Generating

-

Deploy to remote sites

$ hexo deploy
- -

More info: Deployment

-]]>
-