简介
在上一篇文章中,我们已经完成了 BH1750 光照传感器的数据采集与 MQTT 上报,并对 I²C 通讯协议 进行了功能验证。 本篇文章将继续扩展项目功能 —— 我们将使用一块 1.8 寸 TFT 彩色显示屏(驱动芯片:ST7735) 来 实时显示传感器数据,同时借此机会 实践并测试 SPI 通讯协议 的使用。

ST7735 是一款由 Sitronix 出品的 TFT-LCD 控制驱动芯片,常用于 1.44~1.8 寸的彩色显示屏。该芯片通过 SPI 接口 与主控(如 ESP32)通信, 而这次我们使用是Arduino进行的编程,得益于强大的库管理器,所以并不需要担心如何编写驱动。只需要按照对应的PIN将杜邦线连接成功即可。 幸运的又是这个ESP32C5的底板非常nice,已经将所有C5的Pin全部引出了,而且还标注了SPI的定义PIN。
1- 首先我们在程序中定义这次我们需要使用到的PIN以便于使用ST7735库
- #define TFT_CS 3 // 片选(Chip Select)
- #define TFT_DC 4 // 数据/命令选择
- #define TFT_RST 25 // 硬件复位
- #define TFT_BL 2 // 背光控制
- #define TFT_SCLK 23 // SPI 时钟
- #define TFT_MOSI 24 // SPI 主输出从输入
复制代码 我这块屏幕是几年前买某宙的,其中SCLK在屏幕上的定义是SCL, MOSI在屏幕上的定义是SDA (因为ESP32-C5作为主机设备,所以连接Master out slaver IN MOSI)
2- 初始化屏幕
- pinMode(TFT_BL, OUTPUT);
- digitalWrite(TFT_BL, HIGH); // 打开背光
- SPI.begin(TFT_SCLK, -1, TFT_MOSI);
- tft.initR(INITR_BLACKTAB);
复制代码 首先对屏幕进行初始化,这个背光的PIN如果不适用的话可以直接接3.3V或者悬空,这样就可以节省出来一个IO。
3- 初始化屏幕方向显示
- tft.setRotation(3);
- tft.fillScreen(ST77XX_BLACK);
- tft.setTextColor(ST77XX_WHITE);
- tft.setTextSize(1);
- tft.setCursor(10, 10);
- tft.println("ST7735 Ready!");
复制代码 屏幕方向的话可以使用tft.setRotation(); 的函数进行设置。
4- 在主循环中持续读取数据,并且更新显示
- tft.fillScreen(ST77XX_BLACK);
- tft.setCursor(10, 15);
- tft.setTextSize(1);
- tft.setTextColor(ST77XX_CYAN);
- tft.println("ESP32 Sensor");
-
- tft.setCursor(10, 35);
- tft.setTextSize(2);
- tft.setTextColor(ST77XX_GREEN);
- tft.printf("Lux: %.1f", lux);
复制代码 5- 显示WIFI的状态信息
- tft.setTextSize(1);
- tft.setCursor(10, 65);
- tft.setTextColor(wifi_connected ? ST77XX_YELLOW : ST77XX_RED);
- tft.printf("WiFi: %s", wifi_connected ? "Connected" : "Disconnected");
-
- tft.setCursor(10, 80);
- tft.setTextColor(mqtt.connected() ? ST77XX_YELLOW : ST77XX_RED);
- tft.printf("MQTT: %s", mqtt.connected() ? "OK" : "Retrying...");
复制代码
完整代码如下:
- #include <WiFi.h>
- #include <WiFiClient.h>
- #include <MQTT.h>
- #include <Wire.h>
- #include <BH1750.h>
- #include <SPI.h>
- #include <Adafruit_GFX.h>
- #include <Adafruit_ST7735.h>
-
- // ===== WiFi 配置 =====
- #define STA_SSID "ImmortalWrt-5G"
- #define STA_PASS "mazha1997"
- #define AP_SSID "esp32-v6"
-
- // ===== MQTT 配置 =====
- #define MQTT_HOST "192.168.1.153"
- #define MQTT_PORT 1884
- #define MQTT_USER "root"
- #define MQTT_PASS "123456"
- #define MQTT_CLIENT_ID "esp32-client"
-
- // ===== ST7735 引脚定义 =====
- #define TFT_CS 3
- #define TFT_DC 4
- #define TFT_RST 25
- #define TFT_BL 2
- #define TFT_SCLK 23
- #define TFT_MOSI 24
-
- // ===== 全局对象 =====
- WiFiClient net;
- MQTTClient mqtt(256);
- BH1750 lightMeter;
- Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
-
- // ===== 全局状态 =====
- static volatile bool wifi_connected = false;
-
- // ===== MQTT 回调函数 =====
- void mqttMessageReceived(String &topic, String &payload) {
- Serial.print("MQTT message received: ");
- Serial.print(topic);
- Serial.print(" => ");
- Serial.println(payload);
- }
-
- // ===== MQTT 初始化连接 =====
- void mqttConnect() {
- Serial.print("Connecting to MQTT... ");
- while (!mqtt.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS)) {
- Serial.print(".");
- delay(1000);
- }
- Serial.println("\nMQTT connected!");
- mqtt.subscribe("esp32/test");
- mqtt.publish("esp32/status", "ESP32 connected successfully!");
- }
-
- // ===== WiFi 事件处理 =====
- void wifiOnConnect() {
- Serial.println("STA Connected");
- Serial.print("STA IPv4: ");
- Serial.println(WiFi.localIP());
-
- mqtt.begin(MQTT_HOST, MQTT_PORT, net);
- mqtt.onMessage(mqttMessageReceived);
- mqttConnect();
- }
-
- void wifiOnDisconnect() {
- Serial.println("STA Disconnected");
- delay(1000);
- WiFi.begin(STA_SSID, STA_PASS);
- }
-
- void WiFiEvent(WiFiEvent_t event) {
- switch (event) {
- case ARDUINO_EVENT_WIFI_AP_START:
- WiFi.softAPsetHostname(AP_SSID);
- break;
- case ARDUINO_EVENT_WIFI_STA_START:
- WiFi.setHostname(AP_SSID);
- break;
- case ARDUINO_EVENT_WIFI_STA_GOT_IP:
- wifi_connected = true;
- wifiOnConnect();
- break;
- case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
- wifi_connected = false;
- wifiOnDisconnect();
- break;
- default:
- break;
- }
- }
-
- // ===== 初始化 =====
- void setup() {
- Serial.begin(115200);
- Serial.println("ESP32 Booting...");
-
- // ===== 初始化 ST7735 =====
- pinMode(TFT_BL, OUTPUT);
- digitalWrite(TFT_BL, HIGH); // 打开背光
- SPI.begin(TFT_SCLK, -1, TFT_MOSI);
- tft.initR(INITR_BLACKTAB);
-
- tft.setRotation(3);
- tft.fillScreen(ST77XX_BLACK);
- tft.setTextColor(ST77XX_WHITE);
- tft.setTextSize(1);
- tft.setCursor(10, 10);
- tft.println("ST7735 Ready!");
-
- // ===== 初始化 I2C & BH1750 =====
- Wire.begin(9, 10); // SDA=9, SCL=10
- if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
- Serial.println("BH1750 initialized successfully.");
- } else {
- Serial.println("BH1750 not detected! Check wiring.");
- tft.setTextColor(ST77XX_RED);
- tft.println("BH1750 ERROR!");
- }
-
- // ===== 初始化 Wi-Fi =====
- WiFi.disconnect(true);
- WiFi.onEvent(WiFiEvent);
- WiFi.mode(WIFI_MODE_APSTA);
- WiFi.softAPenableIPv6();
- WiFi.softAP(AP_SSID);
- WiFi.enableIPv6();
- WiFi.begin(STA_SSID, STA_PASS);
- }
-
- // ===== 主循环 =====
- void loop() {
- if (wifi_connected) {
- mqtt.loop();
- if (!mqtt.connected()) {
- mqttConnect();
- }
-
- static unsigned long lastMsg = 0;
- if (millis() - lastMsg > 10000) {
- lastMsg = millis();
-
- // ===== 读取 BH1750 光照强度 =====
- float lux = lightMeter.readLightLevel();
- Serial.printf("Light intensity: %.2f lux\n", lux);
-
- // ===== MQTT 发布数据 =====
- String payload = String("{"lux":") + String(lux, 2) + "}";
- mqtt.publish("esp32/bh1750", payload);
- Serial.println("Published: " + payload);
-
- // ===== 更新 ST7735 屏幕显示 =====
- tft.fillScreen(ST77XX_BLACK);
- tft.setCursor(10, 15);
- tft.setTextSize(1);
- tft.setTextColor(ST77XX_CYAN);
- tft.println("ESP32 Sensor");
-
- tft.setCursor(10, 35);
- tft.setTextSize(2);
- tft.setTextColor(ST77XX_GREEN);
- tft.printf("Lux: %.1f", lux);
-
- tft.setTextSize(1);
- tft.setCursor(10, 65);
- tft.setTextColor(wifi_connected ? ST77XX_YELLOW : ST77XX_RED);
- tft.printf("WiFi: %s", wifi_connected ? "Connected" : "Disconnected");
-
- tft.setCursor(10, 80);
- tft.setTextColor(mqtt.connected() ? ST77XX_YELLOW : ST77XX_RED);
- tft.printf("MQTT: %s", mqtt.connected() ? "OK" : "Retrying...");
- }
- }
-
- while (Serial.available()) {
- Serial.write(Serial.read());
- }
- }
复制代码
至此便完成了ST7735的驱动。库管理器就是好用,不用费尽心思去调试驱动。还没有测试,不知道Mind + 支不支持这个板子,如果支持的话Block类的编程将会更简单上手。
|