Files
jiacun-20s-200A/MOUDLE/H7690C.c
T
2026-08-25 17:30:40 +08:00

3647 lines
98 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
* @file H7690C.c
* @author
* @version
* @date
* @brief
******************************************************************************
* @attention
*
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "global.h"
#include "rtc.h"
#include "string.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#if LTE_Conn
//延时
#define ERR_timeEnd1 30/2 //持续ERR后重启计数,因遇到ERR会2s后再发报文,所以/2 30s
#define ERR_timeEnd2 60/2 //持续ERR后重启计数,因遇到ERR会2s后再发报文,所以/2 1min
#define RST_timeEnd 60*4 //指令持续无有效回复,执行4G重启 4min
#define RSSI13_timeEnd 60*4 //开机发现信号弱,等待恢复 4min
#define RSSI99_timeEnd 10 //开机可能出现rssi=99,等待恢复 10s
#define RSSI_timeEnd 30*4 //正常通信发现信号弱,等待恢复 4min
#define timed_Delay 51 //定时上报[属性]的延时
//通用定义
#define PIN_LTE_RST GPIO_Pin_12 //PC12 4G复位
#define PIN_LTE_CTRL GPIO_Pin_2 //PD2 输出几秒高电平,用以启动4G模块
#define LTE_UART UART4
#define LTE_Send LTE_printf
#define LTE_MON_CNT 6000 //6000*10ms = 60s
#define LTE_OTA_CNT 6000*3 //6000*3*10ms = 60*3s
#define LTE_ONLINE_CNT 6000*16 //持续未上线的倒计时数
#define LTE_TIMEDPUB_CNT 6000*2 //持续未发送属性的倒计时数
#define LTE_RX_BUF_LEN 1000 //接收的最大长度
#define LTE_TX_BUF_LEN 2000 //发送的最大长度
#define LTEMEM_LEN 2000 //定时发送数据的缓存长度
char LTE_Rx_Buf[LTE_RX_BUF_LEN];
char LTE_Tx_Buf[LTE_TX_BUF_LEN];
uint16_t LTE_Rx_BufIndex;
uint16_t LTE_Moni_Count; //无通信时重启4G
uint32_t LTE_Moni_Count2; //长时间不上线重启4G
uint32_t property_pub_count; //上线后长时间未上报属性重启MQTT服务
char LTEMem_Buf[LTEMEM_LEN]; //定时发送数据的缓冲区,也方便计算长度
uint16_t LTEMem_len; //所存内容长度,在发送给4G模块前计算出
//状态标志
uint8_t LTE_Onflag; //4G模块开机成功标志 (暂无作用但保留)
uint8_t LTE_SIMflag; //4G模块识别到SIM卡标志 (暂无作用但保留)
uint8_t LTE_Networkflag; //4G模块联网功能开关状态 (暂无作用但保留)
uint8_t LTE_Onlineflag; //4G模块联网标志 0:未联网 1:已联网 0xAA:错误,尝试重新联网解决
uint8_t LTE_PinRST_Flag; //4G模块需通过引脚重启标志 1:关闭4G 2:开启4G
uint8_t LTE_NoMoni_Flag; //4G模块不应该继续定时监控的标志 在正常联网但SN号不存在时启用
//4G模块开机等待
#define OpenTime 10
#define CloseTime 5
uint8_t LTE_WarmDelay; //4G模块开机等待时间
//4G模块回复ERR后发送等待
#define ResendTime 2
uint8_t LTE_ResendDelay; //4G模块对当前指令回复ERR,重新发送等待倒计时
//4G模块无回复后发送等待(实际时间要加上原有1s/0.25s)
#define WaitRxTime 2
uint8_t LTE_WaitRxDelay; //4G模块对当前指令无回复,重新发送等待倒计时
uint8_t LTE_WaitRxFlg; //有发送指令,需要在无回复时执行等待的标志
//4G通信错误计数
uint16_t LTE_ErrCnt; //未连接MQTT前发生的错误计数(持续发生就重启)
uint16_t MQTT_ErrCnt; //在连接/已连接MQTT后发生的错误计数(先尝试重启MQTT,还是不行就检查网络)
uint8_t Order_RevCount; //在接收MQTT下发指令的延时,用于防范“有头无尾”一直存在
uint8_t CSQ_ErrCnt; //在正常流程中,发送CSQ或CGREG收到Err的错误计数(持续发送就重启)
//4G异常状态:繁忙
uint8_t LTE_BUSY_cnt; //当4G模块卡死,问什么都回复BUSY的计数(持续发送就重启)
//重置状态指令
//1.重启模块
uint8_t CRESET_flag; //重启 0xAA:多次重启失败
uint8_t CRESET_step; //执行步骤 0~2:退出MQTT服务 3:重启
uint8_t CRESET_count; //执行次数 连续5次后执行引脚重启并清零。成功连接云平台后释放
//2.重启MQTT
uint8_t MQTT_RST_flag; //重启MQTT服务 0xAA:多次重启失败
uint8_t MQTT_RST_step; //执行步骤 0~2:退出MQTT服务
uint8_t MQTT_RST_count; //执行次数 连续5次后执行CGREG。成功连接云平台后释放
//3.重新联网
uint8_t CFUN_flag; //重新联网 0xAA:多次重启失败
uint8_t CFUN_step; //执行步骤 0:断网 1:联网 2:查询联网状态
uint8_t CFUN_count; //执行次数 连续5次后执行CGREG。联网正常后释放
uint8_t searching_cnt; //当CGREG=2,说明正在找网,等待3s再次询问,持续30s无变化,再次尝试重联网
//常规指令
//1.查询信号质量
uint8_t CSQ_flag; //执行查询信号质量指令的标志
char str_rssi[5]; //信号强度对应字符串
uint8_t LTE_rssi; //信号强度
uint16_t rssiLow_count; //若信号强度过低,持续发生就重启
uint16_t rssi99_count; //若信号值异常,给4G等待一点时间
//2.查询是否正常联网
uint8_t CGREG_flag; //执行查询网络注册状态指令的标志
uint16_t CGREG_count; //此时rssi正常,但网络注册状态有误,持续发生就重启
uint8_t LTE_register;//联网状态
//3.连接MQTT服务器
uint8_t MQTT_START_flag; //执行连接MQTT服务器的标志
uint8_t MQTT_START_step; //执行步骤
uint8_t MQTT_START_count;//出现"+MQTTSTART:1",尝试重启MQTT解决。超过5次转为查询CGREG
uint8_t LTE_LINK_flag; //已连接到服务器的标志
//4.连接成功后,获取当前SIM卡的CICCID
uint8_t CICCID_flag; //执行获取CICCID的标志
char ICCID[21]; //CICCID字符串
//5.连接成功后,订阅主题
uint8_t SUBTOPIC_flag; //执行订阅主题的标志
uint8_t SUBTOPIC_step; //执行步骤
uint8_t LTE_UNSUB_Flag;//需要先取消绑定的标志
//6.连接并订阅成功后,请求[校时]
uint8_t CALITIME_flag; //执行请求[校时]的标志
uint8_t CALITIME_step; //执行步骤
//final.已连上平台,走正常通信流程
uint8_t MQTT_READY_flag; //MQTT执行正常通信流程的标志
uint8_t MQTT_timed_count; //定时上报[属性]的倒计时
uint8_t LTE_status; //执行内容
uint8_t LTE_step; //执行步骤
//正常使用中.超时保护
uint8_t check_sub_count; //查询订阅的超时保护
// 【正常通信流程】
// 0.询问LBS数据(1)
// 1.询问信号质量(1)
// 2.定时上报[属性](5)
// 3.等待60s定时(n)
// 4.检查是否正常订阅主题(1)
//0xA0.若存在事件,立即上报所有[事件](5)
//0xA1.立刻回复写[服务](5)
//0xA2.立刻回复写[属性](5)
//0xA3.立刻回复读[属性](5)
#define ask_lbs 0
#define ask_rssi 1
#define send_timed 2
#define wait_timed 3
#define check_sub 4
#define event_pub 0xA0
#define srvc_pub 0xA1
#define setPara_pub 0xA2
#define getPara_pub 0xA3
// 【具体步骤】
// 0_0 [询问LBS数据] 0:获取4G基站数据
// 1_1~2 [询问信号质量] 1:获取信号质量 2:获取联网状态
// 2_6~10 [定时上报属性] 6:主题长度 7:主题内容 8:属性长度 9:属性内容 10:确认上传
// 3_11 [60s定时] 11:定时等待
// 4_12~22 [检查] 12:检查是否订阅主题
// 13~14:重新订阅[校时]主题
// 15~16:重新订阅[服务]主题
// 17~18:重新订阅写[属性]主题
// 19~20:重新订阅读[属性]主题
// 21~22:重新订阅OTA升级信息主题
//0xA0_101~105[立即上报事件] 101:主题长度 102:主题内容 103:属性长度 104:属性内容 105:确认上传
//0xA1_106~110[立即回复写服务] 106:主题长度 107:主题内容 108:属性长度 109:属性内容 110:确认上传
//0xA2_111~115[立即回复写属性] 111:主题长度 112:主题内容 113:属性长度 114:属性内容 115:确认上传
//0xA3_116~120[立即回复读属性] 116:主题长度 117:主题内容 118:属性长度 119:属性内容 120:确认上传
#define ask_lbs_step1 0
#define ask_rssi_step1 1
#define ask_rssi_step2 2
#define send_timed_step1 6
#define send_timed_step2 7
#define send_timed_step3 8
#define send_timed_step4 9
#define send_timed_step5 10
#define wait_timed_step1 11
#define check_sub_step01 12
#define check_sub_step11 13
#define check_sub_step12 14
#define check_sub_step21 15
#define check_sub_step22 16
#define check_sub_step31 17
#define check_sub_step32 18
#define check_sub_step41 19
#define check_sub_step42 20
#define check_sub_step51 21
#define check_sub_step52 22
#define event_pub_step1 101
#define event_pub_step2 102
#define event_pub_step3 103
#define event_pub_step4 104
#define event_pub_step5 105
#define srvc_pub_step1 106
#define srvc_pub_step2 107
#define srvc_pub_step3 108
#define srvc_pub_step4 109
#define srvc_pub_step5 110
#define setPara_pub_step1 111
#define setPara_pub_step2 112
#define setPara_pub_step3 113
#define setPara_pub_step4 114
#define setPara_pub_step5 115
#define getPara_pub_step1 116
#define getPara_pub_step2 117
#define getPara_pub_step3 118
#define getPara_pub_step4 119
#define getPara_pub_step5 120
//【OTA升级】
//0xAA.OTA升级完成后,上线回复升级完成
#define ota_fine_pub 0xAA
#define ota_fine_pub_step1 221
#define ota_fine_pub_step2 222
#define ota_fine_pub_step3 223
#define ota_fine_pub_step4 224
#define ota_fine_pub_step5 225
//功能参数
char timestamp_str[10+2]; //时间校准值字符串
uint32_t timestamp; //时间校准值
uint8_t LBS_Dataflag; //LBS数据标志 1:已获取到经纬度信息 0xAA:暂无数据
char LBS_initial_str[60]; //原始数据字符串
double LBS_lon,LBS_lat; //经纬度值(GCJ-02)
double WGS84_lon,WGS84_lat; //经纬度值(WGS84)
//特殊:事件、服务、写属性、读属性
#define INCIDENT_PUB_MAX 5 //一次性最多上传5条事件
uint8_t incident_pub_count;
const char* incident_str;
uint8_t incident_len;
uint32_t incident_time;
char ID_str[22]; //写[服务]/写[属性]/读[属性]时,操作设备的ID,最多20位
uint8_t ID_len;
uint8_t incident_reply_count; //回复操作计数 一共5步,若执行10次都没完成,可能是中间哪里卡住了,从头再开始发
uint8_t putSrvc_reply_count; //回复操作计数
uint8_t setPara_reply_count; //回复操作计数
uint8_t getPara_reply_count; //回复操作计数
uint8_t otaFine_reply_count; //回复操作计数【OTA升级】
char Str_Buf[30]; //在合并字符串和数据到一起的缓冲区
uint8_t putSrvc_reply_namelen; //写服务的名称长度
uint8_t putSrvc_reply_strlen; //写服务的内容长度
uint16_t setPara_reply_sumlen; //写属性的内容长度,{}内的总长度(4G需提前计算)
uint16_t getPara_reply_sumlen; //读属性的内容长度,{}内的总长度(4G需提前计算)
uint8_t LTE_sleep_flag; //4G也进入休眠标志
uint8_t pre_sleep_flag; //休眠前置标志 1:收到休眠指令后回复(暂无) 2:准备上报启动休眠事件 3:正在上报启动休眠事件 4:上报属性 5:退出MQTT服务后跳转休眠 0xA0:退出休眠后要上报退出休眠事件 0xAA:执行上报退出休眠事件
uint8_t pre_sleep_waitCnt; //休眠前置操作等待计数,若持续1min未执行结束,也直接跳到休眠最后一步:关闭4G
uint32_t sleepOn_time; //启动休眠时间
uint32_t sleepOff_time; //退出休眠时间
/**写服务变量名**/
#define srvc_ForceOn "\"PutForceOn\""
#define srvc_CurCali "\"PutCurCali\""
/**读写参数结构体**/
//不需要写入Flash变量的序号
#define Idx_WrFlash 4 //<4
//type!=0 但写入需额外执行动作的序号
#define Idx_Protocol 0
#define Idx_CYC 2
//type!=0 但读出需额外执行动作的序号
#define Idx_Protocol 0
//type!=0 但读出需另外赋值的序号
#define Idx_SOC 1
#define Idx_Capacity 3
//type==0 需单独配置变量的序号
#define Idx_COV_Vol 12
#define Idx_COVR_Vol 13
#define Idx_CUV_Vol 14
#define Idx_CUVR_Vol 15
#define Idx_SC_Cur 16
#define Idx_SC_Delay 17
uint16_t Wr_Temp;
//建立参数信息结构体
typedef struct
{
const char *name; //参数字符串,如 "Protocol"
void *data; //指向存储变量的指针,如 &protocol
int16_t min; //最小值(用于类型1~4的写范围判断,无符号的转int16_t存储)[不用时置0]
int16_t max; //最大值(用于类型1~4的写范围判断,无符号的转int16_t存储)[不用时置0]
uint8_t bitIdx;//位索引,如bit15(用于类型5)[不用时置0]
uint8_t type; //变量类型(0=不管 1=uint8_t 2=uint16_t 3=int8_t 4=int16_t 5=bool允许 6=bool禁止)
} ParamInfo;
//建立参数表,用于setPara和getPara
const ParamInfo paramTable[] =
{
//系统参数 0~3
{"\"Protocol\"", &protocol, 0, ProtocolSum, 0, 1}, //u8 //不写Flash //需写入EEPROM
{"\"SOC\"", &bmsMem.write_Soc, 0, 100, 0, 1}, //u8 //不写Flash //会在别处自动存EE //读出取bmsMem.soc
{"\"CYC\"", &bmsMem.cycleCount, 0, 0xFFFF, 0, 2}, //u16 //不写Flash //会在别处自动存EE //若超过paraMem.sohcali_stopTime,会在别处修正 //需置cumuliCapClear_flag=1
{"\"Capacity\"", &bmsMem.write_Capacity, 1, 1000, 0, 2}, //u16 //不写Flash //会在别处自动存EE //读出取fcc_Ah
//逆变器相关 4~7
{"\"InverterChgVol\"", &bmsMem.inverter_chgVolLimit, 1, 600, 0, 2}, //u16
{"\"InverterDsgVol\"", &bmsMem.inverter_dsgVolLimit, 1, 600, 0, 2}, //u16
{"\"InverterChgCur\"", &bmsMem.inverter_chgCurLimit, 1, 6000, 0, 2}, //u16
{"\"InverterDsgCur\"", &bmsMem.inverter_dsgCurLimit, 1, 6000, 0, 2}, //u16
//电压相关 8~15
{"\"POV_Vol\"", &paraMem.pack_ovv, 1, 600, 0, 2}, //u16
{"\"POVR_Vol\"", &paraMem.pack_ovrv, 1, 600, 0, 2}, //u16
{"\"PUV_Vol\"", &paraMem.pack_uvv, 1, 600, 0, 2}, //u16
{"\"PUVR_Vol\"", &paraMem.pack_uvrv, 1, 600, 0, 2}, //u16
{"\"COV_Vol\"", &Wr_Temp, 20, 5000, 0, 0}, //更新后,在别处写入真正参数 //读出取cell_OV
{"\"COVR_Vol\"", &Wr_Temp, 20, 5000, 0, 0}, //更新后,在别处写入真正参数 //读出取cell_OVR
{"\"CUV_Vol\"", &Wr_Temp, 20, 5000, 0, 0}, //更新后,在别处写入真正参数 //读出取cell_UV
{"\"CUVR_Vol\"", &Wr_Temp, 20, 5000, 0, 0}, //更新后,在别处写入真正参数 //读出取cell_UVR
//电流相关 16~21
{"\"SC_Cur\"", &Wr_Temp, 0, 15, 0, 0}, //更新后,在别处写入真正参数
{"\"SC_Delay\"", &Wr_Temp, 0, 15, 0, 0}, //更新后,在别处写入真正参数
{"\"OCC_Cur\"", &bmsMem.mcu_occ, 1, 255, 0, 1}, //u8
{"\"OCC_Delay\"", &bmsMem.mcu_occ_t, 1, 255, 0, 1}, //u8
{"\"OCD1_Cur\"", &bmsMem.mcu_ocd, 1, 255, 0, 1}, //u8
{"\"OCD1_Delay\"", &bmsMem.mcu_ocd_t, 1, 255, 0, 1}, //u8
//温度相关 22~29
{"\"OTC_Temp\"", &bmsMem.mcu_otc, -45, 115, 0, 3}, //i8
{"\"OTCR_Temp\"", &bmsMem.mcu_otcr, -45, 115, 0, 3}, //i8
{"\"OTD_Temp\"", &bmsMem.mcu_otd, -45, 115, 0, 3}, //i8
{"\"OTDR_Temp\"", &bmsMem.mcu_otdr, -45, 115, 0, 3}, //i8
{"\"UTC_Temp\"", &bmsMem.mcu_utc, -45, 115, 0, 3}, //i8
{"\"UTCR_Temp\"", &bmsMem.mcu_utcr, -45, 115, 0, 3}, //i8
{"\"UTD_Temp\"", &bmsMem.mcu_utd, -45, 115, 0, 3}, //i8
{"\"UTDR_Temp\"", &bmsMem.mcu_utdr, -45, 115, 0, 3}, //i8
};
////用于填充写[属性]的数组
////pm: 0表示正数,1表示负数
//void Record_setPara(const char* name, uint16_t data, uint8_t pm)
//{
// //if(setPara_reply_num >= SETPARA_SUM) return;
//
// setPara_reply_name[setPara_reply_num] = name; //名称
// setPara_reply_temp[setPara_reply_num] = data; //数值
// setPara_reply_pm[setPara_reply_num] = pm; //正负
//
// setPara_reply_num++;
// setPara_reply_sumlen += strlen(name)+2+uint_str_len(data); //名称长度(包括"")+数值长度+外面固定长度
//
// if(pm == 1)
// {
// setPara_reply_sumlen += 1; //负号
// }
//}
////用于填充读[属性]的数组
////pm: 0表示正数,1表示负数
//void Record_getPara(const char* name, uint16_t data, uint8_t pm)
//{
// //if(getPara_reply_num >= GETPARA_SUM) return;
//
// getPara_reply_name[getPara_reply_num] = name; //名称
// getPara_reply_temp[getPara_reply_num] = data; //数值
// getPara_reply_pm[getPara_reply_num] = pm; //正负
//
// getPara_reply_num++;
// getPara_reply_sumlen += strlen(name)+2+uint_str_len(data); //名称长度(包括"")+数值长度+外面固定长度
//
// if(pm == 1)
// {
// getPara_reply_sumlen += 1; //负号
// }
//}
//LTE专用的printf函数
int LTE_printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int len = vsnprintf(LTE_Tx_Buf, sizeof(LTE_Tx_Buf), fmt, args);
va_end(args);
for(int i = 0; i < len; i++)
{
while(!(UART4->SR & USART_SR_TXE)); // 等待发送完成
UART4->DR = LTE_Tx_Buf[i];
}
LTE_WaitRxFlg = 1; //有发送,可延时等待接收
return len;
}
//填充上报[属性]的缓冲区,并计算长度
void LTE_CombineStr(const char *fmt, ...)
{
//更新内容
va_list args;
va_start(args, fmt);
int len = vsnprintf(LTEMem_Buf + LTEMem_len, sizeof(LTEMem_Buf) - LTEMem_len, fmt, args);
va_end(args);
//更新长度
if(len > 0)
{
LTEMem_len += len;
}
}
//相关引脚初始化
void LTE_4G_IO_Init(void)
{
//初始化引脚
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD , ENABLE);
GPIO_InitStructure.GPIO_Pin = PIN_LTE_RST; //4G复位控制引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PIN_LTE_CTRL; //4G开机控制引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_ResetBits(GPIOC, PIN_LTE_RST); //4G复位控制脚,默认置低,关闭状态
GPIO_ResetBits(GPIOD, PIN_LTE_CTRL); //4G开机控制脚,默认置低,之后通过高电平脉冲开/关
}
//开机
//脉冲宽度100ms(范围100ms~2s),开机时间(UART)0.8s
void LTE_4G_Open(void)
{
GPIO_ResetBits(GPIOD, PIN_LTE_CTRL);
delay_ms(50);
GPIO_SetBits(GPIOD, PIN_LTE_CTRL);
delay_ms(200);
GPIO_ResetBits(GPIOD, PIN_LTE_CTRL);
delay_ms(50);
LTE_WarmDelay = OpenTime; //开机等待
}
//关机
//脉冲宽度2s(范围>1.5s),关机时间(UART)2.1s
void LTE_4G_Close(void)
{
GPIO_ResetBits(GPIOD, PIN_LTE_CTRL);
delay_ms(50);
GPIO_SetBits(GPIOD, PIN_LTE_CTRL);
delay_ms(2000);
GPIO_ResetBits(GPIOD, PIN_LTE_CTRL);
delay_ms(50);
LTE_WarmDelay = CloseTime; //关机等待
}
//复位
//脉冲宽度100ms(范围100ms~2s),建议仅在紧急情况使用
void LTE_4G_Reset(void)
{
// GPIO_ResetBits(GPIOC, PIN_LTE_RST);
// delay_ms(50);
// GPIO_SetBits(GPIOC, PIN_LTE_RST);
// delay_ms(200);
// GPIO_ResetBits(GPIOC, PIN_LTE_RST);
// delay_ms(50);
//
// LTE_WarmDelay = OpenTime; //开机等待
//采用更温和的手段,引脚重启
LTE_PinRST_Flag = 1;
}
//清空标志
void LTE_4G_ClearFlg(void)
{
//状态标志
LTE_Onflag = 0;
LTE_SIMflag = 0;
LTE_Networkflag = 0;
LTE_Onlineflag = 0;
//LTE_PinRST_Flag = 0;
LTE_NoMoni_Flag = 0;
//错误计数
LTE_ErrCnt = 0;
MQTT_ErrCnt = 0;
//重置状态标志
CRESET_flag = 0;
CRESET_step = 0;
MQTT_RST_flag = 0;
MQTT_RST_step = 0;
CFUN_flag = 0;
CFUN_step = 0;
//常规指令
//1.信号质量
CSQ_flag = 0;
LTE_rssi = 0;
//2.联网
CGREG_flag = 0;
//3.连接MQTT
MQTT_START_flag = 0;
MQTT_START_step = 0;
LTE_LINK_flag = 0;
//4.SIM卡的CICCID
CICCID_flag = 0;
//5.订阅主题
SUBTOPIC_flag = 0;
SUBTOPIC_step = 0;
//6.请求[校时]
CALITIME_flag = 0;
CALITIME_step = 0;
//final.正常通信流程
MQTT_READY_flag = 0;
MQTT_timed_count = 0;
LTE_status = 0;
LTE_step = 0;
//服务、写属性、读属性
putSrvc_reply_flg = 0;
setPara_reply_flg = 0;
getPara_reply_flg = 0;
//OTA升级
LTE_OTA_Flag = 0;
}
//清空接收缓冲区
void LTE_4G_ClearBuf(void)
{
LTE_Rx_BufIndex = 0;
memset(LTE_Rx_Buf, 0, LTE_RX_BUF_LEN);
}
//初始化通讯
void LTE_4G_Init(void)
{
LTE_4G_ClearFlg();
LTE_4G_ClearBuf();
LTE_Moni_Count = LTE_MON_CNT;
uf_UART4_Init(115200);
}
//持续1min未收到任何数据,初始化串口和4G模块
void LTE_TIM_Moni(void)
{
if((LTE_WarmDelay == 0) && (LTE_sleep_flag == 0) && (LTE_NoMoni_Flag == 0)) //开机等待不算+休眠不算+联网正常但无SN号不算+等待上报不算
{
LTE_Moni_Count--;
if(LTE_Moni_Count == 0) //持续无回复重启4G
{
LTE_4G_Init();
LTE_PinRST_Flag = 1;
}
if(MQTT_READY_flag == 0)
{
LTE_Moni_Count2++;
if(LTE_Moni_Count2 > LTE_ONLINE_CNT) //长期未上线重启4G
{
LTE_Moni_Count2 = 0;
LTE_4G_Init();
LTE_PinRST_Flag = 1;
}
}
else
{
LTE_Moni_Count2 = 0;
}
}
if(((LTE_LINK_flag == 1) || (MQTT_READY_flag == 1)) && (LTE_OTA_Flag == 0)) //已连接/已上线,不在OTA,但一直未上报属性
{
property_pub_count++;
if(property_pub_count > LTE_TIMEDPUB_CNT)
{
property_pub_count = 0;
MQTT_RST_flag = 1; //重启MQTT
MQTT_RST_step = 0;
LTE_LINK_flag = 0; //已连接标志清零
MQTT_START_flag = 0;
MQTT_READY_flag = 0;
MQTT_timed_count = 0;
LTE_OTA_Flag = 0; //OTA升级标志清零
}
}
else
{
property_pub_count = 0;
}
}
//下发[时钟同步]报文的处理
void LTE_4G_SUB_NTP(void)
{
if(strstr(LTE_Rx_Buf, "\"timestamp\"")) //
{
uint8_t len = 0; //字符串长度
//获取时间戳
//{"timestamp":1753858296}
const char* timeKey = "\"timestamp\":";
char* timeStart = strstr(LTE_Rx_Buf, timeKey); timeStart += strlen(timeKey);
char* timeEnd = strchr(timeStart, '}');
len = timeEnd - timeStart;
strncpy(timestamp_str, timeStart, len);
timestamp_str[len] = '\0';
sscanf(timestamp_str, "%u", &timestamp);
if(LSEErrFlag == 0) //晶振正常时
{
//刷新休眠时间
RTC_UpdateFlag = 1;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); //使能PWR和BKP外设时钟
PWR_BackupAccessCmd(ENABLE); //使能RTC和后备寄存器访问
RTC_SetCounter(timestamp); //设置RTC计数器的值
RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成
RTC_Get();
}
}
}
//分析4G基站定位
void LTE_4G_GET_LBS(void)
{
if(strstr(LTE_Rx_Buf, "+CLBS:"))
{
//获取原始数据字符串
uint8_t len = 0; //字符串长度
//+CLBS: 0,31.191534,120.600830,550
const char* dataKey = "+CLBS: ";
char* dataStart = strstr(LTE_Rx_Buf, dataKey); dataStart += strlen(dataKey);
char* dataEnd = strchr(dataStart, '\r');
len = dataEnd - dataStart;
strncpy(LBS_initial_str, dataStart, len);
LBS_initial_str[len] = '\0';
//分析数据
uint16_t temp1,temp2;
//纬度格式:31.191534 (-180.000000~180.000000)
//经度格式:120.600830 (-90.000000~90.000000)
sscanf(LBS_initial_str, "%hu,%lf,%lf,%hu", &temp1, &LBS_lat, &LBS_lon, &temp2);
//转换到国际通用坐标系
gcj02_to_wgs84(LBS_lon, LBS_lat, &WGS84_lon, &WGS84_lat);
//可以上传基站定位
LBS_Dataflag = 1;
}
}
//用于填充定时上报[属性]的数组
void LTE_Record_pubData(void)
{
//清空数组
LTEMem_len = 0;
memset(LTEMem_Buf, 0, LTEMEM_LEN);
//内容更新
LTE_CombineStr("{"); //1
LTE_CombineStr("\"BmsSN\":\"%s\",", BMS_SN); //5+4 + 9+2
LTE_CombineStr("\"PackSN\":\"%s\",", PACK_SN); //6+4 + 15+2
LTE_CombineStr("\"SysTime\":\"%u\",", timecount); //7+4 + 10+2
if(ScreenVersion[0] == 0)
{
LTE_CombineStr("\"FirmwareVersion\":\"%s\",", FirmwareVersion); //15+4 + 11+2
LTE_CombineStr("\"HardwareVersion\":\"%s\",", HardwareVersion); //15+4 + 5+2
}
else
{
LTE_CombineStr("\"FirmwareVersion\":\"%s\",", FirmwareVersion); //15+4 + 11+2
LTE_CombineStr("\"HardwareVersion\":\"%s\",", HardwareVersion); //15+4 + 5+2
LTE_CombineStr("\"ScreenVersion\":\"%s\",", ScreenVersion); //13+4 + 5+2
}
//采集数据
LTE_CombineStr("\"PackVol\":%u,", bmsMem.packVoltage); //7+4 + 10
LTE_CombineStr("\"PackCur\":%d,", bmsMem.packCurrent); //7+4 + 10
LTE_CombineStr("\"VolMax\":%d,", cellVoltageMax); //6+4 + 5
LTE_CombineStr("\"VolMin\":%d,", cellVoltageMin); //6+4 + 5
LTE_CombineStr("\"VolMaxIndex\":%u,", bmsMem.cellVoltageMaxIndex); //11+4 + 2
LTE_CombineStr("\"VolMinIndex\":%u,", bmsMem.cellVoltageMinIndex); //11+4 + 2
LTE_CombineStr("\"FCC\":%u,", bmsMem.ncc/3600); //3+4 + 7
LTE_CombineStr("\"RCC\":%u,", bmsMem.rcc/3600); //3+4 + 7
LTE_CombineStr("\"SOC\":%u,", bmsMem.soc); //3+4 + 3
LTE_CombineStr("\"SOH\":%u,", bmsMem.soh); //3+4 + 3
LTE_CombineStr("\"CYC\":%u,", bmsMem.cycleCount); //3+4 + 5
//电压
LTE_CombineStr("\"CellVol1\":%d,", cellVol[0]); //8+4 + 5
LTE_CombineStr("\"CellVol2\":%d,", cellVol[1]); //8+4 + 5
LTE_CombineStr("\"CellVol3\":%d,", cellVol[2]); //8+4 + 5
LTE_CombineStr("\"CellVol4\":%d,", cellVol[3]); //8+4 + 5
LTE_CombineStr("\"CellVol5\":%d,", cellVol[4]); //8+4 + 5
LTE_CombineStr("\"CellVol6\":%d,", cellVol[5]); //8+4 + 5
LTE_CombineStr("\"CellVol7\":%d,", cellVol[6]); //8+4 + 5
LTE_CombineStr("\"CellVol8\":%d,", cellVol[7]); //8+4 + 5
LTE_CombineStr("\"CellVol9\":%d,", cellVol[8]); //8+4 + 5
LTE_CombineStr("\"CellVol10\":%d,", cellVol[9]); //9+4 + 5
LTE_CombineStr("\"CellVol11\":%d,", cellVol[10]); //9+4 + 5
LTE_CombineStr("\"CellVol12\":%d,", cellVol[11]); //9+4 + 5
LTE_CombineStr("\"CellVol13\":%d,", cellVol[12]); //9+4 + 5
LTE_CombineStr("\"CellVol14\":%d,", cellVol[13]); //9+4 + 5
LTE_CombineStr("\"CellVol15\":%d,", cellVol[14]); //9+4 + 5
LTE_CombineStr("\"CellVol16\":%d,", cellVol[15]); //9+4 + 5
LTE_CombineStr("\"CellVol17\":%d,", cellVol[16]); //9+4 + 5
LTE_CombineStr("\"CellVol18\":%d,", cellVol[17]); //9+4 + 5
LTE_CombineStr("\"CellVol19\":%d,", cellVol[18]); //9+4 + 5
LTE_CombineStr("\"CellVol20\":%d,", cellVol[19]); //9+4 + 5
//温度
LTE_CombineStr("\"MosT1\":%.1f,", (float)(bmsMem.afe_T1-2731)/10); //5+4 + 5
LTE_CombineStr("\"MosT2\":%.1f,", (float)(bmsMem.afe_T2-2731)/10); //5+4 + 5
LTE_CombineStr("\"AmbientT\":%.1f,", (float)(bmsMem.afe_T3-2731)/10); //8+4 + 5
LTE_CombineStr("\"BatteryT1\":%.1f,", (float)(bmsMem.mcu_T1-2731)/10); //9+4 + 5
LTE_CombineStr("\"BatteryT2\":%.1f,", (float)(bmsMem.mcu_T2-2731)/10); //9+4 + 5
LTE_CombineStr("\"BatteryT3\":%.1f,", (float)(bmsMem.mcu_T3-2731)/10); //9+4 + 5
LTE_CombineStr("\"BatteryT4\":%.1f,", (float)(bmsMem.mcu_T4-2731)/10); //9+4 + 5
//常见状态
LTE_CombineStr("\"ChargeStatus\":%s,", Status[ChargeStatus]); //12+4 + 5
LTE_CombineStr("\"DischargeStatus\":%s,", Status[DischargeStatus]); //15+4 + 5
LTE_CombineStr("\"PreChargeStatus\":%s,", Status[PreChargeStatus]); //15+4 + 5
LTE_CombineStr("\"ChgMosStatus\":%s,", Status[ChgMosStatus]); //12+4 + 5
LTE_CombineStr("\"DsgMosStatus\":%s,", Status[DsgMosStatus]); //12+4 + 5
LTE_CombineStr("\"PchgMosStatus\":%s,", Status[PchgMosStatus]); //13+4 + 5
if(ChgLimitStatus) LTE_CombineStr("\"ChgLimitStatus\":true,"); //14+4 + 5
//特殊状态
if(LockOCC) LTE_CombineStr("\"LockOCC\":true,"); //7+4 + 5
if(LockOCD1) LTE_CombineStr("\"LockOCD1\":true,"); //8+4 + 5
if(LockOCD2) LTE_CombineStr("\"LockOCD2\":true,"); //8+4 + 5
if(LockSP) LTE_CombineStr("\"LockSP\":true,"); //6+4 + 5
if(LockSC) LTE_CombineStr("\"LockSC\":true,"); //6+4 + 5
if(ChgMosFault) LTE_CombineStr("\"ChgMosFault\":true,"); //11+4 + 5
if(DsgMosFault) LTE_CombineStr("\"DsgMosFault\":true,"); //11+4 + 5
if(DOStatus) LTE_CombineStr("\"DOStatus\":true,"); //8+4 + 5
if(ForceOffUV) LTE_CombineStr("\"ForceOffUV\":true,"); //10+4 + 5
//保护
if(PackOV) LTE_CombineStr("\"PackOV\":true,"); //6+4 + 5
if(PackUV) LTE_CombineStr("\"PackUV\":true,"); //6+4 + 5
if(CellOV) LTE_CombineStr("\"CellOV\":true,"); //6+4 + 5
if(CellUV) LTE_CombineStr("\"CellUV\":true,"); //6+4 + 5
if(PF) LTE_CombineStr("\"PF\":true,"); //2+4 + 5
if(L0V) LTE_CombineStr("\"L0V\":true,"); //3+4 + 5
if(OCC) LTE_CombineStr("\"OCC\":true,"); //3+4 + 5
if(OCD1) LTE_CombineStr("\"OCD1\":true,"); //4+4 + 5
if(OCD2) LTE_CombineStr("\"OCD2\":true,"); //4+4 + 5
if(SP) LTE_CombineStr("\"SP\":true,"); //2+4 + 5
if(SC) LTE_CombineStr("\"SC\":true,"); //2+4 + 5
if(McuOTC) LTE_CombineStr("\"McuOTC\":true,"); //6+4 + 5
if(McuOTD) LTE_CombineStr("\"McuOTD\":true,"); //6+4 + 5
if(McuUTC) LTE_CombineStr("\"McuUTC\":true,"); //6+4 + 5
if(McuUTD) LTE_CombineStr("\"McuUTD\":true,"); //6+4 + 5
if(AmbientOTC) LTE_CombineStr("\"AmbientOTC\":true,"); //10+4 + 5
if(AmbientOTD) LTE_CombineStr("\"AmbientOTD\":true,"); //10+4 + 5
if(AmbientUTC) LTE_CombineStr("\"AmbientUTC\":true,"); //10+4 + 5
if(AmbientUTD) LTE_CombineStr("\"AmbientUTD\":true,"); //10+4 + 5
if(MosOTC) LTE_CombineStr("\"MosOTC\":true,"); //6+4 + 5
if(MosOTD) LTE_CombineStr("\"MosOTD\":true,"); //6+4 + 5
//if(MosUTC) LTE_CombineStr("\"MosUTC\":true,"); //6+4 + 5
//if(MosUTD) LTE_CombineStr("\"MosUTD\":true,"); //6+4 + 5
//报警
if(PackOVWarning) LTE_CombineStr("\"PackOVWarning\":true,"); //6+4 + 5
if(PackUVWarning) LTE_CombineStr("\"PackUVWarning\":true,"); //6+4 + 5
if(CellOVWarning) LTE_CombineStr("\"CellOVWarning\":true,"); //6+4 + 5
if(CellUVWarning) LTE_CombineStr("\"CellUVWarning\":true,"); //6+4 + 5
if(OCCWarning) LTE_CombineStr("\"OCCWarning\":true,"); //3+4 + 5
if(OCDWarning) LTE_CombineStr("\"OCDWarning\":true,"); //3+4 + 5
if(McuOTCWarning) LTE_CombineStr("\"McuOTCWarning\":true,"); //6+7+4 + 5
if(McuOTDWarning) LTE_CombineStr("\"McuOTDWarning\":true,"); //6+7+4 + 5
if(McuUTCWarning) LTE_CombineStr("\"McuUTCWarning\":true,"); //6+7+4 + 5
if(McuUTDWarning) LTE_CombineStr("\"McuUTDWarning\":true,"); //6+7+4 + 5
if(AmbientOTCWarning) LTE_CombineStr("\"AmbientOTCWarning\":true,"); //10+7+4 + 5
if(AmbientOTDWarning) LTE_CombineStr("\"AmbientOTDWarning\":true,"); //10+7+4 + 5
if(AmbientUTCWarning) LTE_CombineStr("\"AmbientUTCWarning\":true,"); //10+7+4 + 5
if(AmbientUTDWarning) LTE_CombineStr("\"AmbientUTDWarning\":true,"); //10+7+4 + 5
if(MosOTCWarning) LTE_CombineStr("\"MosOTCWarning\":true,"); //6+7+4 + 5
if(MosOTDWarning) LTE_CombineStr("\"MosOTDWarning\":true,"); //6+7+4 + 5
//if(MosUTCWarning) LTE_CombineStr("\"MosUTCWarning\":true,"); //6+7+4 + 5
//if(MosUTDWarning) LTE_CombineStr("\"MosUTDWarning\":true,"); //6+7+4 + 5
//4G信息
LTE_CombineStr("\"ICCID\":\"%s\",", ICCID); //5+4 + 20+2
if(LBS_Dataflag == 1)
{
LTE_CombineStr("\"rssi\":%u,", LTE_rssi); //4+4 + 2+2
LTE_CombineStr("\"coords\":\"%.7f,%.7f\"}", WGS84_lon, WGS84_lat); //6+4 + 21+3
}
else
{
LTE_CombineStr("\"rssi\":%u}", LTE_rssi); //4+4 + 2+2
//LTE_CombineStr("\"coords\":null}"); //0
}
LTE_CombineStr("\r\n"); //+2 最后有换行
}
//下发[服务]报文的处理
//(只填充回复相关不执行)
void LTE_4G_SUB_Service(void)
{
if(strstr(LTE_Rx_Buf, "\"request_id\"")) //有ID格式
{
//将ID内容拓印到数组
//{"request_id":"123124sdf",…}
ID_len = GetID(LTE_Rx_Buf, ID_str);
if(ID_len == 0)
{
putSrvc_reply_flg = 0xBB; //设备拒绝执行
return;
}
//识别指令
if(strstr(LTE_Rx_Buf, srvc_ForceOn)) //控制欠压强制复位
{
putSrvc_reply_flg = 1;
putSrvc_reply_namestr = srvc_ForceOn;
putSrvc_reply_namelen = 10+2;
//更新控制位
if(strstr(LTE_Rx_Buf, "\"open\""))
{
//当前总体和单体欠压的报警/保护位都置0
bmsMem.bStatus1 &= ~0x0202;
bmsMem.bStatus3 &= ~0x0A00;
//状态置1,更新计时起点
bmsMem.balanceStatus |= 0x0020;
if(LSEErrFlag!=1)
{
uvofftimecount = RTC_GetCounter();
uvofftime = 300;
}
else
{
uvoff_Moni_Count = UVOff_MON_CNT;
}
putSrvc_reply_str = "\"open\"";
putSrvc_reply_strlen = 4+2;
}
else if(strstr(LTE_Rx_Buf, "\"close\""))
{
bmsMem.balanceStatus &= 0xffdf;
putSrvc_reply_str = "\"close\"";
putSrvc_reply_strlen = 5+2;
}
else //未收到正确内容
{
putSrvc_reply_flg = 0xBB; //设备拒绝执行
}
}
else if(strstr(LTE_Rx_Buf, srvc_CurCali)) //控制执行电流校准
{
putSrvc_reply_flg = 1;
putSrvc_reply_namestr = srvc_CurCali;
putSrvc_reply_namelen = 10+2;
if(strstr(LTE_Rx_Buf, "\"zero\""))
{
cali.cmdZero = 2; //执行零点校准标志置2,与上位机做区分
putSrvc_reply_str = "\"zero\"";
putSrvc_reply_strlen = 4+2;
}
else if(strstr(LTE_Rx_Buf, "\"gain\"") && strstr(LTE_Rx_Buf, "\"GainCur\""))
{
char gain_str[10]; //1~2147483647
uint8_t len = 0; //字符串长度
uint32_t temp; //无符号过程量
//获取校准电流值
len = GetStr("\"GainCur\":", '}', '}', LTE_Rx_Buf, gain_str);
sscanf(gain_str, "%u", &temp);
//符合范围的放入
if((temp>=1) && (temp<=0x7FFFFFFF) && (len > 0))
{
//执行增益校准标志置2,与上位机做区分
cali.cmdGain = 2;
cali.current = temp;
memset(Str_Buf, 0, 30); //清空
sprintf(Str_Buf, "\"gain\",\"GainCur\":%u", temp); //填充
putSrvc_reply_str = Str_Buf;
putSrvc_reply_strlen = 17+len;
}
else
{
putSrvc_reply_flg = 0xBB; //设备拒绝执行
}
}
else
{
putSrvc_reply_flg = 0xBB; //设备拒绝执行
}
}
else
{
putSrvc_reply_flg = 0xAA; //设备无该属性
}
}
else //无request_id
{
putSrvc_reply_flg = 0xBB; //设备拒绝执行
}
}
//用于填充写[属性]的数组
//pm: 0表示正数,1表示负数
void Record_setPara(const char* name, uint16_t data, uint8_t pm)
{
//if(setPara_reply_num >= SETPARA_SUM) return;
setPara_reply_name[setPara_reply_num] = name; //名称
setPara_reply_temp[setPara_reply_num] = data; //数值
setPara_reply_pm[setPara_reply_num] = pm; //正负
setPara_reply_num++;
setPara_reply_sumlen += strlen(name)+2+uint_str_len(data); //名称长度(包括"")+数值长度+外面固定长度
if(pm == 1)
{
setPara_reply_sumlen += 1; //负号
}
}
//下发写[属性]报文的处理
//{"request_id":"123124sdf","Protocol":1}
void LTE_4G_SUB_SETPARA(void)
{
if(strstr(LTE_Rx_Buf, "\"request_id\"")) //有ID格式
{
//将ID内容拓印到数组
//{"request_id":"123124sdf","POV_Vol":250}
ID_len = GetID(LTE_Rx_Buf, ID_str);
if(ID_len == 0)
{
setPara_reply_flg = 0xBB; //设备拒绝执行
return;
}
if(strstr(LTE_Rx_Buf, "\"data\":{") && strstr(LTE_Rx_Buf, "}}"))
{
uint8_t i;
char para_str[6]; //0~65535 或 -32768~32767
uint16_t len = 0; //字符串长度
uint16_t temp; //无符号过程量
int16_t temp_T; //有符号过程量
uint8_t FlashStore_Flag = 0; //更新到Flash的标志
//获取原始数据,包括'{''}'
const char* paramsKey = "\"data\":";
char* paramsStart = strstr(LTE_Rx_Buf, paramsKey); paramsStart += strlen(paramsKey);
char* paramsEnd = strchr(paramsStart, '}');
len = paramsEnd - paramsStart;
if(len > sizeof(params_str)-2) //防溢出
{
len = sizeof(params_str)-2;
}
strncpy(params_str, paramsStart, len);
params_str[len] = '}';
params_str[len+1] = '\0';
//识别存在的参数,并给予对应值
setPara_reply_num = 0;
setPara_reply_sumlen = 0;
//遍历参数表
for(i=0; i<sizeof(paramTable)/sizeof(ParamInfo); i++)
{
if(strstr(params_str, paramTable[i].name)) //存在对应名称
{
//获取参数值
len = GetStrFromJson(paramTable[i].name, params_str, para_str);
//1~4根据类型赋值
if(paramTable[i].type <= 2) //0.1.2
{
sscanf(para_str, "%hu", &temp);
}
else if((paramTable[i].type >= 3) && (paramTable[i].type <= 4)) //3.4
{
sscanf(para_str, "%hd", &temp_T);
}
//根据类型进行不同判断
if(paramTable[i].type == 0) //需单独配置
{
//符合范围的放入
if((temp >= paramTable[i].min) && (temp <= paramTable[i].max) && (len > 0))
{
if(i == Idx_COV_Vol) //"\"COV_Vol\""
{
temp = temp/5;
bmsMem.ee_ovt_ldrt_ovh &= 0xfc;//~0x03
bmsMem.ee_ovt_ldrt_ovh += (temp & 0x0300) >>8;
bmsMem.ee_ovl = temp & 0x00ff;
temp = temp*5;
cell_OV = temp;
//记录回复信息
Record_setPara(paramTable[i].name, temp, 0);
}
else if(i == Idx_COVR_Vol) //"\"COVR_Vol\""
{
temp = temp/5;
bmsMem.ee_uvt_ovrh &= 0xfc;//~0x03
bmsMem.ee_uvt_ovrh += (temp & 0x0300) >>8;
bmsMem.ee_ovrl = temp & 0x00ff;
temp = temp*5;
cell_OVR = temp;
//记录回复信息
Record_setPara(paramTable[i].name, temp, 0);
}
else if(i == Idx_CUV_Vol) //"\"CUV_Vol\""
{
temp = temp/20;
bmsMem.ee_uv = temp;
temp = temp*20;
cell_UV = temp;
//记录回复信息
Record_setPara(paramTable[i].name, temp, 0);
}
else if(i == Idx_CUVR_Vol) //"\"CUVR_Vol\""
{
temp = temp/20;
bmsMem.ee_uvr = temp;
temp = temp*20;
cell_UVR = temp;
//记录回复信息
Record_setPara(paramTable[i].name, temp, 0);
}
else if(i == Idx_SC_Cur) //"\"SC_Cur\""
{
uint16_t scv,scc;
bmsMem.ee_scv_sct &= 0x0F;
bmsMem.ee_scv_sct |= (temp & 0x0f)<<4;
if(temp == 0x0B)
{
scv = 400;
}
else
{
scv = 50 + 30 * temp;
}
scc = scv * AFE_Multiple;
//记录额外的回复信息
Record_setPara(paramTable[i].name, temp, 0);
Record_setPara("\"SC_Current\"", scc, 0);
}
else if(i == Idx_SC_Delay) //"\"SC_Delay\""
{
uint16_t sct;
bmsMem.ee_scv_sct &= 0xF0;
bmsMem.ee_scv_sct |= (temp & 0x0f);
sct = 0 + 64 * temp;
//记录额外的回复信息
Record_setPara(paramTable[i].name, temp, 0);
Record_setPara("\"SC_DelayTime\"", sct, 0);
}
}
else
{
setPara_reply_flg = 0xBB; //设备拒绝执行
}
}
else if(paramTable[i].type == 1) //u8
{
//符合范围的放入
if((temp >= (uint8_t)paramTable[i].min) && (temp <= (uint8_t)paramTable[i].max) && (len > 0))
{
//赋值
*(uint8_t*)paramTable[i].data = (uint8_t)temp;
//记录回复信息
Record_setPara(paramTable[i].name, temp, 0);
//额外操作
if(i == Idx_Protocol) //"\"Protocol\""
{
EEPROM_WrMulByte(EE_PROTOCOL,&protocol);
delay_ms(5);
uf_CAN1_Init();//CAN的波特率更新
//SCR_DispProcotol(); //屏幕显示更新
protocol_reply_flg = 1;
protocol_reply_index = setPara_reply_num-1; //在记录回复信息时+1了
if(protocol == 0)
{
//"ProtocolName":null
setPara_reply_sumlen += 12+4+4;
}
else
{
//"ProtocolName":"Sol-Ark"
setPara_reply_sumlen += 12+6+strlen(protocolStrings[protocol-1]);
}
}
}
else
{
setPara_reply_flg = 0xBB; //设备拒绝执行
}
}
else if(paramTable[i].type == 2) //u16
{
//符合范围的放入
if((temp >= (uint16_t)paramTable[i].min) && (temp <= (uint16_t)paramTable[i].max) && (len > 0))
{
//赋值
*(uint16_t*)paramTable[i].data = temp;
//记录回复信息
Record_setPara(paramTable[i].name, temp, 0);
//额外操作
if(i == Idx_CYC) //"\"CYC\""
{
cumuliCapClear_flag = 1; //保存时清空累积容量
}
}
else
{
setPara_reply_flg = 0xBB; //设备拒绝执行
}
}
else if(paramTable[i].type == 3) //i8
{
//符合范围的放入
if((temp_T >= paramTable[i].min) && (temp_T <= paramTable[i].max) && (len > 0))
{
//记录回复信息
if(temp_T >= 0)
{
//赋值
*(int8_t*)paramTable[i].data = (int8_t)temp_T;
//记录回复信息
Record_setPara(paramTable[i].name, temp_T, 0); //正
}
else
{
//赋值
*(int8_t*)paramTable[i].data = (int8_t)temp_T;
//记录回复信息
Record_setPara(paramTable[i].name, -temp_T, 1); //负
}
}
else
{
setPara_reply_flg = 0xBB; //设备拒绝执行
}
}
//除了个别参数外,都要执行写Flash更新
if((i >= Idx_WrFlash) && (setPara_reply_flg < 0xAA))
{
FlashStore_Flag = 1;
}
}
}
if(setPara_reply_num > 0)
{
setPara_reply_flg = 1; //正常回复
setPara_reply_sumlen -= 1; //最后不是逗号,长度去掉
}
else if(setPara_reply_flg != 0xBB) //无任何符合的值&不是因为参数不符合范围
{
setPara_reply_flg = 0xAA; //设备无所有属性
}
//某个参数更新,要同步更新Flash
if(FlashStore_Flag != 0)
{
//计算CRC校验值
static uint8_t temp[AFE_MCU_LEN];
memcpy(temp, &bmsMem.ee_sconf1, AFE_MCU_LEN);
bmsMem.ee_tr = CRC8_Cal(&temp[0],25);
bmsMem.mcu_crc = CRC8_Cal(&temp[26], 13);
//bmsMem中数据更新到FLASH A区和B区和AFE EEPORM
if((MEMORY_UpdateFlash(FLASH_DATA_A_BASE) == 0) && (MEMORY_UpdateFlash(FLASH_DATA_B_BASE) == 0))
{
staPack.bits.flashUpdate= 0;
if(MEMORY_UpdateAFE() ==0) //更新AFE的EEPROM
{
staPack.bits.eepromUpdate = 0;
}
else
{
staPack.bits.eepromUpdate = 1;
}
}
else
{
staPack.bits.flashUpdate = 1;
}
bmsMem.packStatus = staPack.byte;
}
}
else
{
setPara_reply_flg = 0xBB; //设备拒绝执行
}
}
else //无request_id
{
setPara_reply_flg = 0xBB; //设备拒绝执行
}
}
//用于填充读[属性]的数组
//pm: 0表示正数,1表示负数
void Record_getPara(const char* name, uint16_t data, uint8_t pm)
{
//if(getPara_reply_num >= GETPARA_SUM) return;
getPara_reply_name[getPara_reply_num] = name; //名称
getPara_reply_temp[getPara_reply_num] = data; //数值
getPara_reply_pm[getPara_reply_num] = pm; //正负
getPara_reply_num++;
getPara_reply_sumlen += strlen(name)+2+uint_str_len(data); //名称长度(包括"")+数值长度+外面固定长度
if(pm == 1)
{
getPara_reply_sumlen += 1; //负号
}
}
//下发读[属性]报文的处理
//{"request_id":"123124sdf","params":{"Protocol"}}
void LTE_4G_SUB_GETPARA(void)
{
if(strstr(LTE_Rx_Buf, "\"request_id\"")) //有ID格式
{
//将ID内容拓印到数组
//{"request_id":"123124sdf","params":{"POV_Vol","COV_Vol"}}
ID_len = GetID(LTE_Rx_Buf, ID_str);
if(ID_len == 0)
{
getPara_reply_flg = 0xBB; //设备拒绝执行
return;
}
if(strstr(LTE_Rx_Buf, "\"params\":[") && strstr(LTE_Rx_Buf, "]}"))
{
uint8_t i;
uint16_t len = 0; //字符串长度
uint16_t temp; //无符号过程量
int16_t temp_T; //有符号过程量
//获取原始数据
const char* paramsKey = "\"params\":[";
char* paramsStart = strstr(LTE_Rx_Buf, paramsKey); paramsStart += strlen(paramsKey);
char* paramsEnd = strchr(paramsStart, ']');
len = paramsEnd - paramsStart;
if(len > sizeof(params_str)-1) //防溢出
{
len = sizeof(params_str)-1;
}
strncpy(params_str, paramsStart, len);
params_str[len] = '\0';
//识别存在的参数,并给予对应值
getPara_reply_num = 0;
getPara_reply_sumlen = 0;
//遍历参数表
for(i=0; i<sizeof(paramTable)/sizeof(ParamInfo); i++)
{
if(strstr(params_str, paramTable[i].name)) //存在对应名称
{
if(paramTable[i].type == 0) //需单独配置
{
if(i == Idx_COV_Vol)
{
//赋值
temp = cell_OV;
//记录回复信息
Record_getPara(paramTable[i].name, temp, 0);
}
else if(i == Idx_COVR_Vol)
{
//赋值
temp = cell_OVR;
//记录回复信息
Record_getPara(paramTable[i].name, temp, 0);
}
else if(i == Idx_CUV_Vol)
{
//赋值
temp = cell_UV;
//记录回复信息
Record_getPara(paramTable[i].name, temp, 0);
}
else if(i == Idx_CUVR_Vol)
{
//赋值
temp = cell_UVR;
//记录回复信息
Record_getPara(paramTable[i].name, temp, 0);
}
else if(i == Idx_SC_Cur)
{
//赋值
uint16_t scv,scc;
temp = (bmsMem.ee_scv_sct & 0xF0)>>4;
if(temp == 0x0B)
{
scv = 400;
}
else
{
scv = 50 + 30 * temp;
}
scc = scv * AFE_Multiple;
//记录回复信息
Record_getPara(paramTable[i].name, temp, 0);
Record_getPara("\"SC_Current\"", scc, 0);
}
else if(i == Idx_SC_Delay)
{
//赋值
uint16_t sct;
temp = bmsMem.ee_scv_sct & 0x0F;
sct = 0 + 64 * temp;
//记录回复信息
Record_getPara(paramTable[i].name, temp, 0);
Record_getPara("\"SC_DelayTime\"", sct, 0);
}
}
else if(paramTable[i].type == 1) //u8
{
//赋值
if(i == Idx_SOC)
{
temp = bmsMem.soc;
}
else
{
temp = *(uint8_t*)paramTable[i].data;
}
//记录回复信息
Record_getPara(paramTable[i].name, temp, 0);
//额外回复
if(i == Idx_Protocol)
{
protocol_reply_flg = 1;
protocol_reply_index = getPara_reply_num-1; //在记录回复信息时+1了
if(protocol == 0)
{
//"ProtocolName":null
getPara_reply_sumlen += 12+4+4;
}
else
{
//"ProtocolName":"Sol-Ark"
getPara_reply_sumlen += 12+6+strlen(protocolStrings[protocol-1]);
}
}
}
else if(paramTable[i].type == 2) //u16
{
//赋值
if(i == Idx_Capacity)
{
temp = fcc_Ah;
}
else
{
temp = *(uint16_t*)paramTable[i].data;
}
//记录回复信息
Record_getPara(paramTable[i].name, temp, 0);
}
else if(paramTable[i].type == 3) //i8
{
//赋值
temp_T = *(int8_t*)paramTable[i].data;
//记录回复信息
if(temp_T >= 0)
{
Record_getPara(paramTable[i].name, temp_T, 0); //正
}
else
{
Record_getPara(paramTable[i].name, -temp_T, 1); //负
}
}
}
}
if(getPara_reply_num > 0)
{
getPara_reply_flg = 1; //回复
getPara_reply_sumlen -= 1; //最后不是逗号,长度去掉
}
else //无任何符合的值
{
getPara_reply_flg = 0xAA; //设备无所有属性
}
}
else
{
getPara_reply_flg = 0xBB; //设备拒绝执行
}
}
else //无request_id
{
getPara_reply_flg = 0xBB; //设备拒绝执行
}
}
//接收数据,在串口中断执行
void LTE_4G_IT_Receive(void)
{
//接收数据
uint8_t received_byte = USART_ReceiveData(LTE_UART);
//防止数组溢出
if(LTE_Rx_BufIndex < LTE_RX_BUF_LEN - 1)
{
LTE_Rx_Buf[LTE_Rx_BufIndex] = received_byte;
LTE_Rx_BufIndex++;
}
else
{
LTE_4G_ClearBuf();
}
//更新计时
if(LTE_OTA_Flag == 0)
{
LTE_Moni_Count = LTE_MON_CNT;
}
else
{
LTE_Moni_Count = LTE_OTA_CNT;
}
}
//处理数据,接收报文识别后执行
//波特率115200
void LTE_4G_IT_Update(void)
{
/*收到OK或>或ERROR,认为回复完整,开始分析*/
if((LTE_Rx_BufIndex >= 2) && (strstr(LTE_Rx_Buf, "OK")))
{
char tempStr[2]; //用于分析回复内容
uint8_t len = 0;
uint16_t temp;
if(LTE_Onlineflag == 0) LTE_ErrCnt = 0;
else MQTT_ErrCnt = 0;
/** 重启状态指令的回复 **/
//(重启4G模块,不考虑回复OK)
//(重启MQTT,不考虑回复OK)
//重新联网,尝试解决通信故障
if(CFUN_flag == 1)
{
//0.
if(strstr(LTE_Rx_Buf, "AT+CFUN=0"))
{
CFUN_flag = 1;
CFUN_step = 1; //准备执行下一步
LTE_Networkflag = 0; //已关闭联网
}
//1.
else if(strstr(LTE_Rx_Buf, "AT+CFUN=1"))
{
CFUN_flag = 1;
CFUN_step = 2; //重启网络完成,执行下一步:等待3s后,获取当前网络状态
LTE_Networkflag = 1; //已打开联网
CFUN_count++;
if(CFUN_count > 5)
{
CFUN_count = 0;
CFUN_flag = 0xAA; //重新联网5次失败,跳转发CGREG,直到重启(因为本来下一步也是CGREG,所以放在这里计数也可以)
CFUN_step = 0;
}
}
//2.3.4.等待
//5.
else if(strstr(LTE_Rx_Buf, "AT+CGREG?"))
{
CFUN_flag = 0;
CFUN_step = 0; //该次重联网流程完成
//+CGREG: 0,1\r\n\r\nOK
len = GetStr("+CGREG: 0,", 0x0d, 0x0d, LTE_Rx_Buf, tempStr);
sscanf(tempStr, "%hu", &temp);
if(len > 0)
{
//获取联网状态
LTE_register = temp;
//显示在屏幕
sprintf(LTEStatus_str + strlen(LTEStatus_str), " = %d", LTE_register);
if(temp == 2) //正在搜索网络,需要等几秒再询问
{
searching_cnt++;
if(searching_cnt <= 10)
{
CFUN_flag = 1;
CFUN_step = 2; //等待3s后,再次获取当前网络状态
}
else
{
searching_cnt = 0;
LTE_Onlineflag = 0xAA; //联网错误 //若持续30s还没好,进入原有判断流程
}
}
else
{
searching_cnt = 0;
if((temp == 1) || (temp == 5))
{
LTE_Onlineflag = 1; //联网正常
if(LTE_rssi == 99) //此前rssi异常,正常后需重新获取rssi
{
CSQ_flag = 1;
LTE_rssi = 0;
}
MQTT_START_flag = 0;
MQTT_START_step = 0; //保证后续联网操作是从第1步走
CFUN_count = 0; //计数清零
}
else //包括CGREG:0,11
{
LTE_Onlineflag = 0xAA; //联网错误
}
}
}
else
{
LTE_Onlineflag = 0xAA; //联网错误
}
}
}
/** 连接云平台之前指令的回复 **/
//查询网络注册状态
else if(CGREG_flag == 1)
{
if(strstr(LTE_Rx_Buf, "AT+CGREG?"))
{
//+CGREG: 0,1\r\n\r\nOK
len = GetStr("+CGREG: 0,", 0x0d, 0x0d, LTE_Rx_Buf, tempStr);
sscanf(tempStr, "%hu", &temp);
if(len > 0)
{
//获取联网状态
LTE_register = temp;
//显示在屏幕
sprintf(LTEStatus_str + strlen(LTEStatus_str), " = %d", LTE_register);
if((temp == 1) || (temp == 5))
{
LTE_Onlineflag = 1; //联网正常
if(LTE_rssi == 99) //此前rssi异常,正常后需重新获取rssi
{
CSQ_flag = 1;
LTE_rssi = 0;
}
MQTT_START_flag = 0;
MQTT_START_step = 0; //保证后续联网操作是从第1步走
CGREG_flag = 0; //完成
CGREG_count = 0; //计数清零
CFUN_flag = 0; //(若是在CFUN=0xAA后才恢复,也需要清零)
CFUN_count = 0; //计数清零
}
else //包括CGREG:0,11
{
LTE_Onlineflag = 0xAA; //联网错误
CGREG_count++;
if(CGREG_count > RST_timeEnd) //4min
{
CGREG_flag = 0;
CGREG_count = 0;
CRESET_flag = 1; //重启
CRESET_step = 0;
}
}
}
else
{
LTE_Onlineflag = 0xAA; //联网错误
CGREG_count++;
if(CGREG_count > RST_timeEnd) //8min
{
CGREG_flag = 0;
CGREG_count = 0;
CRESET_flag = 1; //重启
CRESET_step = 0;
}
}
}
else //测试发现在这里执行但有时不回复,这里也加上
{
LTE_Onlineflag = 0xAA; //联网错误
CGREG_count++;
if(CGREG_count > RST_timeEnd) //8min
{
CGREG_flag = 0;
CGREG_count = 0;
CRESET_flag = 1; //重启
CRESET_step = 0;
}
}
}
//查询信号质量
else if(CSQ_flag == 1)
{
if(strstr(LTE_Rx_Buf, "AT+CSQ"))
{
// +CSQ: 23,99\r\n\r\nOK
len = GetStr("+CSQ: ", ',', ',', LTE_Rx_Buf, tempStr);
sscanf(tempStr, "%hu", &temp);
if(len > 0)
{
//获得信号强度
LTE_rssi = temp;
//显示在屏幕
sprintf(LTEStatus_str + strlen(LTEStatus_str), " = %d", LTE_rssi);
}
}
}
//连接MQTT服务器
else if(MQTT_START_flag == 1)
{
//0.
if(strstr(LTE_Rx_Buf, "AT+CMQTTSTART"))
{
if(strstr(LTE_Rx_Buf, "+CMQTTSTART: 1")) //异常
{
MQTT_START_flag = 0; //执行连接标志清零(会在重启MQTT结束后可以再置1)
MQTT_START_step = 0;
MQTT_START_count++;
if(MQTT_START_count <= 5)
{
MQTT_RST_flag = 1; //重启MQTT功能
MQTT_RST_step = 0;
}
else if(MQTT_START_count <= 6)
{
//CGREG_flag = 1; //重启MQTT服务无用,或有可能是未被发现的联网异常,转检查CGREG
LTE_Onlineflag = 0; //重新检查联网情况
CSQ_flag = 1; //重新获取此时的rssi
LTE_rssi = 0;
}
else
{
MQTT_START_count = 0;
CRESET_flag = 1; //联网无异常仍执行到这一步有问题,执行重启
CRESET_step = 0;
}
}
else //"+CMQTTSTART: 0"4G模块有时不会回复这句话(Bug),所以不做判断
{
MQTT_START_flag = 1;
MQTT_START_step = 1; //准备下一步
}
}
//1.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTACCQ"))
{
MQTT_START_flag = 1;
MQTT_START_step = 2; //准备下一步
}
//2.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTCONNECT"))
{
LTE_LINK_flag = 1; //连接服务器成功
MQTT_START_flag = 0;
MQTT_START_step = 0; //完成
CRESET_count = 0; //计数清零
MQTT_RST_count = 0; //计数清零
CICCID_flag = 1; //跳转:获取CICCID
}
}
/** 已连接云平台,正在基础配置指令的回复 **/
//查询CICCID
else if(CICCID_flag == 1)
{
if(strstr(LTE_Rx_Buf, "AT+CICCID") && strstr(LTE_Rx_Buf, "+ICCID:"))
{
uint16_t i,j;
// +ICCID: 89860869102570311585\r\n\r\nOK
for(i=0;i<LTE_Rx_BufIndex-27;i++) //获得关键字符':'
{
if(LTE_Rx_Buf[i] == ':')
{
for(j=0;j<20;j++)
{
ICCID[j] = LTE_Rx_Buf[i+j+2]; //填充ICCID
}
ICCID[20] = '\0'; //填充结尾
break;
}
}
CICCID_flag = 0; //完成
SUBTOPIC_flag = 1; //跳转:订阅主题的开头
SUBTOPIC_step = 0;
}
}
//订阅主题
else if(SUBTOPIC_flag == 1)
{
//1.订阅[校时]的主题
if(SUBTOPIC_step == 1)
{
SUBTOPIC_step = 2; //订阅成功,跳转:订阅[服务]的主题
}
//3.订阅[服务]的主题
else if(SUBTOPIC_step == 3)
{
SUBTOPIC_step = 4; //订阅成功,跳转:订阅写[属性]的主题
}
//5.订阅写[属性]的主题
else if(SUBTOPIC_step == 5)
{
SUBTOPIC_step = 6; //订阅成功,跳转:订阅读[属性]的主题
}
//7.订阅读[属性]的主题
else if(SUBTOPIC_step == 7)
{
SUBTOPIC_step = 8; //订阅成功,跳转:订阅OTA升级信息的主题
}
//9.订阅OTA升级信息的主题
else if(SUBTOPIC_step == 9)
{
SUBTOPIC_flag = 0; //完成
SUBTOPIC_step = 0;
CALITIME_flag = 1; //订阅成功,跳转:请求[校时]
CALITIME_step = 0;
}
}
//请求[校时]
else if(CALITIME_flag == 1)
{
//1.主题内容
if(CALITIME_step == 1)
{
CALITIME_step = 2; //主题接收OK,准备下一步
}
//2.执行上报
else if(CALITIME_step == 2)
{
CALITIME_flag = 0; //完成
CALITIME_step = 0;
MQTT_READY_flag = 1; //MQTT连接准备全部完成
MQTT_timed_count = 0;
if((LTE_OTA_fineFlag == 0xAA) || (LTE_OTA_fineFlag == 0xBB))
{
LTE_status = ota_fine_pub;
LTE_step = ota_fine_pub_step1; //跳转:发送OTA升级完成
}
else
{
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
}
}
}
/** 已连接云平台且配置完成,正常通信指令的回复 **/
else if(MQTT_READY_flag == 1)
{
//0.询问LBS数据
if(LTE_status == ask_lbs)
{
//0.
if(strstr(LTE_Rx_Buf, "AT+CLBS=1") && (LTE_step == ask_lbs_step1))
{
LTE_4G_GET_LBS();
LTE_status = ask_rssi;
LTE_step = ask_rssi_step1; //不论是否成功,都继续下一步:检测信号质量
}
}
//1.检查4G信号质量
else if(LTE_status == ask_rssi)
{
//1.检查信号质量
if(strstr(LTE_Rx_Buf, "AT+CSQ") && (LTE_step == ask_rssi_step1))
{
len = GetStr("+CSQ: ", ',', ',', LTE_Rx_Buf, tempStr);
sscanf(tempStr, "%hu", &temp);
if(len > 0)
{
//获取信号质量
LTE_rssi = temp;
//显示在屏幕
sprintf(LTEStatus_str + strlen(LTEStatus_str), " = %d", LTE_rssi);
if((LTE_rssi > 13) && (LTE_rssi < 99)) //14~98
{
rssiLow_count = 0;
LTE_status = send_timed;
LTE_step = send_timed_step1; //完成,跳转:定时上报[属性]
}
else
{
rssiLow_count++;
if(rssiLow_count <= RSSI_timeEnd) //4min内一直质量差,保持询问CSQ和CGREG,等待信号质量变好
{
LTE_status = ask_rssi;
LTE_step = ask_rssi_step2; //信号弱,跳转询问CGREG
}
else
{
rssiLow_count = 0;
CRESET_flag = 1; //重启,再次连接MQTT
CRESET_step = 0;
}
}
}
}
//2.检查联网情况
else if(strstr(LTE_Rx_Buf, "AT+CGREG?") && (LTE_step == ask_rssi_step2))
{
//+CGREG: 0,1\r\n\r\nOK
len = GetStr("+CGREG: 0,", 0x0d, 0x0d, LTE_Rx_Buf, tempStr);
sscanf(tempStr, "%hu", &temp);
if(len > 0)
{
//获取联网状态
LTE_register = temp;
//显示在屏幕
sprintf(LTEStatus_str + strlen(LTEStatus_str), " = %d", LTE_register);
if((temp == 1) || (temp == 5))
{
LTE_status = ask_rssi;
LTE_step = ask_rssi_step1; //联网正常,跳转继续询问CSQ
}
else //包括CGREG:0,11
{
LTE_Onlineflag = 0xAA; //联网错误
LTE_LINK_flag = 0; //清零连接状态,等待重联网
MQTT_START_flag = 0;
MQTT_READY_flag = 0;
MQTT_timed_count = 0;
}
}
else
{
LTE_Onlineflag = 0xAA; //联网错误
LTE_LINK_flag = 0; //清零连接状态,等待重联网
MQTT_START_flag = 0;
MQTT_READY_flag = 0;
MQTT_timed_count = 0;
}
}
}
//2.定时上报[属性]
else if(LTE_status == send_timed)
{
//2.
if(LTE_step == send_timed_step2)
{
LTE_status = send_timed;
LTE_step = send_timed_step3; //主题接收OK,准备下一步
}
//4.
else if(LTE_step == send_timed_step4)
{
LTE_status = send_timed;
LTE_step = send_timed_step5; //内容接收OK,准备下一步
}
//5.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPUB") && (LTE_step == send_timed_step5))
{
property_pub_count = 0; //完成定时上报属性,定时检查计数清零
incident_pub_count = 0; //完成定时上报属性,对上报事件个数的限制清零
incident_DataFlg = 0; //完成定时上报属性,下次事件可以记录实时数据
if(pre_sleep_flag != 4)
{
LTE_status = wait_timed;
LTE_step = wait_timed_step1; //上报[属性]完成,跳转:等待定时
}
else
{
pre_sleep_flag = 5; //退出MQTT后,执行休眠
LTE_LINK_flag = 0;
MQTT_RST_flag = 1;
MQTT_RST_step = 0;
MQTT_READY_flag = 0;
MQTT_timed_count = 0;
}
}
}
//3.等待30s定时(无)
//4.检查是否正常订阅主题,有缺就补
else if(LTE_status == check_sub)
{
//0.检查订阅
if(strstr(LTE_Rx_Buf, "AT+CMQTTSUB?") && (LTE_step == check_sub_step01))
{
check_sub_count = 0; //检查订阅的超时计数清零
if(strstr(LTE_Rx_Buf, "/ext/ntp") == 0) //缺少了[校时]主题
{
LTE_status = check_sub;
LTE_step = check_sub_step11; //无订阅,跳转:再次订阅[校时]的主题
}
else if(strstr(LTE_Rx_Buf, "/thing/service/invoke") == 0) //缺少了[服务]主题
{
LTE_status = check_sub;
LTE_step = check_sub_step21; //无订阅,跳转:再次订阅[服务]的主题
}
else if(strstr(LTE_Rx_Buf, "/thing/property/set") == 0) //缺少了写[属性]主题
{
LTE_status = check_sub;
LTE_step = check_sub_step31; //无订阅,跳转:再次订阅写[属性]的主题
}
else if(strstr(LTE_Rx_Buf, "/thing/property/get") == 0) //缺少了读[属性]主题
{
LTE_status = check_sub;
LTE_step = check_sub_step41; //无订阅,跳转:再次订阅写[属性]的主题
}
else if(strstr(LTE_Rx_Buf, "/ota/device/upgrade/101") == 0) //缺少了OTA升级信息主题
{
LTE_status = check_sub;
LTE_step = check_sub_step51; //无订阅,跳转:再次订阅写[属性]的主题
}
//都有正常订阅
else
{
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
}
}
//1.订阅[校时]的主题
else if(LTE_step == check_sub_step11)
{
check_sub_count = 0; //检查订阅的超时计数清零
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
MQTT_timed_count += 2;
}
//2.订阅[服务]的主题
else if(LTE_step == check_sub_step21)
{
check_sub_count = 0; //检查订阅的超时计数清零
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
MQTT_timed_count += 2;
}
//3.订阅写[属性]的主题
else if(LTE_step == check_sub_step31)
{
check_sub_count = 0; //检查订阅的超时计数清零
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
MQTT_timed_count += 2;
}
//4.订阅读[属性]的主题
else if(LTE_step == check_sub_step41)
{
check_sub_count = 0; //检查订阅的超时计数清零
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
MQTT_timed_count += 2;
}
//5.订阅OTA升级信息的主题
else if(LTE_step == check_sub_step51)
{
check_sub_count = 0; //检查订阅的超时计数清零
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
MQTT_timed_count += 2;
}
}
//0xA0.若存在事件,立即上报所有[事件]
else if(LTE_status == event_pub)
{
//2.
if(LTE_step == event_pub_step2)
{
LTE_status = event_pub;
LTE_step = event_pub_step3; //主题接收OK,准备下一步
}
//4.
else if(LTE_step == event_pub_step4)
{
LTE_status = event_pub;
LTE_step = event_pub_step5; //内容接收OK,准备下一步
}
//5.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPUB") && (LTE_step == event_pub_step5))
{
incident_reply_count = 0;
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
incident_pub_count++; //记录上报数量,一次性不能超过5个
incident_flag = 0; //当前事件上报完成,之后可检测下次[事件]
if(pre_sleep_flag == 3)
{
pre_sleep_flag = 4; //启动休眠事件,上报完成,然后执行上报休眠前属性
}
else if(pre_sleep_flag == 0xAA)
{
pre_sleep_flag = 0; //退出休眠事件,上报完成
}
}
}
//0xA1.立即回复写[服务]
else if(LTE_status == srvc_pub)
{
//2.
if(LTE_step == srvc_pub_step2)
{
LTE_status = srvc_pub;
LTE_step = srvc_pub_step3; //主题接收OK,准备下一步
}
//4.
else if(LTE_step == srvc_pub_step4)
{
LTE_status = srvc_pub;
LTE_step = srvc_pub_step5; //内容接收OK,准备下一步
}
//5.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPUB") && (LTE_step == srvc_pub_step5))
{
putSrvc_reply_count = 0;
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
putSrvc_reply_flg = 0;
putSrvc_reply_count = 0;
}
}
//0xA2.立即回复写[属性]
else if(LTE_status == setPara_pub)
{
//2.
if(LTE_step == setPara_pub_step2)
{
LTE_status = setPara_pub;
LTE_step = setPara_pub_step3; //主题接收OK,准备下一步
}
//4.
else if(LTE_step == setPara_pub_step4)
{
LTE_status = setPara_pub;
LTE_step = setPara_pub_step5; //内容接收OK,准备下一步
}
//5.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPUB") && (LTE_step == setPara_pub_step5))
{
setPara_reply_count = 0;
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
setPara_reply_flg = 0;
setPara_reply_count = 0;
}
}
//0xA3.立即回复读[属性]
else if(LTE_status == getPara_pub)
{
//2.
if(LTE_step == getPara_pub_step2)
{
LTE_status = getPara_pub;
LTE_step = getPara_pub_step3; //主题接收OK,准备下一步
}
//4.
else if(LTE_step == getPara_pub_step4)
{
LTE_status = getPara_pub;
LTE_step = getPara_pub_step5; //内容接收OK,准备下一步
}
//5.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPUB") && (LTE_step == getPara_pub_step5))
{
getPara_reply_count = 0;
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
getPara_reply_flg = 0;
getPara_reply_count = 0;
}
}
//0xAA.转存完成,设备上线后主动上报OTA升级完成
else if(LTE_status == ota_fine_pub)
{
//2.
if(LTE_step == ota_fine_pub_step2)
{
LTE_status = ota_fine_pub;
LTE_step = ota_fine_pub_step3; //主题接收OK,准备下一步
}
//4.
else if(LTE_step == ota_fine_pub_step4)
{
LTE_status = ota_fine_pub;
LTE_step = ota_fine_pub_step5; //内容接收OK,准备下一步
}
//5.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPUB") && (LTE_step == ota_fine_pub_step5))
{
otaFine_reply_count = 0;
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
//更新EE_OTA完成标志,为0
LTE_OTA_fineFlag = 0;
OTAfine_WrFlg = 0xAA;
}
}
}
}
else if((LTE_Rx_BufIndex >= 1) && (strstr(LTE_Rx_Buf, ">")))
{
if(LTE_Onlineflag == 0) LTE_ErrCnt = 0;
else MQTT_ErrCnt = 0;
/** 已连接云平台,正在基础配置指令的回复 **/
//订阅主题
if(SUBTOPIC_flag == 1)
{
//0.订阅[校时]的主题
if(strstr(LTE_Rx_Buf, "AT+CMQTTSUB=0,31,1") && (SUBTOPIC_step == 0))
{
SUBTOPIC_step = 1; //准备下一步
}
//2.订阅[服务]的主题
else if(strstr(LTE_Rx_Buf, "AT+CMQTTSUB=0,39,1") && (SUBTOPIC_step == 2))
{
SUBTOPIC_step = 3; //准备下一步
}
//4.订阅写[属性]的主题
else if(strstr(LTE_Rx_Buf, "AT+CMQTTSUB=0,37,1") && (SUBTOPIC_step == 4))
{
SUBTOPIC_step = 5; //准备下一步
}
//6.订阅读[属性]的主题
else if(strstr(LTE_Rx_Buf, "AT+CMQTTSUB=0,37,1") && (SUBTOPIC_step == 6))
{
SUBTOPIC_step = 7; //准备下一步
}
//8.订阅OTA升级信息的主题
else if(strstr(LTE_Rx_Buf, "AT+CMQTTSUB=0,33,1") && (SUBTOPIC_step == 8))
{
SUBTOPIC_step = 9; //准备下一步
}
}
//请求[校时]
else if(CALITIME_flag == 1)
{
//0.主题长度
if(strstr(LTE_Rx_Buf, "AT+CMQTTTOPIC") && (CALITIME_step == 0))
{
CALITIME_step = 1; //准备下一步
}
}
/** 已连接云平台且配置完成,正常通信指令的回复 **/
else if(MQTT_READY_flag == 1)
{
//0.询问LBS数据(无)
//1.定时上报[属性]
if(LTE_status == send_timed)
{
//1.
if(strstr(LTE_Rx_Buf, "AT+CMQTTTOPIC") && (LTE_step == send_timed_step1))
{
LTE_status = send_timed;
LTE_step = send_timed_step2; //准备下一步
}
//3.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPAYLOAD") && (LTE_step == send_timed_step3))
{
LTE_status = send_timed;
LTE_step = send_timed_step4; //准备下一步
}
}
//3.等待30s定时(无)
//4.检查是否正常订阅主题,有缺就补
else if(LTE_status == check_sub)
{
//1.补订阅[校时]的主题
if(strstr(LTE_Rx_Buf, "AT+CMQTTSUB=0,31,1") && (LTE_step == check_sub_step11))
{
check_sub_count = 0; //检查订阅的超时计数清零
LTE_step = check_sub_step12; //准备下一步
}
//2.补订阅[服务]的主题
else if(strstr(LTE_Rx_Buf, "AT+CMQTTSUB=0,39,1") && (LTE_step == check_sub_step21))
{
check_sub_count = 0; //检查订阅的超时计数清零
LTE_step = check_sub_step22; //准备下一步
}
//3.补订阅写[属性]的主题
else if(strstr(LTE_Rx_Buf, "AT+CMQTTSUB=0,37,1") && (LTE_step == check_sub_step31))
{
check_sub_count = 0; //检查订阅的超时计数清零
LTE_step = check_sub_step32; //准备下一步
}
//4.补订阅读[属性]的主题
else if(strstr(LTE_Rx_Buf, "AT+CMQTTSUB=0,37,1") && (LTE_step == check_sub_step41))
{
check_sub_count = 0; //检查订阅的超时计数清零
LTE_step = check_sub_step42; //准备下一步
}
//5.补订阅OTA升级信息的主题
else if(strstr(LTE_Rx_Buf, "AT+CMQTTSUB=0,33,1") && (LTE_step == check_sub_step51))
{
check_sub_count = 0; //检查订阅的超时计数清零
LTE_step = check_sub_step52; //准备下一步
}
}
//0xA0.若存在事件,立即上报所有[事件]
else if(LTE_status == event_pub)
{
//1.
if(strstr(LTE_Rx_Buf, "AT+CMQTTTOPIC") && (LTE_step == event_pub_step1))
{
LTE_status = event_pub;
LTE_step = event_pub_step2; //准备下一步
}
//3.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPAYLOAD") && (LTE_step == event_pub_step3))
{
LTE_status = event_pub;
LTE_step = event_pub_step4; //准备下一步
}
}
//0xA1.立即回复写[服务]
else if(LTE_status == srvc_pub)
{
//1.
if(strstr(LTE_Rx_Buf, "AT+CMQTTTOPIC") && (LTE_step == srvc_pub_step1))
{
LTE_status = srvc_pub;
LTE_step = srvc_pub_step2; //准备下一步
}
//3.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPAYLOAD") && (LTE_step == srvc_pub_step3))
{
LTE_status = srvc_pub;
LTE_step = srvc_pub_step4; //准备下一步
}
}
//0xA2.立即回复写[属性]
else if(LTE_status == setPara_pub)
{
//1.
if(strstr(LTE_Rx_Buf, "AT+CMQTTTOPIC") && (LTE_step == setPara_pub_step1))
{
LTE_status = setPara_pub;
LTE_step = setPara_pub_step2; //准备下一步
}
//3.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPAYLOAD") && (LTE_step == setPara_pub_step3))
{
LTE_status = setPara_pub;
LTE_step = setPara_pub_step4; //准备下一步
}
}
//0xA3.立即回复读[属性]
else if(LTE_status == getPara_pub)
{
//1.
if(strstr(LTE_Rx_Buf, "AT+CMQTTTOPIC") && (LTE_step == getPara_pub_step1))
{
LTE_status = getPara_pub;
LTE_step = getPara_pub_step2; //准备下一步
}
//3.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPAYLOAD") && (LTE_step == getPara_pub_step3))
{
LTE_status = getPara_pub;
LTE_step = getPara_pub_step4; //准备下一步
}
}
//0xAA.转存完成,设备上线后主动上报OTA升级完成
else if(LTE_status == ota_fine_pub)
{
//1.
if(strstr(LTE_Rx_Buf, "AT+CMQTTTOPIC") && (LTE_step == ota_fine_pub_step1))
{
LTE_status = ota_fine_pub;
LTE_step = ota_fine_pub_step2; //准备下一步
}
//3.
else if(strstr(LTE_Rx_Buf, "AT+CMQTTPAYLOAD") && (LTE_step == ota_fine_pub_step3))
{
LTE_status = ota_fine_pub;
LTE_step = ota_fine_pub_step4; //准备下一步
}
}
}
}
else if((LTE_Rx_BufIndex >= 5) && (strstr(LTE_Rx_Buf, "ERROR")))
{
if((CRESET_flag == 0) && (MQTT_RST_flag == 0) && (strstr(LTE_Rx_Buf, "AT+CMQTTSTOP") == 0)) //不考虑因重启的前置步骤而导致的ERROR
{
LTE_ResendDelay = ResendTime;
if(LTEStatus_flg == 1)
{
strcat(LTEStatus_str, " ERR");
}
if(LTE_Onlineflag == 0) //未联网时
{
LTE_ErrCnt++;
if(LTE_ErrCnt > ERR_timeEnd1) //最大:持续30s,重启4G模块
{
LTE_ErrCnt = 0;
CRESET_flag = 1; //重启
CRESET_step = 0;
}
}
else //已联网时
{
MQTT_ErrCnt++;
if(MQTT_ErrCnt > ERR_timeEnd2) //最大:持续1min,重启4G模块
{
MQTT_ErrCnt = 0;
CRESET_flag = 1; //重启
CRESET_step = 0;
}
else if(((MQTT_ErrCnt > 3) && (MQTT_START_flag == 1)) || ((MQTT_ErrCnt > 15) && (LTE_LINK_flag == 1))) //连接MQTT时出现的ERROR等3次(6s),后续出现的ERROR等15次(30s)
{
MQTT_RST_count++;
if(MQTT_RST_count <= 5)
{
MQTT_START_flag = 0; //退出连接
MQTT_START_step = 0;
MQTT_RST_flag = 1; //重启MQTT
MQTT_RST_step = 0;
LTE_LINK_flag = 0; //已连接标志清零
MQTT_START_flag = 0;
MQTT_READY_flag = 0;
MQTT_timed_count = 0;
LTE_OTA_Flag = 0; //OTA升级标志清零
}
else
{
MQTT_RST_count = 0;
//CGREG_flag = 1; //重启MQTT服务无用,或有可能是未被发现的联网异常,转检查CGREG
LTE_Onlineflag = 0; //重新检查联网情况
CSQ_flag = 1; //重新获取此时的rssi
LTE_rssi = 0;
}
}
else if(LTE_status == ask_rssi)
{
CSQ_ErrCnt++;
if(CSQ_ErrCnt > 15) //对应30S左右
{
CSQ_ErrCnt = 0;
CRESET_flag = 1; //重启
CRESET_step = 0;
}
}
}
}
}
/*特殊回复:状态*/
//正常初始化
if((LTE_Rx_BufIndex >= 10) && strstr(LTE_Rx_Buf, "ATREADY: 1"))
{
LTE_Onflag = 1; //4G模块已开机
}
//SIM卡
if((LTE_Rx_BufIndex >= 12) && strstr(LTE_Rx_Buf, "+CPIN: READY"))
{
LTE_SIMflag = 1; //SIM卡正常
}
if((LTE_Rx_BufIndex >= 18) && strstr(LTE_Rx_Buf, "+CPIN: SIM REMOVED"))
{
LTE_SIMflag = 0; //未检测到SIM卡
}
if((LTE_Rx_BufIndex >= 23) && strstr(LTE_Rx_Buf, "+SIMCARD: NOT AVAILABLE"))
{
LTE_SIMflag = 0; //未检测到SIM卡
}
/*特殊回复:4G模块异常*/
if((LTE_Rx_BufIndex >= 4) && strstr(LTE_Rx_Buf, "BUSY"))
{
if(LTEStatus_flg == 1)
{
strcat(LTEStatus_str, " BUSY");
}
LTE_BUSY_cnt++;
if(LTE_BUSY_cnt > 30)
{
LTE_BUSY_cnt = 0;
LTE_PinRST_Flag = 1; //通过引脚重启4G模块
}
}
else
{
LTE_BUSY_cnt = 0;
}
}
//根据当前已知信息,选择接下来要执行的指令
//可能同时赋值多个命令,但只会一个个执行
void LTE_4G_IQ_Update(void)
{
/** 通信云平台之前的状态改动 **/
if(MQTT_READY_flag == 0)
{
if(LTE_Onlineflag == 0xAA) //信号异常或CGREG回复0,0 -> 都是驻网失败,执行5次找网,仍然失败就执行重启
{
if(CFUN_flag == 0) //尝试断网重连,手动找网
{
CFUN_flag = 1;
CFUN_step = 0;
}
else if(CFUN_flag == 0xAA) //5次失败,保持发CGREG指令,直到执行重启
{
CGREG_flag = 1;
}
return;
}
//1.采集信号质量(这里特指成功通信云平台前的)
if(LTE_rssi <= 13) //未询问或信号质量差 -> 持续询问信号质量直到信号变好,或者持续4min后执行重启
{
rssiLow_count++;
if(rssiLow_count <= RSSI13_timeEnd) //4min
{
CSQ_flag = 1;
}
else
{
rssiLow_count = 0;
CSQ_flag = 0;
CRESET_flag = 1; //重启
CRESET_step = 0;
}
}
else if(LTE_rssi == 99)
{
rssi99_count++;
if(rssi99_count <= RSSI99_timeEnd) //10s
{
CSQ_flag = 1;
}
else
{
rssi99_count = 0;
LTE_Onlineflag = 0xAA; //尝试重新联网
}
}
else //已获取到好的信号质量(14~98) -> 下一步检查联网状态 -> 联网成功且存在SN号时,尝试连到MQTT服务器
{
rssiLow_count = 0; //计数清零
rssi99_count = 0; //计数清零
CSQ_flag = 0;
//在通信质量好的前提下,
//2.询问是否联网
if(LTE_Onlineflag == 0) //此前不知是否正常联网 -> 询问联网状态
{
CGREG_flag = 1;
}
//3.网络正常,进行MQTT配置
else if(LTE_Onlineflag == 1) //通信正常 -> 继续
{
if((LTE_LINK_flag == 0) && (MQTT_RST_flag == 0)) //连接成功后&正重启MQTT时就不执行
{
if((BMS_SN[0] != 0) && (BMS_SN[8] != 0)) //SN号头尾都有值说明存在,可以连接MQTT
{
LTE_NoMoni_Flag = 0;
MQTT_START_flag = 1;
//MQTT_START_step = 0;
}
else
{
LTE_NoMoni_Flag = 1;
}
}
}
}
}
/** 通信云平台成功后的状态改动 **/
else
{
/*监控平台下发报文,除了校准时间,其他收到1条并回复后才接收处理下一条*/
if(strstr(LTE_Rx_Buf, "+CMQTTRXSTART") && strstr(LTE_Rx_Buf, "+CMQTTRXEND")) //有头有尾
{
//校准系统时间
if(strstr(LTE_Rx_Buf, "/ext/ntp"))
{
LTE_4G_SUB_NTP();
}
else if((pre_sleep_flag < 2) && (putSrvc_reply_flg == 0) && (setPara_reply_flg == 0) && (getPara_reply_flg == 0))
{
//下发[服务]指令
if(strstr(LTE_Rx_Buf, "/thing/service/invoke"))
{
LTE_4G_SUB_Service();
}
//写[属性]
else if(strstr(LTE_Rx_Buf, "/thing/property/set"))
{
LTE_4G_SUB_SETPARA();
}
//读[属性]
else if(strstr(LTE_Rx_Buf, "/thing/property/get"))
{
LTE_4G_SUB_GETPARA();
}
//OTA升级
else if(strstr(LTE_Rx_Buf, "/ota/device/upgrade/101"))
{
LTE_NoMoni_Flag = 0;
LTE_OTA_Info();
}
}
}
/*正常通信中,持续检查是否有需要立即上报的内容*/
if(LTE_step <= 105) //不在回复时,若需要回复则执行回复
{
//上报启动休眠最优先
if(pre_sleep_flag == 2)
{
pre_sleep_flag = 3;
LTE_status = event_pub;
LTE_step = event_pub_step1; //跳转:立即上报[事件]:启动休眠
MQTT_timed_count = 0; //清零定时上报倒计时
}
//上报退出休眠最优先
else if(pre_sleep_flag == 0xA0)
{
pre_sleep_flag = 0xAA;
LTE_status = event_pub;
LTE_step = event_pub_step1; //跳转:立即上报[事件]:退出休眠
MQTT_timed_count = 0; //清零定时上报倒计时
}
//上报过启动休眠后,确保不会因其他打扰执行剩下的休眠前步骤
else if(pre_sleep_flag < 2)
{
//回复写[服务]>回复写[属性]>回复读[属性]>立即上报[事件]
if(putSrvc_reply_flg != 0)
{
LTE_status = srvc_pub;
LTE_step = srvc_pub_step1; //跳转:立即回复写[服务]操作
MQTT_timed_count = 0; //清零定时上报倒计时
}
else if(setPara_reply_flg != 0)
{
LTE_status = setPara_pub;
LTE_step = setPara_pub_step1; //跳转:立即回复写[属性]操作
MQTT_timed_count = 0; //清零定时上报倒计时
}
else if(getPara_reply_flg != 0)
{
LTE_status = getPara_pub;
LTE_step = getPara_pub_step1; //跳转:立即回复写[属性]操作
MQTT_timed_count = 0; //清零定时上报倒计时
}
}
}
if(LTE_step <= 100) //若不在上报事件和回复时,判断是否要上报事件
{
if(incident_pub_count < INCIDENT_PUB_MAX)
{
Transmit_incident(); //如果有报警/保护/加热提醒,立即准备上报
if(incident_flag != 0)
{
LTE_status = event_pub;
LTE_step = event_pub_step1; //跳转:立即上报[事件]
MQTT_timed_count = 0; //清零定时上报倒计时
}
}
}
/*定时上报[属性]的内容和长度更新*/
if((LTE_status == send_timed) && (LTE_step == send_timed_step3))
{
if(incident_DataFlg == 0) LTE_Record_pubData();
}
}
}
//该函数用于发送报文,1s执行1次
//定时上报数据,每60s一次
void LTE_4G_IQ_Transmit(void)
{
if(LTE_NoMoni_Flag == 0) //不在发送AT指令的状态不算
{
if((LTE_Rx_BufIndex == 0) && (LTE_WaitRxFlg == 1)) //有发送指令却没有回复 //只执行1次
{
LTE_WaitRxFlg = 0;
LTE_WaitRxDelay = WaitRxTime;
//若此时已上线,定时上报倒计时对应-3s //定时上报时序1s,等待共3s
if(MQTT_READY_flag == 1)
{
if(((int)LTE_status >= ask_lbs) && (LTE_status <= send_timed))
{
MQTT_timed_count += WaitRxTime+1;
}
}
return;
}
}
LTE_Rx_BufIndex = 0;
memset(LTE_Rx_Buf, 0, LTE_RX_BUF_LEN); //填入前先清空
memset(LTE_Tx_Buf, 0, LTE_TX_BUF_LEN);
/** 重启状态 **/
//1.重启4G模块
if(CRESET_flag == 1)
{
if(CRESET_count < 5) //AT指令通信重启
{
switch(CRESET_step) //0~2:失败也没关系 3:不考虑收到回复
{
case 0:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "RST 4G step1");
CRESET_step = 1;
LTE_Send("AT+CMQTTDISC=0\r\n"); //断开与服务器的连接
break;
case 1:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "RST 4G step2");
CRESET_step = 2;
LTE_Send("AT+CMQTTREL=0\r\n"); //解除客户关系
break;
case 2:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "RST 4G step3");
CRESET_step = 3;
LTE_Send("AT+CMQTTSTOP\r\n"); //停止MQTT服务
break;
case 3:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "RST 4G step4");
CRESET_flag = 0;
CRESET_step = 0;
CRESET_count++;
LTE_Send("AT+CRESET\r\n");
LTE_WarmDelay = OpenTime; //开机等待
LTE_4G_Init(); //芯片也重启通信相关
break;
default:
CRESET_step = 0; //非法值改为第一步
break;
}
}
else //引脚重启
{
CRESET_count = 0; //之后再经过5次后才会再做一次
LTE_PinRST_Flag = 1; //跳转执行引脚重启
}
}
//2.重启MQTT服务
else if(MQTT_RST_flag == 1)
{
switch(MQTT_RST_step) //0~3,失败也没关系
{
case 0:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "RST MQTT step1");
MQTT_RST_step = 1;
LTE_Send("AT+CMQTTDISC=0\r\n"); //断开与服务器的连接
break;
case 1:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "RST MQTT step2");
MQTT_RST_step = 2;
LTE_Send("AT+CMQTTREL=0\r\n"); //解除客户关系
break;
case 2:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "RST MQTT step3");
MQTT_RST_flag = 0;
MQTT_RST_step = 0;
LTE_Send("AT+CMQTTSTOP\r\n"); //停止MQTT服务
//MQTT停止,休眠前置步骤全部完成,进入休眠
if(pre_sleep_flag == 5)
{
pre_sleep_flag = 0;
LTE_sleep_flag = 1;
}
//尝试再次连接
else if((BMS_SN[0] != 0) && (BMS_SN[8] != 0)) //SN号头尾都有值说明存在,可以连接MQTT
{
MQTT_START_flag = 1;
MQTT_START_step = 0; //重新启动MQTT服务
LTE_LINK_flag = 0; //已连接标志清零
}
break;
default:
MQTT_RST_step = 0; //非法值改为第一步
break;
}
}
//3.重新联网
else if(CFUN_flag == 1)
{
switch(CFUN_step)
{
case 0:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "RST NET step1");
LTE_Send("AT+CFUN=0\r\n");
break;
case 1:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "RST NET step2");
LTE_Send("AT+CFUN=1\r\n");
break;
case 2:
CFUN_step = 3;
break;
case 3:
CFUN_step = 4;
break;
case 4:
CFUN_step = 5;
break;
case 5:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "check network");
LTE_Send("AT+CGREG?\r\n");
break;
default:
CFUN_step = 0; //非法值改为第一步
break;
}
}
/** 连接云平台之前 **/
//查询网络注册状态
else if(CGREG_flag == 1)
{
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "ask network");
LTE_Send("AT+CGREG?\r\n");
}
//查询信号质量
else if(CSQ_flag == 1)
{
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "ask rssi");
LTE_Send("AT+CSQ\r\n");
}
//连接MQTT服务器
else if(MQTT_START_flag == 1)
{
switch(MQTT_START_step)
{
case 0:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "MQTT step1");
LTE_Send("AT+CMQTTSTART\r\n"); //启动MQTT服务
break;
case 1:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "MQTT step2");
//LTE_Send("AT+CMQTTACCQ=0,\"jdg0bcu4RMG!rmt0ubv\"\r\n"); //38字节
LTE_Send("AT+CMQTTACCQ=0,\"%.23s\"\r\n", VersionMem.ClientID); //输入服务器clientId
break;
case 2:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "MQTT step3");
//LTE_Send("AT+CMQTTCONNECT=0,\"tcp://mqtt_zn.ricnsmart.com\",60,1,\"device\",\"E6Mk2Rj6uhFU4Zgy3kWCbghvaDYka8Dz\"\r\n"); //98字节
LTE_Send("AT+CMQTTCONNECT=0,\"%.40s:%hu\",60,1,\"%.40s\",\"%.40s\"\r\n", VersionMem.host, VersionMem.port, VersionMem.UserName, VersionMem.PassWord); //输入host和密码
break;
default:
MQTT_START_step = 0; //非法值改为第一步
break;
}
}
/** 已连接云平台,正在基础配置 **/
//查询CICCID
else if(CICCID_flag == 1)
{
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "ask ICCID");
LTE_Send("AT+CICCID\r\n");
}
//订阅主题
else if(SUBTOPIC_flag == 1)
{
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "sub topic");
if(LTE_UNSUB_Flag == 1)
{
LTE_UNSUB_Flag = 0;
EEPROM_WrMulByte(EE_UNSUB,&LTE_UNSUB_Flag);
delay_ms(5);
LTE_Send("AT+CMQTTUNSUB=0,1\r\n");
return;
}
switch(SUBTOPIC_step)
{
/**订阅[校时]的主题**/
case 0:
LTE_Send("AT+CMQTTSUB=0,31,1\r\n"); //订阅主题长度 "/ext/ntp/101/030200001/response"=31Byte
break;
case 1:
//LTE_Send("/ext/ntp/101/0000000030200001/response");
LTE_Send("/ext/ntp/101/%s/response", BMS_SN); //订阅的主题 (只有这个不用换新行)
break;
/**订阅[服务]的主题**/
case 2:
LTE_Send("AT+CMQTTSUB=0,39,1\r\n"); //下发主题长度 "/sys/101/030200001/thing/"=25Byte "service/invoke"=14Byte
break;
case 3:
//LTE_Send("/sys/101/030200001/thing/service/invoke");
LTE_Send("/sys/101/%s/thing/service/invoke", BMS_SN); //上报的主题 (只有这个不用换新行)
break;
/**订阅写[属性]的主题**/
case 4:
LTE_Send("AT+CMQTTSUB=0,37,1\r\n"); //订阅主题长度 "/sys/101/030200001/thing/"=25Byte "property/set"=12Byte
break;
case 5:
//LTE_Send("/sys/101/030200001/thing/property/set");
LTE_Send("/sys/101/%s/thing/property/set", BMS_SN); //订阅的主题 (只有这个不用换新行)
break;
/**订阅读[属性]的主题**/
case 6:
LTE_Send("AT+CMQTTSUB=0,37,1\r\n"); //订阅主题长度 "/sys/101/030200001/thing/"=25Byte "property/get"=12Byte
break;
case 7:
//LTE_Send("/sys/101/030200001/thing/property/get");
LTE_Send("/sys/101/%s/thing/property/get", BMS_SN); //订阅的主题 (只有这个不用换新行)
break;
/**订阅OTA升级信息的主题**/
case 8:
LTE_Send("AT+CMQTTSUB=0,33,1\r\n"); //订阅主题长度 "/ota/device/upgrade/101/030200001"=33Byte
break;
case 9:
//LTE_Send("/ota/device/upgrade/101/030200001");
LTE_Send("/ota/device/upgrade/101/%s", BMS_SN); //订阅的主题 (只有这个不用换新行)
break;
default:
SUBTOPIC_step = 0; //非法值改为第一步
break;
}
}
//请求[校时]
else if(CALITIME_flag == 1)
{
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "ask systime");
switch(CALITIME_step)
{
case 0:
LTE_Send("AT+CMQTTTOPIC=0,30\r\n"); //上报主题长度 "/ext/ntp/101/030200001/request"=30Byte
break;
case 1:
//LTE_Send("/ext/ntp/101/030200001/request");
LTE_Send("/ext/ntp/101/%s/request", BMS_SN); //上报的主题 (只有这个不用换新行)
break;
case 2:
LTE_Send("AT+CMQTTPUB=0,1,30\r\n"); //至少上报1次+30s内等待服务器回复
break;
default:
CALITIME_step = 0; //非法值改为第一步
break;
}
}
/** 已连接云平台且配置完成,正常通信 **/
else if(MQTT_READY_flag == 1)
{
/*定时上报[属性]*/
//0.询问LBS数据
if(LTE_status == ask_lbs)
{
switch(LTE_step)
{
case ask_lbs_step1:
LTE_Send("AT+CLBS=1\r\n"); //获取4G基站定位信息
break;
default:
LTE_step = ask_lbs_step1; //非法值改为第一步
break;
}
}
//1.询问信号质量
else if(LTE_status == ask_rssi)
{
switch(LTE_step)
{
case ask_rssi_step1:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "check rssi");
LTE_Send("AT+CSQ\r\n"); //询问信号质量
break;
case ask_rssi_step2:
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "check network");
LTE_Send("AT+CGREG?\r\n"); //询问联网情况
break;
default:
LTE_step = ask_rssi_step1; //非法值改为第一步
break;
}
}
//2.定时上报[属性]
else if(LTE_status == send_timed)
{
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "send property");
switch(LTE_step)
{
case send_timed_step1:
LTE_Send("AT+CMQTTTOPIC=0,38\r\n"); //上报主题长度 "/sys/101/030200001/thing/"=25Byte "property/post"=13Byte
break;
case send_timed_step2:
//LTE_Send("/sys/101/030200001/thing/property/post");
LTE_Send("/sys/101/%s/thing/property/post", BMS_SN); //上报的主题 (只有这个不用换新行)
break;
case send_timed_step3:
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", LTEMem_len); //上报内容长度 = 数据长度+固定字符长度+回车
break;
case send_timed_step4:
LTE_Send(LTEMem_Buf); //发送缓存区内容
break;
case send_timed_step5:
LTE_Send("AT+CMQTTPUB=0,1,30\r\n"); //至少上报1次+30s内等待服务器回复
break;
default:
LTE_step = send_timed_step1; //非法值改为第一步
break;
}
}
//3.等待60s定时
else if(LTE_status == wait_timed)
{
switch(LTE_step)
{
case wait_timed_step1:
LTE_NoMoni_Flag = 1;
MQTT_timed_count++; //倒计时
if(MQTT_timed_count > timed_Delay)
{
LTE_NoMoni_Flag = 0;
MQTT_timed_count = 0;
LTE_status = check_sub;
LTE_step = check_sub_step01; //倒计时结束,跳转:检查订阅
}
break;
default:
LTE_step = wait_timed_step1; //非法值改为第一步
break;
}
}
//4.检查是否正常订阅主题
else if(LTE_status == check_sub)
{
check_sub_count++;
if(check_sub_count > 2) //在这里连续2次(6s)无有效响应
{
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //跳转:正常流程第一步
check_sub_count = 0;
}
switch(LTE_step)
{
//查询订阅
case check_sub_step01:
LTE_Send("AT+CMQTTSUB?\r\n"); //查询订阅
break;
//重新订阅[校时]
case check_sub_step11:
LTE_Send("AT+CMQTTSUB=0,31,1\r\n"); //订阅主题长度 "/ext/ntp/101/030200001/response"=31Byte
break;
case check_sub_step12:
//LTE_Send("/ext/ntp/101/030200001/response");
LTE_Send("/ext/ntp/101/%s/response", BMS_SN); //订阅的主题 (只有这个不用换新行)
break;
//重新订阅[服务]
case check_sub_step21:
LTE_Send("AT+CMQTTSUB=0,39,1\r\n"); //下发主题长度 "/sys/101/030200001/thing/"=25Byte "service/invoke"=14Byte
break;
case check_sub_step22:
//LTE_Send("/sys/101/030200001/thing/service/invoke");
LTE_Send("/sys/101/%s/thing/service/invoke", BMS_SN); //上报的主题 (只有这个不用换新行)
break;
//重新订阅写[属性]
case check_sub_step31:
LTE_Send("AT+CMQTTSUB=0,37,1\r\n"); //订阅主题长度 "/sys/101/030200001/thing/property/set"=37Byte
break;
case check_sub_step32:
//LTE_Send("/sys/101/030200001/thing/property/set");
LTE_Send("/sys/101/%s/thing/property/set", BMS_SN); //订阅的主题 (只有这个不用换新行)
break;
//重新订阅读[属性]
case check_sub_step41:
LTE_Send("AT+CMQTTSUB=0,37,1\r\n"); //订阅主题长度 "/sys/101/030200001/thing/property/get"=37Byte
break;
case check_sub_step42:
//LTE_Send("/sys/101/030200001/thing/property/get");
LTE_Send("/sys/101/%s/thing/property/get", BMS_SN); //订阅的主题 (只有这个不用换新行)
break;
//重新订阅OTA升级信息
case check_sub_step51:
LTE_Send("AT+CMQTTSUB=0,33,1\r\n"); //订阅主题长度 "/ota/device/upgrade/101/030200001"=33Byte
break;
case check_sub_step52:
//LTE_Send("/ota/device/upgrade/101/030200001");
LTE_Send("/ota/device/upgrade/101/%s", BMS_SN); //订阅的主题 (只有这个不用换新行)
break;
default:
LTE_step = check_sub_step01; //非法值改为第一步
break;
}
}
/*突发立即上报*/
//0xA0.若存在事件,立即上报所有[事件]
else if(LTE_status == event_pub)
{
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "send event");
incident_reply_count++;
//尝试1次重新回复
if(incident_reply_count == 10)
{
LTE_step = event_pub_step1;
}
//仍然失败退出回复
else if(incident_reply_count >= 20)
{
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //上报[事件]完成,跳转:正常流程第一步
incident_pub_count++; //记录上报数量,一次性不能超过5个
incident_flag = 0; //当前事件上报完成,之后可检测下次[事件]
incident_reply_count = 0;
}
switch(LTE_step) //event_pub_step11~event_pub_step5
{
case event_pub_step1:
LTE_Send("AT+CMQTTTOPIC=0,35\r\n"); //上报主题长度 "/sys/101/030200001/thing/"=25Byte "event/post"=10Byte
break;
case event_pub_step2:
//LTE_Send("/sys/101/030200001/thing/event/post");
LTE_Send("/sys/101/%s/thing/event/post", BMS_SN); //上报的主题 (只有这个不用换新行)
break;
case event_pub_step3:
if(pre_sleep_flag == 3) //启动休眠true HappenTimeLTESleeptrue 8+14
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", uint_str_len(sleepOn_time)+4+10+8+9+2); //上报内容长度 = sleepOn_time长度+true长度4+时间名长度10+休眠名长度8+固定字符长度9+回车2
}
else if(pre_sleep_flag == 0xAA) //退出休眠false
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", uint_str_len(sleepOff_time)+5+10+8+9+2); //上报内容长度 = sleepOff_time长度+false长度5+时间名长度10+休眠名长度8+固定字符长度9+回车2
}
else if(incident_flag == 1) //上报true
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", incident_len+4+10+9+2); //上报内容长度 = [时间长度]+true长度4+时间名长度10+[事件名长度]+固定字符长度9+回车2
}
else if(incident_flag == 2) //上报false
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", incident_len+5+10+9+2); //上报内容长度 = [时间长度]+false长度5+时间名长度10+[事件名长度]+固定字符长度9+回车2
}
break;
case event_pub_step4:
if(pre_sleep_flag == 3) //启动休眠true
{
LTE_Send("{\"HappenTime\":%u,\"LTESleep\":true}\r\n", sleepOn_time);
}
else if(pre_sleep_flag == 0xAA) //退出休眠false
{
LTE_Send("{\"HappenTime\":%u,\"LTESleep\":false}\r\n", sleepOff_time);
}
else if(incident_flag == 1) //上报true
{
LTE_Send("{\"HappenTime\":%u,\"%s\":true}\r\n", incident_time, incident_str);
}
else if(incident_flag == 2) //上报false
{
LTE_Send("{\"HappenTime\":%u,\"%s\":false}\r\n", incident_time, incident_str);
}
break;
case event_pub_step5:
LTE_Send("AT+CMQTTPUB=0,1,30\r\n"); //至少上报1次+30s内等待服务器回复
break;
default:
LTE_step = event_pub_step1; //非法值改为第一步
break;
}
}
//0xA1.立即回复写[服务]
else if(LTE_status == srvc_pub)
{
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "reply setService");
putSrvc_reply_count++;
//尝试1次重新回复
if(putSrvc_reply_count == 10)
{
LTE_step = srvc_pub_step1;
}
//仍然失败退出回复
else if(putSrvc_reply_count >= 20)
{
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //回复写[属性]完成,跳转:正常流程第一步
putSrvc_reply_flg = 0;
putSrvc_reply_count = 0;
}
switch(LTE_step) //srvc_pub_step1~srvc_pub_step5
{
case srvc_pub_step1:
LTE_Send("AT+CMQTTTOPIC=0,52\r\n"); //上报主题长度 "/sys/101/2025071201000023/thing/"=32Byte "service/invoke_reply"=20Byte
break;
case srvc_pub_step2:
//LTE_Send("/sys/101/2025071201000023/thing/service/invoke_reply");
LTE_Send("/sys/101/%s/thing/service/invoke_reply", BMS_SN); //上报的主题 (只有这个不用换新行)
break;
case srvc_pub_step3:
if(putSrvc_reply_flg == 1)
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", ID_len+putSrvc_reply_namelen+putSrvc_reply_strlen+28+2); //上报内容长度 = 数据长度+固定字符长度+回车
}
else if(putSrvc_reply_flg == 0xAA)
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", ID_len+29+2); //上报内容长度 = 数据长度+固定字符长度+回车
}
else if(putSrvc_reply_flg == 0xBB)
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", ID_len+29+2); //上报内容长度 = 数据长度+固定字符长度+回车
}
break;
case srvc_pub_step4:
if(putSrvc_reply_flg == 1) //正确
{
//{"request_id":"123124sdf","code":0,"PutForceOn":"close"}
LTE_Send("{\"request_id\":\"%s\",\"code\":0,%s:%s}\r\n", ID_str, putSrvc_reply_namestr, putSrvc_reply_str);
}
else if(putSrvc_reply_flg == 0xAA) //错误-设备无该属性
{
//{"request_id":"123124sdf","code":6411}
LTE_Send("{\"request_id\":\"%s\",\"code\":6411}\r\n", ID_str);
}
else if(putSrvc_reply_flg == 0xBB) //错误-设备拒绝执行
{
//{"request_id":"123124sdf","code":6405}
LTE_Send("{\"request_id\":\"%s\",\"code\":6405}\r\n", ID_str);
}
break;
case srvc_pub_step5:
LTE_Send("AT+CMQTTPUB=0,1,30\r\n"); //至少上报1次+30s内等待服务器回复
break;
default:
LTE_step = srvc_pub_step1; //非法值改为第一步
break;
}
}
//0xA2.立即回复写[属性]
else if(LTE_status == setPara_pub)
{
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "reply setPara");
setPara_reply_count++;
//尝试1次重新回复
if(setPara_reply_count == 10)
{
LTE_step = setPara_pub_step1;
}
//仍然失败退出回复
else if(setPara_reply_count >= 20)
{
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //回复写[属性]完成,跳转:正常流程第一步
setPara_reply_flg = 0;
setPara_reply_count = 0;
}
switch(LTE_step) //setPara_pub_step1~setPara_pub_step5
{
case setPara_pub_step1:
LTE_Send("AT+CMQTTTOPIC=0,43\r\n"); //上报主题长度 "/sys/101/030200001/thing/"=25Byte "property/set_reply"=18Byte
break;
case setPara_pub_step2:
//LTE_Send("/sys/101/030200001/thing/property/set_reply");
LTE_Send("/sys/101/%s/thing/property/set_reply", BMS_SN); //上报的主题 (只有这个不用换新行)
break;
case setPara_pub_step3:
if(setPara_reply_flg == 1) //正确
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", ID_len+uint_str_len(setPara_reply_num+protocol_reply_flg)+setPara_reply_sumlen+47+2); //上报内容长度 = ID长度+num长度+数据长度+固定字符长度+回车
}
else if(setPara_reply_flg == 0xAA)
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", ID_len+29+2); //上报内容长度 = 数据长度+固定字符长度+回车
}
else if(setPara_reply_flg == 0xBB)
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", ID_len+29+2); //上报内容长度 = 数据长度+固定字符长度+回车
}
break;
case setPara_pub_step4:
if(setPara_reply_flg == 1) //正确
{
uint8_t i;
//{"request_id":"123124sdf","code":0,"get_num":2,"data":{"POV_Vol":250,"COV_Vol":3600}}
LTE_Send("{\"request_id\":\"%s\",\"code\":0,\"set_num\":%hu,\"data\":", ID_str, setPara_reply_num+protocol_reply_flg);
LTE_Send("{");
for(i=0;i<setPara_reply_num;i++)
{
if(setPara_reply_pm[i] == 0) //正数
{
LTE_Send("%s:%hu", setPara_reply_name[i], setPara_reply_temp[i]);
}
else if(setPara_reply_pm[i] == 1) //负数
{
LTE_Send("%s:-%hu", setPara_reply_name[i], setPara_reply_temp[i]);
}
//else if(setPara_reply_pm[i] == 3) //true
//{
// LTE_Send("%s:true", setPara_reply_name[i]);
//}
//else if(setPara_reply_pm[i] == 4) //false
//{
// LTE_Send("%s:false", setPara_reply_name[i]);
//}
if((protocol_reply_flg == 1) && (i == protocol_reply_index)) //回复协议时,同步回复协议名称
{
protocol_reply_flg = 0;
LTE_Send(",");
LTE_Send("\"ProtocolName\":");
if(protocol == 0)
{
LTE_Send("null");
}
else
{
LTE_Send("\"%s\"", protocolStrings[protocol-1]);
}
}
if(i < setPara_reply_num-1) //没传完时,加逗号
{
LTE_Send(",");
}
}
LTE_Send("}");
LTE_Send("}\r\n");
}
else if(setPara_reply_flg == 0xAA) //错误-设备无该属性
{
//{"request_id":"123124sdf","code":6411}
LTE_Send("{\"request_id\":\"%s\",\"code\":6411}\r\n", ID_str);
}
else if(setPara_reply_flg == 0xBB) //错误-设备拒绝执行
{
//{"request_id":"123124sdf","code":6405}
LTE_Send("{\"request_id\":\"%s\",\"code\":6405}\r\n", ID_str);
}
break;
case setPara_pub_step5:
LTE_Send("AT+CMQTTPUB=0,1,30\r\n"); //至少上报1次+30s内等待服务器回复
break;
default:
LTE_step = setPara_pub_step1; //非法值改为第一步
break;
}
}
//0xA3.立即回复读[属性]
else if(LTE_status == getPara_pub)
{
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "reply getPara");
getPara_reply_count++;
//尝试1次重新回复
if(getPara_reply_count == 10)
{
LTE_step = getPara_pub_step1;
}
//仍然失败退出回复
else if(getPara_reply_count >= 20)
{
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //回复写[属性]完成,跳转:正常流程第一步
getPara_reply_flg = 0;
getPara_reply_count = 0;
}
switch(LTE_step) //getPara_pub_step1~getPara_pub_step5
{
case getPara_pub_step1:
LTE_Send("AT+CMQTTTOPIC=0,43\r\n"); //上报主题长度 "/sys/101/030200001/thing/"=25Byte "property/get_reply"=18Byte
break;
case getPara_pub_step2:
//LTE_Send("/sys/101/030200001/thing/property/get_reply");
LTE_Send("/sys/101/%s/thing/property/get_reply", BMS_SN); //上报的主题 (只有这个不用换新行)
break;
case getPara_pub_step3:
if(getPara_reply_flg == 1)
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", ID_len+uint_str_len(getPara_reply_num+protocol_reply_flg)+getPara_reply_sumlen+47+2); //上报内容长度 = ID长度+num长度+数据长度+固定字符长度+回车 //数据长度是指{}内的长度
}
else if(getPara_reply_flg == 0xAA)
{
LTE_Send("AT+CMQTTPAYLOAD=0,%u\r\n", ID_len+29+2); //上报内容长度 = 数据长度+固定字符长度+回车
}
break;
case getPara_pub_step4:
if(getPara_reply_flg == 1) //正确
{
uint8_t i;
//{"request_id":"123124sdf","code":0,"get_num":2,"data":{"POV_Vol":250,"COV_Vol":3600}}
LTE_Send("{\"request_id\":\"%s\",\"code\":0,\"get_num\":%hu,\"data\":", ID_str, getPara_reply_num+protocol_reply_flg);
LTE_Send("{");
for(i=0;i<getPara_reply_num;i++)
{
if(getPara_reply_pm[i] == 0) //正数
{
LTE_Send("%s:%hu", getPara_reply_name[i], getPara_reply_temp[i]);
}
else if(getPara_reply_pm[i] == 1) //负数
{
LTE_Send("%s:-%hu", getPara_reply_name[i], getPara_reply_temp[i]);
}
//else if(getPara_reply_pm[i] == 3) //true
//{
// LTE_Send("%s:true", getPara_reply_name[i]);
//}
//else if(getPara_reply_pm[i] == 4) //false
//{
// LTE_Send("%s:false", getPara_reply_name[i]);
//}
if((protocol_reply_flg == 1) && (i == protocol_reply_index)) //回复协议时,同步回复协议名称
{
protocol_reply_flg = 0;
LTE_Send(",");
LTE_Send("\"ProtocolName\":");
if(protocol == 0)
{
LTE_Send("null");
}
else
{
LTE_Send("\"%s\"", protocolStrings[protocol-1]);
}
}
if(i < getPara_reply_num-1) //没传完时,加逗号
{
LTE_Send(",");
}
}
LTE_Send("}");
LTE_Send("}\r\n");
}
else if(getPara_reply_flg == 0xAA) //错误-设备无所有属性
{
//{"request_id":"123124sdf","code":6411}
LTE_Send("{\"request_id\":\"%s\",\"code\":6411}\r\n", ID_str);
}
else if(setPara_reply_flg == 0xBB) //错误-设备拒绝执行
{
//{"request_id":"123124sdf","code":6405}
LTE_Send("{\"request_id\":\"%s\",\"code\":6405}\r\n", ID_str);
}
break;
case getPara_pub_step5:
LTE_Send("AT+CMQTTPUB=0,1,30\r\n"); //至少上报1次+30s内等待服务器回复
break;
default:
LTE_step = getPara_pub_step1; //非法值改为第一步
break;
}
}
//0xAA.转存完成,设备上线后主动上报OTA升级完成
else if(LTE_status == ota_fine_pub)
{
LTEStatus_flg = 1;
strcpy(LTEStatus_str, "reply ota_finish");
otaFine_reply_count++;
//尝试1次重新回复
if(otaFine_reply_count == 10)
{
LTE_step = ota_fine_pub_step1;
}
//仍然失败退出回复
else if(otaFine_reply_count >= 20)
{
LTE_status = ask_lbs;
LTE_step = ask_lbs_step1; //回复OTA升级完成,跳转:正常流程第一步
otaFine_reply_count = 0;
}
switch(LTE_step) //ota_fine_pub_step1~ota_fine_pub_step5
{
case ota_fine_pub_step1:
LTE_Send("AT+CMQTTTOPIC=0,32\r\n"); //上报主题长度 23+9=32Byte
break;
case ota_fine_pub_step2:
LTE_Send("/ota/device/inform/101/%s", BMS_SN); //上报的主题 (只有这个不用换新行)
break;
case ota_fine_pub_step3:
LTE_Send("AT+CMQTTPAYLOAD=0,12\r\n"); //上报内容长度 = 数据长度+固定字符长度+回车
break;
case ota_fine_pub_step4:
if(LTE_OTA_fineFlag == 0xAA)
{
LTE_Send("{\"code\":0}\r\n"); //升级成功
}
else
{
LTE_Send("{\"code\":6}\r\n"); //仍保持原程序
}
break;
case ota_fine_pub_step5:
LTE_Send("AT+CMQTTPUB=0,1,30\r\n"); //至少上报1次+30s内等待服务器回复
break;
default:
LTE_step = ota_fine_pub_step1; //非法值改为第一步
break;
}
}
}
}
#endif