STM32项目实战:基于STM32F103的智能农业监控系统

文章目录

    • 一、前言
      • [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 传感器读数异常

问题排查:

  1. 检查传感器供电
  2. 验证通信线路
  3. 检查传感器校准

6.2 通信失败

问题排查:

  1. 检查WiFi信号强度
  2. 验证MQTT服务器配置
  3. 检查SIM卡状态(GPRS)

七、总结

7.1 核心知识点

  1. 多传感器融合:多源数据采集与处理
  2. 低功耗设计:STOP模式与电源管理
  3. 无线通信:MQTT协议与物联网
  4. 自动控制:阈值判断与执行控制

7.2 扩展方向

  • 添加摄像头监控
  • 集成气象站功能
  • 实现AI病虫害识别
  • 添加太阳能追踪

7.3 学习资源


💡 提示:农业环境恶劣,注意设备的防水、防尘、防雷设计。

相关推荐
ACP广源盛139246256731 小时前
IX8024与科学大模型的碰撞@ACP#筑牢科研 AI 算力高速枢纽分享
运维·服务器·网络·数据库·人工智能·嵌入式硬件·电脑
一起搞IT吧3 小时前
Android性能系列专题理论之十:systrace/perfetto相关指标知识点细节含义总结
android·嵌入式硬件·智能手机·性能优化
Truffle7电子3 小时前
STM32CubeIDE/Programmer/Touch GFX 应用
stm32·单片机·嵌入式硬件
constant_LDX4 小时前
步进电机开发(一、硬件设计)
单片机·嵌入式硬件
北山有鸟5 小时前
修改源码法和插件法
嵌入式硬件·学习
richxu202510015 小时前
嵌入式学习之路->stm32篇->(14)通用定时器(上)
stm32·单片机·嵌入式硬件·学习
Deitymoon5 小时前
STM32——串口通信(USART)
单片机·嵌入式硬件
iCxhust5 小时前
微机原理实践教程(C语言篇)---A002流水灯
c语言·开发语言·单片机·嵌入式硬件·51单片机·课程设计·微机原理
Deitymoon7 小时前
STM32——外部中断按键控制led
stm32·单片机·嵌入式硬件