引言
ESP8266 以其低成本和 Wi-Fi 功能成为物联网项目的热门选择。ILI9341 TFT 液晶屏则以其适中的价格和良好的显示效果,成为 ESP8266 的理想搭档。然而,将两者结合使用时,经常会出现花屏、镜像、显示不全等问题。本文将深入剖析这些问题的原因,并提供详细的解决方案,助您轻松驾驭 ESP8266 + ILI9341 的组合。
硬件连接
正确连接 ESP8266 和 ILI9341 是首要任务。下表列出了典型连接方式:
| ILI9341 引脚 | ESP8266 引脚 | 说明 |
|---|---|---|
| VCC | 3.3V | 电源 (3.3V) |
| GND | GND | 地 |
| CS | D8 | 片选 (Chip Select) |
| RST/RESET | D2 | 复位 (Reset) |
| DC/RS | D1 | 数据/命令 (Data/Command) |
| SDI/MOSI | D7 | SPI 数据输入 (MOSI) |
| SCK | D5 | SPI 时钟 (SCLK) |
| LED | 3.3V | 背光 (或通过电阻,不连接屏幕不亮,见下文) |
| SDO/MISO | D6 | (本例中未使用) |
重要提示:
- 电源: ESP8266 和 ILI9341 必须 使用 3.3V 电源。
- LED 背光: 部分 ILI9341 模块的 LED 引脚可直接接 3.3V,部分则需串联限流电阻(如 220Ω 或 330Ω)。请务必查阅您购买的屏幕模块的规格书!
- ESP8266 SPI 引脚: ESP8266 默认的 SPI 引脚为:
D5 (GPIO14)-SCKD7 (GPIO13)-MOSID6 (GPIO12)-MISO(本例中未使用)
软件设置 (Arduino IDE)
-
安装库:
- 打开 Arduino IDE。
- "工具" -> "管理库..."。
- 搜索并安装 "Adafruit GFX Library" 和 "Adafruit ILI9341"。
-
代码框架(竖屏示例):
#include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_ILI9341.h> // 引脚定义 (根据您的实际接线修改) #define TFT_CS D8 #define TFT_DC D1 #define TFT_RST D2 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); void setup() { Serial.begin(115200); // 用于调试 Serial.println("ILI9341 初始化..."); delay(500); // **重要:** 上电延时,确保屏幕稳定 tft.begin(); // 初始化 ILI9341 SPI.setFrequency(1000000); // **重要:** 设置 SPI 速度 (1 MHz, 稳定) tft.setRotation(0); // 设置屏幕方向:竖屏 // 设置显示区域 (竖屏 240x320) uint8_t caset_data[] = {0x00, 0x00, 0x00, 0xEF}; // 列地址 0-239 tft.sendCommand(ILI9341_CASET, caset_data, 4); uint8_t raset_data[] = {0x00, 0x00, 0x01, 0x3F}; // 行地址 0-319 tft.sendCommand(ILI9341_PASET, raset_data, 4); tft.writeCommand(ILI9341_RAMWR); // 准备写入像素数据 // 设置 MADCTL (Memory Access Control) uint8_t madctl_data = 0xE8; // 竖屏常用值,可能需要调整 (见下文) tft.sendCommand(ILI9341_MADCTL, &madctl_data, 1); tft.fillScreen(ILI9341_BLACK); // 清屏 (黑色) // 显示一些文字 tft.setTextColor(ILI9341_WHITE); tft.setTextSize(2); tft.setCursor(20, 50); tft.println("Hello, ESP8266!"); tft.setTextSize(3); tft.setTextColor(ILI9341_YELLOW); tft.setCursor(40, 120); tft.print("ILI9341"); } void loop() { // (此处可以添加其他代码,例如读取传感器数据并显示) delay(1000); }
常见问题及解决方案
以下是 ESP8266 + ILI9341 组合的常见显示问题及其解决方案:
-
花屏 (Garbage Data):
-
原因:
- SPI 速度过快: ESP8266 的 SPI 速度可能超过 ILI9341 的承受范围。
- 接线问题: 松动、过长或受干扰的连接。
- 电源问题: 不稳定的电源或电压不足。
- 初始化序列问题: 库通常会自动处理,但某些特殊屏幕可能需要手动调整。
-
解决方案:
- 降低 SPI 速度(首要): 使用
SPI.setFrequency(1000000);将 SPI 速度设置为 1 MHz(或更低)。 - 检查接线: 确保所有连接牢固、紧凑,远离干扰源。
- 检查电源: 用万用表确认 ILI9341 的 VCC 引脚电压稳定在 3.3V。
- 增加上电延时: 在
tft.begin();前加入delay(500);。
- 降低 SPI 速度(首要): 使用
-
-
镜像 (Mirroring) 和倒置 (Inversion):
-
原因: MADCTL (Memory Access Control) 寄存器设置不当。
-
解决方案:
- 理解 MADCTL: MADCTL 是一个 8 位寄存器,控制屏幕的扫描方向、行列顺序和颜色:
- Bit 7 (MY): 行地址顺序 (0: 从上到下, 1: 从下到上)
- Bit 6 (MX): 列地址顺序 (0: 从左到右, 1: 从右到左)
- Bit 5 (MV): 行/列交换 (0: 不交换, 1: 交换) <-- 竖屏/横屏的关键
- Bit 4 (ML): 垂直刷新 (0: 从上到下, 1: 从下到上)
- Bit 3 (RGB): 颜色顺序 (0: RGB, 1: BGR) <-- ILI9341 通常是 BGR
- Bits 2-0: 未使用
- 设置 MADCTL:
uint8_t madctl_data = 0x...; // 根据需要设置值 tft.sendCommand(ILI9341_MADCTL, &madctl_data, 1);- 常用 MADCTL 值:
setRotation(0)(竖屏):0x68或0xE8setRotation(1)(横屏):0x48或0xC8
- 重要:更改 MADCTL 值或旋转方向后, 务必完全断电重启!
- 理解 MADCTL: MADCTL 是一个 8 位寄存器,控制屏幕的扫描方向、行列顺序和颜色:
-
-
分辨率错误/显示不全:
-
原因:
- Adafruit_ILI9341 库未能自动识别屏幕的正确分辨率。
- MADCTL 设置错误。
-
解决方案:
- 强制设置显示区域 (CASET 和 PASET):
// 横屏 (320x240) uint8_t caset_data[] = {0x00, 0x00, 0x01, 0x3F}; // 列: 0-319 uint8_t raset_data[] = {0x00, 0x00, 0x00, 0xEF}; // 行: 0-239 // 竖屏 (240x320) // uint8_t caset_data[] = {0x00, 0x00, 0x00, 0xEF}; // 列: 0-239 // uint8_t raset_data[] = {0x00, 0x00, 0x01, 0x3F}; // 行: 0-319 tft.sendCommand(ILI9341_CASET, caset_data, 4); // 设置列地址 tft.sendCommand(ILI9341_PASET, raset_data, 4); // 设置行地址 tft.writeCommand(ILI9341_RAMWR); // 准备写入像素数据 - 结合 MADCTL 调整: 确保 MADCTL 设置与屏幕方向和 CASET/PASET 设置一致。
- 强制设置显示区域 (CASET 和 PASET):
-
总结
通过掌握以上方法,您应该能够解决 ESP8266 与 ILI9341 TFT 屏幕组合的绝大多数显示问题。记住,细心检查硬件、理解 MADCTL、正确设置显示区域是成功的关键。祝您的项目顺利!
横屏模式 (setRotation(1)) 代码,并加入了详细注释和可能需要的调整:
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// ILI9341 引脚定义 (根据您的实际接线)
#define TFT_CS D8 // 片选
#define TFT_DC D1 // 数据/命令
#define TFT_RST D2 // 复位
// 创建 Adafruit_ILI9341 对象
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
void setup() {
Serial.begin(115200); // 初始化串口,用于调试
Serial.println("ILI9341 Test!");
delay(500); // **重要:** 上电延时,确保 ILI9341 稳定
tft.begin(); // 初始化 ILI9341 屏幕
SPI.setFrequency(1000000); // **重要:** 设置 SPI 时钟频率为 1 MHz (保守值)
tft.setRotation(1); // 设置屏幕为横屏模式 (1:横屏)
// ********** 设置显示区域 (横屏 320x240) **********
// CASET (Column Address Set) - 设置列地址范围
uint8_t caset_data[] = {0x00, 0x00, 0x01, 0x3F}; // 0x0000 到 0x013F (0-319)
tft.sendCommand(ILI9341_CASET, caset_data, 4);
// PASET (Page Address Set) - 设置行地址范围
uint8_t raset_data[] = {0x00, 0x00, 0x00, 0xEF}; // 0x0000 到 0x00EF (0-239)
tft.sendCommand(ILI9341_PASET, raset_data, 4);
tft.writeCommand(ILI9341_RAMWR); // **重要:** 发送 RAM Write 命令,准备写入像素数据
// ********** 设置 MADCTL (Memory Access Control) **********
uint8_t madctl_data;
// 对于 setRotation(1) (横屏),通常 0x48 或 0xC8 是正确的值
// 0x48: 正常
// 0xC8: 垂直翻转 (如果 0x48 显示上下颠倒,就用 0xC8)
madctl_data = 0x48; // 先尝试 0x48
tft.sendCommand(ILI9341_MADCTL, &madctl_data, 1);
delay(1000); // 更改 MADCTL 后短暂延时
// 清屏 (黑色)
tft.fillScreen(ILI9341_BLACK);
// 设置文本颜色 (白色)
tft.setTextColor(ILI9341_WHITE);
// 设置文本大小 (2)
tft.setTextSize(2);
// 设置光标位置 (x=20, y=50)
tft.setCursor(20, 50);
// 显示文字
tft.println("Hello, ESP8266!");
// 设置文本大小 (3)
tft.setTextSize(3);
// 设置文本颜色 (黄色)
tft.setTextColor(ILI9341_YELLOW);
// 设置光标位置 (x=40, y=120)
tft.setCursor(40, 120);
// 显示文字
tft.print("ILI9341");
delay(1000); // 观察显示效果
}
void loop() {
delay(1000); // 简单延时
}
代码的关键点和解释:
-
#define TFT_CS D8,#define TFT_DC D1,#define TFT_RST D2:- 这些是引脚定义,将 ESP8266 的 D8、D1 和 D2 引脚分别定义为 ILI9341 屏幕的 CS、DC 和 RST 引脚。
- 请根据您的实际接线修改这些定义!
-
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);:- 创建一个
Adafruit_ILI9341对象,用于控制 ILI9341 屏幕。 - 将之前定义的引脚传递给构造函数。
- 创建一个
-
Serial.begin(115200);:- 初始化串口通信,波特率为 115200。这用于通过串口监视器进行调试。
-
delay(500);:- 非常重要: 上电延时。在 ESP8266 和 ILI9341 上电后,需要一个短暂的延时(至少几百毫秒),以确保 ILI9341 控制器完全初始化并准备好接收命令。
-
tft.begin();:- 初始化 ILI9341 屏幕。这会发送一系列初始化命令给 ILI9341 控制器。
-
SPI.setFrequency(1000000);:- 非常重要: 设置 SPI 时钟频率为 1 MHz (1000000 Hz)。这是一个相对保守(慢)的值,可以最大程度地兼容不同的 ILI9341 屏幕和 ESP8266 板。
- 如果 1 MHz 工作正常,您可以尝试逐渐增加这个值(例如,2 MHz、4 MHz、8 MHz 等),以找到您的硬件配置下的最高稳定速度。但请记住,过高的 SPI 速度会导致数据错误(花屏)。
-
tft.setRotation(1);:- 设置屏幕的旋转方向。
0: 竖屏(肖像模式),240x3201: 横屏(风景模式),320x240,您的代码中使用的就是这个2: 竖屏(肖像模式,180 度旋转)3: 横屏(风景模式,180 度旋转)
- 设置屏幕的旋转方向。
-
CASET和PASET(设置显示区域):uint8_t caset_data[] = {0x00, 0x00, 0x01, 0x3F}; // 0-319 (列) tft.sendCommand(ILI9341_CASET, caset_data, 4); uint8_t raset_data[] = {0x00, 0x00, 0x00, 0xEF}; // 0-239 (行) tft.sendCommand(ILI9341_PASET, raset_data, 4);ILI9341_CASET(Column Address Set):设置要显示的列的起始和结束地址。ILI9341_PASET(Page Address Set):设置要显示的行的起始和结束地址。- 对于横屏模式 (
setRotation(1)),我们设置:- 列:0-319 (0x0000 - 0x013F)
- 行:0-239 (0x0000 - 0x00EF)
-
tft.writeCommand(ILI9341_RAMWR);:- 非常重要: 在设置完显示区域(
CASET和PASET)后,必须发送ILI9341_RAMWR(Memory Write) 命令。这告诉 ILI9341 控制器,接下来我们要开始写入像素数据到显存了。
- 非常重要: 在设置完显示区域(
-
MADCTL(Memory Access Control):uint8_t madctl_data = 0x48; // 尝试 0x48,如果不行,尝试 0xC8 tft.sendCommand(ILI9341_MADCTL, &madctl_data, 1);MADCTL是一个非常重要的寄存器,它控制着屏幕的扫描方向、行/列地址顺序以及颜色顺序(RGB 或 BGR)。- 对于
setRotation(1)(横屏),通常0x48或0xC8是正确的值。0x48: 正常(没有垂直翻转)0xC8: 垂直翻转(如果0x48显示上下颠倒,就用0xC8)
- 如果您的屏幕显示仍然有问题(例如,上下镜像),请尝试将
0x48改为0xC8。
-
文本显示:
tft.fillScreen(ILI9341_BLACK);: 清屏为黑色。tft.setTextColor(ILI9341_WHITE);: 设置文本颜色为白色。tft.setTextSize(2);: 设置文本大小为 2。tft.setCursor(20, 50);: 设置光标位置(x=20, y=50)。tft.println("Hello, ESP8266!");: 显示一行文字。tft.setTextSize(3);,tft.setTextColor(ILI9341_YELLOW);,tft.setCursor(40, 120);,tft.print("ILI9341");: 显示另一行文字。
总结:
这段代码提供了一个坚实的基础,用于在横屏模式下使用 ESP8266 和 ILI9341 屏幕。如果您的屏幕仍然显示不正常,请务必:
- 仔细检查接线。
- 尝试不同的
madctl_data值(0x48或0xC8)。 - 确保在更改
madctl_data或setRotation()后,完全断电重启 ESP8266 和屏幕。 - 如果可以, 提供您的屏幕型号和购买链接, 这能帮助提供更具体的建议
加入wifi功能
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <map>
#include <vector>
const char* ssid = "yang1234"; // 请替换为你的 Wi-Fi SSID
const char* password = "y123456789"; // 请替换为你的 Wi-Fi 密码
#define TFT_CS D8
#define TFT_DC D1
#define TFT_RST D2
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
ESP8266WebServer server(80);
struct LineData {
String text;
uint16_t color;
uint8_t size;
int16_t y;
};
std::map<int, LineData> lines;
// --- 图片数据结构 ---
struct ImageData {
std::vector<uint16_t> pixels;
int16_t width;
int16_t height;
int16_t y_offset; // 图片的 Y 轴偏移量
};
ImageData image;
// 全局变量,控制是否使用 GBR 格式
bool useGBR = true; // GBR 格式
void handleSet();
void handleImage(); // 新增图片处理函数
void handleNotFound();
void updateDisplay();
void connectToWiFi();
uint16_t parseColor(String colorString);
void setup() {
Serial.begin(115200);
tft.begin();
SPI.setFrequency(1000000);
tft.setRotation(0);
uint8_t caset_data[] = {0x00, 0x00, 0x00, 0xEF};
tft.sendCommand(ILI9341_CASET, caset_data, 4);
uint8_t raset_data[] = {0x00, 0x00, 0x01, 0x3F};
tft.sendCommand(ILI9341_PASET, raset_data, 4);
tft.writeCommand(ILI9341_RAMWR);
uint8_t madctl_data = 0xE8;
tft.sendCommand(ILI9341_MADCTL, &madctl_data, 1);
tft.fillScreen(ILI9341_BLACK);
connectToWiFi();
server.on("/set", HTTP_POST, handleSet);
server.on("/image", HTTP_POST, handleImage); // 处理图片请求
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
updateDisplay();
}
void loop() {
server.handleClient();
}
void connectToWiFi() {
WiFi.begin(ssid, password);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected! IP address:");
Serial.println(WiFi.localIP());
Serial.print("请在Python脚本中将 esp8266_ip 替换为: ");
Serial.println(WiFi.localIP());
}
void handleSet() {
lines.clear();
for (int i = 0; i < 100; i++) {
String lineKey = "line" + String(i);
if (server.hasArg(lineKey)) {
LineData line;
line.text = server.arg(lineKey);
String colorKey = "color" + String(i);
if (server.hasArg(colorKey)) {
line.color = parseColor(server.arg(colorKey));
} else {
line.color = ILI9341_WHITE;
}
String sizeKey = "size" + String(i);
if (server.hasArg(sizeKey)) {
int size = server.arg(sizeKey).toInt();
line.size = (size >= 1 && size <= 7) ? size : 2;
} else {
line.size = 2;
}
lines[i] = line;
}
}
updateDisplay();
server.send(200, "text/plain", "OK");
}
// --- 处理图片上传 ---
void handleImage() {
if (server.hasArg("width") && server.hasArg("height") && server.hasArg("data")) {
int width = server.arg("width").toInt();
int height = server.arg("height").toInt();
String data = server.arg("data");
if (width > 0 && height > 0 && data.length() > 0) {
image.width = width;
image.height = height;
image.pixels.clear();
image.pixels.reserve(width * height); // 预留空间
// 将接收到的字符串数据转换为像素数据
for (int i = 0; i < data.length(); i += 4) { // 假设每像素 4 字符 (16进制)
if (i + 4 <= data.length()) {
String hexColor = data.substring(i, i + 4);
unsigned long colorValue = strtoul(hexColor.c_str(), NULL, 16);
image.pixels.push_back(colorValue);
}
}
image.y_offset = 0; // 默认图片 Y 轴偏移量为 0
if (server.hasArg("y_offset")) {
image.y_offset = server.arg("y_offset").toInt();
}
updateDisplay(); // 更新显示
server.send(200, "text/plain", "Image OK");
} else {
server.send(400, "text/plain", "Invalid image parameters");
}
} else {
server.send(400, "text/plain", "Image parameters missing");
}
}
void handleNotFound() {
server.send(404, "text/plain", "404 Not Found");
}
void updateDisplay() {
tft.fillScreen(ILI9341_BLACK);
int16_t yPos = 20;
for (auto& [lineNum, line] : lines) {
line.y = yPos;
// --- 左对齐 ---
int16_t xPos = 20; // 左边距为 20 像素
tft.setCursor(xPos, line.y);
tft.setTextColor(line.color);
tft.setTextSize(line.size);
tft.println(line.text);
yPos += line.size * 6 * (tft.getRotation() % 2 == 0 ? 1 : 2) + 15; // 15 像素行间距
}
// --- 显示图片 ---
if (!image.pixels.empty()) {
int16_t startY = yPos + image.y_offset; // 图片的起始 Y 坐标,在文字下方
for (int y = 0; y < image.height; y++) {
for (int x = 0; x < image.width; x++) {
if (x < tft.width() && (startY + y) < tft.height()) { // 边界检查
tft.drawPixel(x, startY + y, image.pixels[y * image.width + x]);
}
}
}
}
}
uint16_t parseColor(String colorString) {
if (colorString == "red") return ILI9341_RED;
if (colorString == "green") return ILI9341_GREEN;
if (colorString == "blue") return ILI9341_BLUE;
if (colorString == "yellow") return ILI9341_YELLOW;
if (colorString == "cyan") return ILI9341_CYAN;
if (colorString == "magenta") return ILI9341_MAGENTA;
if (colorString == "white") return ILI9341_WHITE;
if (colorString == "black") return ILI9341_BLACK;
if (colorString == "orange") return ILI9341_ORANGE;
if (colorString.startsWith("#") && colorString.length() == 7) {
long number = strtol(colorString.substring(1).c_str(), NULL, 16);
uint8_t r = (number >> 16) & 0xFF;
uint8_t g = (number >> 8) & 0xFF;
uint8_t b = number & 0xFF;
uint16_t color565;
if (useGBR) {
// GBR 转换: G(5) B(6) R(5)
color565 = ((g & 0xF8) << 8) | ((b & 0xFC) << 3) | (r >> 3);
Serial.println("Using GBR conversion");
} else {
// RGB565 转换 (默认)
color565 = tft.color565(r, g, b);
Serial.println("Using RGB conversion");
}
// --- 串口调试输出 ---
Serial.print("Color String: ");
Serial.println(colorString);
Serial.print("R: "); Serial.println(r);
Serial.print("G: "); Serial.println(g);
Serial.print("B: "); Serial.println(b);
Serial.print("565 Color: "); Serial.println(color565);
return color565;
}
return ILI9341_WHITE;
}
ESP8266_ILI9341 项目的 README 文件。它采用了您提供的优秀模板的结构和风格,旨在让任何接手此项目的人都能一目了然。
ESP8266 智能双控触摸屏 (v4.5)
这是一个高度可靠功能完备的 ESP8266 物联网(IoT)控制器。它以一块 ILI9341 触摸屏为核心,通过一个简洁的双按钮界面,实现了对两个独立网络设备(Home Assistant 实体和任意 HTTP 设备)的远程控制。
项目集成了优雅的网页日志系统OTA 在线更新功能,并采用了一个经过优化的软件待机模式,在保证绝对可靠唤醒的前提下,通过关闭屏幕关闭Wi-Fi并降低CPU频率,实现了显著的功耗降低。
[此处应有项目运行时的照片]
✨ 核心功能
- 📱 双按钮触摸界面: 在屏幕上提供两个清晰独立的触摸按钮,分别控制两个不同的智能设备。
- 🌐 双设备网络遥控:
- 通过 Home Assistant API 控制一个设备(例如开关灯光)。
- 通过发送 HTTP GET 请求 控制另一个设备(例如其他ESP模块或任何支持URL控制的设备)。
- 💤 智能软件待机: 经过优化的低功耗模式,比常规待机功耗更低。
- 一分钟无操作后,自动 关闭Wi-Fi关闭屏幕控制器及背光,并将CPU降频至80MHz 以最大限度节省能源。
- 👆 触摸唤醒: 在待机模式下,任何触摸都会立即可靠地唤醒设备,恢复全部功能。
- 📋 网页事件日志:
- 通过浏览器访问
/logs页面,可查看带有精确时间戳的设备事件历史。 - 日志内容包括:系统启动待机/唤醒Wi-Fi连接状态触摸坐标按钮触发动作等。
- 通过浏览器访问
- ☁️ OTA 在线更新: 无需连接数据线,通过网页即可上传新固件进行更新。
- 🕒 NTP 自动校时: 自动从网络时间服务器同步时间,确保日志时间戳的准确性。
🛠️ 硬件清单
- 主控: ESP8266 开发板 (例如 NodeMCU Wemos D1 Mini)。
- 显示屏: ILI9341 TFT 触摸屏模块 (2.4寸 240x320 SPI接口 带XPT2046触摸控制器)。
- 电源: 5V MicroUSB 电源。
- 杜邦线 若干。
🔌 硬件接线
| 组件/功能 | ESP8266 引脚 (GPIO) | 连接到屏幕模块引脚 | 功能描述 |
|---|---|---|---|
| TFT 显示 | 15 (D8) | CS |
屏幕片选 |
| 5 (D1) | DC / RS |
屏幕数据/命令选择 | |
| 4 (D2) | RST |
屏幕复位 | |
| 触摸 | 0 (D3) | T_CS |
触摸芯片片选 |
| SPI (共享) | 14 (D5) | SCK / T_CLK |
并联到屏幕和触摸的时钟线 |
| 12 (D6) | MISO / T_DO |
并联到屏幕和触摸的数据输出 | |
| 13 (D7) | MOSI / T_DIN |
并联到屏幕和触摸的数据输入 | |
| 电源 | 3V3 | VCC |
为屏幕和触摸模块供电 |
| GND | GND |
公共地线 |
背光控制 (两种方案可选)
-
方案一 (推荐,支持待机):
- 将 ESP8266 的
D0(GPIO 16) 引脚连接到屏幕模块的LED(或BL) 引脚。本项目的代码基于此方案编写。
- 将 ESP8266 的
-
方案二 (极简,屏幕常亮):
- 将屏幕模块的
LED引脚直接连接到 ESP8266 的3.3V引脚。如果采用此方案,您可以将代码中所有与TFT_LED相关的行删除。
- 将屏幕模块的
⚙️ 软件与配置
1. 准备 Arduino IDE
- 安装 Arduino IDE: 从 官方网站 下载并安装。
- 配置 ESP8266 开发板环境:
- 打开
文件->首选项。 - 在 "附加开发板管理器网址" 中,填入:
http://arduino.esp8266.com/stable/package_esp8266com_index.json - 打开
工具->开发板->开发板管理器,搜索esp8266并安装。
- 打开
- 安装所需库:
- 打开
工具->管理库。 - 搜索并安装以下所有库:
Adafruit GFX LibraryAdafruit ILI9341XPT2046_TouchscreenArduinoJsonNTPClientby Fabrice Weinberg
- 打开
2. 配置固件
用 Arduino IDE 打开项目代码 (.ino 文件),所有您需要修改的配置项都集中在文件的最顶部。
a. 配置 WiFi:
const char* ssid = "你的WiFi名称"
const char* password = "你的WiFi密码"
b. 配置 Home Assistant 和 HTTP 设备:
const char* ha_host = "192.168.31.22"
const int ha_port = 8123
const char* ha_token = "你的HA长期访问令牌"
const char* ha_entity_id = "switch.你的HA实体ID"
const char* led_on_url = "http://你的设备IP/开灯指令"
const char* led_off_url = "http://你的设备IP/关灯指令"
c. (重要!) 配置触摸屏校准:
每个触摸屏都有细微差异。请使用我们之前的校准程序获取您屏幕的专属 min/max 坐标,并替换 handleTouch() 函数中的以下两行:
// 示例值,请务必替换为您自己的校准值
int screen_x = map(p.y 295 3750 0 240)
int screen_y = map(p.x 358 3810 0 320)
🚀 使用方法
- 上传代码: 在 Arduino IDE 中选择您的开发板型号 (例如
NodeMCU 1.0) 和端口,然后点击上传。 - 获取 IP 地址: 上传成功后,打开
工具->串口监视器(波特率设为 115200),等待 ESP8266 连接上 WiFi 后,会打印出设备的 IP 地址。 - 开始使用:
- 屏幕控制: 直接点击屏幕上的按钮即可控制设备。设备将在无操作1分钟后自动进入待机模式(屏幕熄灭),再次触摸即可唤醒。
- 网页访问:
- 在浏览器中输入获取到的 IP 地址,可以访问主页。
- 点击主页上的 “查看事件日志” 按钮,或直接访问
http://[IP地址]/logs来查看详细的操作历史。 - 若要更新固件,请访问
http://[IP地址]/update。
评论区(0 条)
发表评论⏳ 加载编辑器…