文章目录
-
- 一、前言
-
- [1.1 技术背景](#1.1 技术背景)
- [1.2 应用场景](#1.2 应用场景)
- [1.3 读者收获](#1.3 读者收获)
- [1.4 技术栈](#1.4 技术栈)
- 二、环境准备
-
- [2.1 硬件要求](#2.1 硬件要求)
- [2.2 传感器连接](#2.2 传感器连接)
- 三、核心实现
-
- [3.1 DHT22温湿度传感器](#3.1 DHT22温湿度传感器)
- [3.2 BH1750光照传感器](#3.2 BH1750光照传感器)
- [3.3 土壤湿度传感器](#3.3 土壤湿度传感器)
- [3.4 ESP8266 WiFi通信](#3.4 ESP8266 WiFi通信)
- [3.5 主控程序](#3.5 主控程序)
- 四、系统架构
-
- [4.1 数据流图](#4.1 数据流图)
- 五、测试验证
-
- [5.1 传感器校准](#5.1 传感器校准)
- [5.2 通信测试](#5.2 通信测试)
- 六、故障排查
-
- [6.1 传感器读数异常](#6.1 传感器读数异常)
- [6.2 通信失败](#6.2 通信失败)
- 七、总结
-
- [7.1 核心知识点](#7.1 核心知识点)
- [7.2 扩展方向](#7.2 扩展方向)
- [7.3 学习资源](#7.3 学习资源)
一、前言
1.1 技术背景
智能农业是现代农业发展的重要方向,通过物联网技术实现农业环境的实时监测和精准控制,可以显著提高农业生产效率、降低资源消耗、改善农产品质量。
STM32F103系列微控制器凭借其低功耗、丰富的外设接口和较高的性价比,成为农业物联网终端设备的理想选择。本教程将介绍如何基于STM32F103构建一个完整的智能农业监控系统。
1.2 应用场景
- 温室大棚:温湿度、光照、CO2浓度监测
- 农田灌溉:土壤湿度监测与自动灌溉
- 水产养殖:水质监测(pH、溶解氧、温度)
- 畜牧养殖:环境监控与动物行为监测
- 气象监测:微型气象站
1.3 读者收获
完成本教程后,你将掌握:
- 多传感器数据采集与融合
- 低功耗设计与电源管理
- GPRS/WiFi无线通信
- 数据存储与历史记录
- 远程监控与报警系统
- 太阳能供电系统设计
1.4 技术栈
硬件平台:
- 主控芯片:STM32F103C8T6
- 温湿度传感器:DHT11 / DHT22 / SHT30
- 土壤湿度传感器:电容式/电阻式
- 光照传感器:BH1750
- 通信模块:ESP8266 WiFi / SIM800L GPRS
- 显示模块:OLED12864
- 存储模块:SD卡 / Flash
软件工具:
- IDE:Keil MDK-ARM / STM32CubeIDE
- 固件库:STM32Cube HAL库
- 通信协议:MQTT / HTTP
二、环境准备
2.1 硬件要求
系统框图:
通信模块
控制输出
传感器组
STM32F103主控
电源系统
太阳能板
12V/10W
锂电池
12V/20Ah
充电管理
5V稳压
3.3V稳压
ARM Cortex-M3
72MHz
ADC
I2C1/I2C2
USART1/2/3
SPI1
RTC
DHT22
温湿度
土壤湿度
传感器
BH1750
光照强度
CO2传感器
雨量传感器
风速传感器
继电器1
灌溉
继电器2
通风
继电器3
补光
蜂鸣器
报警
ESP8266
WiFi
SIM800L
GPRS
OLED
本地显示
SD卡
数据存储
硬件清单:
- STM32F103C8T6最小系统板 × 1
- DHT22温湿度传感器 × 1
- 电容式土壤湿度传感器 × 2
- BH1750光照传感器 × 1
- ESP8266 WiFi模块 × 1
- SIM800L GPRS模块 × 1
- OLED12864显示屏 × 1
- SD卡模块 × 1
- 继电器模块 × 3
- 太阳能板12V/10W × 1
- 锂电池12V/20Ah × 1
- 充电管理模块 × 1
- 防水外壳 × 1
2.2 传感器连接
DHT22连接:
| DHT22引脚 | STM32引脚 | 说明 |
|---|---|---|
| VCC | 3.3V | 电源 |
| DATA | PA0 | 单总线数据 |
| GND | GND | 地线 |
BH1750连接(I2C):
| BH1750引脚 | STM32引脚 | 说明 |
|---|---|---|
| VCC | 3.3V | 电源 |
| GND | GND | 地线 |
| SCL | PB6 | I2C1_SCL |
| SDA | PB7 | I2C1_SDA |
| ADDR | GND | 地址0x23 |
土壤湿度传感器:
- 信号输出 → PA1(ADC1_IN1)
- VCC → 5V
- GND → GND
三、核心实现
3.1 DHT22温湿度传感器
📄 创建文件:
Inc/dht22.h
c
/* dht22.h - DHT22温湿度传感器驱动 */
#ifndef __DHT22_H
#define __DHT22_H
#include "main.h"
/* 引脚定义 */
#define DHT22_PORT GPIOA
#define DHT22_PIN GPIO_PIN_0
/* 数据格式 */
typedef struct {
int16_t temperature; /* 温度(扩大10倍) */
uint16_t humidity; /* 湿度(扩大10倍) */
uint8_t valid; /* 数据有效标志 */
} DHT22_DataTypeDef;
/* 函数声明 */
void DHT22_Init(void);
uint8_t DHT22_Read(DHT22_DataTypeDef *data);
#endif /* __DHT22_H */
📄 创建文件:
Src/dht22.c
c
/* dht22.c - DHT22温湿度传感器驱动实现 */
#include "dht22.h"
#define DHT22_OUTPUT() { \
GPIO_InitTypeDef GPIO_InitStruct = {0}; \
GPIO_InitStruct.Pin = DHT22_PIN; \
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; \
GPIO_InitStruct.Pull = GPIO_NOPULL; \
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; \
HAL_GPIO_Init(DHT22_PORT, &GPIO_InitStruct); \
}
#define DHT22_INPUT() { \
GPIO_InitTypeDef GPIO_InitStruct = {0}; \
GPIO_InitStruct.Pin = DHT22_PIN; \
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; \
GPIO_InitStruct.Pull = GPIO_NOPULL; \
HAL_GPIO_Init(DHT22_PORT, &GPIO_InitStruct); \
}
#define DHT22_HIGH() HAL_GPIO_WritePin(DHT22_PORT, DHT22_PIN, GPIO_PIN_SET)
#define DHT22_LOW() HAL_GPIO_WritePin(DHT22_PORT, DHT22_PIN, GPIO_PIN_RESET)
#define DHT22_READ() HAL_GPIO_ReadPin(DHT22_PORT, DHT22_PIN)
/**
* @brief 微秒延时
*/
static void delay_us(uint32_t us)
{
volatile uint32_t count;
for (count = 0; count < us * 8; count++);
}
/**
* @brief DHT22初始化
*/
void DHT22_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = DHT22_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(DHT22_PORT, &GPIO_InitStruct);
DHT22_HIGH();
}
/**
* @brief 读取DHT22数据
*/
uint8_t DHT22_Read(DHT22_DataTypeDef *data)
{
uint8_t i, j;
uint8_t buf[5] = {0};
uint16_t temp, hum;
/* 发送起始信号 */
DHT22_OUTPUT();
DHT22_LOW();
delay_us(1000); /* 拉低1ms */
DHT22_HIGH();
delay_us(30); /* 拉高30us */
DHT22_INPUT();
/* 等待DHT22响应 */
delay_us(40);
if (DHT22_READ()) return 1;
delay_us(80);
if (!DHT22_READ()) return 1;
delay_us(80);
/* 读取40位数据 */
for (j = 0; j < 5; j++) {
buf[j] = 0;
for (i = 0; i < 8; i++) {
/* 等待低电平结束 */
while (!DHT22_READ());
delay_us(40);
/* 判断是0还是1 */
if (DHT22_READ()) {
buf[j] |= (1 << (7 - i));
while (DHT22_READ());
}
}
}
/* 校验 */
if ((buf[0] + buf[1] + buf[2] + buf[3]) != buf[4]) {
return 2; /* 校验失败 */
}
/* 解析数据 */
hum = (buf[0] << 8) | buf[1];
temp = (buf[2] << 8) | buf[3];
/* 处理负温度 */
if (temp & 0x8000) {
temp = -(temp & 0x7FFF);
}
data->humidity = hum;
data->temperature = temp;
data->valid = 1;
return 0;
}
3.2 BH1750光照传感器
📄 创建文件:
Inc/bh1750.h
c
/* bh1750.h - BH1750光照传感器驱动 */
#ifndef __BH1750_H
#define __BH1750_H
#include "main.h"
#define BH1750_ADDR 0x23 /* ADDR引脚接地 */
/* 命令 */
#define BH1750_POWER_DOWN 0x00
#define BH1750_POWER_ON 0x01
#define BH1750_RESET 0x07
#define BH1750_CONT_H_RES 0x10 /* 连续高分辨率模式 */
#define BH1750_CONT_H_RES2 0x11 /* 连续高分辨率模式2 */
#define BH1750_CONT_L_RES 0x13 /* 连续低分辨率模式 */
#define BH1750_ONE_H_RES 0x20 /* 单次高分辨率模式 */
#define BH1750_ONE_H_RES2 0x21
#define BH1750_ONE_L_RES 0x23
/* 函数声明 */
void BH1750_Init(void);
uint8_t BH1750_SendCommand(uint8_t cmd);
uint8_t BH1750_ReadLight(uint16_t *light);
#endif /* __BH1750_H */
📄 创建文件:
Src/bh1750.c
c
/* bh1750.c - BH1750光照传感器驱动实现 */
#include "bh1750.h"
extern I2C_HandleTypeDef hi2c1;
/**
* @brief BH1750初始化
*/
void BH1750_Init(void)
{
BH1750_SendCommand(BH1750_POWER_ON);
HAL_Delay(10);
BH1750_SendCommand(BH1750_RESET);
HAL_Delay(10);
BH1750_SendCommand(BH1750_CONT_H_RES);
HAL_Delay(180); /* 首次测量等待 */
}
/**
* @brief 发送命令
*/
uint8_t BH1750_SendCommand(uint8_t cmd)
{
HAL_StatusTypeDef status;
status = HAL_I2C_Master_Transmit(&hi2c1, BH1750_ADDR << 1, &cmd, 1, 100);
return (status == HAL_OK) ? 0 : 1;
}
/**
* @brief 读取光照强度
* @param light 光照强度值(单位:lux)
*/
uint8_t BH1750_ReadLight(uint16_t *light)
{
HAL_StatusTypeDef status;
uint8_t buf[2];
status = HAL_I2C_Master_Receive(&hi2c1, BH1750_ADDR << 1, buf, 2, 100);
if (status == HAL_OK) {
*light = ((buf[0] << 8) | buf[1]) / 1.2;
return 0;
}
return 1;
}
3.3 土壤湿度传感器
📄 创建文件:
Src/soil_moisture.c
c
/* soil_moisture.c - 土壤湿度传感器 */
#include "main.h"
extern ADC_HandleTypeDef hadc1;
/**
* @brief 土壤湿度传感器初始化
*/
void Soil_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
ADC_ChannelConfTypeDef sConfig = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC1_CLK_ENABLE();
/* 配置PA1为模拟输入 */
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* 配置ADC */
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc1);
/* 配置通道1 */
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
/**
* @brief 读取土壤湿度
* @return 湿度百分比(0-100)
*/
uint8_t Soil_Read(void)
{
uint32_t adc_value;
uint8_t moisture;
/* 启动ADC转换 */
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);
adc_value = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
/* 转换为百分比 */
/* 假设:0V=100%湿度,3.3V=0%湿度 */
/* 12位ADC: 0-4095 */
if (adc_value > 4000) adc_value = 4000;
if (adc_value < 100) adc_value = 100;
moisture = (uint8_t)((4000 - adc_value) * 100 / 3900);
return moisture;
}
3.4 ESP8266 WiFi通信
📄 创建文件:
Inc/esp8266.h
c
/* esp8266.h - ESP8266 WiFi模块驱动 */
#ifndef __ESP8266_H
#define __ESP8266_H
#include "main.h"
/* MQTT服务器配置 */
#define MQTT_SERVER "mqtt.broker.com"
#define MQTT_PORT 1883
#define MQTT_USER "username"
#define MQTT_PASS "password"
#define MQTT_CLIENT_ID "agriculture_001"
/* 主题 */
#define TOPIC_TEMP "farm/sensor/temperature"
#define TOPIC_HUMI "farm/sensor/humidity"
#define TOPIC_SOIL "farm/sensor/soil"
#define TOPIC_LIGHT "farm/sensor/light"
#define TOPIC_CONTROL "farm/control/#"
/* 函数声明 */
void ESP8266_Init(void);
uint8_t ESP8266_SendCommand(char *cmd, char *response, uint32_t timeout);
uint8_t ESP8266_ConnectWiFi(char *ssid, char *password);
uint8_t ESP8266_ConnectMQTT(char *server, uint16_t port);
uint8_t ESP8266_Publish(char *topic, char *message);
uint8_t ESP8266_Subscribe(char *topic);
#endif /* __ESP8266_H */
📄 创建文件:
Src/esp8266.c
c
/* esp8266.c - ESP8266 WiFi模块驱动实现 */
#include "esp8266.h"
extern UART_HandleTypeDef huart2;
/**
* @brief ESP8266初始化
*/
void ESP8266_Init(void)
{
/* 复位ESP8266 */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
HAL_Delay(1000);
/* 测试AT指令 */
ESP8266_SendCommand("AT\r\n", "OK", 1000);
/* 关闭回显 */
ESP8266_SendCommand("ATE0\r\n", "OK", 1000);
/* 设置工作模式 */
ESP8266_SendCommand("AT+CWMODE=1\r\n", "OK", 1000);
}
/**
* @brief 发送AT指令
*/
uint8_t ESP8266_SendCommand(char *cmd, char *response, uint32_t timeout)
{
uint8_t rx_buffer[256];
uint32_t start;
HAL_UART_Transmit(&huart2, (uint8_t *)cmd, strlen(cmd), 1000);
start = HAL_GetTick();
memset(rx_buffer, 0, sizeof(rx_buffer));
while ((HAL_GetTick() - start) < timeout) {
HAL_UART_Receive(&huart2, rx_buffer, sizeof(rx_buffer), 100);
if (strstr((char *)rx_buffer, response) != NULL) {
return 0;
}
}
return 1;
}
/**
* @brief 连接WiFi
*/
uint8_t ESP8266_ConnectWiFi(char *ssid, char *password)
{
char cmd[128];
sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, password);
return ESP8266_SendCommand(cmd, "OK", 10000);
}
/**
* @brief 连接MQTT服务器
*/
uint8_t ESP8266_ConnectMQTT(char *server, uint16_t port)
{
char cmd[128];
/* 设置MQTT用户配置 */
sprintf(cmd, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n",
MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS);
ESP8266_SendCommand(cmd, "OK", 5000);
/* 连接MQTT服务器 */
sprintf(cmd, "AT+MQTTCONN=0,\"%s\",%d,1\r\n", server, port);
return ESP8266_SendCommand(cmd, "OK", 10000);
}
/**
* @brief 发布消息
*/
uint8_t ESP8266_Publish(char *topic, char *message)
{
char cmd[256];
sprintf(cmd, "AT+MQTTPUB=0,\"%s\",\"%s\",1,0\r\n", topic, message);
return ESP8266_SendCommand(cmd, "OK", 5000);
}
/**
* @brief 订阅主题
*/
uint8_t ESP8266_Subscribe(char *topic)
{
char cmd[128];
sprintf(cmd, "AT+MQTTSUB=0,\"%s\",1\r\n", topic);
return ESP8266_SendCommand(cmd, "OK", 5000);
}
3.5 主控程序
📄 创建文件:
Src/main.c
c
/* main.c - 智能农业监控主程序 */
#include "main.h"
#include "dht22.h"
#include "bh1750.h"
#include "esp8266.h"
/* 传感器数据结构 */
typedef struct {
int16_t temperature; /* 温度 x10 */
uint16_t humidity; /* 湿度 x10 */
uint8_t soil_moisture; /* 土壤湿度 0-100 */
uint16_t light; /* 光照 lux */
uint8_t valid; /* 数据有效 */
} SensorDataTypeDef;
/* 阈值配置 */
typedef struct {
int16_t temp_high; /* 温度上限 */
int16_t temp_low; /* 温度下限 */
uint8_t soil_threshold; /* 灌溉阈值 */
uint16_t light_threshold; /* 补光阈值 */
} ThresholdTypeDef;
/* 全局变量 */
SensorDataTypeDef sensor_data;
ThresholdTypeDef threshold = {350, 100, 30, 500};
volatile uint8_t data_ready = 0;
/* 函数声明 */
void System_Init(void);
void Read_All_Sensors(void);
void Check_Thresholds(void);
void Control_Irrigation(uint8_t on);
void Control_Ventilation(uint8_t on);
void Control_Lighting(uint8_t on);
void Send_Data_Cloud(void);
void Enter_LowPower(void);
/**
* @brief 系统初始化
*/
void System_Init(void)
{
HAL_Init();
SystemClock_Config();
/* 初始化外设 */
UART1_Init(); /* 调试串口 */
UART2_Init(); /* ESP8266 */
I2C1_Init(); /* BH1750, OLED */
ADC1_Init(); /* 土壤湿度 */
RTC_Init();
/* 初始化传感器 */
DHT22_Init();
BH1750_Init();
Soil_Init();
/* 初始化通信模块 */
ESP8266_Init();
ESP8266_ConnectWiFi("SSID", "PASSWORD");
ESP8266_ConnectMQTT(MQTT_SERVER, MQTT_PORT);
ESP8266_Subscribe(TOPIC_CONTROL);
DEBUG_PRINT("\r\n===========================\r\n");
DEBUG_PRINT("智能农业监控系统启动\r\n");
DEBUG_PRINT("===========================\r\n");
}
/**
* @brief 读取所有传感器
*/
void Read_All_Sensors(void)
{
DHT22_DataTypeDef dht_data;
/* 读取温湿度 */
if (DHT22_Read(&dht_data) == 0) {
sensor_data.temperature = dht_data.temperature;
sensor_data.humidity = dht_data.humidity;
}
/* 读取土壤湿度 */
sensor_data.soil_moisture = Soil_Read();
/* 读取光照 */
BH1750_ReadLight(&sensor_data.light);
sensor_data.valid = 1;
data_ready = 1;
DEBUG_PRINT("温度: %d.%d°C, 湿度: %d.%d%%, 土壤: %d%%, 光照: %d lux\r\n",
sensor_data.temperature/10, sensor_data.temperature%10,
sensor_data.humidity/10, sensor_data.humidity%10,
sensor_data.soil_moisture, sensor_data.light);
}
/**
* @brief 检查阈值并控制
*/
void Check_Thresholds(void)
{
/* 温度控制 */
if (sensor_data.temperature > threshold.temp_high) {
Control_Ventilation(1); /* 开启通风 */
DEBUG_PRINT("温度过高,开启通风\r\n");
} else if (sensor_data.temperature < threshold.temp_low) {
Control_Ventilation(0); /* 关闭通风 */
}
/* 灌溉控制 */
if (sensor_data.soil_moisture < threshold.soil_threshold) {
Control_Irrigation(1); /* 开启灌溉 */
DEBUG_PRINT("土壤干燥,开启灌溉\r\n");
} else if (sensor_data.soil_moisture > threshold.soil_threshold + 20) {
Control_Irrigation(0); /* 关闭灌溉 */
}
/* 补光控制 */
if (sensor_data.light < threshold.light_threshold) {
Control_Lighting(1); /* 开启补光 */
} else {
Control_Lighting(0); /* 关闭补光 */
}
}
/**
* @brief 控制灌溉
*/
void Control_Irrigation(uint8_t on)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12,
on ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
/**
* @brief 控制通风
*/
void Control_Ventilation(uint8_t on)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,
on ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
/**
* @brief 控制补光
*/
void Control_Lighting(uint8_t on)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14,
on ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
/**
* @brief 发送数据到云端
*/
void Send_Data_Cloud(void)
{
char msg[128];
if (!sensor_data.valid) return;
/* 发送温度 */
sprintf(msg, "{\"value\":%d.%d}",
sensor_data.temperature/10, sensor_data.temperature%10);
ESP8266_Publish(TOPIC_TEMP, msg);
/* 发送湿度 */
sprintf(msg, "{\"value\":%d.%d}",
sensor_data.humidity/10, sensor_data.humidity%10);
ESP8266_Publish(TOPIC_HUMI, msg);
/* 发送土壤湿度 */
sprintf(msg, "{\"value\":%d}", sensor_data.soil_moisture);
ESP8266_Publish(TOPIC_SOIL, msg);
/* 发送光照 */
sprintf(msg, "{\"value\":%d}", sensor_data.light);
ESP8266_Publish(TOPIC_LIGHT, msg);
DEBUG_PRINT("数据已发送到云端\r\n");
}
/**
* @brief 进入低功耗模式
*/
void Enter_LowPower(void)
{
DEBUG_PRINT("进入低功耗模式\r\n");
/* 关闭外设 */
HAL_ADC_DeInit(&hadc1);
/* 进入STOP模式 */
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
/* 唤醒后重新初始化 */
SystemClock_Config();
ADC1_Init();
DEBUG_PRINT("从低功耗模式唤醒\r\n");
}
/**
* @brief 主函数
*/
int main(void)
{
uint32_t last_read = 0;
uint32_t last_send = 0;
System_Init();
while (1) {
/* 定时读取传感器(每30秒) */
if (HAL_GetTick() - last_read >= 30000) {
last_read = HAL_GetTick();
Read_All_Sensors();
Check_Thresholds();
}
/* 定时发送数据(每5分钟) */
if (HAL_GetTick() - last_send >= 300000) {
last_send = HAL_GetTick();
Send_Data_Cloud();
}
/* 低功耗处理 */
if (data_ready) {
data_ready = 0;
Enter_LowPower();
}
HAL_Delay(100);
}
}
四、系统架构
4.1 数据流图
应用层
通信层
处理层
传感器层
温湿度
湿度
光照
原始数据
处理结果
控制指令
历史数据
控制状态
MQTT/HTTP
DHT22
土壤传感器
BH1750
数据采集
数据处理
本地存储
控制决策
WiFi/4G
云平台
手机APP
Web端
报警通知
五、测试验证
5.1 传感器校准
温湿度校准:
- 使用标准温湿度计对比
- 记录校准系数
土壤湿度校准:
- 干燥状态:读取ADC值
- 饱和状态:读取ADC值
- 建立映射关系
5.2 通信测试
WiFi连接测试:
- 信号强度测试
- 断线重连测试
MQTT通信测试:
- 发布/订阅测试
- QoS等级测试
六、故障排查
6.1 传感器读数异常
问题排查:
- 检查传感器供电
- 验证通信线路
- 检查传感器校准
6.2 通信失败
问题排查:
- 检查WiFi信号强度
- 验证MQTT服务器配置
- 检查SIM卡状态(GPRS)
七、总结
7.1 核心知识点
- 多传感器融合:多源数据采集与处理
- 低功耗设计:STOP模式与电源管理
- 无线通信:MQTT协议与物联网
- 自动控制:阈值判断与执行控制
7.2 扩展方向
- 添加摄像头监控
- 集成气象站功能
- 实现AI病虫害识别
- 添加太阳能追踪
7.3 学习资源
💡 提示:农业环境恶劣,注意设备的防水、防尘、防雷设计。