系统总体架构设计
好,咱们开始聊系统架构。说实话,很多初学者一上来就急着写代码、焊电路板,结果做到一半发现各个模块连不起来——这种坑我踩过不止一次。所以这一章,咱们先把骨架搭好。
药盒安全用药检测与异常报警系统,说白了就是一套「感知-决策-执行-通知」的闭环。我习惯把整个系统拆成三块来看:硬件怎么搭、软件怎么跑、数据怎么流。咱们一个一个说。
硬件架构
硬件是系统的地基。地基不稳,上层再漂亮也没用。我个人习惯先画一张硬件框图,把每个模块的角色定清楚。
主控MCU
这是整个系统的大脑。我推荐用ESP32系列,原因有三:
- 自带Wi-Fi和蓝牙,省掉一个通信模块
- 双核处理器,一个核跑传感器采集,一个核跑通信协议
- 价格便宜,开发资料多,社区活跃
嗯,这里要注意:ESP32的ADC有非线性问题。我在项目里吃过这个亏——采集到的药盒重量数据跳来跳去,后来加了软件滤波才搞定。
传感器模块
药盒需要感知什么?我总结了三类:
- 药盒状态传感器:霍尔传感器或微动开关,检测药盒盖子是否打开
- 用药检测传感器:称重传感器(HX711+压力传感器),检测药片是否被取出
- 环境传感器:DHT22温湿度传感器,监测药品存储环境是否超标
执行器模块
执行器负责「动手」。我一般配置:
- 蜂鸣器:异常时发出警报声,分贝值建议在85dB以上
- LED指示灯:绿色表示正常,红色表示异常,黄色表示待处理
- 振动马达:给老人或视障用户提供触觉反馈
通信模块
ESP32自带Wi-Fi,所以通信模块基本就是它了。但如果你用STM32或其他MCU,就需要外接ESP8266或4G模块。我个人建议:
- 家庭场景:Wi-Fi + MQTT
- 户外/无Wi-Fi场景:4G Cat.1模块 + MQTT over TCP
软件架构
软件架构我分成三层:嵌入式端、云端、移动端。每一层各司其职,互不干扰。
嵌入式端(MCU固件)
这一层跑在ESP32上。我习惯用FreeRTOS做任务调度,把系统拆成几个独立任务:
// 伪代码示意
Task1: 传感器采集任务(每500ms执行一次)
Task2: 用药逻辑判断任务(事件触发)
Task3: MQTT通信任务(每2秒上报一次)
Task4: 异常报警任务(优先级最高)
为什么要用RTOS?说白了,如果不用操作系统,你写个while(1)大循环,传感器采集时通信卡住,通信时报警延迟——这种问题我调试过整整两天。
云端(后端服务)
云端我推荐用Python Flask或FastAPI搭一个轻量服务。主要做三件事:
- 接收MQTT消息,解析用药数据
- 存储到数据库(MySQL或SQLite都行)
- 分析异常规则,触发报警推送
移动端(App/小程序)
移动端我用Flutter开发,跨平台省事。主要功能:
- 查看用药记录(谁、什么时间、吃了什么药)
- 接收报警推送(漏服、多服、环境异常)
- 远程设置参数(用药提醒时间、报警阈值)
数据流设计
数据怎么流?我画了一条线:从药盒到手机,中间经过云端。咱们一步步拆。
第一步:用药数据采集
传感器采集原始数据。比如称重传感器输出的是电压值,经过HX711转换成数字量。我习惯在MCU端做一次预处理:
// 称重数据预处理
float raw_weight = hx711_read();
float filtered_weight = moving_average_filter(raw_weight, 5); // 滑动平均滤波
float actual_weight = filtered_weight - tare_weight; // 去皮操作
第二步:数据上传
MCU通过MQTT把数据发到云端。数据格式我用JSON,简单明了:
{
"device_id": "pillbox_001",
"timestamp": 1700000000,
"weight": 12.5,
"temperature": 25.3,
"humidity": 45.2,
"lid_status": "open"
}
上传频率我设的是2秒一次。太频繁浪费流量,太慢又怕漏掉关键事件。
第三步:数据分析
云端收到数据后,做两件事:
- 存储:写入数据库,保留历史记录
- 规则判断:检查是否触发异常条件
举个例子,如果检测到药盒盖子打开后,重量没有变化——说明用户可能只是看了看,没吃药。这时候云端会标记一条「疑似漏服」记录。
第四步:异常报警
一旦触发异常,云端通过MQTT或HTTP推送通知到移动端。我设计了几种报警等级:
| 报警等级 | 触发条件 | 响应方式 |
|---|---|---|
| 一级(紧急) | 多服/漏服超过2小时 | 蜂鸣器+App推送+短信 |
| 二级(警告) | 环境温湿度超标 | App推送+LED红灯 |
| 三级(提醒) | 用药时间到 | 蜂鸣器短鸣+LED绿灯闪烁 |
通信协议设计
通信协议我选了MQTT和HTTP两种。为什么用两个?
MQTT:用于实时数据上报
MQTT是发布/订阅模式,非常适合物联网场景。我设计的话题(Topic)结构:
pillbox/{device_id}/data // 传感器数据上报
pillbox/{device_id}/alarm // 报警事件
pillbox/{device_id}/command // 云端下发指令
MQTT的QoS我设成1(至少一次),保证数据不丢,但允许重复。为什么不用QoS 2?因为药盒数据重复一条没关系,但丢一条可能就漏了报警。
HTTP:用于配置和查询
HTTP用在非实时场景。比如:
- App查询历史用药记录
- 用户修改用药提醒时间
- 固件OTA升级
HTTP的优点是简单、调试方便。我习惯用RESTful风格,比如:
GET /api/v1/records?device_id=001&date=2024-01-01
POST /api/v1/config
PUT /api/v1/alarm/threshold
好了,系统架构就聊到这儿。你想想看,硬件、软件、数据、协议——这四个维度都理清楚了,后面写代码、焊电路才不会跑偏。下一章咱们开始动手搭建开发环境,到时候我会把工具链和调试技巧一并分享。