去年帮朋友改造了一个小型蔬菜大棚,用Arduino搭建了一套完整的智能监控系统。这个系统不仅能自动调节温湿度、监测空气质量,还能根据土壤情况自动灌溉,所有数据都能通过手机实时查看和远程控制。整套方案成本不到200元,比市面上动辄上千的成品设备实惠多了。
这个项目最核心的价值在于实现了三大功能模块的协同工作:
选用Arduino Mega 2560作为主控板,主要考虑以下几点:
提示:如果预算有限,Arduino Uno也能满足基本需求,但需要特别注意I/O资源分配。
选用DHT11主要基于以下考量:
SGP30是专门针对室内空气质量监测设计的数字传感器:
选用常见的电阻式土壤湿度传感器:
整个系统的硬件连接遵循以下原则:
具体接线配置如下:
| 设备 | Arduino引脚 | 备注 |
|---|---|---|
| DHT11 | D2 | 单总线接口 |
| SGP30 | SDA(20)/SCL(21) | I2C接口 |
| OLED | SDA(20)/SCL(21) | I2C地址0x3C |
| HC-05蓝牙 | RX1(19) | 硬件串口1 |
| 土壤传感器 | A0 | 模拟输入 |
| 步进电机 | D8-D11 | ULN2003驱动 |
| 加湿器继电器 | D3 | 数字输出 |
| 水泵继电器 | D4 | 数字输出 |
| 风扇 | D5 | PWM控制 |
系统软件采用模块化设计,主要包含以下功能模块:
传感器数据采集模块
控制逻辑模块
人机交互模块
系统管理模块
DHT11的数据采集需要注意以下几点:
典型实现代码:
cpp复制#define DHT_PIN 2
#define DHT_TYPE DHT11
DHT dht(DHT_PIN, DHT_TYPE);
void setup() {
dht.begin();
}
void loop() {
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("读取DHT11失败!");
return;
}
// 显示和处理数据
displayData(t, h);
processHumidityControl(h);
delay(2000); // 最小间隔2秒
}
加湿控制逻辑需要考虑:
控制逻辑实现:
cpp复制#define HUMIDIFIER_PIN 3
#define HYSTERESIS 5 // 滞后带宽
float targetHumidity = 60.0;
bool humidifierState = false;
void processHumidityControl(float humidity) {
if (humidity < targetHumidity - HYSTERESIS/2 && !humidifierState) {
digitalWrite(HUMIDIFIER_PIN, HIGH);
humidifierState = true;
Serial.println("加湿器开启");
}
else if (humidity > targetHumidity + HYSTERESIS/2 && humidifierState) {
digitalWrite(HUMIDIFIER_PIN, LOW);
humidifierState = false;
Serial.println("加湿器关闭");
}
}
初始化代码:
cpp复制#include "Adafruit_SGP30.h"
Adafruit_SGP30 sgp;
uint32_t lastMeasurement = 0;
void setup() {
if (!sgp.begin()){
Serial.println("SGP30初始化失败");
while (1);
}
// 预热等待
delay(30000);
// 读取基线(如果有存储)
// sgp.setIAQBaseline(baselineCO2, baselineTVOC);
}
void loop() {
if (millis() - lastMeasurement > 1000) {
if (!sgp.IAQmeasure()) {
Serial.println("测量失败");
return;
}
Serial.print("TVOC: "); Serial.print(sgp.TVOC); Serial.print(" ppb\t");
Serial.print("CO2: "); Serial.print(sgp.eCO2); Serial.println(" ppm");
processAirQuality(sgp.eCO2, sgp.TVOC);
lastMeasurement = millis();
}
}
通风控制策略:
控制逻辑:
cpp复制#define WINDOW_OPEN_PIN 8
#define WINDOW_CLOSE_PIN 9
void processAirQuality(float co2, float tvoc) {
if (co2 > 1000 || tvoc > 500) {
openWindow();
}
else if (co2 < 800 && tvoc < 300) {
closeWindow();
}
}
void openWindow() {
// 控制步进电机开窗
// 实际实现需要根据具体机械结构调整
digitalWrite(WINDOW_OPEN_PIN, HIGH);
delay(500); // 适当延时
digitalWrite(WINDOW_OPEN_PIN, LOW);
}
void closeWindow() {
// 控制步进电机关窗
digitalWrite(WINDOW_CLOSE_PIN, HIGH);
delay(500);
digitalWrite(WINDOW_CLOSE_PIN, LOW);
}
土壤湿度测量常见问题:
改进方案:
实现代码:
cpp复制#define SOIL_PIN A0
#define SAMPLE_COUNT 10
#define DRY_VALUE 620 // 需要实际标定
#define WET_VALUE 310 // 需要实际标定
int readSoilMoisture() {
int sum = 0;
for (int i = 0; i < SAMPLE_COUNT; i++) {
sum += analogRead(SOIL_PIN);
delay(10);
}
return sum / SAMPLE_COUNT;
}
int getMoisturePercent(int raw) {
// 将原始值转换为百分比
int percent = map(raw, DRY_VALUE, WET_VALUE, 0, 100);
return constrain(percent, 0, 100);
}
void loop() {
int soilValue = readSoilMoisture();
int moisturePercent = getMoisturePercent(soilValue);
processIrrigation(moisturePercent);
delay(1000);
}
灌溉系统设计要点:
控制实现:
cpp复制#define PUMP_PIN 4
#define MIN_IRRIGATION_INTERVAL 3600000 // 1小时
unsigned long lastIrrigationTime = 0;
int irrigationThreshold = 30;
void processIrrigation(int moisturePercent) {
unsigned long currentTime = millis();
if (moisturePercent < irrigationThreshold &&
currentTime - lastIrrigationTime > MIN_IRRIGATION_INTERVAL) {
startIrrigation();
lastIrrigationTime = currentTime;
}
}
void startIrrigation() {
digitalWrite(PUMP_PIN, HIGH);
delay(10000); // 灌溉10秒
digitalWrite(PUMP_PIN, LOW);
}
HC-05蓝牙模块配置要点:
AT命令配置示例:
code复制AT+NAME=GreenHouseCtrl
AT+ROLE=0 // 从模式
AT+CMODE=1 // 任意设备连接
AT+UART=9600,0,0
设计简洁高效的通信协议:
下位机→手机(数据上报)
格式:TEMP:25.3|HUMI:58%|TVOC:200ppb|CO2:800ppm|SOIL:45%
手机→下位机(控制指令)
蓝牙数据接收处理:
cpp复制String btBuffer = "";
void loop() {
while (btSerial.available()) {
char c = btSerial.read();
if (c == '\n') {
processCommand(btBuffer);
btBuffer = "";
} else {
btBuffer += c;
}
}
}
void processCommand(String cmd) {
cmd.trim();
if (cmd == "FAN_ON") {
digitalWrite(FAN_PIN, HIGH);
}
else if (cmd == "FAN_OFF") {
digitalWrite(FAN_PIN, LOW);
}
else if (cmd == "WINDOW_OPEN") {
openWindow();
}
else if (cmd == "WINDOW_CLOSE") {
closeWindow();
}
else if (cmd == "WATER_NOW") {
startIrrigation();
}
}
这个项目从构思到实现历时约两周,期间遇到了不少挑战,也积累了一些宝贵经验:
传感器校准至关重要
不同批次的传感器可能存在差异,使用前务必进行校准。特别是土壤湿度传感器,需要在实际土壤环境中进行干湿标定。
系统稳定性优先
农业应用对稳定性要求很高,所有关键控制都应该有手动干预接口和异常保护机制。
电源管理不容忽视
大棚环境通常供电条件有限,设计时一定要考虑电源的稳定性和可靠性,必要时采用独立供电方案。
扩展性要考虑
随着种植需求变化,系统可能需要增加新的功能模块,硬件选型和软件架构都要预留扩展空间。
维护便捷性
设计时要考虑后期维护的便利性,比如传感器更换、软件升级等操作应该尽可能简单。
这套系统经过三个月的实际运行,表现稳定可靠,帮助朋友的大棚产量提高了约20%。后续计划增加光照监测和自动补光功能,进一步完善智能化管理。