• 3
    回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

【 2025 DigiKey 杯】基于 ESP32-P4智能气象预警终端系统

视频演示地址:【基于ESP32-P4智能气象预警终端系统】

摘要

大家好,我是颜七岁。在"万物智联"的时代浪潮下,我参与了2025年DigiKey全球创客挑战赛,设计并实现了一套基于ESP32-P4的智能气象预警终端系统。该系统由气象信息采集板和显示终端两大部分组成,能够实时采集包括温湿度、气压、光照、紫外线、二氧化碳浓度、风速风向以及雷电预警在内的多种环境数据,并通过LoRa无线传输至显示终端进行可视化展示。系统采用模块化设计理念,从传感器选型、硬件电路设计、通信协议制定到软件编程,完整实现了从"方案构思"到"实物实现"的全流程开发,是物联网技术在环境监测领域的典型应用。

应用场景

本系统适用于多种需要实时气象监测与预警的场景,具有广泛的应用价值:

智慧农业:实时监测农田微气候,包括温湿度、光照强度、二氧化碳浓度等关键参数,为精准灌溉、科学施肥、病虫害防治提供数据支持,同时雷电预警功能可提前通知农户采取防护措施,减少经济损失。

城市环境监测:部署于社区、校园、公园等公共场所,提供局部气象信息服务,实时显示空气质量、温湿度舒适度等信息,恶劣天气预警功能可提前通知居民做好防护准备,提升城市管理智能化水平。

本次采用Scheme- it在线设计工具实现系统框图:https://www.digikey.com/en/schemeit

硬件选型与电路设计

采集板主要采集气象信息。主控采用STM32F103芯片。显示面板使用M5STACK TAB5开发板制作。选用的关键元器件均来自DigiKey平台的支持,具体选型如下:

1. 采集板主控芯片

STM32F103:意法半导体推出的一款基于 ARM Cortex-M3 内核的高性能 32 位微控制器,在嵌入式学习入门或常规的嵌入式产品中也有大量的应用,好处就是资源丰富,教程多,上手快的特点。

2. 传感器模块

温湿度传感器:AHT20一款高精度、完全校准的I2C数字输出温湿度复合传感器。采用了新一代的ASIC专用芯片、改进的MEMS半导体电容式湿度传感元件和标准片上温度传感元件。具有性能可靠、即插即用、性价比极高的温湿度传感器,是当前嵌入式项目和消费电子产品中温湿度测量的热门选择。

气压传感器:BME280气压传感器,采用I2C接口通信,精度高、功耗低,非常适合气象监测应用。气压测量精度±1hPa,完全满足气象监测的精度要求。

光照传感器:BH1750是一款数字式环境光强度传感器,通过I2C接口输出16位数字信号,测量范围0-65535 lux,无需外部元件即可工作。它采用ROHM的光敏二极管技术,具有接近人眼的光谱响应特性,功耗极低(典型值0.12μA),支持高分辨率模式(1lx精度)和低功耗模式,广泛应用于智能手机、平板电脑、智能家居等设备的自动背光调节系统。

紫外线传感器:S12SD是一款模拟输出的UV-B波段紫外线传感器,测量波长范围280-315nm,输出电流与UV强度成正比。它采用GaN基光电二极管技术,具有高灵敏度和快速响应特性,工作电压2.7-5.5V,功耗仅0.1mA,适用于户外紫外线监测、防晒提醒、气象监测等应用场景,可直接与MCU的ADC接口连接使用。

二氧化碳传感器:SGP30采用金属氧化物半导体技术,可测量CO2浓度和TVOC(总挥发性有机化合物),采用I2C接口通信,响应速度快,功耗低。CO2测量范围400-60000 ppm,TVOC测量范围0-60000 ppb,能够有效监测空气质量。

风速风向传感器:选用485通信接口的风速风向传感器。该传感器采用RS485接口通信,支持Modbus协议,测量精度高,稳定性好。风速测量范围0-60m/s,风向测量范围0-360°,需12V供电,通过升压模块实现供电转换。

雷电预警传感器:选用AS3935模块。该模块可检测雷电活动,提供雷电距离和强度信息,采用I2C或SPI接口通信,能够提前预警雷电风险,保障户外设备安全。

屏幕显示模块:选用0.96寸OLED模块。该模块具有低功耗,显示亮度高,可视角度广等特点。采用IIC通讯实现屏幕数据显示。

3. 通信模块

LoRa模块:选用SX1278芯片的LoRa模块。该模块采用LoRa调制技术,传输距离远(可达数公里),功耗低,抗干扰能力强,非常适合气象监测这种需要远距离、低功耗传输的应用场景。

系统硬件框图:

4. 显示板硬件

Tab5 是一款面向开发者的高度可扩展便携式智能物联网终端开发设备,集成了双芯片架构和丰富的硬件资源。其主控采用基于 RISC‑V 架构的 ESP32‑P4 SoC,并配备 16MB Flash 与 32MB PSRAM。无线模块则选用 ESP32-C6-MINI-1U,支持 Wi-Fi 6,其天线系统可在内置 3D 天线与外部 MMCX 天线接口之间自由切换,灵活适应不同部署环境,确保数据吞吐与低时延控制。

5. 电源管理

供电单元:使用AMS1117-3.3实现外部5V电压转换成3.3V电源芯片,为后级的传感器和显示器供电。

升压模块:选用S09 DC-DC升压模块,将5V电压升压至12V,为风速风向传感器供电。

6. 硬件设计

采集板原理图设计:

采集板PCB设计图:

焊接后实物图:

软件编写

软件部分基于Arduino框架开发环境,采用模块化编程思想,提升代码可读性与可维护性。具体实现如下:

1. 开发环境搭建

采集板使用STM32常用的STM32Cubemx+Keil5完成

Arduino框架:基于Arduino框架开发,充分利用丰富的第三方库资源,提高开发效率。

2. 采集板固件设计

传感器驱动:为每个传感器编写独立的驱动函数,包括初始化、数据读取、数据转换等功能,实现模块化设计,便于维护和扩展。

数据采集:采用定时采集方式,每隔500ms采集一次各传感器数据。

		//每0.5S获取传感器数据
		if (CompareTime(&TimeSensor_Get))
    {
        SetTime(&TimeSensor_Get, 500); // 每500ms进来一次

				AHT20_Get_Value(&Humiture);
				
				bmp280_read_float(&bmp280_dev, &temperature, &pressure, &humidity);							
				Alt=data_conversion(pressure,temperature);
				pressurehpa=pressure*2/100.0;

			
				BH1750_ReadData(g_ucaDataBuff,2);/*获取照度数据*/
        ftmp = (g_ucaDataBuff[0]<<8 | g_ucaDataBuff[1]) / 1.2f + 0.5f;/*转换照度数据*/
        g_usLux = (uint16_t)ftmp;	
										
				ult_value = Get_ADC_Value();	
				UV_VALUE = Get_Ultraviolet_Intensity(ult_value);
				
			//SGP30读取
				if (sgp30_read(&CO2, &TVOC) == 0)
				{
						sgp30_data.CO2 = CO2;
						sgp30_data.TVOC = TVOC;
		//        usartPrintf(huart1, "CO2: %d ppm, TVOC: %d ppb\r\n", CO2, TVOC);
				}
				else
				{
		//        usartPrintf(huart1, "SGP30 read failed\r\n");
				}

			
			  GET_Wind_Speed_Data();
			GET_Wind_Direction_Data();

		}	

LoRa发送:通过LoRa模块将封装好的数据帧发送出去,支持数据重传机制,确保数据传输的可靠性。

		if (CompareTime(&TimeWiFi_Send))
    {
			SetTime(&TimeWiFi_Send, 500); // 每3000ms进来一次
			static char jsonString[300]; // 假设 JSON 字符串不超过 512 字节
			snprintf(jsonString, sizeof(jsonString),
					"{\"T\":%.1f,\"H\":%.1f,\"P\":%.1f,\"L\":%u,"
					"\"UV\":%d,\"TVOC\":%d,\"Ws\":%.1f,\"Wl\":%.1f,"
					"\"Fx\":\"%s\",\"Wa\":%.1f,\"Ld\":%d}",
					Humiture.Temp,
					Humiture.RH,
					pressurehpa,
					g_usLux,
					UV_VALUE,
					TVOC,
					windSpeed,
					windLevel,
					fengxiang,
					Wind_Angle,
					lightning_distance
			);


			usartPrintf(huart1, "%s\r\n", jsonString);		
			
		}

3. 显示板固件设计

LoRa接收:通过LoRa模块接收采集板发送的数据帧。采用JSON数据解析,提取各传感器数据,并进行单位转换和数据处理。

void parseSerialJSON() {
  while (mySerial.available()) {
    char c = mySerial.read();

    if (c == '\n') {

      StaticJsonDocument<512> doc;
      DeserializationError err = deserializeJson(doc, serialBuffer);

      if (!err) {

        // ===== 温湿度 & 气压 =====
        if (doc.containsKey("T"))
          sensorData.temperature = doc["T"].as<float>();

        if (doc.containsKey("H"))
          sensorData.humidity = doc["H"].as<float>();

        if (doc.containsKey("P"))
          sensorData.pressure = doc["P"].as<float>();

        // ===== 光照 =====
        if (doc.containsKey("L"))
          sensorData.lightLux = doc["L"].as<uint32_t>();

        // ===== UV =====
        if (doc.containsKey("UV"))
          sensorData.uv = doc["UV"].as<int>();

        // ===== TVOC =====
        if (doc.containsKey("TVOC"))
          sensorData.tvoc = doc["TVOC"].as<int>();

        // ===== 风速 & 风力 =====
        if (doc.containsKey("Ws"))
          sensorData.windSpeed = doc["Ws"].as<float>();

        if (doc.containsKey("Wl"))
          sensorData.windLevel = doc["Wl"].as<float>();

        // ===== 风向字符串 =====
        if (doc.containsKey("Fx")) {
          const char* fx = doc["Fx"];
          strncpy(sensorData.windDirStr, fx,
                  sizeof(sensorData.windDirStr) - 1);
          sensorData.windDirStr[sizeof(sensorData.windDirStr) - 1] = '\0';
        }

        // ===== 风向角 =====
        if (doc.containsKey("Wa"))
          sensorData.windAngle = doc["Wa"].as<float>();

        // ===== 雷电距离=====
        if (doc.containsKey("Ld")) {
            sensorData.lightningDistance = doc["Ld"].as<float>();
            sensorData.lightning = (sensorData.lightningDistance > 0);
        }

        drawUI();
      }

      serialBuffer = "";
    }
    else {
      if (serialBuffer.length() < 512)
        serialBuffer += c;
      else
        serialBuffer = "";
    }
  }

}

图形界面:基于LVGL库开发图形界面,包括主界面、数据详情界面、历史数据界面等。主界面实时显示各项气象参数,如温度、湿度、气压、光照、紫外线、CO2浓度、风速、风向等,以及雷电预警信息。

void drawUI() {
  canvas.fillScreen(TFT_WHITE);
  uint16_t greenColor = display.color565(120, 180, 70);
  // ===== 顶部标题条 =====
  canvas.fillRoundRect(0, 0, screenWidth, 60, 4, greenColor);
  canvas.setTextDatum(TL_DATUM);
  canvas.setTextSize(3);
  canvas.setTextColor(TFT_WHITE);
  canvas.drawString("Weather IOT Platform", 20, 20);
  char buf[16];
  int row = 0;
  // ================= 第 1 行 =================
  // 温度
  snprintf(buf, sizeof(buf), "%.1f", sensorData.temperature);
  drawCard(marginSide + 0 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "TEMP", buf, "C");
  // 湿度
  snprintf(buf, sizeof(buf), "%.0f", sensorData.humidity);
  drawCard(marginSide + 1 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "HUMID", buf, "%");
  // 气压
  snprintf(buf, sizeof(buf), "%.0f", sensorData.pressure);
  drawCard(marginSide + 2 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "PRESS", buf, "hPa");
  // 光照
  snprintf(buf, sizeof(buf), "%u", sensorData.lightLux);
  drawCard(marginSide + 3 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "LIGHT", buf, "Lux");
  // ================= 第 2 行 =================
  row = 1;
  // UV
  snprintf(buf, sizeof(buf), "%d", sensorData.uv);
  drawCard(marginSide + 0 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "UV", buf, "UV");
  // TVOC
  snprintf(buf, sizeof(buf), "%d", sensorData.tvoc);
  drawCard(marginSide + 1 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "CO2", buf, "ppb");
  // 雷电距离
  snprintf(buf, sizeof(buf), "%.1f", sensorData.lightningDistance);
  drawCard(marginSide + 2 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "LIGHT DIST", buf, "km");
  // 雷电状态
  if (sensorData.lightning) {
    strcpy(buf, "ALERT");
  } else {
    strcpy(buf, "NORMAL");
  }
  drawCard(marginSide + 3 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "LIGHT STATE", buf, "");
  // ================= 第 3 行 =================
  row = 2;
  // 风速
  snprintf(buf, sizeof(buf), "%.1f", sensorData.windSpeed);
  drawCard(marginSide + 0 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "WIND SPD", buf, "m/s");
  // 风等级
  snprintf(buf, sizeof(buf), "%.1f", sensorData.windLevel);
  drawCard(marginSide + 1 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "WIND LV", buf, "");
  // 风向
  snprintf(buf, sizeof(buf), "%s", sensorData.windDirStr);
  drawCard(marginSide + 2 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "WIND DIR", buf, "");
  // 风向角
  snprintf(buf, sizeof(buf), "%.1f", sensorData.windAngle);
  drawCard(marginSide + 3 * (cardWidth + spacingX),
           marginTop + row * (cardHeight + spacingY),
           cardWidth, cardHeight, "WIND ANG", buf, "o");
  canvas.pushSprite(0, 0);
}

至此以上完成了气象数据的采集,传输,显示三部分。之所以选择模块化设计,主要考虑到可以加快制作周期,快速验证功能。后续的升级版可全部换成板载器件,减少体积,另外升级版再加入锂电池管理与太阳能部分,可实现自主的数据采集与供电管理。

感谢您的耐心阅读。鉴于我的技术水平有限,若存在任何疏漏或错误,恳请您能够提出宝贵的意见。

视频展示:

致谢

感谢DigiKey与电源网联合举办的"实创无界·电燃灵感"2025全球创客挑战赛,为我们提供了从元件选型到技术交流的全链路支持。DigiKey全球元件库的丰富资源和技术文档,为我的硬件选型和电路设计提供了重要参考;电源网论坛的技术交流平台,让我能够与行业专家和广大电子爱好者深入交流,解决开发过程中遇到的各种技术难题。期待未来继续与全球创客一起,用技术推动创新,用实践点燃灵感,共同探索电子设计的无限可能。祝电源网越办越好!

作品开源代码分享

全部回复(3)
正序查看
倒序查看
颜七岁
LV.1
2
01-06 10:18

采集与显示代码开源:https://pan.baidu.com/s/1dBiqowP7Sg90U35vxHoqdA?pwd=HC26

0
回复
03-02 13:25

【DigiKey杯点评】+ pcb板布局还可以进行二次优化,缩小板的尺寸,元件选型和布线更加优化。

0
回复
大_树
LV.2
4
03-12 11:03

【DigiKey 杯点评】这款基于 ESP32-P4 的智能气象预警终端系统模块化设计思路清晰,传感器选型精准且贴合气象监测需求,还通过 LoRa 实现无线数据传输,JSON 格式封装数据让解析更便捷,LVGL 打造的可视化 UI 也让数据展示更直观,同时兼顾智慧农业、城市环境监测等多场景应用,落地性拉满。

0
回复