/** ****************************************************************************** * @file H7690C.c * @author * @version * @date * @brief ****************************************************************************** * @attention * * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" #include "global.h" #include "rtc.h" #include "string.h" #include #include #include #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\"", ¶Mem.pack_ovv, 1, 600, 0, 2}, //u16 {"\"POVR_Vol\"", ¶Mem.pack_ovrv, 1, 600, 0, 2}, //u16 {"\"PUV_Vol\"", ¶Mem.pack_uvv, 1, 600, 0, 2}, //u16 {"\"PUVR_Vol\"", ¶Mem.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", ×tamp); 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= 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>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 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,<E_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= 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= 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