370 lines
8.7 KiB
Markdown
370 lines
8.7 KiB
Markdown
# 智能宠物喂食器 - MQTT 通信协议
|
||
|
||
## 概述
|
||
|
||
本文档描述智能宠物喂食器微信小程序与 STM32 单片机之间的 MQTT 通信协议。
|
||
|
||
## MQTT 连接配置
|
||
|
||
- **Broker 地址**: 根据实际情况配置
|
||
- **Broker 端口**: 根据实际情况配置(通常为 1883 或 8883)
|
||
- **连接方式**: TLS 加密连接(推荐)
|
||
- **客户端 ID**: 自动生成
|
||
|
||
## 主题列表
|
||
|
||
| 主题 | 方向 | 说明 |
|
||
|------|------|------|
|
||
| `petfeeder/sensor` | STM32 → 小程序 | 传感器数据上报 |
|
||
| `petfeeder/status` | STM32 → 小程序 | 设备状态上报 |
|
||
| `petfeeder/control` | 小程序 → STM32 | 控制指令下发 |
|
||
| `petfeeder/config` | 小程序 → STM32 | 配置参数下发 |
|
||
|
||
---
|
||
|
||
## 一、传感器数据上报
|
||
|
||
**Topic**: `petfeeder/sensor`
|
||
**方向**: STM32 → 小程序
|
||
**频率**: 建议每 30 秒上报一次,或数据变化时立即上报
|
||
|
||
### 数据格式
|
||
|
||
```json
|
||
{
|
||
"temperature": 25.5,
|
||
"humidity": 60,
|
||
"foodWeight": 500,
|
||
"waterLevel": 1
|
||
}
|
||
```
|
||
|
||
### 字段说明
|
||
|
||
| 字段 | 类型 | 范围/值 | 说明 |
|
||
|------|------|---------|------|
|
||
| `temperature` | Float | -20~100 | 温度,单位:°C |
|
||
| `humidity` | Integer | 0~100 | 湿度,单位:% |
|
||
| `foodWeight` | Integer | 0~5000 | 食物重量,单位:克 |
|
||
| `waterLevel` | Integer | 0 或 1 | 水位状态:0=缺水,1=满水 |
|
||
|
||
### 示例代码(STM32 C)
|
||
|
||
```c
|
||
// 构造传感器数据 JSON
|
||
void send_sensor_data(float temp, int hum, int weight, int water) {
|
||
char payload[128];
|
||
snprintf(payload, sizeof(payload),
|
||
"{\"temperature\":%.1f,\"humidity\":%d,\"foodWeight\":%d,\"waterLevel\":%d}",
|
||
temp, hum, weight, water);
|
||
|
||
// 发布到 MQTT broker
|
||
mqtt_publish("petfeeder/sensor", payload);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 二、设备状态上报
|
||
|
||
**Topic**: `petfeeder/status`
|
||
**方向**: STM32 → 小程序
|
||
**触发**: 设备状态变化时上报,或小程序主动查询时上报
|
||
|
||
### 数据格式
|
||
|
||
```json
|
||
{
|
||
"mode": "auto"
|
||
}
|
||
```
|
||
|
||
### 字段说明
|
||
|
||
| 字段 | 类型 | 可选值 | 说明 |
|
||
|------|------|--------|------|
|
||
| `mode` | String | `auto` \| `manual` | 运行模式:auto=自动模式,manual=手动模式 |
|
||
|
||
### 示例代码(STM32 C)
|
||
|
||
```c
|
||
// 发送状态数据
|
||
void send_device_status(const char* mode) {
|
||
char payload[64];
|
||
snprintf(payload, sizeof(payload), "{\"mode\":\"%s\"}", mode);
|
||
|
||
mqtt_publish("petfeeder/status", payload);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 三、控制指令下发
|
||
|
||
**Topic**: `petfeeder/control`
|
||
**方向**: 小程序 → STM32
|
||
|
||
### 3.1 手动喂食指令
|
||
|
||
```json
|
||
{
|
||
"action": "feed",
|
||
"amount": 50,
|
||
"timestamp": "2024-01-01T12:00:00.000Z"
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `action` | String | 固定值 `"feed"` |
|
||
| `amount` | Integer | 喂食重量,单位:克 |
|
||
| `timestamp` | String | ISO 8601 时间戳(可选) |
|
||
|
||
**STM32 处理逻辑**: 控制舵机或电机转动,投放指定重量的食物
|
||
|
||
---
|
||
|
||
### 3.2 手动补水指令
|
||
|
||
```json
|
||
{
|
||
"action": "addWater",
|
||
"timestamp": "2024-01-01T12:00:00.000Z"
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `action` | String | 固定值 `"addWater"` |
|
||
| `timestamp` | String | ISO 8601 时间戳(可选) |
|
||
|
||
**STM32 处理逻辑**: 控制水泵工作,向水箱注水
|
||
|
||
---
|
||
|
||
### 3.3 设置运行模式
|
||
|
||
```json
|
||
{
|
||
"action": "setMode",
|
||
"mode": "auto",
|
||
"timestamp": "2024-01-01T12:00:00.000Z"
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 可选值 | 说明 |
|
||
|------|------|--------|------|
|
||
| `action` | String | 固定值 `"setMode"` |
|
||
| `mode` | String | `auto` \| `manual` | 要设置的模式 |
|
||
| `timestamp` | String | ISO 8601 时间戳(可选) |
|
||
|
||
**STM32 处理逻辑**: 更新设备的运行模式状态
|
||
|
||
---
|
||
|
||
### 3.4 查询设备状态
|
||
|
||
```json
|
||
{
|
||
"action": "getStatus",
|
||
"timestamp": "2024-01-01T12:00:00.000Z"
|
||
}
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `action` | String | 固定值 `"getStatus"` |
|
||
| `timestamp` | String | ISO 8601 时间戳(可选) |
|
||
|
||
**STM32 处理逻辑**: 立即发送当前状态到 `petfeeder/status` 主题
|
||
|
||
---
|
||
|
||
## 四、配置参数下发
|
||
|
||
**Topic**: `petfeeder/config`
|
||
**方向**: 小程序 → STM32
|
||
|
||
### 数据格式
|
||
|
||
```json
|
||
{
|
||
"feedTimes": ["08:00", "18:00"],
|
||
"singleFeedWeight": 50
|
||
}
|
||
```
|
||
|
||
### 字段说明
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `feedTimes` | Array\<String\> | 喂食时间点数组,格式 `HH:MM`,最多2个时间点 |
|
||
| `singleFeedWeight` | Integer | 单次喂食重量,单位:克 |
|
||
|
||
### STM32 处理逻辑
|
||
|
||
1. 解析 `feedTimes` 数组,提取时间点
|
||
2. 存储到 RTC 或内部 Flash
|
||
3. 设置 RTC 闹钟,在指定时间触发自动喂食
|
||
4. 根据 `singleFeedWeight` 控制喂食量
|
||
|
||
### 示例代码(STM32 C)
|
||
|
||
```c
|
||
// 解析配置数据
|
||
void handle_config(const char* payload) {
|
||
// 使用 JSON 解析库(如 cJSON)解析 payload
|
||
// 提取 feedTimes 和 singleFeedWeight
|
||
|
||
// 示例:存储喂食时间
|
||
char time1[8] = {0};
|
||
char time2[8] = {0};
|
||
int weight = 50;
|
||
|
||
// 解析 JSON(使用 cJSON)
|
||
cJSON* root = cJSON_Parse(payload);
|
||
cJSON* feedTimes = cJSON_GetObjectItem(root, "feedTimes");
|
||
if (feedTimes && cJSON_IsArray(feedTimes)) {
|
||
if (cJSON_GetArraySize(feedTimes) >= 1) {
|
||
strcpy(time1, cJSON_GetArrayItem(feedTimes, 0)->valuestring);
|
||
}
|
||
if (cJSON_GetArraySize(feedTimes) >= 2) {
|
||
strcpy(time2, cJSON_GetArrayItem(feedTimes, 1)->valuestring);
|
||
}
|
||
}
|
||
|
||
cJSON* weightItem = cJSON_GetObjectItem(root, "singleFeedWeight");
|
||
if (weightItem) {
|
||
weight = weightItem->valueint;
|
||
}
|
||
|
||
// 设置 RTC 闹钟
|
||
set_alarm(time1, weight);
|
||
if (strlen(time2) > 0) {
|
||
set_alarm(time2, weight);
|
||
}
|
||
|
||
cJSON_Delete(root);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 五、STM32 MQTT 订阅列表
|
||
|
||
STM32 需要订阅以下主题以接收小程序指令:
|
||
|
||
| 主题 | 说明 |
|
||
|------|------|
|
||
| `petfeeder/control` | 接收控制指令 |
|
||
| `petfeeder/config` | 接收配置参数 |
|
||
|
||
---
|
||
|
||
## 六、通信流程示例
|
||
|
||
### 6.1 自动喂食流程
|
||
|
||
```
|
||
1. STM32 启动后连接 MQTT Broker
|
||
2. STM32 订阅 petfeeder/control 和 petfeeder/config
|
||
3. STM32 定时上报传感器数据到 petfeeder/sensor
|
||
4. RTC 闹钟触发时间到
|
||
5. STM32 自动喂食(投放 singleFeedWeight 克食物)
|
||
6. STM32 上报新的 foodWeight 到 petfeeder/sensor
|
||
```
|
||
|
||
### 6.2 手动喂食流程
|
||
|
||
```
|
||
1. 用户在小程序点击"喂食"按钮
|
||
2. 小程序发送控制指令到 petfeeder/control
|
||
3. STM32 收到 feed 指令
|
||
4. STM32 控制舵机投放指定重量的食物
|
||
5. STM32 更新 foodWeight 并上报到 petfeeder/sensor
|
||
```
|
||
|
||
### 6.3 模式切换流程
|
||
|
||
```
|
||
1. 用户在小程序切换模式开关
|
||
2. 小程序发送 setMode 指令到 petfeeder/control
|
||
3. STM32 收到指令,更新运行模式
|
||
4. STM32 发送新的 mode 状态到 petfeeder/status
|
||
5. 小程序更新界面显示
|
||
```
|
||
|
||
---
|
||
|
||
## 七、STM32 建议实现
|
||
|
||
### 7.1 定时任务
|
||
|
||
- **传感器上报**: 每 30 秒上报一次传感器数据
|
||
- **心跳保持**: 每 60 秒发送一次 MQTT PING
|
||
- **状态检查**: RTC 中断检查是否到达喂食时间
|
||
|
||
### 7.2 硬件接口
|
||
|
||
| 功能 | 硬件接口 | 说明 |
|
||
|------|----------|------|
|
||
| 温度传感器 | ADC/DHT22 | 温度采集 |
|
||
| 湿度传感器 | ADC/DHT22 | 湿度采集 |
|
||
| 食物重量 | ADC/称重模块 | 称重传感器 |
|
||
| 水位检测 | GPIO/ADC | 水位开关或浮子传感器 |
|
||
| 喂食执行 | PWM/GPIO | 舵机或步进电机 |
|
||
| 补水执行 | GPIO | 水泵控制 |
|
||
| RTC | 内部RTC/DS3231 | 实时时钟,用于定时喂食 |
|
||
|
||
### 7.3 JSON 解析库推荐
|
||
|
||
STM32 可使用以下 JSON 库:
|
||
- **cJSON**: 轻量级,资源占用小
|
||
- **Jansson**: 功能完整,稍大
|
||
- **ArduinoJson**: 如果使用 Arduino 框架
|
||
|
||
---
|
||
|
||
## 八、调试建议
|
||
|
||
### 8.1 MQTT 测试工具
|
||
|
||
使用以下工具测试通信协议:
|
||
- **MQTTX**: 跨平台 MQTT 客户端
|
||
- **mosquitto_pub/sub**: 命令行工具
|
||
|
||
### 8.2 测试步骤
|
||
|
||
1. STM32 上电后,用 MQTTX 订阅 `petfeeder/sensor`
|
||
2. 检查传感器数据是否正确上报
|
||
3. 用 MQTTX 发布测试消息到 `petfeeder/control`
|
||
4. 验证 STM32 是否正确响应指令
|
||
5. 打开小程序,测试完整功能
|
||
|
||
---
|
||
|
||
## 九、注意事项
|
||
|
||
1. **JSON 格式**: 所有 MQTT 消息必须是有效的 JSON 格式
|
||
2. **时间格式**: timestamp 使用 ISO 8601 标准格式
|
||
3. **错误处理**: STM32 应校验接收到的 JSON 格式,避免解析错误
|
||
4. **断线重连**: MQTT 断线后自动重连,重连后重新上报状态
|
||
5. **数据范围**: 传感器数据应在合理范围内,避免异常值
|
||
6. **喂食保护**: 避免短时间内重复喂食,设置最小间隔(如 10 分钟)
|
||
|
||
---
|
||
|
||
## 十、版本历史
|
||
|
||
| 版本 | 日期 | 说明 |
|
||
|------|------|------|
|
||
| v1.0 | 2024-02-10 | 初始版本 |
|
||
|
||
---
|
||
|
||
## 联系与反馈
|
||
|
||
如有问题或建议,请通过以下方式联系:
|
||
- 项目地址: [项目 GitHub 链接]
|
||
- Issue: [GitHub Issues]
|