芯查查logo
  • 物料选型
  • 数据服务
    1. 新产品
    2. 查替代
    3. 丝印反查
    4. 查品牌
    5. PCN/PDN
    6. 查方案
    7. 查代理
    8. 数据合作
  • SaaS/方案
      SaaS产品
    1. 供应链波动监测预警
    2. 半导体产业链地图
    3. BOM管理
    4. 解决方案
    5. 汽车电子
    6. 政府机构
    7. 数据API
  • 商城
  • 行业资讯
    1. 资讯
    2. 直播
  • 论坛社区
    1. 论坛
    2. 学习
    3. 测评中心
    4. 活动中心
    5. 积分商城
  • 查一下
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
  • 举报
😁😂😃😄😅😆😉😊😋😌😍😏😒😓😔😖😘😚😜😝😞😠😡😢😣😤😥😨😩😪😫😭😰😱😲😳😵😷😸😹😺😻😼😽😾😿🙀🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏✂✅✈✉✊✋✌✏✒✔✖✨✳✴❄❇❌❎❓❔❕❗❤➕➖➗➡➰🚀🚃🚄🚅🚇🚉🚌🚏🚑🚒🚓🚕🚗🚙🚚🚢🚤🚥🚧🚨🚩🚪🚫🚬🚭🚲🚶🚹🚺🚻🚼🚽🚾🛀Ⓜ🅰🅱🅾🅿🆎🆑🆒🆓🆔🆕
@好友

全部评论

加载中
游客登录通知
已选择 0 人
自定义圈子
移动
发布帖子
发布动态
发布问答
最新帖子
【星允派 NEBULA PI】18:使用PWM驱动RGB灯【星允派 NEBULA PI】17:使用消息队列创建工程项目【拆解活动】开源恒温加热台拆解分析5A快速充电宝1.0【开源项目】DIY智能手表Monica:极客的腕上科技艺术品
热门版块
查看更多
问型号
问技术
问行情
汽车电子工程师论坛
工业电子专区
新手入门指南
单片机/MCU论坛
PCB设计
开源项目
每日打卡

143

收藏

分享

微信扫码
分享给好友

评论