大棚环境控制:温湿度、光照、CO₂ 的全自动调节

灌溉是最基础的,大棚环境控制才是真正的多变量系统——温湿度、光照、CO₂ 浓度相互耦合,开窗通风降了温也降了湿,补光灯升温还费电。这篇讲四套执行器的联动策略和 PID 控制算法。


大棚环控的四根操纵杆

执行器 控制目标 功率 成本
顶通风扇 降温、排湿 100-200W 80 元/台
遮阳网电机 降光照、降温 50W 120 元/套
LED 补光灯 补光(阴雨天) 50-200W 150 元/盏
CO₂ 气肥阀 补 CO₂ 10W 100 元/套

冲突与耦合——为什么不能各管各的

举个典型场景:中午 12 点,大棚温度飙到 38℃,天窗自动全开,遮阳网拉了一半——温度降下来了,但 CO₂ 浓度从 500ppm 跌到 300ppm(外面大气也就 420,大棚靠植物呼吸维持高 CO₂)。光合作用效率降了,蔬菜不长个。

这就是多变量耦合:降温 ← → CO₂ 流失 ← → 湿度下降。不能分别设三个独立的 if-else。


策略一:优先级 + 状态机

给四种执行器排优先级,避免冲突:

触发条件 → 动作                           优先级
─────────────────────────────────────────────
temp > 40℃     → 全部天窗 + 遮阳网全开      P0(紧急)
temp > 35℃     → 天窗开 70%, 遮阳 50%       P1
temp > 30℃     → 天窗开 30%                 P2
humidity > 85% → 天窗开 50%(排湿)           P1
humidity < 40% → 天窗全关 + 微喷加湿         P2
light < 20000Lx(阴天) → 补光灯开            P3
co2 < 400ppm → CO₂ 气肥开                   P3
降雨 → 天窗全关                              P0
大风(>6级) → 天窗全关                        P0

实现——状态机:

public enum GreenhouseState {
    NORMAL,       // 正常
    COOLING,      // 降温中
    DEHUMIDIFYING,// 排湿中
    HEATING,      // 加热中
    CO2_ENRICHMENT, // 补CO₂
    EMERGENCY     // 紧急状态(极端天气)
}

public class GreenhouseController {
    private GreenhouseState currentState = GreenhouseState.NORMAL;
    
    public void tick(SensorData data, WeatherInfo weather) {
        // P0 紧急状态优先
        if (data.getAirTemp() > 40 || weather.isRaining() || weather.windLevel() > 6) {
            emergencyProtocol(data, weather);
            return;
        }
        
        // P1 高温/高湿
        if (data.getAirTemp() > 35) {
            transitionTo(GreenhouseState.COOLING);
            setWindow(70);
            setShade(50);
            setCo2(false);  // 开了天窗,CO₂ 流失严重,别开气肥
        } else if (data.getAirTemp() > 30) {
            setWindow(30);
        }
        
        if (data.getAirHumidity() > 85) {
            setWindow(Math.max(currentWindow(), 50));  // 取天窗开度最大值
        }
        
        // P3 补光(天窗不能全关,否则不透气)
        if (data.getLight() < 20000 && data.getAirTemp() < 35) {
            setLight(true);
        }
        
        // P3 CO₂ 气肥(天窗开度<30%时才有效)
        if (data.getCo2() < 400 && getWindowOpenPercent() < 30) {
            setCo2(true);
        }
    }
}

策略二:PID 控制——精确到度

状态机适用于「到阈值就切」的大颗粒控制。如果想让温度稳定在 26℃ ± 2℃,上 PID:

public class PIDController {
    private double kp, ki, kd;
    private double setpoint;
    private double integral = 0;
    private double prevError = 0;
    
    /**
     * @param pv 当前值 (Process Value)
     * @return 输出 (0-100),表示天窗开度
     */
    public double compute(double pv) {
        double error = setpoint - pv;
        
        // 积分项限制(防止积分饱和)
        integral = Math.max(-100, Math.min(100, integral + error));
        
        // 微分项
        double derivative = error - prevError;
        prevError = error;
        
        double output = kp * error + ki * integral + kd * derivative;
        
        // 输出限幅 0-100
        return Math.max(0, Math.min(100, output));
    }
}

// 使用
PIDController tempPID = new PIDController(3.0, 0.05, 1.0, 26.0);  // 目标 26℃
double windowOpening = tempPID.compute(sensorData.getAirTemp());
setWindow((int) windowOpening);

PID 参数调试口诀:

  • kp 太大:来回震荡,降不下来就升回去
  • ki 太大:调节慢,过冲大
  • kd 太大:对噪声敏感,输出抖动

大棚场景的参考值:Kp=3.0, Ki=0.05, Kd=1.0(以天窗开度 0-100 为输出去调试)。


策略三:双 PID 级联——温度控制专用

温度-湿度耦合的终极解法是串级 PID:

                       ┌──────────────┐
  温度设定(26℃) ──→ [温度PID] ──→ [天窗PID] ──→ 天窗伺服电机
                       ↑              ↑
                    当前温度        天窗位置反馈

外层温度 PID 输出的是「期待的天窗开度」,内层天窗 PID 把天窗精准开到那个角度。这种结构抗干扰能力远超单 PID。

// 外环:温度 PID
double desiredWindowPos = outerPID.compute(currentTemp);

// 内环:天窗位置 PID
double motorPwm = innerPID.compute(desiredWindowPos - currentWindowPos);
setWindowMotorPwm(motorPwm);

硬接线:把四个执行器连上 ESP32

// 引脚分配
#define FAN_PIN       12    // 通风扇(PWM 调速)
#define SHADE_UP_PIN  13    // 遮阳网 升(继电器)
#define SHADE_DN_PIN  14    // 遮阳网 降(继电器)
#define LIGHT_PIN     15    // 补光灯(PWM 调光)
#define CO2_VALVE_PIN 26    // CO₂ 电磁阀

// 遮阳网电机控制(正反转继电器)
void setShade(int percent) {
    int currentPos = readShadePosition();  // 用霍尔传感器或编码器读当前位置
    int targetPos = map(percent, 0, 100, 0, 1000);  // 0-1000 脉冲
    
    if (targetPos > currentPos) {
        digitalWrite(SHADE_UP_PIN, LOW);
        digitalWrite(SHADE_DN_PIN, HIGH);  // 下降 = 遮阳
    } else {
        digitalWrite(SHADE_DN_PIN, LOW);
        digitalWrite(SHADE_UP_PIN, HIGH);  // 上升 = 收网
    }
}

// 通风扇 PWM 调速
void setFan(int speed) {
    // speed: 0-100
    ledcWrite(0, map(speed, 0, 100, 0, 255));
}

效果数据

部署前后对比(河北某番茄棚,面积 400㎡):

指标 人工管理 自动控制
日均温度波动 22-38℃ (16℃振幅) 24-30℃ (6℃振幅)
日均湿度波动 40-95% 55-80%
CO₂ 日均浓度 350ppm 550ppm
电费/月 180 元 220 元(补光灯多了)
产量/季 约 1500kg 约 1950kg (+30%)
人工巡检 3次/天,30分钟 0次(手机推送)

多出的 40 元电费换来 450kg 增产,ROI 超过 10:1。


下一篇:《畜牧养殖 AI:用摄像头数猪、测重、识别生病》——从大棚到猪舍,摄像头能干什么?

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐