当前位置:首页 > 消费电子 > 消费电子
[导读]智能加湿器“精准控湿”不是读个数再开关继电器就完事。DHT11这类单总线传感器受时序和温漂影响大,量产更稳的是SHT30一类I2C数字温湿度传感器 。软件层真正要做的是:定时采样→滤波→校验丢弃→滞回判定→驱动雾化片,别让主循环每毫秒读一次、别让继电器抖着起停。


智能加湿器“精准控湿”不是读个数再开关继电器就完事。DHT11这类单总线传感器受时序和温漂影响大,量产更稳的是SHT30一类I2C数字温湿度传感器 。软件层真正要做的是:定时采样→滤波→校验丢弃→滞回判定→驱动雾化片,别让主循环每毫秒读一次、别让继电器抖着起停。

一、传感器读取:I2C单次采样

SHT30默认地址0x44,发单次测量命令0x2400(时钟不拉伸),等十几毫秒读6字节:温度MSB/LSB/CRC、湿度MSB/LSB/CRC 。

#define SHT30_ADDR 0x44

#define CMD_MEAS_H  0x24

#define CMD_MEAS_L  0x00


int sht30_read(float *t, float *h){

   uint8_t cmd[2]={CMD_MEAS_H,CMD_MEAS_L};

   i2c_write(SHT30_ADDR, cmd, 2);

   delay_ms(20);

   uint8_t buf[6];

   if(i2c_read(SHT30_ADDR, buf, 6)!=0) return -1;


   uint16_t raw_t = (buf[0]<<8)|buf[1];

   uint16_t raw_h = (buf[3]<<8)|buf[4];

   *t = -45.0f + 175.0f*raw_t/65535.0f;

   *h = 100.0f*raw_h/65535.0f;

   return 0;

}

工程上别每帧都读,2~5s一次足够,房间湿度本来就是慢变量;读失败直接丢弃这次数据,不拿旧值凑数 。

二、采样滤波:IIR+突变丢弃

原始湿度会跳,尤其开门、喷雾回流、传感器靠近出雾口。先过一阶IIR,再滤掉异常跳变:

static float hum_filt;

float humidity_filter(float raw){

   if(raw<0||raw>100) return hum_filt;        // 量程外丢弃

   float f = hum_filt + (raw-hum_filt)*0.3f;

   if(fabsf(f-hum_filt) > 8.0f)              // 单帧跳8%当干扰

       return hum_filt;

   hum_filt = f;

   return f;

}

系数0.2~0.3够用,别拉到0.5以上,否则喷雾瞬间会把设定值“假饱和”。

三、闭环控制:滞回优先,别上来就PID

家用加湿器目标一般是“50%±5%”,不是“恒50.0%”。滞回控制最合适:低于下限开、高于上限关,中间保持原状态 。

#define HUM_TARGET 50

#define HUM_HYST   3

static uint8_t mist_on;


void humidity_control(float h){

   if(h < HUM_TARGET-HUM_HYST){

       mist_on = 1;

   }else if(h > HUM_TARGET+HUM_HYST){

       mist_on = 0;

   }

   mist_drive(mist_on);

}

回差别设太小。目标50只设47开/50关,继电器一天跳几千次,雾化片触点都扛不住 。

需要连续调雾量(机房恒湿、实验室)才上增量PID,位置式容易一开机推满:

float pid_inc(float err, float err_last){

   static float out=0;

   float d = err-err_last;

   out += KP*d + KI*err;          // 简化增量

   if(out>100)out=100; if(out<0)out=0;

   return out;

}

KI要按控制周期缩放,2s周期和200ms周期的Ki不是同一个数 。

四、驱动雾化片:PWM而非硬开关

超声雾化片别用继电器直接通断,寿命和噪声都差。MCU输出PWM→三极管/MOS推挽→雾化片谐振驱动 。

void mist_drive(uint8_t on){

   if(on) pwm_set_duty(MIST_TIM, MIST_CH, 70);  // 70%占空比

   else   pwm_set_duty(MIST_TIM, MIST_CH, 0);

}

睡眠档可降到30%~40%占空比减噪;连续PID场景就把pid_out映射到占空比。

五、安全保护:缺水优先于控湿

闭环再准,无水干烧一次雾化片就废。水位探针/干簧管进GPIO,任何控制输出前先判水位 :

void mist_drive(uint8_t on){

   if(!water_present()){          // 无水强制断

       pwm_set_duty(MIST_TIM, MIST_CH, 0);

       buzzer_alarm();

       return;

   }

   pwm_set_duty(MIST_TIM, MIST_CH, on?70:0);

}

附加兜底:

传感器连续N次读失败→停止加湿,报传感器故障

湿度长时间不升(比如10分钟没变化)→疑似水位/堵塞,停机

开机软启动,占空比从0渐升到目标,别瞬间满功率

出雾口回流导致传感器假高→传感器远离雾道,走风管采样更稳

六、任务节奏(裸机/RTOS)

2s   -> SHT30读一次

2s   -> IIR滤波+量程检查

2s   -> 滞回判定

1s   -> 水位/保护检查

中断 -> 按键改目标湿度

别把i2c读和控制在同一个紧循环里死等,HAL_delay类阻塞会卡主循环。

七、落坑清单

主循环每10ms读SHT30→I2C拥塞、传感器自热

不用CRC/校验→偶尔255或0照常控

单帧跳变直接采用→误关误开

回差设0.5%→继电器啸叫

继电器硬切雾化片→触点粘连

传感器放出雾口正上方→读数虚高

缺水不拦截→干烧裂片

PID位置式直出→开机满占空

读失败拿上一次值硬凑→越控越偏

八、落地顺序

I2C接SHT30,2s采一次

原始值做IIR+跳变丢弃

滞回控制输出on/off

PWM驱MOS而不是继电器

水位探针优先于湿度逻辑

读失败计数→故障停机

睡眠档降占空比

要恒湿±2%再换增量PID

加湿器闭环的本质不是算法多高级,是“采样别抖、判定别急、执行别硬切”。家用场景滞回控制够稳,PID是按需选项不是标配;传感器读数干净了,回差给够,雾化片用PWM软驱,基本不会出现“一直加湿到60%还不停”或“继电器咔咔响”。真正量产翻车大多不在控制逻辑,在缺水保护和传感器位置——这两处漏了,闭环再漂亮也白搭。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭