当前位置:首页 > 消费电子 > 消费电子
[导读]智能晾衣架最怕三件事:升到顶不停烧电机、降到底继续拽断钢丝、中途卡住还硬推。固件不能把“按键→拉高GPIO”当控制逻辑,得做成状态机:方向指令只改目标,电机执行、限位消抖、电流判堵转全在定时任务里跑。


智能晾衣架最怕三件事:升到顶不停烧电机、降到底继续拽断钢丝、中途卡住还硬推。固件不能把“按键→拉高GPIO”当控制逻辑,得做成状态机:方向指令只改目标,电机执行、限位消抖、电流判堵转全在定时任务里跑。

一、电机驱动:H桥+PWM,别直接IO推

小功率机型用TB6612/L298N驱动直流减速电机,正反转靠AIN1/AIN2电平,速度靠PWM:

void motor_up(void){

   gpio_write(AIN1,1); gpio_write(AIN2,0);

   pwm_set(DUTY_UP);          // 软启动从30%爬升

}

void motor_down(void){

   gpio_write(AIN1,0); gpio_write(AIN2,1);

   pwm_set(DUTY_DOWN);

}

void motor_stop(void){

   pwm_set(0);

   gpio_write(AIN1,0); gpio_write(AIN2,0);

}

要点:

启动占空比从低往上调,别一上来100%,减少启动电流冲击

停止先清零PWM再关方向脚,避免H桥直通

上升速度可比下降快一档,下降要慢,防夹人

方向切换前必须先stop,至少几ms死区

二、限位检测:硬件冗余+软件消抖

上/下限位用微动开关或霍尔开关,位置在卷线机构两端。微动稳、霍尔无机械磨损,量产常两者并存:霍尔做主定位,微动做硬件兜底。

硬件层:限位开关常闭触点串进电机控制回路,MCU死机也能断。

软件层:GPIO读限位必须消抖,机械开关抖动5~20ms,连续采样确认:

#define LIMIT_OK_CNT 4      // 40ms@10ms

static uint8_t up_cnt,dn_cnt;

uint8_t limit_up,limit_down;


void limit_task_10ms(void){

   if(gpio_read(UP_LIMIT)==0){ if(++up_cnt>=LIMIT_OK_CNT) limit_up=1; }

   else { up_cnt=0; limit_up=0; }


   if(gpio_read(DN_LIMIT)==0){ if(++dn_cnt>=LIMIT_OK_CNT) limit_down=1; }

   else { dn_cnt=0; limit_down=0; }

}

判定优先级最高,任何状态都先查限位:

void motor_guard(void){

   if(dir==UP && limit_up){

       motor_stop(); dir=STOP; err=ERR_TOP;

   }

   if(dir==DOWN && limit_down){

       motor_stop(); dir=STOP; err=ERR_BOTTOM;

   }

}

别在按键中断里直接停电机,也别只判一次电平——抖动会误触发。

三、遇阻停止:电流采样判堵转

下降途中衣架碰人头、钢丝绳卡导轨,电机没到限位但已经堵转。反电动势消失,电流会持续拉高。

电机电源串采样电阻或用ACS712/INA180接ADC:

#define I_RUN_MAX   1200    // mA,按机型标定

static uint16_t cur_buf[8];

static uint8_t ci;


void stall_task_10ms(void){

   uint16_t cur = adc_current_ma();

   cur_buf[ci]=cur; ci=(ci+1)%8;


   uint32_t sum=0; for(int i=0;i<8;i++) sum+=cur_buf[i];

   uint16_t avg = sum/8;


   if(dir!=STOP && avg>I_RUN_MAX){

       motor_stop();

       dir=STOP;

       err=ERR_STALL;

       buzz_alarm();

       // 下降遇阻回退一小段

       if(last_dir==DOWN) motor_up(); delay_ms(300); motor_stop();

   }

}

关键细节:

避开启动电流:起步300ms内不判堵转,否则正常启动被误断

用滑动平均不用单次采样,尖峰干扰不敏感

阈值按实测定:正常带载0.3~0.8A,堵转1.2A以上

遇阻后别继续同方向重试,下降场景回退一段更安全

有编码器可加“有电流无脉冲”判据,比纯电流更稳

四、主状态机

别用while(down){...}阻塞,主循环只跑任务:

typedef enum{STOP,UP,DOWN}dir_t;

static dir_t dir=STOP,last_dir=STOP;


void ctrl_set(dir_t d){ dir=d; last_dir=d; }


void sys_10ms(void){

   limit_task_10ms();

   motor_guard();        // 限位最高优先级

   stall_task_10ms();    // 遇阻

   switch(dir){

       case UP:   motor_up(); break;

       case DOWN: motor_down(); break;

       case STOP: motor_stop(); break;

   }

}

按键/APP/遥控都只调ctrl_set(),不碰GPIO;电机动作统一出口,避免多处写AIN脚状态撕裂。

五、落坑清单

按键中断里直接拉GPIO→方向脚竞争

限位读一次就信→机械抖动误停

只做软件限位无限位开关→MCU死机冲顶

启动瞬间判电流→正常起步被断

堵转后继续同方向推→电机烧毁

PWM不软启动→启动电流冲击继电器

下降速度和上升一样快→夹人没反应时间

霍尔失效没微动兜底→到顶不停

遇阻不回退→衣架卡死在障碍物上

方向切换不停机→H桥瞬间直通

六、落地顺序

TB6612接电机,先调正反转+PW

上/下限位接GPIO,常闭硬件串回路

10ms任务里连续采样消抖

限位触发无条件停电机

ADC接电流采样,标正常/堵转阈值

起步300ms避让,滑动平均判堵转

下降遇阻停+回退

状态机统一出口,按键只改dir

过载/超重可再加称重阈值

晾衣架安全逻辑的本质不是“能升降”,是任何异常都能在几十毫秒内断电。限位开关是最后一道墙,电流堵转是过程保护,状态机是防止多处控制互相打架。固件里最稳的写法永远是:指令只改目标方向、电机动作只有一个出口、限位优先于方向、遇阻先停再回退——别让“再走一点点”的侥幸逻辑留在下降分支里。



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