1. 项目概述
这个基于ESP32单片机的无线点菜系统,是我在餐饮行业数字化转型背景下开发的一套低成本智能点餐解决方案。系统通过硬件终端、手机APP和后台管理三端联动,实现了从点餐到结算的全流程数字化管理。
核心功能包括:
- 顾客通过触摸屏或语音指令点餐
- 订单数据实时同步至商家后台
- 支持离线缓存确保断网可用
- 多终端数据一致性保障
相比传统纸质菜单,这套系统具有以下优势:
- 降低人力成本:服务员只需送餐,无需记录订单
- 提升点餐效率:顾客自主操作,减少等待时间
- 减少人为错误:系统自动计算金额,避免算错账
- 便于数据分析:后台可统计菜品销量等经营数据
2. 硬件设计详解
2.1 核心控制器选型
选用ESP32-WROOM-32D作为主控芯片,主要基于以下考量:
性能参数对比表:
| 型号 | 主频 | Flash | RAM | 无线 | 价格 |
|---|---|---|---|---|---|
| ESP8266 | 80MHz | 4MB | 80KB | WiFi | 低 |
| ESP32 | 240MHz | 4MB | 520KB | WiFi+BT | 中 |
| STM32F103 | 72MHz | 128KB | 20KB | 需外接 | 高 |
选择ESP32的关键因素:
- 内置WiFi模块节省外围电路
- 双核处理器适合多任务处理
- 丰富的外设接口(12位ADC、8个IO等)
- 成熟的开发环境和社区支持
实际使用中发现,ESP32的蓝牙功能在本项目中并未使用,但双核特性在处理网络通信和界面刷新时优势明显。
2.2 显示模块优化
2.2.1 屏幕选型历程
最初使用0.96寸OLED,但存在以下问题:
- 显示区域仅128x64像素
- 单色显示视觉效果差
- 同时显示3个菜品信息非常拥挤
升级为1.8寸ST7735S TFT彩屏后:
- 分辨率提升至128x160
- 支持65K色彩显示
- 可视面积增大400%
2.2.2 中文字库解决方案
常规方案直接使用官方库显示英文,中文需要特殊处理:
-
取模工具选择:
- 使用波特律动LED字模生成器
- 设置参数:16x16点阵、逐行式取模
-
显示异常排查:
c复制// 初始显示代码 tft.print("小龙虾"); // 显示乱码问题原因:
- 屏幕扫描方向为横向
- 字模数据排列方式不匹配
-
最终解决方案:
c复制// 修正后的显示函数 void drawCN(int x, int y, const uint8_t *d, uint16_t color) { for(int row=0; row<16; row++){ uint8_t byteLeft = p[row*2+1]; uint8_t byteRight = p[row*2]; for(int col=0; col<8; col++){ if(byteLeft & (0x80>>col)) tft.drawPixel(x+col, y+row, color); } for(int col=0; col<8; col++){ if(byteRight & (0x80>>col)) tft.drawPixel(x+8+col, y+row, color); } } }
2.3 语音模块集成
采用ASRPRO开发板实现语音交互,主要配置:
语音指令映射表:
| 语音命令 | 识别ID | 串口输出 | 语音反馈 |
|---|---|---|---|
| "一份小龙虾" | 11 | "11" | "好的,一份小龙虾" |
| "结账" | 55 | "55" | "好的,正在加载账单" |
| "最大音量" | 100 | - | "音量调整到最大" |
关键配置代码:
c复制// 天问Block生成的语音识别代码
void ASR_CODE(){
if(snid == 11) Serial1.println("11");
if(snid == 55) Serial1.println("55");
if(snid == 100) vol_set(7);
}
实测中发现,在嘈杂环境中需要将麦克风灵敏度调高,同时避免将扬声器与麦克风放置过近,否则容易产生回声干扰。
3. 软件系统架构
3.1 三层架构设计
系统采用分层设计,各层职责明确:
-
硬件终端层:
- 负责数据采集和人机交互
- 包含ESP32主控、TFT屏幕、语音模块
-
通信传输层:
- 基于TCP长连接
- 数据格式:JSON封装
json复制{ "type": "order", "dishes": [ {"id":1, "name":"小龙虾", "price":68, "count":2} ], "total": 136 } -
应用层:
- 手机点餐页面
- 商家管理后台
- 数据统计界面
3.2 关键通信机制
3.2.1 长连接维护
c复制// ESP32端的WiFi连接管理
void wifiTask(void *pv){
while(1){
if(WiFi.status() != WL_CONNECTED){
WiFi.reconnect();
vTaskDelay(5000);
}
vTaskDelay(1000);
}
}
3.2.2 数据同步策略
采用"操作即同步"原则:
- 本地操作立即反馈
- 异步推送至服务器
- 失败则存入Flash
- 定时重试机制
3.3 多终端数据一致性
实现方案:
- 版本号机制:每个订单变更递增版本号
- 冲突解决:最后操作优先
- 状态同步:500ms轮询+事件推送
核心代码片段:
javascript复制// 网页端的长轮询实现
function longPolling(){
fetch('/getUpdate?version='+lastVersion)
.then(res => res.json())
.then(data => {
if(data.newVersion > lastVersion){
updateUI(data);
lastVersion = data.newVersion;
}
setTimeout(longPolling, 500);
});
}
4. 核心功能实现
4.1 菜品管理模块
4.1.1 数据结构设计
c复制// ESP32端的菜品结构体
typedef struct {
char name[20]; // 菜品名称
float price; // 单价
uint8_t count; // 当前数量
uint8_t voiceId; // 语音指令ID
} Dish;
4.1.2 商家后台功能
商家后台提供以下管理功能:
- 菜品增删改查
- 价格实时调整
- 热门菜品推荐设置
后台界面关键操作:
javascript复制// 添加菜品AJAX请求
fetch(`/addDish?name=${name}&price=${price}`, {
method: 'POST'
}).then(res => {
if(res.ok) showToast('添加成功');
});
4.2 订单处理流程
4.2.1 正常流程
- 顾客选择菜品
- 数据实时同步至后台
- 厨房打印订单
- 顾客扫码支付
- 订单状态更新
4.2.2 异常处理
- 网络中断:本地缓存订单
- 支付超时:15分钟自动取消
- 菜品售罄:实时状态推送
4.3 支付系统集成
支付流程设计:
- 生成订单唯一ID
- 调用支付接口获取二维码
- 轮询支付状态
- 支付成功更新数据库
安全措施:
- 订单金额服务端校验
- 支付令牌有效期5分钟
- 敏感信息HTTPS传输
5. 系统优化与实测
5.1 性能优化措施
-
内存管理:
- 使用PSRAM存储菜品图片
- 采用内存池分配策略
-
渲染优化:
- 局部刷新代替全屏重绘
- 预加载常用界面
-
网络优化:
- 数据压缩传输
- 心跳包间隔调整
5.2 实测数据
压力测试结果:
| 指标 | 单终端 | 10终端并发 |
|---|---|---|
| 点餐响应 | <200ms | <800ms |
| 数据同步 | <300ms | <1s |
| 断网恢复 | 自动 | 自动 |
硬件稳定性:
- 连续工作72小时无重启
- 温度范围:-10℃~50℃正常
- 抗干扰能力:通过EMC测试
6. 开发经验总结
6.1 关键问题解决
-
屏幕闪烁问题:
- 原因:SPI通信速率过高
- 解决:降频至20MHz并优化时序
-
语音误触发:
- 原因:环境噪声干扰
- 解决:增加唤醒词确认机制
-
数据不同步:
- 原因:网络抖动导致丢包
- 解决:引入ACK重传机制
6.2 实用技巧分享
-
ESP32开发技巧:
- 使用FreeRTOS任务管理外设
- 合理设置看门狗超时时间
- 启用OTA方便远程升级
-
界面优化建议:
- 使用LVGL等GUI框架
- 重要操作提供触觉反馈
- 色彩搭配考虑色盲用户
-
量产注意事项:
- 选择工业级元器件
- 做好防水防油处理
- 预留固件升级接口
7. 项目扩展方向
-
功能扩展:
- 加入会员系统
- 增加菜品评价功能
- 对接外卖平台
-
硬件升级:
- 改用ESP32-S3提升性能
- 增加NFC支付模块
- 集成温湿度传感器
-
数据分析:
- 销售趋势预测
- 菜品关联分析
- 客流统计分析
这个项目从原型到量产历时3个月,期间解决了多个技术难点,最终实现的系统已在5家餐厅稳定运行半年。最大的体会是:嵌入式开发必须兼顾硬件稳定性和软件灵活性,同时要充分考虑实际使用场景的特殊需求。
