一、项目概述
随着全球农业现代化的不断推进,智能农业监测系统应运而生。此项目旨在通过实时监测土壤湿度、温度等环境数据,结合作物生长状态的分析,提高农业生产效率和作物质量。通过引入STM32单片机、OpenCV图像处理技术和后端数据分析系统,项目能够有效解决农业生产中的以下问题:
-
实时监测:传统农业依赖人工监测,效率低,且易受主观因素影响。本项目通过自动化监测,提供实时数据。
-
病虫害检测:利用图像处理技术,及时识别作物病虫害,减少损失。
-
数据分析与决策支持:后端系统分析历史数据,提供科学的农业管理建议。
通过上述功能,本项目为农民提供了一种高效、可靠的农业管理工具,推动农业生产智能化。
二、系统架构
系统架构设计需满足数据采集、处理和分析的需求。整体架构可分为以下几个主要部分:
-
数据采集模块:使用STM32单片机连接土壤湿度传感器和温度传感器,定时采集土壤和气候数据。
-
数据处理模块:通过OpenCV对作物生长状态进行图像分析,检测病虫害。
-
后端系统:服务器端处理分析数据,提供决策支持,并通过API将数据传递给前端应用。
-
数据库系统:存储历史数据,便于后续的趋势分析和决策支持。
系统架构图
选型与技术栈
-
单片机:STM32系列,具备丰富的IO接口和低功耗特性。
-
传感器:土壤湿度传感器、温度传感器(如DHT11)。
-
图像处理:OpenCV库,用于图像采集和处理。
-
通信协议:使用MQTT或HTTP协议进行数据传输。
-
后端框架:Python Flask框架,便于快速开发RESTful API。
-
数据库:MySQL或SQLite,用于存储历史数据。
三、环境搭建
硬件环境
-
STM32开发板
-
土壤湿度传感器
-
温度传感器(DHT11)
-
摄像头模块(如USB摄像头)
-
路由器(用于网络连接)
软件环境
-
开发工具:Keil uVision或STM32CubeIDE
-
编程语言:C/C++(STM32部分),Python(后端部分)
-
数据库管理系统:MySQL或SQLite
-
图像处理库:OpenCV
安装步骤
- STM32开发环境配置:
-
下载并安装STM32CubeIDE。
-
配置开发板的连接,安装对应的驱动程序。
- Python环境配置:
-
安装Python:
sudo apt-get install python3 python3-pip
-
安装Flask和OpenCV:
pip install Flask opencv-python
- 数据库配置:
-
安装MySQL:
sudo apt-get install mysql-server
-
创建数据库和表:
CREATE DATABASE smart_agriculture; USE smart_agriculture; CREATE TABLE sensor_data ( id INT AUTO_INCREMENT PRIMARY KEY, moisture FLOAT, temperature FLOAT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP );
注意事项
-
确保STM32开发板与PC的连接正常,避免串口配置错误。
-
在安装OpenCV时,可能需要安装额外的依赖库,确保图像处理功能正常。
四、代码实现
数据采集模块(STM32)
在智能农业监测系统中,数据采集模块是系统的核心部分,负责实时采集土壤湿度和温度数据。这里我们使用STM32单片机,通过连接DHT11温度传感器和土壤湿度传感器,定期进行数据采集。以下是STM32的数据采集代码示例及详细说明。
代码示例
#include "stm32f4xx_hal.h"
#include "dht11.h" // 包含DHT11传感器的库
#include "soil_moisture.h" // 自定义土壤湿度传感器库
// 定义传感器引脚
#define DHT11_PIN GPIO_PIN_1
#define SOIL_MOISTURE_PIN GPIO_PIN_2
// 定义采集周期
#define SAMPLE_PERIOD 5000 // 5秒采样一次
// 函数原型
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
void collectSensorData(void);
int main(void) {
// 初始化HAL库
HAL_Init();
// 配置系统时钟
SystemClock_Config();
// 初始化GPIO
MX_GPIO_Init();
// 主循环
while (1) {
collectSensorData(); // 采集传感器数据
HAL_Delay(SAMPLE_PERIOD); // 延时5秒
}
}
void collectSensorData(void) {
float humidity, temperature, soilMoisture;
// 读取DHT11传感器数据
if (DHT11_Read(DHT11_PIN, &humidity, &temperature) == HAL_OK) {
// 成功读取温度和湿度
printf("Temperature: %.2f °C, Humidity: %.2f %%\n", temperature, humidity);
} else {
// 读取失败
printf("Failed to read from DHT11\n");
}
// 读取土壤湿度传感器数据
soilMoisture = SoilMoisture_Read(SOIL_MOISTURE_PIN);
printf("Soil Moisture: %.2f\n", soilMoisture);
}
// 系统时钟配置函数
void SystemClock_Config(void) {
// 这里配置系统时钟,具体内容根据使用的STM32型号进行调整
}
// GPIO初始化函数
static void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 开启GPIO时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置DHT11引脚
GPIO_InitStruct.Pin = DHT11_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // DHT11为输入引脚
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置土壤湿度传感器引脚
GPIO_InitStruct.Pin = SOIL_MOISTURE_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; // 模拟输入
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
代码说明
-
库引用:
-
#include "stm32f4xx_hal.h"
:包含STM32硬件抽象层库,提供对硬件的抽象接口。 -
#include "dht11.h"
:包含DHT11传感器的驱动库,负责读取温度和湿度数据。 -
#include "soil_moisture.h"
:自定义的土壤湿度传感器库,用于读取土壤湿度值。
-
-
宏定义:
-
DHT11_PIN
和SOIL_MOISTURE_PIN
:定义DHT11和土壤湿度传感器的连接引脚。 -
SAMPLE_PERIOD
:定义数据采集的时间间隔,这里设置为5秒。
-
-
主函数:
-
HAL_Init()
:初始化HAL库。 -
SystemClock_Config()
:配置系统时钟,具体实现根据所选STM32型号设置。 -
MX_GPIO_Init()
:初始化GPIO引脚。
-
-
数据采集函数
collectSensorData
:-
使用
DHT11_Read
函数读取DHT11传感器的温度和湿度数据,返回成功与否的状态。 -
使用
SoilMoisture_Read
函数读取土壤湿度数据,并打印到控制台。
-
-
GPIO引脚配置:
-
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
:将引脚设置为模拟输入模式,以便读取土壤湿度传感器的模拟信号。 -
GPIO_InitStruct.Pin = DHT11_PIN;
:选择用于DHT11的GPIO引脚。 -
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
:将该引脚设置为输入模式,因为DHT11传感器需要读取数据。 -
GPIO_InitStruct.Pull = GPIO_NOPULL;
:设置引脚不使用上拉或下拉电阻,以确保DHT11传感器正常工作。 -
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
:初始化GPIO引脚。 -
对土壤湿度传感器引脚进行类似的配置:
-
数据处理模块(OpenCV)
在数据处理模块中,我们利用OpenCV库对作物的生长状态进行分析,特别是对病虫害的检测。以下是一个基本的使用OpenCV进行图像处理的代码示例。
代码示例
import cv2
import numpy as np
def detect_pests(image_path):
# 读取输入图像
image = cv2.imread(image_path)
# 转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 使用高斯模糊去噪声
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 边缘检测
edges = cv2.Canny(blurred, 100, 200)
# 寻找轮廓
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 在原图上绘制轮廓
for contour in contours:
if cv2.contourArea(contour) > 100: # 过滤小轮廓
cv2.drawContours(image, [contour], -1, (0, 255, 0), 2) # 绘制绿色轮廓
# 显示结果
cv2.imshow('Detected Pests', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
detect_pests('crop_image.jpg') # 替换为实际的作物图像路径
代码说明
-
库引用:
-
import cv2
:导入OpenCV库。 -
import numpy as np
:导入NumPy库,用于数值计算。
-
-
函数
detect_pests
:-
def detect_pests(image_path)
:定义一个函数,接收图像路径作为参数。 -
cv2.imread(image_path)
:读取指定路径的图像。 -
cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
:将图像转换为灰度图,以便于后续处理。
-
-
图像处理步骤:
-
cv2.GaussianBlur(gray, (5, 5), 0)
:对灰度图应用高斯模糊,以减少噪声。 -
cv2.Canny(blurred, 100, 200)
:使用Canny边缘检测算法提取边缘。 -
cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
:寻找图像中的轮廓。
-
-
轮廓绘制:
- 遍历所有轮廓,使用
cv2.drawContours
在原图上绘制超过100个像素的轮廓。
- 遍历所有轮廓,使用
-
结果显示:
-
cv2.imshow('Detected Pests', image)
:显示处理后的图像。 -
cv2.waitKey(0)
和cv2.destroyAllWindows()
:等待用户
-
后端系统
在后端系统中,我们将使用Flask框架处理前端发来的请求,提供数据接口,并将处理后的数据存储到数据库中。以下是一个简单的后端实现示例。
代码示例
from flask import Flask, request, jsonify
import mysql.connector
app = Flask(__name__)
# 数据库连接配置
db_config = {
'user': 'your_username',
'password': 'your_password',
'host': 'localhost',
'database': 'smart_agriculture'
}
@app.route('/submit_data', methods=['POST'])
def submit_data():
"""接收传感器数据并存储到数据库"""
data = request.json
moisture = data.get('moisture')
temperature = data.get('temperature')
try:
# 连接数据库
connection = mysql.connector.connect(**db_config)
cursor = connection.cursor()
# 插入数据
insert_query = "INSERT INTO sensor_data (moisture, temperature) VALUES (%s, %s)"
cursor.execute(insert_query, (moisture, temperature))
connection.commit()
return jsonify({"message": "Data inserted successfully!"}), 201
except mysql.connector.Error as err:
return jsonify({"error": str(err)}), 500
finally:
cursor.close()
connection.close()
@app.route('/get_data', methods=['GET'])
def get_data():
"""获取历史传感器数据"""
try:
connection = mysql.connector.connect(**db_config)
cursor = connection.cursor()
# 查询数据
cursor.execute("SELECT * FROM sensor_data ORDER BY timestamp DESC")
results = cursor.fetchall()
# 转换为字典列表
data = [{"id": row[0], "moisture": row[1], "temperature": row[2], "timestamp": row[3]} for row in results]
return jsonify(data), 200
except mysql.connector.Error as err:
return jsonify({"error": str(err)}), 500
finally:
cursor.close()
connection.close()
if __name__ == "__main__":
app.run(debug=True)
代码说明
-
库引用:
-
from flask import Flask, request, jsonify
:导入Flask相关模块,用于创建Web应用和处理HTTP请求。 -
import mysql.connector
:导入MySQL连接器,用于连接和操作MySQL数据库。
-
-
Flask应用配置:
app = Flask(__name__)
:创建Flask应用实例。
-
数据库连接配置:
db_config
字典中包含数据库的连接信息,包括用户名、密码、主机和数据库名称。
-
数据提交接口:
-
@app.route('/submit_data', methods=['POST'])
:定义一个POST请求的路由,用于接收传感器数据。 -
data = request.json
:获取请求中的JSON数据。 -
通过
mysql.connector.connect(**db_config)
连接数据库。 -
使用SQL INSERT语句将传感器数据插入数据库。
-
-
数据获取接口:
-
@app.route('/get_data', methods=['GET'])
:定义一个GET请求的路由,用于返回历史传感器数据。 -
执行SQL SELECT语句查询所有传感器数据,并将结果转换为字典列表。
-
返回JSON格式的响应。
-
-
启动Flask应用:
if __name__ == "__main__": app.run(debug=True)
:在调试模式下启动Flask应用。
数据库设计
为了支持智能农业监测系统的功能,我们需要设计合适的数据库结构。以下是数据库表的简单设计:
数据库表结构
CREATE TABLE sensor_data (
id INT AUTO_INCREMENT PRIMARY KEY,
moisture FLOAT NOT NULL,
temperature FLOAT NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
表结构说明
-
id:主键,自增字段,用于唯一标识每条记录。
-
moisture:土壤湿度值,浮点型,表示当前的土壤湿度。
-
temperature:温度值,浮点型,表示当前环境温度。
五、项目总结
在本项目中,我们设计并实现了一个智能农业监测系统,主要功能包括实时监测土壤湿度和温度,利用图像处理技术检测作物生长状态(如病虫害),并将数据存储到数据库中以供后续分析。系统架构明确,模块分工合理,具体实现步骤如下:
- 数据采集模块:
-
使用STM32单片机和传感器(DHT11和土壤湿度传感器)进行实时数据采集。
-
定期将采集到的数据通过后端接口发送到服务器。
- 图像处理模块:
-
利用OpenCV进行作物图像处理,通过边缘检测和轮廓提取分析作物的健康状况。
-
针对检测到的病虫害,生成相应的分析结果。
- 后端系统:
-
使用Flask框架搭建RESTful API,接收前端提交的传感器数据,并将其存储到MySQL数据库中。
-
提供获取历史数据的接口,方便用户查看历史记录并进行数据分析。
- 数据库管理:
- 设计合理的数据库表结构,以存储传感器数据及其时间戳,支持数据的高效存取和查询。