MOLUN
创作者认证
ESP32-S3 环境监测驱动板项目文档
项目概述
项目名称:ESP32-S3多功能环境监测驱动板
设计人员:MolunSmartHome
设计工具:嘉立创EDA专业版
软件平台:Arduino框架 + PlatformIO
版本号:v2.0
一、硬件规格总览
1.1 核心组件清单
类别 | 组件型号 | 封装 | 数量 | 备注 |
主控芯片 | ESP32-S3-WROOM-1 | QFN-56 | 1 | 使用内部晶振 |
显示屏 | ST7735S 0.96寸 SPI屏 | 8/13pin | 1 | 128x160分辨率 |
显示屏 | SSD1306/SSD1315 OLED | 4pin I2C | 1 | 128x64/128x128 |
温湿度传感器 | SHT30/SHT40 | I2C | 1 | 地址0x44 |
温湿度传感器 | AHT20 | I2C | 1 | 地址0x38(备用) |
气压传感器 | BMP280 | I2C | 1 | 地址0x76 |
环境光传感器 | VEML7700 | I2C | 1 | 地址0x10 |
环境光传感器 | BH1750 | I2C | 1 | 地址0x23(备用) |
雷达模组 | 安信可RD-03 | UART | 1 | 或萤火工场CEM5861 |
音频反馈 | 无源蜂鸣器 | 0603 | 1 | PWM驱动 |
视觉反馈 | WS2812B RGB灯珠 | 5050 | 1 | 单线协议 |
电源管理 | TP4054充电芯片 | SOT-23-6 | 1 | 锂电池充电管理 |
二、完整IO引脚分配
2.1 功能引脚分配表
GPIO | 功能描述 | 接口类型 | 程序定义 | 备注 |
1 | 电池电压检测 | ADC输入 | BATTERY_ADC_PIN |
电阻分压电路 |
2 | 板载状态LED | GPIO输出 | LED_PIN |
低电平有效 |
5 | WiFi配网按钮 | GPIO输入 | WIFI_BUTTON_PIN |
内部上拉,低电平触发 |
7 | 屏幕背光控制 | PWM输出 | TFT_BL_PIN |
ST7735S背光驱动 |
8 | ST7735S片选 | SPI | TFT_CS_PIN |
低电平有效 |
9 | ST7735S数据/命令 | SPI | TFT_DC_PIN |
数据/命令选择 |
10 | ST7735S复位 | SPI | TFT_RES_PIN |
硬件复位 |
11 | SPI主出从入 | SPI | TFT_MOSI_PIN |
数据发送 |
12 | SPI时钟 | SPI | TFT_SCK_PIN |
时钟信号 |
13 | 无源蜂鸣器 | PWM输出 | BUZZER_PIN |
LEDC通道0 |
14 | 雷达OUT中断 | GPIO中断 | RADAR_OUT_PIN |
上升沿触发 |
15 | 雷达数据接收 | UART1 | RADAR_RX_PIN |
接雷达TX引脚 |
16 | 雷达数据发送 | UART1 | RADAR_TX_PIN |
接雷达RX引脚 |
17 | I2C数据线 | I2C | I2C_SDA_PIN |
上拉4.7kΩ |
18 | I2C时钟线 | I2C | I2C_SCL_PIN |
上拉4.7kΩ |
21 | WS2812B数据线 | 单线协议 | WS2812B_PIN |
串联220Ω电阻 |
2.2 备用引脚分配
GPIO | 功能描述 | 程序定义 | 推荐用途 |
3 | 全功能GPIO | EXT_GPIO3 |
第二UART TX |
4 | 全功能GPIO | EXT_GPIO4 |
第二UART RX |
6 | 全功能GPIO | EXT_GPIO6 |
通用PWM输出 |
33 | 仅输入GPIO | BTN_GPIO33 |
扩展按钮 |
34 | 仅输入GPIO | BTN_GPIO34 |
扩展按钮 |
35 | 仅输入+ADC | ADC_GPIO35 |
模拟传感器 |
36 | 仅输入+ADC | ADC_GPIO36 |
模拟传感器 |
37 | 仅输入GPIO | BTN_GPIO37 |
扩展开关 |
38 | 仅输入GPIO | BTN_GPIO38 |
扩展开关 |
47 | 全功能GPIO | EXT_GPIO47 |
通用IO |
48 | 全功能GPIO | EXT_GPIO48 |
通用IO |
2.3 I2C设备地址分配
设备名称 | I2C地址 | 程序定义 | 检测函数 |
OLED显示屏 | 0x3C | OLED_ADDRESS |
detectOLED() |
SHT30/SHT40 | 0x44 | SHT3X_ADDRESS |
detectSHT3X() |
AHT20 | 0x38 | AHT20_ADDRESS |
detectAHT20() |
BMP280 | 0x76 | BMP280_ADDRESS |
detectBMP280() |
VEML7700 | 0x10 | VEML7700_ADDRESS |
detectVEML7700() |
BH1750 | 0x23 | BH1750_ADDRESS |
detectBH1750() |
三、软件架构设计
3.1 项目文件结构
firmware/
├── src/
│ ├── main.cpp # 主程序入口
│ ├── config.h # 引脚定义和配置
│ ├── sensor_manager.cpp # 传感器管理
│ ├── display_manager.cpp # 显示管理
│ ├── radar_processor.cpp # 雷达数据处理
│ ├── power_manager.cpp # 电源管理
│ └── wifi_manager.cpp # 网络连接
├── lib/
│ └── TFT_eSPI/ # 屏幕驱动库
├── include/
│ ├── sensor_types.h # 传感器数据类型
│ └── display_types.h # 显示数据类型
└── platformio.ini # 项目配置
3.2 PlatformIO配置文件
[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
monitor_speed = 115200
lib_deps =
bodmer/TFT_eSPI
adafruit/Adafruit AHTX0
adafruit/Adafruit BMP280 Library
adafruit/Adafruit VEML7700
adafruit/SHT31
adafruit/SHT4x
clawson/BH1750
fastled/FastLED
olikraus/U8g2
build_flags =
-D CORE_DEBUG_LEVEL=3
-D BAUDRATE=115200
3.3 主程序头文件 (config.h)
#ifndef CONFIG_H
#define CONFIG_H
// ==================== 引脚定义 ====================
// 显示引脚
#define TFT_CS_PIN 8
#define TFT_DC_PIN 9
#define TFT_RES_PIN 10
#define TFT_MOSI_PIN 11
#define TFT_SCK_PIN 12
#define TFT_BL_PIN 7
// 传感器引脚
#define I2C_SDA_PIN 17
#define I2C_SCL_PIN 18
#define BATTERY_ADC_PIN 1
// 雷达引脚
#define RADAR_RX_PIN 15
#define RADAR_TX_PIN 16
#define RADAR_OUT_PIN 14
// 用户交互引脚
#define BUZZER_PIN 13
#define WS2812B_PIN 21
#define LED_PIN 2
#define WIFI_BUTTON_PIN 5
// 备用引脚
#define EXT_GPIO3 3
#define EXT_GPIO4 4
#define EXT_GPIO6 6
#define ADC_GPIO35 35
#define ADC_GPIO36 36
// ==================== I2C地址定义 ====================
#define OLED_ADDRESS 0x3C
#define SHT3X_ADDRESS 0x44
#define AHT20_ADDRESS 0x38
#define BMP280_ADDRESS 0x76
#define VEML7700_ADDRESS 0x10
#define BH1750_ADDRESS 0x23
// ==================== 系统配置 ====================
#define SERIAL_BAUDRATE 115200
#define RADAR_BAUDRATE 256000
#define I2C_CLOCK_SPEED 400000
// 屏幕配置
#define TFT_WIDTH 128
#define TFT_HEIGHT 160
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
// 传感器采样间隔(ms)
#define TEMP_SAMPLE_INTERVAL 2000
#define LIGHT_SAMPLE_INTERVAL 1000
#define PRESSURE_SAMPLE_INTERVAL 5000
#endif
3.4 主程序框架 (main.cpp)
#include <Arduino.h>
#include "config.h"
#include <TFT_eSPI.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <FastLED.h>
// 全局对象定义
TFT_eSPI tft = TFT_eSPI();
U8G2_SSD1306_128X64_NONAME_F_HW_I2C oled(U8G2_R0, U8X8_PIN_NONE);
CRGB leds[1];
// 传感器数据结构
struct SensorData {
float temperature;
float humidity;
float pressure;
float altitude;
float lightLux;
float batteryVoltage;
bool radarPresence;
};
SensorData sensorData;
bool displayOnOLED = false;
// 函数声明
void initPins();
void initDisplays();
void initSensors();
void initRadar();
void readSensors();
void updateDisplay();
void handleRadarInterrupt();
void checkBattery();
void beep(int freq, int duration);
void setup() {
Serial.begin(SERIAL_BAUDRATE);
delay(1000);
Serial.println("=== ESP32-S3环境监测系统启动 ===");
initPins();
initDisplays();
initSensors();
initRadar();
// 开机提示音
beep(1000, 200);
beep(1200, 200);
Serial.println("系统初始化完成");
}
void loop() {
readSensors();
updateDisplay();
checkBattery();
// 处理雷达中断
if (sensorData.radarPresence) {
beep(1500, 300);
sensorData.radarPresence = false;
}
delay(1000);
}
// 引脚初始化
void initPins() {
// 输入引脚配置
pinMode(WIFI_BUTTON_PIN, INPUT_PULLUP);
pinMode(RADAR_OUT_PIN, INPUT);
pinMode(BATTERY_ADC_PIN, INPUT);
// 输出引脚配置
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH); // 初始关闭
// PWM引脚配置
ledcSetup(0, 5000, 8); // 背光PWM通道
ledcAttachPin(TFT_BL_PIN, 0);
ledcSetup(1, 1000, 8); // 蜂鸣器PWM通道
ledcAttachPin(BUZZER_PIN, 1);
// I2C初始化
Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);
Wire.setClock(I2C_CLOCK_SPEED);
}
// 显示初始化
void initDisplays() {
// 初始化SPI屏幕
tft.init();
tft.setRotation(3);
tft.fillScreen(TFT_BLACK);
ledcWrite(0, 255); // 背光全亮
// 检测OLED是否存在
Wire.beginTransmission(OLED_ADDRESS);
if (Wire.endTransmission() == 0) {
oled.begin();
oled.clearDisplay();
displayOnOLED = true;
Serial.println("OLED显示屏检测到");
} else {
Serial.println("使用SPI显示屏");
}
}
// 雷达中断处理
void IRAM_ATTR handleRadarInterrupt() {
sensorData.radarPresence = true;
}
3.5 传感器管理模块 (sensor_manager.cpp)
#include "config.h"
#include <Adafruit_SHT31.h>
#include <Adafruit_AHTX0.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_VEML7700.h>
#include <BH1750.h>
Adafruit_SHT31 sht30;
Adafruit_AHTX0 aht20;
Adafruit_BMP280 bmp280;
Adafruit_VEML7700 veml7700;
BH1750 bh1750;
bool sht30Detected = false;
bool aht20Detected = false;
bool bmp280Detected = false;
bool veml7700Detected = false;
bool bh1750Detected = false;
void initSensors() {
// 检测SHT30
if (sht30.begin(SHT3X_ADDRESS)) {
sht30Detected = true;
Serial.println("SHT30传感器检测到");
}
// 检测AHT20
if (aht20.begin()) {
aht20Detected = true;
Serial.println("AHT20传感器检测到");
}
// 检测BMP280
if (bmp280.begin(BMP280_ADDRESS)) {
bmp280Detected = true;
bmp280.setSampling(Adafruit_BMP280::MODE_NORMAL,
Adafruit_BMP280::SAMPLING_X2,
Adafruit_BMP280::SAMPLING_X16,
Adafruit_BMP280::FILTER_X16,
Adafruit_BMP280::STANDBY_MS_1);
Serial.println("BMP280传感器检测到");
}
// 检测VEML7700
if (veml7700.begin()) {
veml7700Detected = true;
veml7700.setGain(VEML7700_GAIN_1_8);
veml7700.setIntegrationTime(VEML7700_IT_100MS);
Serial.println("VEML7700传感器检测到");
}
// 检测BH1750
if (bh1750.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
bh1750Detected = true;
Serial.println("BH1750传感器检测到");
}
}
void readSensors() {
static unsigned long lastTempRead = 0;
static unsigned long lastPressureRead = 0;
static unsigned long lastLightRead = 0;
unsigned long currentTime = millis();
// 读取温湿度
if (currentTime - lastTempRead >= TEMP_SAMPLE_INTERVAL) {
if (sht30Detected) {
sensorData.temperature = sht30.readTemperature();
sensorData.humidity = sht30.readHumidity();
} else if (aht20Detected) {
sensors_event_t humidity, temp;
aht20.getEvent(&humidity, &temp);
sensorData.temperature = temp.temperature;
sensorData.humidity = humidity.relative_humidity;
}
lastTempRead = currentTime;
}
// 读取气压
if (currentTime - lastPressureRead >= PRESSURE_SAMPLE_INTERVAL) {
if (bmp280Detected) {
sensorData.pressure = bmp280.readPressure();
sensorData.altitude = bmp280.readAltitude(1013.25);
}
lastPressureRead = currentTime;
}
// 读取光照
if (currentTime - lastLightRead >= LIGHT_SAMPLE_INTERVAL) {
if (veml7700Detected) {
sensorData.lightLux = veml7700.readLux();
} else if (bh1750Detected) {
sensorData.lightLux = bh1750.readLightLevel();
}
lastLightRead = currentTime;
}
// 读取电池电压
int adcValue = analogRead(BATTERY_ADC_PIN);
sensorData.batteryVoltage = (adcValue / 4095.0) * 3.3 * 2;
}
3.6 显示管理模块 (display_manager.cpp)
#include "config.h"
void updateDisplay() {
if (displayOnOLED) {
displayOnOLEDScreen();
} else {
displayOnTFT();
}
}
void displayOnTFT() {
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(1);
tft.setCursor(0, 0);
tft.printf("温度: %.1fC", sensorData.temperature);
tft.setCursor(0, 15);
tft.printf("湿度: %.1f%%", sensorData.humidity);
tft.setCursor(0, 30);
tft.printf("气压: %.1fhPa", sensorData.pressure / 100.0);
tft.setCursor(0, 45);
tft.printf("光照: %.0flux", sensorData.lightLux);
tft.setCursor(0, 60);
tft.printf("电池: %.2fV", sensorData.batteryVoltage);
// 雷达状态显示
tft.setCursor(0, 75);
if (sensorData.radarPresence) {
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.print("雷达: 检测到目标");
} else {
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.print("雷达: 无目标");
}
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
void displayOnOLEDScreen() {
oled.clearBuffer();
oled.setFont(u8g2_font_6x10_tf);
oled.setCursor(0, 10);
oled.printf("T:%.1fC H:%.1f%%", sensorData.temperature, sensorData.humidity);
oled.setCursor(0, 25);
oled.printf("P:%.1fhPa L:%.0flux", sensorData.pressure / 100.0, sensorData.lightLux);
oled.setCursor(0, 40);
oled.printf("B:%.2fV", sensorData.batteryVoltage);
oled.setCursor(0, 55);
if (sensorData.radarPresence) {
oled.print("RADAR: DETECTED");
} else {
oled.print("RADAR: CLEAR");
}
oled.sendBuffer();
}
3.7 雷达处理模块 (radar_processor.cpp)
#include "config.h"
HardwareSerial radarSerial(1);
void initRadar() {
radarSerial.begin(RADAR_BAUDRATE, SERIAL_8N1, RADAR_RX_PIN, RADAR_TX_PIN);
// 设置雷达中断
attachInterrupt(digitalPinToInterrupt(RADAR_OUT_PIN), handleRadarInterrupt, RISING);
// 发送雷达初始化命令
uint8_t initCmd[] = {0xFD, 0xFC, 0xFB, 0xFA}; // RD-03示例命令
radarSerial.write(initCmd, sizeof(initCmd));
Serial.println("雷达模块初始化完成");
}
void processRadarData() {
if (radarSerial.available()) {
String data = radarSerial.readStringUntil('\n');
if (data.length() > 0) {
Serial.print("雷达数据: ");
Serial.println(data);
// 解析雷达数据
if (data.indexOf("movement") != -1) {
sensorData.radarPresence = true;
}
}
}
}
3.8 电源管理模块 (power_manager.cpp)
#include "config.h"
void checkBattery() {
float voltage = sensorData.batteryVoltage;
// 低电量警告
if (voltage < 3.5) {
digitalWrite(LED_PIN, LOW); // LED亮起警告
beep(800, 500); // 低电量提示音
// 自动降低背光亮度省电
ledcWrite(0, 100);
} else if (voltage < 3.7) {
// 中等电量,中等亮度
ledcWrite(0, 150);
digitalWrite(LED_PIN, HIGH);
} else {
// 电量充足,最大亮度
ledcWrite(0, 255);
digitalWrite(LED_PIN, HIGH);
}
}
void beep(int freq, int duration) {
if (freq > 0) {
ledcWriteTone(1, freq);
delay(duration);
ledcWriteTone(1, 0);
}
}
// 自动背光调节基于环境光
void autoBrightness() {
int brightness;
if (sensorData.lightLux > 500) {
brightness = 255; // 强光环境
} else if (sensorData.lightLux > 100) {
brightness = 150; // 正常环境
} else {
brightness = 50; // 弱光环境
}
ledcWrite(0, brightness);
}
四、功能特性
4.1 主要功能
环境监测:温湿度、气压、光照强度实时监测
人体检测:雷达模组检测人体存在
双显示支持:自动检测并切换SPI和OLED屏幕
智能电源管理:根据电量自动调节背光和提示
多传感器备份:自动选择可用的传感器
4.2 扩展功能
WiFi配网:通过按钮触发智能配网
数据记录:支持传感器数据存储和导出
远程监控:可通过网络远程查看数据
报警系统:支持阈值报警和声音提示
五、使用说明
5.1 编译和烧录
安装PlatformIO IDE
打开项目文件夹
连接ESP32-S3开发板
点击编译和上传
5.2 硬件连接
连接SPI屏幕到指定引脚
连接I2C传感器到SDA/SCL
连接雷达模组到UART引脚
连接锂电池到TP4054
5.3 操作说明
开机:自动检测硬件并初始化
显示切换:自动选择可用的显示屏
雷达检测:检测到人体时发出声音提示
低电量:自动降低亮度并发出警告
文档信息
设计人员:MolunSmartHome
软件版本:v2.0
最后更新:2025年10月
支持邮箱:molun@msn.cn
完整的项目代码和硬件设计文件可在GitHub仓库获取:
[项目仓库链接]
版块:
电子DIY
2025/10/02 22:34
全部评论