diff --git a/V1.4/STM32F103_App1/HardWare/NETWORK/net_wifi.c b/V1.4/STM32F103_App1/HardWare/NETWORK/net_wifi.c index c25f9a4..f3ec1e9 100644 --- a/V1.4/STM32F103_App1/HardWare/NETWORK/net_wifi.c +++ b/V1.4/STM32F103_App1/HardWare/NETWORK/net_wifi.c @@ -126,17 +126,19 @@ void net_wifi_process(void) int r; while ((r = mqttc_process()) == 1) { } if (r == -1) { - log_warn("> WiFi: TCP closed, need reconnect"); - g_wifi_mqtt_ready = 0; - return; + /* 收到 CLOSED:服务器主动断开 TCP(被平台踢下线),直接复位重连 */ + log_error("> WiFi: connection closed by server (kicked offline by platform), system reset"); + HAL_Delay(100); + NVIC_SystemReset(); } - /* 30s 一次 PINGREQ;上一帧 PINGREQ 未收到 PINGRESP 判断链 */ - if (HAL_GetTick() - s_ping_tick >= 30000) { + /* 15s 一次 PINGREQ;上一帧 PINGREQ 未收到 PINGRESP 判断链 */ + if (HAL_GetTick() - s_ping_tick >= 15000) { if (g_mqttc_ping_outstanding) { - log_warn("> WiFi: ping timeout, need reconnect"); - g_wifi_mqtt_ready = 0; - return; + /* 心跳超时:服务器无响应(假在线/网络异常),直接复位重连 */ + log_error("> WiFi: ping timeout (server no response), system reset"); + HAL_Delay(100); + NVIC_SystemReset(); } s_ping_tick = HAL_GetTick(); mqttc_ping(); diff --git a/V1.4/STM32F103_App1/HardWare/NETWORK/network.c b/V1.4/STM32F103_App1/HardWare/NETWORK/network.c index bc3a6ec..0c26896 100644 --- a/V1.4/STM32F103_App1/HardWare/NETWORK/network.c +++ b/V1.4/STM32F103_App1/HardWare/NETWORK/network.c @@ -252,14 +252,26 @@ void NET_publish_status(int sw1, int feeding, int sw2, int sw3, int sw4, /* ver 字段:固件版本号,平台据此可识别设备是否发生了 OTA 回退 */ /* sw1 与 feeding 都映射继电器 1 状态(无秤模式两者等效), * 两个字段都上报,平台的 sw1 开关和 feeding 状态才能同步刷新 */ + /* 无秤模式(PRODUCT_WITH_FEED_SCALE=0)不上报 zero/onceWt 字段 */ if (s_backend == NET_BACKEND_4G) { +#if PRODUCT_WITH_FEED_SCALE CAT1_printf("AT+MPUB=\"/iot/data/up/%s\",0,0,\"{\\22header\\22:\\22iot.prop.post\\22,\\22body\\22:{\\22ver\\22:%u,\\22weight\\22:%.1f,\\22onceWt\\22:%.1f,\\22zero\\22:%.1f,\\22sw1\\22:%d,\\22feeding\\22:%d,\\22sw2\\22:%d,\\22sw3\\22:%d,\\22sw4\\22:%d}}\"", MqttInfoStr.ClientID, (unsigned)MqttInfoStr.Ver, zero_kg, once_wt_kg, weight_kg, sw1, feeding, sw2, sw3, sw4); +#else + CAT1_printf("AT+MPUB=\"/iot/data/up/%s\",0,0,\"{\\22header\\22:\\22iot.prop.post\\22,\\22body\\22:{\\22ver\\22:%u,\\22weight\\22:%.1f,\\22sw1\\22:%d,\\22feeding\\22:%d,\\22sw2\\22:%d,\\22sw3\\22:%d,\\22sw4\\22:%d}}\"", + MqttInfoStr.ClientID, (unsigned)MqttInfoStr.Ver, zero_kg, sw1, feeding, sw2, sw3, sw4); +#endif } else { char json[256]; +#if PRODUCT_WITH_FEED_SCALE snprintf(json, sizeof(json), "{\"header\":\"iot.prop.post\",\"body\":{\"ver\":%u,\"weight\":%.1f,\"onceWt\":%.1f,\"zero\":%.1f,\"sw1\":%d,\"feeding\":%d,\"sw2\":%d,\"sw3\":%d,\"sw4\":%d}}", (unsigned)MqttInfoStr.Ver, zero_kg, once_wt_kg, weight_kg, sw1, feeding, sw2, sw3, sw4); +#else + snprintf(json, sizeof(json), + "{\"header\":\"iot.prop.post\",\"body\":{\"ver\":%u,\"weight\":%.1f,\"sw1\":%d,\"feeding\":%d,\"sw2\":%d,\"sw3\":%d,\"sw4\":%d}}", + (unsigned)MqttInfoStr.Ver, zero_kg, sw1, feeding, sw2, sw3, sw4); +#endif net_wifi_publish_up(json); } net_at_unlock(); diff --git a/V1.4/STM32F103_App1/HardWare/RELAY/relay.c b/V1.4/STM32F103_App1/HardWare/RELAY/relay.c index c058f1e..d73a2ef 100644 --- a/V1.4/STM32F103_App1/HardWare/RELAY/relay.c +++ b/V1.4/STM32F103_App1/HardWare/RELAY/relay.c @@ -276,6 +276,12 @@ void relayAction(uint8_t *data) } #endif } else if (proto_locate((char *)data, "onceWt")) { +#if FEED_SCALE_DISABLED + /* 无秤模式:无单次投喂量概念,拒绝设置 */ + log_warn("> RELAY: onceWt rejected (no scale)"); + NET_publish_response(CmdId, 0, "no scale on this device"); + return; +#else /* 单独设置单次投喂量, 持久化到 EEPROM */ uint16_t once_wt_100g = 0; proto_get_kg100((char *)data, "onceWt", &once_wt_100g); @@ -288,7 +294,14 @@ void relayAction(uint8_t *data) NET_publish_response(CmdId, 1, "OK"); relayStatueUpdata(); return; +#endif } else if (proto_locate((char *)data, "zero")) { +#if FEED_SCALE_DISABLED + /* 无秤模式:无去皮/空载重量概念,拒绝设置 */ + log_warn("> RELAY: zero rejected (no scale)"); + NET_publish_response(CmdId, 0, "no scale on this device"); + return; +#else /* 平台下发空载重量/去皮值,直接解析 value 并保存 */ uint16_t zero_100g = 0; proto_get_kg100((char *)data, "zero", &zero_100g); @@ -301,6 +314,7 @@ void relayAction(uint8_t *data) NET_publish_response(CmdId, 1, "OK"); relayStatueUpdata(); return; +#endif } else { log_warn("> RELAY: no sw/feeding/zero"); return; diff --git a/V1.4/STM32F103_App1/HardWare/SYSINIT/app_loop.c b/V1.4/STM32F103_App1/HardWare/SYSINIT/app_loop.c index b27293f..52e68ff 100644 --- a/V1.4/STM32F103_App1/HardWare/SYSINIT/app_loop.c +++ b/V1.4/STM32F103_App1/HardWare/SYSINIT/app_loop.c @@ -57,7 +57,7 @@ void app_init(void) { log_info(""); log_info("* * * * * * * * * * * * * * * * * *"); - log_info("* Version: 1.4.3 (RTOS) *"); + log_info("* Version: 1.4.0 (RTOS) *"); log_info("* * * * * * * By Helei * * * *"); /* EEPROM 中的 MQTT/版本配置 */ @@ -200,19 +200,22 @@ static void sys_task(void *arg) update_batter(); } - /* 运行时长心跳:每 30s 串口输出一次(天/时/分), + /* 运行时长心跳:联网后每 60s 串口输出一次(天/时/分); + * 未联网(配网/重连中)不打印,避免干扰配网倒计时日志。 * 64 位累计,HAL_GetTick 约 49 天回绕也不受影响 */ { uint32_t now = HAL_GetTick(); up_ms += (uint32_t)(now - up_last); /* 32位差值天然容忍回绕 */ up_last = now; - if (now - up_print >= 30000) { + if (now - up_print >= 60000) { up_print = now; - uint32_t mins = (uint32_t)(up_ms / 60000); - log_info("> Uptime: %uday--%02uh--%02um\r\n", - (unsigned)(mins / 1440), - (unsigned)((mins % 1440) / 60), - (unsigned)(mins % 60)); + if (g_net_mqtt_ready) { + uint32_t mins = (uint32_t)(up_ms / 60000); + log_info("> Uptime: %uday--%02uh--%02um\r\n", + (unsigned)(mins / 1440), + (unsigned)((mins % 1440) / 60), + (unsigned)(mins % 60)); + } } } diff --git a/V1.4/STM32F103_App1/MDK-ARM/STM32F103rb_App1.uvoptx b/V1.4/STM32F103_App1/MDK-ARM/STM32F103rb_App1.uvoptx index bd14b5f..5a8a7b9 100644 --- a/V1.4/STM32F103_App1/MDK-ARM/STM32F103rb_App1.uvoptx +++ b/V1.4/STM32F103_App1/MDK-ARM/STM32F103rb_App1.uvoptx @@ -299,27 +299,27 @@ 0 0 - - - - Drivers/STM32F1xx_HAL_Driver - 1 - 0 - 0 - 0 - 3 + 2 5 1 0 0 0 0 - ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c - stm32f1xx_hal_gpio_ex.c + ../Src/stm32f1xx_hal_timebase_tim.c + stm32f1xx_hal_timebase_tim.c 0 0 + + + + Middlewares/FreeRTOS + 0 + 0 + 0 + 0 3 6 @@ -328,8 +328,8 @@ 0 0 0 - ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c - stm32f1xx_hal_tim.c + ../Middlewares/FreeRTOS/Source/tasks.c + tasks.c 0 0 @@ -341,8 +341,8 @@ 0 0 0 - ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c - stm32f1xx_hal_tim_ex.c + ../Middlewares/FreeRTOS/Source/queue.c + queue.c 0 0 @@ -354,8 +354,8 @@ 0 0 0 - ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c - stm32f1xx_hal_uart.c + ../Middlewares/FreeRTOS/Source/list.c + list.c 0 0 @@ -367,8 +367,8 @@ 0 0 0 - ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c - stm32f1xx_hal.c + ../Middlewares/FreeRTOS/Source/portable/RVDS/ARM_CM3/port.c + port.c 0 0 @@ -380,14 +380,100 @@ 0 0 0 + ../Middlewares/FreeRTOS/Source/portable/MemMang/heap_4.c + heap_4.c + 0 + 0 + + + + + Drivers/STM32F1xx_HAL_Driver + 0 + 0 + 0 + 0 + + 4 + 11 + 1 + 0 + 0 + 0 + 0 + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c + stm32f1xx_hal_gpio_ex.c + 0 + 0 + + + 4 + 12 + 1 + 0 + 0 + 0 + 0 + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c + stm32f1xx_hal_tim.c + 0 + 0 + + + 4 + 13 + 1 + 0 + 0 + 0 + 0 + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c + stm32f1xx_hal_tim_ex.c + 0 + 0 + + + 4 + 14 + 1 + 0 + 0 + 0 + 0 + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c + stm32f1xx_hal_uart.c + 0 + 0 + + + 4 + 15 + 1 + 0 + 0 + 0 + 0 + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c + stm32f1xx_hal.c + 0 + 0 + + + 4 + 16 + 1 + 0 + 0 + 0 + 0 ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c stm32f1xx_hal_rcc.c 0 0 - 3 - 11 + 4 + 17 1 0 0 @@ -399,8 +485,8 @@ 0 - 3 - 12 + 4 + 18 1 0 0 @@ -412,8 +498,8 @@ 0 - 3 - 13 + 4 + 19 1 0 0 @@ -425,8 +511,8 @@ 0 - 3 - 14 + 4 + 20 1 0 0 @@ -438,8 +524,8 @@ 0 - 3 - 15 + 4 + 21 1 0 0 @@ -451,8 +537,8 @@ 0 - 3 - 16 + 4 + 22 1 0 0 @@ -464,8 +550,8 @@ 0 - 3 - 17 + 4 + 23 1 0 0 @@ -477,8 +563,8 @@ 0 - 3 - 18 + 4 + 24 1 0 0 @@ -490,8 +576,8 @@ 0 - 3 - 19 + 4 + 25 1 0 0 @@ -503,8 +589,8 @@ 0 - 3 - 20 + 4 + 26 1 0 0 @@ -519,13 +605,13 @@ Drivers/CMSIS - 1 + 0 0 0 0 - 4 - 21 + 5 + 27 1 0 0 @@ -540,13 +626,13 @@ m_app - 1 + 0 0 0 0 - 5 - 22 + 6 + 28 1 0 0 @@ -566,8 +652,8 @@ 0 0 - 6 - 23 + 7 + 29 1 0 0 @@ -579,8 +665,8 @@ 0 - 6 - 24 + 7 + 30 1 0 0 @@ -592,8 +678,8 @@ 0 - 6 - 25 + 7 + 31 1 0 0 @@ -605,8 +691,8 @@ 0 - 6 - 26 + 7 + 32 1 0 0 @@ -618,8 +704,8 @@ 0 - 6 - 27 + 7 + 33 1 0 0 @@ -631,8 +717,8 @@ 0 - 6 - 28 + 7 + 34 1 0 0 @@ -644,8 +730,8 @@ 0 - 6 - 29 + 7 + 35 1 0 0 @@ -657,8 +743,8 @@ 0 - 6 - 30 + 7 + 36 1 0 0 @@ -670,8 +756,8 @@ 0 - 6 - 31 + 7 + 37 1 0 0 @@ -683,8 +769,8 @@ 0 - 6 - 32 + 7 + 38 1 0 0 @@ -696,8 +782,8 @@ 0 - 6 - 33 + 7 + 39 1 0 0 @@ -709,8 +795,8 @@ 0 - 6 - 34 + 7 + 40 1 0 0 @@ -722,8 +808,8 @@ 0 - 6 - 35 + 7 + 41 1 0 0 @@ -735,8 +821,8 @@ 0 - 6 - 36 + 7 + 42 1 0 0 @@ -748,8 +834,8 @@ 0 - 6 - 37 + 7 + 43 1 0 0 @@ -761,8 +847,8 @@ 0 - 6 - 38 + 7 + 44 1 0 0 @@ -774,8 +860,8 @@ 0 - 6 - 39 + 7 + 45 1 0 0 @@ -787,8 +873,8 @@ 0 - 6 - 40 + 7 + 46 1 0 0 @@ -803,13 +889,13 @@ Doc - 1 + 0 0 0 0 - 7 - 41 + 8 + 47 5 0 0 diff --git a/V1.4/STM32F103_App1/README.md b/V1.4/STM32F103_App1/README.md index c7a66e9..632e848 100644 --- a/V1.4/STM32F103_App1/README.md +++ b/V1.4/STM32F103_App1/README.md @@ -14,7 +14,7 @@ | --- | --- | --- | --- | | net_task | 3 | 3KB | 网络状态机 `NET_process`:4G/WiFi 建链与切换、MQTT 收发、GPS 轮询、OTA 下载 | | app_task | 2 | 2KB | 业务:继电器命令/反馈状态机、断电记忆恢复、投喂秤轮询与保护、状态上报、OTA 确认与健康检查 | -| sys_task | 1 | 1KB | 系统:LED、电量(1s)、蓝牙调试命令、Uptime 打印(30s) | +| sys_task | 1 | 1KB | 系统:LED、电量(1s)、蓝牙调试命令、Uptime 打印(联网后每 60s) | | idle 钩子 | - | - | 喂 IWDG(任务死循环占 CPU → idle 饿死 → 复位,正是期望行为) | 关键设计: @@ -84,7 +84,8 @@ WiFi 建链子顺序(net_wifi_init,阻塞式,等待期间 vTaskDelay 让 ② AT+CWJAP 连代码里固定的 SSID/PASS(esp8266.h 的 WIFI_SSID/WIFI_PASS,60s 倒计时) ③ ESP-Touch SmartConfig 智能配网(60s 倒计时,配到的热点由模块保存) 全部失败 → 回 4G -WiFi 运行:30s MQTT PINGREQ 心跳;TCP 断开(CLOSED)/心跳超时 → 自动重连,重连失败回 4G +WiFi 运行:15s MQTT PINGREQ 心跳;TCP 断开(CLOSED)/心跳超时 → 打印原因并直接整机复位重连 + (CLOSED=服务器主动断开/被平台踢下线;ping 超时=服务器无响应/假在线,最坏检测延迟 ~30s) ``` > 注:已存 AP 的判断用 `AT+CIPSTATUS` 主动查询而非被动等 `WIFI GOT IP` 打印—— @@ -239,12 +240,14 @@ W25Q64 外部 Flash(8MB): | `ver` | 固件版本号 | 每次状态上报携带,平台可据此识别设备是否发生回退 | | `weight` | 空载重量 | 平台显示为去皮重量 `zero` | | `zero` | 剩余料重 | 平台显示为当前剩余料重 | -| `onceWt` | 单次投喂量 | 每次投喂目标重量 | +| `onceWt` | 单次投喂量 | 每次投喂目标重量;**无秤模式不上报、下发设置被拒绝** | | `sw1` / `feeding` | 第一路继电器状态 | 1=投喂中,0=停止;无秤模式下两字段**同时上报**,平台两个开关同步刷新 | | `sw2~sw4` | 备用继电器状态 | 0/1 | | `pow` | 电量状态 | 1=正常,0=低电量 | | `GPS` | 定位坐标 | 仅 4G 通道(Air780EG),GCJ-02 高德坐标系,格式 `"经度,纬度"`,每 5 分钟上报 | +> 注:`zero`(剩余料重)与 `onceWt` 为称重模式专用字段——`PRODUCT_WITH_FEED_SCALE=0` 时状态上报不携带这两个字段,平台下发设置会收到 `no scale on this device` 拒绝应答。 + 下行报文由 `m_app/proto.c` 按键名定位解析(`"sw2"` 不会误中 `"sw21"`,其他字段里的 true/false 不会造成误判)。 ## 串口调试命令