1. 项目概述
自动售货机作为24小时无人零售终端,已经渗透到现代生活的各个角落。从写字楼里的饮料贩卖机到地铁站的零食柜,这种自动化零售解决方案正在改变着我们的消费习惯。而这一切的背后,都离不开一个可靠的控制系统。
基于单片机的自动售货机系统设计,正是这类设备最经典也最实用的实现方案。相比工控机或树莓派等方案,单片机系统具有成本低廉、稳定性高、功耗低的显著优势。我在过去三年里参与过7个不同型号自动售货机的研发,发现STM32系列单片机尤其适合这类应用场景。
这个项目将完整展示如何从零开始搭建一个具备完整功能的自动售货机控制系统。我们将使用STM32F103C8T6作为主控芯片,配合硬币识别模块、RFID读卡器、矩阵键盘等外设,实现商品选择、支付验证、出货控制等核心功能。整个系统设计充分考虑了实际商用环境的需求,包括异常处理、库存管理和远程监控等实用功能。
2. 系统架构设计
2.1 硬件组成框图
一个完整的自动售货机系统通常包含以下几个关键模块:
- 主控单元:STM32F103C8T6最小系统板
- 输入设备:
- 4x4矩阵键盘(商品选择+功能按键)
- RFID读卡器(支持IC卡支付)
- 硬币识别模块(支持1元、5角硬币识别)
- 输出设备:
- 0.96寸OLED显示屏(显示商品信息和系统状态)
- 继电器控制板(控制电机出货)
- 蜂鸣器(操作提示音)
- 通信模块:
- ESP8266 WiFi模块(远程数据传输)
- SIM800C GSM模块(备用通信通道)
- 电源管理:
- 12V转5V DC-DC模块
- 5V转3.3V LDO稳压器
提示:在实际商用环境中,建议为硬币识别模块单独配置一个单片机作为协处理器,避免主控因硬币识别算法而出现响应延迟。
2.2 软件架构设计
系统软件采用分层架构设计,主要分为以下几个层次:
- 硬件抽象层(HAL):直接操作外设的底层驱动
- 设备驱动层:封装各类外设的标准接口
- 业务逻辑层:实现售货机核心业务流程
- 网络服务层:处理远程通信和数据同步
这种架构设计使得系统具有良好的可维护性和扩展性。例如当需要更换RFID读卡器型号时,只需修改设备驱动层的相关代码,不会影响上层业务逻辑。
3. 核心功能实现
3.1 商品选择与显示
商品选择功能通过4x4矩阵键盘实现,16个按键中12个用于商品选择,剩余4个作为功能键(确认、取消、查询、管理员)。按键扫描采用行列扫描法,通过定时器中断实现20ms一次的扫描频率。
c复制// 按键扫描代码示例
void TIM3_IRQHandler(void) {
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
static uint8_t row = 0;
// 逐行扫描
SetRow(row);
uint8_t col = ReadColumn();
if(col != 0xFF) {
key_event = (row << 4) | col;
}
row = (row + 1) % 4;
}
}
商品信息显示使用OLED屏幕,采用页面刷新方式减少闪烁。每个商品对应一个结构体,包含价格、库存、位置等信息:
c复制typedef struct {
uint8_t id;
char name[16];
float price;
uint8_t stock;
uint8_t motor_id;
} Product;
3.2 支付系统实现
支付系统支持两种支付方式:硬币支付和IC卡支付。硬币识别模块通过UART与主控通信,当投入硬币时会发送特定格式的数据帧:
code复制帧头(0xAA) | 币值(0x01=1元) | 校验和 | 帧尾(0x55)
IC卡支付采用Mifare S50卡片,使用RC522读卡器进行读写操作。支付流程如下:
- 用户选择商品后,屏幕显示金额并提示支付方式
- 若选择硬币支付,系统实时累加投入金额并显示剩余应支付
- 若选择IC卡支付,提示刷卡并验证余额
- 支付成功后启动出货流程
注意:实际商用场景中,支付系统需要加入防拆检测和异常处理机制,防止恶意攻击。
3.3 出货控制设计
出货控制采用继电器驱动直流电机方案,每个商品通道对应一个电机。出货流程包含以下步骤:
- 根据商品ID确定对应的电机编号
- 启动电机正转2秒(推动商品)
- 停止电机0.5秒
- 电机反转1秒(复位推杆)
- 检测光电开关状态确认出货成功
出货状态通过红外光电开关检测,当商品掉落时会遮挡光电开关,产生下降沿中断:
c复制void EXTI0_IRQHandler(void) {
if(EXTI_GetITStatus(EXTI_Line0) != RESET) {
EXTI_ClearITPendingBit(EXTI_Line0);
current_product.stock--;
SaveToEEPROM();
}
}
4. 关键问题与解决方案
4.1 硬币识别误判问题
初期测试中发现硬币识别模块在嘈杂环境中容易出现误判。通过以下改进显著提高了识别准确率:
- 在UART接收端加入数字滤波算法
- 设置最小投币间隔时间(300ms)
- 增加物理防抖结构(橡胶垫片)
- 软件校验和验证
改进后的硬币接收流程:
flow复制st=>start: 投币事件
op1=>operation: 硬件去抖(50ms)
op2=>operation: UART数据接收
cond=>condition: 校验通过?
op3=>operation: 更新余额
e=>end
st->op1->op2->cond
cond(yes)->op3->e
cond(no)->e
4.2 多任务调度策略
系统需要同时处理多个任务:按键扫描、显示刷新、网络通信、支付处理等。经过测试,最终采用以下调度方案:
- 高优先级任务(支付处理、出货控制)使用中断驱动
- 中等优先级任务(按键扫描、显示刷新)使用定时器触发
- 低优先级任务(数据同步、状态上报)在主循环中执行
任务优先级设置示例:
c复制NVIC_InitTypeDef NVIC_InitStructure;
// 支付中断最高优先级
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
// 定时器中断中等优先级
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_Init(&NVIC_InitStructure);
4.3 低功耗设计
为降低待机功耗,系统采用了多项节能措施:
- 动态时钟调节:空闲时降低主频至8MHz
- 外设分时供电:非使用时段切断RFID模块电源
- 自适应背光:30秒无操作后降低OLED亮度
- 网络心跳优化:将上报间隔从1分钟延长至5分钟
实测表明,这些优化使系统待机功耗从12W降至4W,节能效果显著。
5. 系统优化与功能扩展
5.1 库存管理系统
为实现库存管理,设计了基于EEPROM的存储方案。商品信息存储结构如下:
| 地址偏移 | 长度 | 内容 |
|---|---|---|
| 0x0000 | 1 | 商品数量N |
| 0x0001 | 20 | 商品1信息 |
| ... | ... | ... |
| 0x00C1 | 20 | 商品N信息 |
每个商品信息占用20字节:
c复制#pragma pack(push, 1)
typedef struct {
uint8_t id;
char name[16];
float price;
uint8_t stock;
uint8_t motor_id;
} EEPROM_Product;
#pragma pack(pop)
库存同步流程:
- 每次出货后更新EEPROM中的库存数据
- 管理员模式下可查看和修改库存
- 远程服务器可通过网络接口同步库存信息
5.2 远程监控功能
通过ESP8266模块实现远程监控,主要功能包括:
- 实时状态上报(温度、库存、交易记录)
- 固件远程升级(OTA)
- 参数远程配置
- 异常报警通知
通信协议采用MQTT+JSON格式,示例数据包:
json复制{
"device_id": "VM001",
"timestamp": 1625097600,
"temperature": 28.5,
"sales": [
{"id":1, "count":5},
{"id":3, "count":2}
],
"alerts": ["low_stock_5"]
}
5.3 异常处理机制
完善的异常处理是商用设备的关键。本系统实现了以下异常处理:
- 出货失败检测:通过光电开关和电流检测双重验证
- 网络断线处理:本地缓存交易记录,网络恢复后重传
- 支付超时:3分钟内未完成支付自动取消
- 非法操作记录:记录异常操作事件供管理员查看
异常处理状态机:
mermaid复制stateDiagram
[*] --> 正常运营
正常运营 --> 出货异常: 光电开关未触发
出货异常 --> 重试出货: 首次异常
重试出货 --> 正常运营: 出货成功
重试出货 --> 退款处理: 再次失败
退款处理 --> 正常运营: 完成退款
6. 实际部署注意事项
经过多个实际项目的验证,总结出以下部署经验:
-
环境适应性:
- 高温环境下需增加散热风扇
- 低温环境需要加热装置防止冷凝
- 潮湿环境要做好电路板三防处理
-
安全性设计:
- 关键数据存储需要加密
- 通信链路使用TLS加密
- 物理防拆开关必不可少
-
维护便利性:
- 设计易开的维护门
- 预留USB配置接口
- 关键部件采用模块化设计
-
长期运行建议:
- 每月清洁光电传感器
- 每季度检查机械部件润滑
- 每年更换易损件(推杆、弹簧等)
在实际项目中,我们遇到过光电开关被灰尘覆盖导致出货检测失败的问题。后来在软件中加入定期自检功能,通过监测光电开关的基准值变化来提醒维护。