3、传感器与检测:光电传感器原理、限位开关应用、电流检测反馈、货物掉落检测逻辑

大家好,我是老张。今天咱们聊聊自动售货机里最容易被忽视、却又最关键的环节——传感器与检测。

你想想看,售货机说白了就是个“黑盒子”。用户投了币,按了按钮,机器就得老老实实把货吐出来。但货道里到底有没有货?货掉没掉下去?电机转到位了没有?这些问题,全靠传感器来回答。

我入行那会儿,第一台自己调试的售货机,就因为少装了一个限位开关,结果电机一直转,把弹簧都拧断了。嗯,从那以后,我对传感器这块就特别上心。

3.1 光电传感器原理

光电传感器,说白了就是“用光来判断有没有东西”。在售货机里,它最常见的用法就是检测货道里还有没有货。

原理其实很简单:发射端发出红外光,接收端等着收光。如果中间有货物挡住,光路断了,接收端就输出一个信号变化。

我个人习惯用对射式光电传感器,而不是反射式。为什么?因为反射式容易受灰尘和货物表面反光影响。我在项目里遇到过,有些饮料瓶包装是镜面的,反射式传感器会误判,明明有货却报“缺货”。

这里给个典型电路参考:

// 光电传感器检测伪代码
#define SENSOR_PIN  GPIO_PIN_5

uint8_t check_货道有货(void) {
    if (HAL_GPIO_ReadPin(SENSOR_GPIO_Port, SENSOR_PIN) == GPIO_PIN_RESET) {
        // 光路被遮挡,说明有货
        return 1;
    } else {
        // 光路通畅,说明缺货
        return 0;
    }
}

注意一点:光电传感器要加防抖处理。我见过不少新手直接读IO口,结果货物晃动一下就误报。加个10ms的软件滤波,稳得很。

小技巧: 光电传感器的安装位置很讲究。太靠前,货物还没完全到位就触发;太靠后,货物掉了一半才检测到。我一般建议装在货道出口前1/3处,这样最可靠。

3.2 限位开关应用

限位开关,在售货机里主要管两件事:电机转没转到头?货盘推没推到位?

说白了就是个机械触点开关。电机带动机构运动,碰到开关,电路就通了或者断了,MCU就知道“到位了”。

我常用的限位开关有两种:

  • 微动开关: 便宜、可靠,适合弹簧货道的复位检测
  • 霍尔传感器: 无接触、寿命长,适合旋转货盘的定位

这里有个坑,我曾经踩过——微动开关的触点抖动。电机停下来的时候,机构会有个回弹,开关会连续通断好几次。如果不做软件消抖,MCU会以为电机没停,继续给指令,结果就是“过冲”。

我的做法是:检测到限位信号后,延迟50ms再确认一次。代码大概这样:

void 限位检测_带消抖(void) {
    if (HAL_GPIO_ReadPin(LIMIT_GPIO_Port, LIMIT_Pin) == GPIO_PIN_SET) {
        HAL_Delay(50);  // 等50ms
        if (HAL_GPIO_ReadPin(LIMIT_GPIO_Port, LIMIT_Pin) == GPIO_PIN_SET) {
            // 确认到位
            电机停止();
        }
    }
}
警告: 限位开关的接线一定要用屏蔽线,或者双绞线。电机启动时的电磁干扰很强,我见过有人用普通杜邦线,结果限位信号乱跳,机器直接“发疯”。

3.3 电流检测反馈

电流检测,这个功能很多人会忽略。但我觉得,它才是售货机控制逻辑里的“隐藏王牌”。

为什么这么说?因为电机堵转、货物卡住、线路短路,这些故障都会反映在电流上。你想想看,电机正常转动时电流是平稳的,一旦堵住,电流会瞬间飙升。

我习惯用采样电阻加运放的方式来做电流检测。成本低,响应快。MCU的ADC读电压,换算成电流值。

典型电路参数:

参数 典型值 说明
采样电阻 0.1Ω 功率要选2W以上
运放增益 50倍 把mV级信号放大到ADC范围
堵转电流阈值 1.5A 根据电机规格调整
空载电流 0.3A 正常转动时的电流

检测逻辑其实不复杂:启动电机后,持续监测电流。如果电流超过阈值并持续200ms以上,就判定为堵转,立即停止电机并报警。

void 电流检测_任务(void) {
    uint16_t adc_value = 读取ADC();
    float current = (adc_value * 3.3 / 4096) / 0.1 / 50;  // 换算成电流
    
    if (current > 堵转阈值) {
        堵转计时++;
        if (堵转计时 > 200) {  // 持续200ms
            电机停止();
            上报故障(FAULT_堵转);
        }
    } else {
        堵转计时 = 0;
    }
}
重点: 电流检测不能只看瞬时值。电机启动瞬间会有浪涌电流,比正常电流大好几倍。我一般会加一个“启动屏蔽期”,前100ms不检测,等电流稳定了再开始判断。

3.4 货物掉落检测逻辑

这个功能,是售货机“出货成功”的最后一道防线。用户付了钱,货到底掉没掉下去?

检测方法有好几种,我挑最实用的说:

  • 红外对射检测: 在出货口装一对红外传感器,货物掉落时遮挡光路,产生一个脉冲信号
  • 声音检测: 货物掉到取物口时会有撞击声,用麦克风拾音判断
  • 电流变化检测: 货物掉落后,电机负载突然减轻,电流会有一个明显的下降沿

我个人最推荐第一种——红外对射。简单、可靠、成本低。但要注意安装位置,别让货物砸到传感器上,不然用不了几次就坏了。

检测逻辑的核心是“超时判断”:

void 出货检测_逻辑(void) {
    启动电机();
    启动掉落计时器(5000);  // 5秒超时
    
    while (掉落计时器_未超时()) {
        if (红外对射_检测到脉冲()) {
            // 检测到货物掉落
            电机停止();
            出货成功();
            return;
        }
    }
    
    // 超时了还没检测到掉落
    电机停止();
    出货失败();
    上报故障(FAULT_出货失败);
}

这里有个细节:脉冲检测要防抖。货物掉落时可能弹跳,产生多个脉冲。我一般只认第一个脉冲,后面的忽略。

避坑指南: 我曾经遇到过一种情况——货物卡在货道里,没掉下去,但红外传感器被货物本身挡住了,一直输出“有货”信号。结果机器认为出货成功,用户却没拿到货。后来我加了“电机停止后重新检测”的逻辑:电机停转后,如果红外传感器还是被遮挡,说明货没掉下去,要报故障。

好了,传感器这块就聊到这儿。总结一句话:光电传感器管有没有货,限位开关管到没到位,电流检测管堵没堵转,掉落检测管成没成功。四者配合好了,售货机才能老老实实干活。

下一章咱们聊聊电机驱动,那可是让货道“动起来”的关键。到时候见。