| 简介 
 在上一篇文章中,我们已经完成了 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库
 
 我这块屏幕是几年前买某宙的,其中SCLK在屏幕上的定义是SCL, MOSI在屏幕上的定义是SDA (因为ESP32-C5作为主机设备,所以连接Master out slaver IN MOSI)复制代码#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 主输出从输入
 
 2- 初始化屏幕
 
 首先对屏幕进行初始化,这个背光的PIN如果不适用的话可以直接接3.3V或者悬空,这样就可以节省出来一个IO。复制代码pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH); // 打开背光
SPI.begin(TFT_SCLK, -1, TFT_MOSI);
tft.initR(INITR_BLACKTAB);
 
 3- 初始化屏幕方向显示
 
 屏幕方向的话可以使用tft.setRotation(); 的函数进行设置。复制代码tft.setRotation(3);
tft.fillScreen(ST77XX_BLACK);
tft.setTextColor(ST77XX_WHITE);
tft.setTextSize(1);
tft.setCursor(10, 10);
tft.println("ST7735 Ready!");
 
 
 4- 在主循环中持续读取数据,并且更新显示
 
 5- 显示WIFI的状态信息复制代码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...");
 
 完整代码如下:
 
 
 复制代码#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类的编程将会更简单上手。
 
 
 |