校园气象站:用LoRa+太阳能打造4公里级数据链路
本帖最后由 云天 于 2025-7-22 21:52 编辑——基于 FireBeetle ESP32 × 云雀气象仪 × LoRaWAN × 10 W 太阳能套件
【缘起:两个真实痛点】
痛点现状我们的目标
远距离传输
教学楼屋顶→实验楼机房 Wi-Fi 只有 80 m,4G 月租高
4 km 级、免流量费
长期供电
220 V 拉线危险,普通充电宝 3 天就没电
连续阴雨天 ≥7 天续航
【系统总览】
气象仪端(Sensor Node)
├─ FireBeetle ESP32
├─ 云雀气象仪(I²C)
├─ LoRaWAN 模块(I²C)
└─ 10 W 太阳能套件(12 V→5 V)
接收端(Receiver Node)
├─ FireBeetle 2 ESP32-E
├─ LoRaWAN 模块(I²C)
└─ Wi-Fi → MQTT → Siot → Mind+ 实时面板
【关键硬件清单】
模块链接数量备注
FireBeetle ESP32
DFR0478
1低功耗版
FireBeetle 2 ESP32-E
DFR0654-F
1WIFI和蓝牙双模通信
云雀气象仪
EDU0157
1五合一传感器
LoRaWAN 模块(EU868)
DFR1115-868
24 km 级
10 W 太阳能套件
KIT0210
1含 18650×3
3D 打印外壳
附件 STL
1IP54 级防水
【硬件接线表】
1.气象仪端(Sensor Node)
云雀气象仪
LoRaWAN
FireBeetle ESP32
太阳能套件
红 VCC
—
5 V
5 V
黑 GND
GND
GND
GND
蓝 SDA
SDA
D21
—
绿 SCL
SCL
D22
—
—
VCC
5 V
5 V
注意:LoRaWAN 模块同时支持 3.3 V/5 V,直接接到 FireBeetle 的 5 V 即可。
2.接收端(Receiver Node)接线同上,只需把 LoRaWAN 模块接到 FireBeetle 2 ESP32-E 的 I²C 引脚即可。
【代码编写】
1.气象仪端(Sensor Node)
#include <DFRobot_LWNode.h>
#include "DFRobot_Atmospherlum.h"
// 创建对象
DFRobot_Atmospherlum_I2Catm(0x42,&Wire);
#define FREQ914900000
DFRobot_LWNode_IIC node(1);//设置节点地址为1
void setup( void ) {
Serial.begin(115200);
delay(5000);
node.begin(/*communication IIC*/&Wire,/*debug UART*/&Serial);
const uint32_t loraConfig[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(loraConfig)||
!node.setEIRP(loraConfig)||
!node.setBW(loraConfig) ||
!node.setSF(loraConfig) ||
!node.start()) {
Serial.println("LoRa init failed");
delay(2000);
}
while(atm.begin()!=0){delay(1000);}
Serial.println("yunque ok");
}
void loop( void ){
String data=atm.getValue("Speed")+","+atm.getValue("Dir")+","+atm.getValue("Temp")+","+atm.getValue("Humi")+","+atm.getValue("Pressure");
delay(2000);
node.sendPacket(2, data);//发送温湿度数据给地址为2的节点
node.sleep(5000);
}
2.接收端(Receiver Node)#include <DFRobot_LWNode.h>
#include <DFRobot_Iot.h>
// 静态常量
const String topics = {"siot/pres","siot/speed","siot/dir","siot/humi","siot/tem"};
// 创建对象
DFRobot_Iot myIot;
#define FREQ914900000
DFRobot_LWNode_IIC node(2);//设置节点地址为2
void rxCBFunc(uint8_t from, void *buffer, uint16_t size, int8_t rssi, int8_t snr){
char *p = (char *)buffer;
Serial.print("recv from: ");
Serial.println(from, HEX);
Serial.print("recv data: ");
for(uint8_t i = 0; i < size; i++){
Serial.print(p);
}
Serial.println();
Serial.println("Text:");
Serial.println((char *)buffer);
Serial.print("rssi=");Serial.println(rssi);
Serial.print("snr=");Serial.println(snr);
String input = (char *)buffer;
String values;// 存放结果
int index = 0;
// 先补一个逗号,方便统一处理
input += ",";
while (input.length() > 0) {
int commaIndex = input.indexOf(',');
if (commaIndex == -1) break;
values = input.substring(0, commaIndex);
input = input.substring(commaIndex + 1);
index++;
}
myIot.publish(topic_1, values, 1);//风速
myIot.publish(topic_2, values, 1);//风向
myIot.publish(topic_4, values, 1);//温度
myIot.publish(topic_3, values, 1);//湿度
myIot.publish(topic_0, values, 1);//气压
}
void setup( void ){
Serial.begin(115200);
pinMode(D9, OUTPUT);
myIot.wifiConnect("***", "********");
while (!myIot.wifiStatus()) {}
digitalWrite(D9, HIGH);
myIot.init("192.168.31.11","siot","5490164669696611","dfrobot", topics, 1883);
myIot.connect();
while (!myIot.connected()) {}
delay(5000);
node.begin(/*communication IIC*/&Wire,/*debug UART*/&Serial);
const uint32_t config[] = {FREQ, DBM16, 125000, 12}; //配置LoRa通信参数
while(!node.setFreq(config) ||
!node.setEIRP(config) ||
!node.setBW(config) ||
!node.setSF(config) ||
!node.start()) {
Serial.println("LoRa init failed, retrying...");
delay(2000);
}
node.setRxCB(rxCBFunc);
}
void loop( void ){
node.sleep(5000);
}
【太阳能供电计算】
[*]日均功耗
ESP32 40 mA + 传感器 40 mA + LoRa 发射 120 mA(占空比 1%)≈ 45 mA
45 mA × 5 V × 24 h = 5.4 Wh
[*]电池容量
18650×3(3.7 V 2600 mAh)= 28.9 Wh
可用 80 % → 23.1 Wh
23.1 Wh ÷ 5.4 Wh ≈ 4.3 天(无日照)
[*]太阳能板补充
10 W × 4 h(冬季)= 40 Wh/日,远超需求 → 阴雨天 7 天无压力。
【演示视频】
https://www.bilibili.com/video/BV1tLgWzdEx9/?share_source=copy_web
页:
[1]