都会明武电子 LOGO 都会明武电子电子模块 · 技术支持
ESP32 2.8 Yellow Screen · 01

ESP32 2.8黄屏 01 源码解说资料

这一页保留原来的 01 版本:重点是 ESP32-2432S028R 黄屏、TFT_eSPI/LVGL 入门、BMI160 和 WiFi 配网源码学习。02 DeepWarpHUD 是另一条新视频,已经单独放到新页面。

01 版本源码学习ESP32 黄屏CYD

源码下载

01 和 02 是不同代码,不要互相覆盖。客户如果看的是这页,就下载 01 源码包。

01 版本源码包

包含 01 资料包中的 .ino、字体文件、PlatformIO 配置、README 和必要配置。

下载 01 源码 ZIP

BMI160 单测源码包

单独测试 BMI160 的 X/Y/Z 数据,包含 main.inoconfig.hlv_conf.h、PlatformIO 配置和接线说明。

下载 BMI160 源码 ZIP

02 新版入口

DeepWarpHUD 番茄钟手势和自动转屏是新视频资料,代码另放,不与 01 混用。

进入 02 资料页

这页主要讲什么

硬件对象

ESP32-2432S028R,常叫 ESP32 2.8 黄屏 / CYD,带 2.8 寸 TFT 屏和触摸功能。

源码重点

屏幕 UI、触摸、WiFi 配网、天气空气数据、番茄计时、BMI160 姿态读数。

客户用法

先下载源码包,按说明打开 .ino 或 PlatformIO 工程,再根据自己的串口和 WiFi 修改。

不要混用

02 的 DeepWarpHUD 代码结构更精简,是新视频使用的独立版本。

BMI160 Single Test UI

BMI160 单独测试 UI

ESP32 2.8黄屏 BMI160 单独测试封面

为什么要单独测试

完整程序里同时有屏幕、触摸、WiFi、天气、番茄计时和横竖屏。如果 BMI160 先没确认正常,后面问题会混在一起。

这个单测版本只看 BMI160 的 X/Y/Z 数据,不切屏、不启动计时。先确认传感器稳定,再合回完整 UI。

SCL IO22SDA IO273.3V地址 0x68/0x69

接线表

BMI160 模块ESP32 黄屏说明
VCC3V3建议 3.3V 供电
GNDGND必须共地
SCLIO22I2C 时钟线
SDAIO27I2C 数据线

排查顺序

  • 先看屏幕能不能正常亮。
  • 再确认 BMI160 地址能扫到 0x680x69
  • 最后轻轻晃动模块,看 X/Y/Z 数值是否变化。
  • 测试 BMI160 时先关闭自动横竖屏,避免晃动后页面跳转。

BMI160 有用源码

下面这些是当前源码里最值得客户看的部分:接线常量、I2C 寄存器读写、BMI160 初始化、读取 X/Y/Z,以及主循环里怎么刷新页面。完整程序仍然以源码 ZIP 为准。

用到的库
#include <lvgl.h>
#include <TFT_eSPI.h>
#include <Wire.h>
#include <math.h>
#include <WiFi.h>
#include <WebServer.h>
#include <DNSServer.h>
#include <Preferences.h>
#include <time.h>
#include <sys/time.h>
接线和地址常量
#define BMI_SDA_PIN 27
#define BMI_SCL_PIN 22

static uint8_t bmiAddr = 0; // 0 = 没找到
I2C 寄存器读写
static bool bmiWriteReg(uint8_t reg, uint8_t val) {
  Wire.beginTransmission(bmiAddr);
  Wire.write(reg);
  Wire.write(val);
  return Wire.endTransmission() == 0;
}

static bool bmiReadRegs(uint8_t reg, uint8_t *buf, uint8_t len) {
  Wire.beginTransmission(bmiAddr);
  Wire.write(reg);
  if (Wire.endTransmission(false) != 0) return false;
  Wire.requestFrom((int)bmiAddr, (int)len);
  for (uint8_t i = 0; i < len; i++) {
    if (!Wire.available()) return false;
    buf[i] = Wire.read();
  }
  return true;
}
初始化 BMI160
static bool bmiInit() {
  Wire.begin(BMI_SDA_PIN, BMI_SCL_PIN);
  Wire.setTimeOut(50);
  Wire.setClock(400000);

  uint8_t candidates[2] = {0x68, 0x69};
  for (uint8_t i = 0; i < 2; i++) {
    bmiAddr = candidates[i];
    uint8_t chipId = 0;
    if (bmiReadRegs(0x00, &chipId, 1) && chipId == 0xD1) {
      bmiWriteReg(0x7E, 0x11); // 加速度计 normal 模式
      delay(50);
      bmiWriteReg(0x40, 0x28); // ACC_CONF:100Hz
      bmiWriteReg(0x41, 0x03); // ACC_RANGE:+-2g
      return true;
    }
  }

  bmiAddr = 0;
  return false;
}
读取 X/Y/Z
static bool bmiReadAccel(float &ax, float &ay, float &az) {
  if (!bmiAddr) return false;
  uint8_t raw[6];
  if (!bmiReadRegs(0x12, raw, 6)) return false;
  int16_t rx = (int16_t)((raw[1] << 8) | raw[0]);
  int16_t ry = (int16_t)((raw[3] << 8) | raw[2]);
  int16_t rz = (int16_t)((raw[5] << 8) | raw[4]);
  const float scale = 2.0f / 32768.0f; // +-2g 量程
  ax = rx * scale;
  ay = ry * scale;
  az = rz * scale;
  return true;
}
setup 里启动 BMI160
bool ok = bmiInit();
Serial.println(ok ? "BMI160 OK" : "BMI160 NOT FOUND");

if (dbgLabel) {
  lv_label_set_text(dbgLabel, ok ? "BMI160 OK" : "BMI160 NOT FOUND");
}
loop 里刷新数据
static uint32_t lastBmiMs = 0;
if (now - lastBmiMs > 120) {
  lastBmiMs = now;
  float ax = 0, ay = 0, az = 0;
  if (bmiReadAccel(ax, ay, az)) {
    handlePomodoroGesture(ax, ay, now);
    if (activeScene == 2 && !pomodoroScreenShown) {
      updateBmiTestPage(ax, ay, az);
    }
  }
}

BMI160 单测视频

这条视频对应本页新增的 BMI160 单独测试 UI。它和 02 DeepWarpHUD 是不同代码,不要混用。

01 视频