零知派ESP32--ADXL335_MPU6050 双传感器地震监测系统
·
项目概述
本项目基于零知派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 秒数据超时检测 + 全屏断电检修弹窗 |
目录
Q1: MPU6050 初始化失败(串口输出 MPU no / MPU id err)
一、硬件系统部分
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 系统初始化
- 串口初始化:
Serial.begin(115200) - ADC 配置:12 位分辨率、11dB 衰减(量程约 3.6V)
- TFT 初始化:
tft.init(),方向 3(横屏) - MPU6050 初始化:I2C 通信、唤醒、读 WHO_AM_I(应返回 0x68)、设置量程 ±2g
- WiFi 连接:
WiFi.begin(SSID, PASS),自动重连 - MQTT 配置:
broker.emqx.io:1883,主题seismic/data,seismic/status。 - GPIO 配置:按键 INPUT_PULLUP,LED OUTPUT LOW
- 创建精灵缓冲区:
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 以下才解除
}
防误报机制:
- 持续计数:必须连续
P_PERSIST(10 次)超阈值才确认 - 迟滞窗口:触发后须降至
P_DB(3.0)以下才解除报警 - 报警冷却:
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 操作步骤
- 硬件连接:按接线方案连接所有组件
- 安装依赖库:TFT_eSPI, PubSubClient, WiFi
- 配置 WiFi:修改代码的
SSID和PASS为你自己的 WiFi - 编译上传:使用零知派编译上传到 ESP32
- 首次使用:
- 将传感器模块静止放置于水平桌面
- 按 S1 键校准 ADXL335 零点
- 按 S2 键校准 MPU6050 零点
- 观察显示:
- TFT 显示两路实时波形和数值
- 轻轻敲击桌面观察波形变化和 SL 值上升
- 远程监控:
- 打开浏览器访问
data/index.html(或部署到服务器) - 页面自动连接 MQTT,显示远程波形和报警
- 打开浏览器访问
- 断电测试:
- 断开 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 + 数据超时)以提高响应速度
更多推荐



所有评论(0)