项目概述

        本项目基于零知派ESP32 开发板,结合 ADXL335(模拟加速度计)和 MPU6050(数字加速度计/陀螺仪)两个传感器,构建了一套双通道地震波监测系统。系统通过 STA/LTA 算法实时检测 P 波(纵波)和 S 波(横波),在 TFT 屏幕上本地显示波形,并通过 MQTT 协议将数据推送至 Web 端仪表盘,实现远程报警与可视化监控。

项目亮点

  • 双传感器冗余设计:ADXL335 负责 S 波检测(高量程),MPU6050 负责 P 波检测(高灵敏度),优势互补
  • STA/LTA 实时触发算法:短时窗平均值/长时窗平均值比值判断地震事件,带持续计数防误报机制
  • 高通滤波器:0.5Hz 一阶 RC 高通滤波,消除直流偏置和低频漂移
  • 本地 + 远程双端显示:TFT 实时波形 + Web 端 MQTT 仪表盘,支持浏览器通知
  • 一键归零校准:两个独立按钮分别校准两路传感器的零点偏移
  • MQTT 断线自动检测:通过 LWT 遗嘱消息 + 数据超时双重机制,实时检测设备断电/离线,Web 端弹出检修提示

项目难点及解决方案

难点 解决方案
模拟传感器噪声大 16 次过采样取平均 + 一阶低通滤波(α=0.20)
阈值触发误报率高 连续超阈值计数(P_PERSIST=10, S_PERSIST=8)+ 消抖迟滞窗口
双通道显示数据抖动 波形实时更新,数字显示 1 秒刷新一次
MQTT 网络不稳定 LWT 遗嘱消息 + 自动重连 + 连接状态指示
断电/离线无法及时感知 ESP32 发布 online/offline 状态 + Web 端 5 秒数据超时检测 + 全屏断电检修弹窗

目录

一、硬件系统部分

1.1 硬件清单

1.2 接线方案

1.3 硬件连接图

1.4 实物连接图

二、软件架构设计

2.1 系统初始化

2.2 主循环逻辑

2.3 MQTT 主题设计

三、代码拆分讲解

3.1 引脚定义与常量

3.2 STA/LTA 算法

3.3 高通滤波器

3.4 ADXL335 采样

3.5 MPU6050 读取

3.6 事件检测与防误报

3.7 MQTT 连接与状态发布

3.8 MQTT 数据发布

3.9 Web 端仪表盘

四、操作过程及数据展示

4.1 操作步骤

4.2 数据展示示意

4.3 视频演示

五、技术原理

5.1 工作原理

5.2 工作模式配置

六、常见问题指引

Q1: MPU6050 初始化失败(串口输出 MPU no / MPU id err)

Q2: ADXL335 数值跳动过大

Q3: WiFi/MQTT 连接不上

Q4: 报警频繁误报或漏报

Q5: Web 页面无数据显示

Q6: 如何修改采样率?

Q7: 断电检修弹窗不弹出?


一、硬件系统部分

1.1 硬件清单

组件 数量 说明
零知派ESP32 开发板 1 主控芯片(240MHz, 4MB Flash)
零知派ESP32扩展板 1 方便接线用
ADXL335 模块(GY-61) 1 三轴模拟加速度计(±3g)
MPU6050 模块 1 三轴数字加速度计(±2g)
TFT 显示屏(ST7789) 1 使用 TFT_eSPI 库驱动
LED灯珠模块 1 报警指示灯
杜邦线/面包板 若干 接线用

1.2 接线方案

ADXL335(GY-61)→ ESP32

ADXL335 ESP32扩展板
VCC 3.3V
GND GND
X_OUT GPIO 32 (ADC)
Y_OUT GPIO 35 (ADC)
Z_OUT GPIO 34 (ADC)

MPU6050 → ESP32

MPU6050 ESP32扩展板
VCC 3.3V
GND GND
SCL GPIO 17
SDA GPIO 16
AD0 GND(I2C 地址 0x68)

LED灯珠模块 → ESP32

LED灯珠模块 ESP32扩展板
IN GPIO 26
VCC 3.3V
GND GND

1.3 硬件连接图

1.4 实物连接图


二、软件架构设计

2.1 系统初始化

  1. 串口初始化Serial.begin(115200)
  2. ADC 配置:12 位分辨率、11dB 衰减(量程约 3.6V)
  3. TFT 初始化tft.init(),方向 3(横屏)
  4. MPU6050 初始化:I2C 通信、唤醒、读 WHO_AM_I(应返回 0x68)、设置量程 ±2g
  5. WiFi 连接WiFi.begin(SSID, PASS),自动重连
  6. MQTT 配置broker.emqx.io:1883,主题 seismic/data,seismic/status。
  7. GPIO 配置:按键 INPUT_PULLUP,LED OUTPUT LOW
  8. 创建精灵缓冲区spr.createSprite(width, height) 用于双缓冲绘图

2.2 主循环逻辑

loop()
├── 按键处理(50ms 消抖)
│   ├── S1 按下 → 校准 ADXL335 零偏 + 清空 STA/LTA 缓冲区
│   └── S2 按下 → 校准 MPU6050 零偏 + 清空 STA/LTA 缓冲区
├── 数据采样(25ms 周期)
│   ├── smp335() → ADXL335 三轴读取、低通滤波、高通滤波、STA/LTA 更新
│   ├── smpMPU() → MPU6050 读取、合矢量、高通滤波、STA/LTA 更新
│   └── chkEv()  → 基于 STA/LTA 比值和持续计数判断 P/S 波事件
├── 显示刷新(1s 周期)
│   ├── drawHdr() → 状态栏(三轴数值、采样率、MQTT 状态、RMS、SL)
│   └── drawDsp() → 波形图(S-WAVE + P-WAVE,双缓冲区 Sprite)
├── MQTT 维护
│   ├── conMQ() → 自动重连
│   └── pubData() → 每 1 秒发布 JSON 数据
└── LED 更新:报警时高电平,正常时低电平

2.3 MQTT 主题设计

主题 方向 QoS Retain 说明
seismic/data ESP32 → Web 0 加速度数据与报警状态(每秒发布)
seismic/status ESP32 ⇄ Web 1 设备在线/离线状态(LWT 遗嘱消息)

三、代码拆分讲解

3.1 引脚定义与常量

  • PIN_X/Y/Z — ADXL335 三轴 ADC 引脚
  • BTN_S1/S2 — 两个校准按键
  • PIN_LED — 报警指示灯
  • MPU_ADDR/SDA/SCL — MPU6050 I2C 地址和引脚
  • VREF/ADC_RES/ZERO_G/SENS — ADXL335 电压转加速度参数
  • SAMPLE_MS = 25 — 采样周期 25ms(即 40Hz)
  • P_TH/S_TH — P 波和 S 波的 STA/LTA 触发阈值
  • P_PERSIST/S_PERSIST — 连续超阈值次数,防止瞬时噪声误触发
  • STA_W = 40 / LTA_W = 600 — 短时窗 40 点(1s)、长时窗 600 点(15s)

3.2 STA/LTA 算法

static void slUpdate(float* sta, int& si, int& sc, float& ss,
                     float* lta, int& li, int& lc, float& ll,
                     float& rr, float v)

核心思想:

  • STA(Short Term Average):最近 40 个样本的平均值,反映瞬时振幅
  • LTA(Long Term Average):最近 600 个样本的平均值,反映背景噪声水平
  • 比值 R = STA / LTA:R 越大表示当前振动越强烈
  • 使用环形缓冲区实现 O(1) 时间复杂度的滑动窗口更新

3.3 高通滤波器

struct HP {
    float pI, pO, a;
    HP(float fc, float fs) {
        float rc = 1.0/(2*PI*fc), dt = 1.0/fs;
        a = rc/(rc+dt);
    }
    float up(float in) {
        pO = a*(pO+in-pI); pI = in; return pO;
    }
};

一阶 RC 高通滤波器,截止频率 0.5Hz(fc=0.5),用于消除直流分量和温度漂移。

3.4 ADXL335 采样

static void smp335() {
    // 16 次过采样取平均降低噪声
    for (int i = 0; i < 16; i++) {
        sx += analogRead(PIN_X);
        // ...
    }
    // 电压 → 加速度转换:(V/VREF - 零偏) / 灵敏度
    float ax = ((sx/16.0/ADC_RES)*VREF - ZERO_G) / SENS;
    // 一阶低通滤波(α = 0.20)
    fx = ALPHA_335*ax + (1-ALPHA_335)*fx;
    // 去零偏 → 高通滤波 → 推入缓冲区 → STA/LTA 更新
}

3.5 MPU6050 读取

// 读取加速度寄存器 0x3B(6 字节,X/Y/Z 各 2 字节)
Wire.write(0x3B);
Wire.requestFrom(MPU_ADDR, 6);
// 合并高低字节 → int16 → 除以 16384(±2g 量程分辨率)
x = rx / 16384.0f - tAX;
// 合矢量:sqrt(x² + y² + z²)

3.6 事件检测与防误报

// P 波检测
if (pR > P_TH) {                     // STA/LTA > 4.5
    if (!pWA && ++pCnt >= P_PERSIST) { // 连续 10 次才确认
        pWA = true; pCnt = 0;
        // 发送 MQTT 报警
        pubAl("p_wave", pR, magM);
    }
} else {
    pCnt = 0;                         // 未超阈值立即清零计数器
    if (pR < P_DB) pWA = false;       // 迟滞窗口:须降到 3.0 以下才解除
}

防误报机制

  1. 持续计数:必须连续 P_PERSIST(10 次)超阈值才确认
  2. 迟滞窗口:触发后须降至 P_DB(3.0)以下才解除报警
  3. 报警冷却ALERT_CD = 10s 内不重复发送相同类型报警

3.7 MQTT 连接与状态发布

static void conMQ() {
    // ...
    if (mq.connect(CID, "seismic/status", 1, true, "offline")) {
        // ▲ LWT 遗嘱消息:ESP32 意外断电时,broker 自动发布 "offline"
        Serial.println("ok");
        mq.publish("seismic/status", "online", true);
        // ▲ retain=true:新连接的 Web 端立即收到最新状态
    }
}

LWT 断电检测原理:

  • MQTT 连接时通过 mq.connect(CID, topic, qos, retain, message) 设置遗嘱消息
  • ESP32 正常运行时会持续发送 seismic/data 数据
  • 当 ESP32 意外断电/断网时,MQTT Broker 在心跳超时后自动向 seismic/status 发布预设的 "offline" 消息
  • Web 端订阅 seismic/status,收到 "offline" 后立即显示全屏断电检修弹窗

3.8 MQTT 数据发布

// 普通数据(每秒)
{
  "335": {"x": 0.12, "y": -0.05, "z": 0.98, "rms": 0.0023, "sl": 1.2},
  "6050": {"mag": 0.0034, "sl": 1.1},
  "al": {"p": 0, "s": 0},
  "t": 12345
}

// 报警数据
{
  "tp": "p_wave", "sl": 6.5, "mg": 0.0456, "t": 12345
}

3.9 Web 端仪表盘

断电/离线检测采用双重保障:

机制 触发条件 响应时间 说明
① LWT 遗嘱消息 MQTT Broker 检测到 ESP32 断开连接 ~15-30s(心跳超时) 主动推送离线状态
② 数据超时检测 Web 端 5 秒未收到 seismic/data 5s 被动检测,双重保险

Web 端响应流程:

收到 "offline" 或 5 秒无数据
  → 顶部离线横幅(红色)
  → 页面变灰(grayscale 滤镜)
  → 右下角 Toast 通知
  → 全屏断电检修弹窗(橙色主题)
      ├── 显示设备最后在线时间
      ├── "设备已断电/离线 — 请前往检修设备电源及通讯连接"
      └── 用户可关闭,30 秒后若仍未恢复则自动重新弹出

Web 端相关核心代码:

// MQTT 状态订阅
client.subscribe('seismic/status');

client.on('message', (topic, payload) => {
  if (topic === 'seismic/status') {
    if (str === 'online') {
      deviceOnline = true;
      // 隐藏断电弹窗,记录最后在线时间
    } else {
      deviceOnline = false;
      showPoweroff();           // 显示断电检修弹窗
    }
  }
});

// 5 秒数据超时检测(双重保障)
setInterval(() => {
  if (lastDataTime > 0 && now - lastDataTime > 5000 && deviceOnline) {
    deviceOnline = false;
    showPoweroff();             // 显示断电检修弹窗
  }
}, 2000);

断电检修弹窗界面:

元素 说明
⚡🔌 图标 + "⛔ 设备断电" 标签 直观断电标识
"设备已断电 / 离线" 标题 橙红色醒目文字
"请前往检修设备电源及通讯连接" 明确的操作指引
"上次在线: HH:MM:SS" 帮助判断断电时间
"我知道了,稍后检修" 按钮 用户确认后 30s 自动重新弹出

四、操作过程及数据展示

4.1 操作步骤

  1. 硬件连接:按接线方案连接所有组件
  2. 安装依赖库:TFT_eSPI, PubSubClient, WiFi
  3. 配置 WiFi:修改代码的 SSID 和 PASS 为你自己的 WiFi
  4. 编译上传:使用零知派编译上传到 ESP32
  5. 首次使用
    • 将传感器模块静止放置于水平桌面
    • 按 S1 键校准 ADXL335 零点
    • 按 S2 键校准 MPU6050 零点
  6. 观察显示
    • TFT 显示两路实时波形和数值
    • 轻轻敲击桌面观察波形变化和 SL 值上升
  7. 远程监控
    • 打开浏览器访问 data/index.html(或部署到服务器)
    • 页面自动连接 MQTT,显示远程波形和报警
  8. 断电测试
    • 断开 ESP32 电源
    • 观察 Web 端是否在 15-30 秒后弹出 ⚠️ 断电检修提示

4.2 数据展示示意

状态 TFT 显示 Web 显示
静止 S/P 波形近乎直线,SL ≈ 1.0 绿色进度条,无报警
轻微振动 波形小幅度波动,SL ≈ 2~4 黄色进度条,无报警
强烈振动(P 波) P-WAVE 区出现红色标签 "P-WAVE" 红色进度条 + 弹窗 + 浏览器通知
强震(S 波) S-WAVE 区出现红色标签 "S-WAVE" 双重报警,LED 亮起
设备断电/离线 TFT 熄灭(断电) 橙色全屏弹窗 + 红色顶部横幅 + 页面变灰

4.3 视频演示

零知派ESP32--双传感器地震监测系统


五、技术原理

5.1 工作原理

地震波基础

  • P 波(纵波):传播速度快(~6km/s),振幅小,先到达
  • S 波(横波):传播速度慢(~3.5km/s),振幅大,破坏性强

检测策略

  • MPU6050(高灵敏度,±2g)检测微弱的 P 波
  • ADXL335(模拟输出,±3g)检测大幅度的 S 波
  • 系统利用 P 波比 S 波先到的时差窗口(EVENT_WIN = 60s),若 S 波触发在 P 波之后 60s 内,标记为 s_corr(关联 S 波),否则为独立 s_wave

5.2 工作模式配置

参数 默认值 说明
SAMPLE_MS 25 采样周期(ms),即 40Hz
P_TH 4.5 P 波 STA/LTA 触发阈值
S_TH 6.0 S 波 STA/LTA 触发阈值
P_DB 3.0 P 波解除报警迟滞阈值
S_DB 4.0 S 波解除报警迟滞阈值
P_PERSIST 10 P 波确认所需连续超阈值次数
S_PERSIST 8 S 波确认所需连续超阈值次数
ALERT_CD 10000 报警冷却时间(ms)
EVENT_WIN 60000 P-S 关联时间窗口(ms)
STA_W / LTA_W 40 / 600 短时窗 / 长时窗长度(样本数)
ALPHA_335 0.20 ADXL335 低通滤波系数
hpS/hpP fc 0.5 Hz 高通滤波器截止频率

可根据实际部署环境的背景噪声水平调节 P_TH 和 S_TH 阈值。背景噪声大的环境应适当提高阈值,安静环境可降低阈值以提高灵敏度。


六、常见问题指引

Q1: MPU6050 初始化失败(串口输出 MPU no / MPU id err)

  • 检查 I2C 接线(SDA→GPIO16, SCL→GPIO17)
  • 确认 AD0 接 GND(地址 0x68)

Q2: ADXL335 数值跳动过大

  • 检查 ADC 衰减设置 analogSetPinAttenuation(pin, ADC_11db)
  • 检查电源是否稳定,建议 3.3V 单独供电

Q3: WiFi/MQTT 连接不上

  • 确认 SSID 和密码正确
  • 检查 MQTT Broker(broker.emqx.io)是否可访问
  • ESP32 和路由器之间信号强度是否足够

Q4: 报警频繁误报或漏报

  • 调整 P_TH / S_TH 阈值
  • 调整 P_PERSIST / S_PERSIST 持续计数次数
  • 检查传感器是否固定牢固,避免机械振动干扰

Q5: Web 页面无数据显示

  • 确认 ESP32 已连接 MQTT(TFT 右上角圆点为绿色)
  • 刷新页面,检查浏览器控制台是否有 WebSocket 错误
  • index.html 中 MQTT WebSocket 端口为 8083

Q6: 如何修改采样率?

  • 修改 SAMPLE_MS 常量的值(当前 25ms = 40Hz)
  • 同时需同步调整 HP 滤波器的采样率参数 1000.0/SAMPLE_MS

Q7: 断电检修弹窗不弹出?

  • 检查 Web 端 index.html 的 5s 数据超时检测是否正确运行
  • MQTT Broker(broker.emqx.io)心跳默认约 15-30s,断电后需等待此时间 Broker 才会发布 LWT
  • 建议同时使用双重检测(LWT + 数据超时)以提高响应速度
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐