#include "ec800m.h" #include "usart.h" #include "systick.h" #include "cJson.h" #include "string.h" #include "log.h" #include "systick.h" #include "main.h" void EC800MPwoerOn(void) { rcu_periph_clock_enable(RCU_GPIOD); gpio_init(GPIOD, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2); gpio_bit_set(GPIOD,GPIO_PIN_2); delay_1ms(5000); gd_pull_EC800M_pwr_up(); gd_pull_EC800M_rst_down(); delay_1ms(50); gd_pull_EC800M_pwr_down(); delay_1ms(320); gd_pull_EC800M_rst_up(); delay_1ms(800); gd_pull_EC800M_pwr_up(); } void EC800MSendCmd(char *buf, uint16_t len) { uint16_t i; uint16_t data; for (i = 0; i < len; i++) { data = buf[i]; usart_data_transmit(COM_EC800, data); while (RESET == usart_flag_get(COM_EC800, USART_FLAG_TBE)) ; } } void EC800MWaitReady() { if(WaitResponse(RSP_READY, 5000)==false) NVIC_SystemReset(); } /* * 函数名:bool WaitResponse(char *expectStr, int timeout) * 输入参数:expectStr 需要匹配的关键字 timeout超时时间 * 输出参数:true flase * 返回值:无 * 函数作用:从UART0_RX_BUF缓冲区中匹配有无对应关键字有关键字则返回true无返回false */ bool WaitResponse(char *expectStr, int timeout) { bool timeoutFlag = false; if (timeout >= 0) { timeoutFlag = true; } // gd_485_send((char *)&UART0_RX_BUF, strlen(UART0_RX_BUF)); 不清楚此处调用485意义 while (1) { delay_1ms(50); if (UART0_RX_STAT > 0) { UART0_RX_STAT = 0; char *p = strstr((char *)&UART0_RX_BUF, expectStr); if (p) { Clear_DMA_Buffer(); return true; } } timeout -= 50; if (timeoutFlag == true && timeout <= 0) { Clear_DMA_Buffer(); return false; } }; } /* * 函数名:void EC800MSetPDP() * 输入参数:无 * 输出参数:无 * 返回值:无 * 函数作用:设置对应运营商和激活ip */ void EC800MSetPDP() { delay_1ms(200); EC800MSendCmd(CMD_SET_PDP, strlen(CMD_SET_PDP)); WaitResponse(RSP_OK, 1000); delay_1ms(200); EC800MSendCmd(CMD_SET_ACTIVE, strlen(CMD_SET_ACTIVE)); WaitResponse(RSP_OK, 1000); delay_1ms(2000); } #define AT_Open "AT+QFOPEN=\"http.txt\",2 \r\n" #define AT_SEEK "AT+QFSEEK=1,0,0\r\n" #define AT_128SEEK "AT+QFSEEK=1,128,0\r\n" #define AT_128Read "AT+QFREAD=1,128\r\n" #define AT_LIST "AT+QFLST=\"*\"\r\n" #define AT_QFLDS "AT+QFLDS=\"UFS\"\r\n" //分包宏 /* * 函数名:bool EC800MGetUrl(char *url) * 输入参数:url 网址信息 * 输出参数:无 * 返回值:无 * 函数作用:从对应的http获取信息 */ bool EC800MGetUrl(char *url,char *dmaBuffer,uint32_t bufferSize) { // Set url EC800MSendCmd(AT_LIST, strlen(AT_LIST)); if(WaitResponse("http.txt", 100)==true) return false; char command[100]; sprintf(command, CMD_SET_URL, strlen(url)); // CMD_SET_URL "%d\r\n" EC800MSendCmd(command, strlen(command)); // 设置服务器URL 响应若参数格式正确,且不发送 HTTP(S) GET/POST 请求:CONNECT WaitResponse(RSP_CONNECT, 100); delay_1ms(200); EC800MSendCmd(url, strlen(url)); // 输入URL if (WaitResponse(RSP_OK, 5000) == false) return false; task_fwdgt_reload(); // Send get request delay_1ms(200); EC800MSendCmd(CMD_GET, strlen(CMD_GET)); // 向服务器发送get请求 if (WaitResponse("QHTTPGET:", 5000) == false) return false; task_fwdgt_reload(); // read to UFS delay_1ms(200); EC800MSendCmd(CMD_GET_TO_FILE, strlen(CMD_GET_TO_FILE)); //"AT+QHTTPREADFILE=\"UFS:http.txt\",80\r\n" if (WaitResponse("QHTTPREADFILE:", 5000) == false) return false; task_fwdgt_reload(); EC800MSendCmd("AT+QFLST=\"*\"\r\n", strlen("AT+QFLST=\"*\"\r\n")); if(WaitResponse("http.txt", 100)==true) return false; // get data from UFS delay_1ms(1000); task_fwdgt_reload(); dma_config_change(dmaBuffer,bufferSize); delay_1ms(1000); task_fwdgt_reload(); EC800MSendCmd(CMD_READ_FILE, strlen(CMD_READ_FILE)); //"AT+QFDWL=http.txt\r\n" delay_1ms(1000); task_fwdgt_reload(); return true; } /* * 函数名:void ConnectMQTTSever(uint8_t *host, uint16_t port, uint8_t keepalive, uint8_t *clientid) * 输入参数:host:mqtt服务器IP port:mqtt端口,keepalive mqtt心跳时间,clientid设备id * 输出参数:无 * 返回值:无 * 函数作用:与服务器建立连接 */ uint32_t try_connect; //记录尝试与平台建立连接的次数,每次1s当计数到1小时后重启设备 void ConnectMQTTSever(uint8_t *host, uint16_t port, uint8_t keepalive, uint8_t *clientid,uint8_t *mqttUserName,uint8_t *mqttPassword) { char cmd[150]; bool success = false; try_connect=0; // 主动断开连接 EC800MSendCmd(CMD_MQTT_DISCONNECT, 0); // 设置mqtt版本 EC800MSendCmd(CMD_MQTT_VERSION, strlen(CMD_MQTT_VERSION)); WaitResponse(RSP_OK, 100); sprintf(cmd, "AT+QMTCFG=\"qmtping\",0,%d\r\n", keepalive); EC800MSendCmd(cmd, strlen(cmd)); WaitResponse(RSP_OK, 0); // EC800MSendCmd(CMD_MQTT_DISCONNECT, 0); sprintf(cmd, "AT+QMTOPEN=0,\"%s\",%d\r\n", host, port); do { EC800MSendCmd(cmd, strlen(cmd)); success = WaitResponse("QMTOPEN: 0,0", 1000); delay_1ms(1000); task_fwdgt_reload(); try_connect++; if(try_connect==60*60){NVIC_SystemReset();} } while (!success); if (success) { if(mqttUserName==NULL) { sprintf(cmd, "AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n", clientid, "", ""); // 后两个为username password } else { sprintf(cmd, "AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n", clientid, mqttUserName, mqttPassword); // 后两个为username password } do { EC800MSendCmd(cmd, strlen(cmd)); success = WaitResponse("QMTCONN: 0,0,0", 1000); delay_1ms(1000); task_fwdgt_reload(); try_connect++; if(try_connect==60*60){NVIC_SystemReset();} } while (!success); } } /* * 函数名:void MQTTPublish(CONFIG_PARAMS *gateway) * 输入参数:CONFIG_PARAMS *gateway 网关内存储信息 * 输出参数:无 * 返回值:无 * 函数作用:读出采集到的数据进行上报,若未采集到数据则不进行任何处理 23/4/4添加testId测试丢包情况7/18日重写此方法 */ void MQTTPublish(void) { GATEWAY_PARAMS *gateway; gateway=get_gateway_config_params(); char *payload_out=malloc(30*1024); //要发送的字符串 char mqtt_publish[200]; //发送字符串的指令 sprintf((char *)payload_out,"{\"deviceId\":\"%s\",\"data\":[",gateway->deviceId);//组成json头部 DEVICE_PARAMS *currentDevice=gateway->device_params; READ_MODBUS_COMMAND *read_modbus_command=NULL; READ_DLT645_COMMAND *read_dlt645_command=NULL; switch(currentDevice->protocol) { case DLT645_07: case DLT645_97: read_dlt645_command=currentDevice->params->node_read_dlt645_command; break; case MODBUS: read_modbus_command=currentDevice->params->node_read_modbus_command; break; } while(1) { __START__WHILE: switch(currentDevice->protocol) { case DLT645_07: case DLT645_97: if(read_dlt645_command->rxLen!=0) { float value; switch(read_dlt645_command->rxLen) { case 4: memcpy(&value, read_dlt645_command->data, 4); sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %.2f},",currentDevice->deviceID,read_dlt645_command->keyword,value); break; case 5: sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": \"%02X%02X%02X%02X%02X\"},",currentDevice->deviceID,read_dlt645_command->keyword,read_dlt645_command->data[4], read_dlt645_command->data[3],read_dlt645_command->data[2],read_dlt645_command->data[1],read_dlt645_command->data[0]); break; break; case 9: memcpy(&value, read_dlt645_command->data, 4); sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\":\"%02X%02X%02X%02X%02X%.2f\"},",currentDevice->deviceID,read_dlt645_command->keyword,read_dlt645_command->data[8], read_dlt645_command->data[7],read_dlt645_command->data[6],read_dlt645_command->data[5],read_dlt645_command->data[4],value); break; } } break; case MODBUS: { if(read_modbus_command->rxLen!=0) { if(read_modbus_command->functionCode==0x03) { if(read_modbus_command->decimalPoint!=0) { float value; memcpy(&value, read_modbus_command->value, 4); // 取出相应的值给value sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %.2f},",currentDevice->deviceID,read_modbus_command->keyword,value); } else { uint32_t value; memcpy(&value, read_modbus_command->value, 4); sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %d},",currentDevice->deviceID,read_modbus_command->keyword,value); } } else if(read_modbus_command->functionCode==0x01) { uint8_t value[4]; uint8_t state; memcpy(&value, read_modbus_command->value, 4); if (value[2] == 0xFF) { state = 1; } else { state = 0; } sprintf(payload_out+strlen(payload_out),"{\"deviceId\":\"%s\",\"%s\": %d},",currentDevice->deviceID,read_modbus_command->keyword,state); } } } break; } switch(currentDevice->protocol) { case DLT645_07: case DLT645_97: read_dlt645_command=read_dlt645_command->nextParams; break; case MODBUS: read_modbus_command=read_modbus_command->nextParams; break; } if(read_dlt645_command==NULL&&read_modbus_command==NULL) { currentDevice=currentDevice->nextDevice; if(currentDevice==NULL) { goto __END__WHILE; } else { read_dlt645_command=currentDevice->params->node_read_dlt645_command; read_modbus_command=currentDevice->params->node_read_modbus_command; } } goto __START__WHILE; } __END__WHILE: if(strlen(payload_out)>40)//小于这个值组成的字符串证明没有数据采集到、就不进行发布 { sprintf(payload_out+strlen(payload_out)-1,"]}"); sprintf((char *)mqtt_publish, "AT+QMTPUBEX=0,0,0,0,\"%s\",%d\r\n", gateway->messageTopic, strlen(payload_out)); EC800MSendCmd(mqtt_publish, strlen(mqtt_publish)); bool success=WaitResponse(">", 1000); if(success) { delay_1ms(50); EC800MSendCmd(payload_out, strlen(payload_out)); } else { NVIC_SystemReset(); } } free(payload_out); payload_out=NULL; } /* * 函数名:void MQTTSubTopic(uint8_t *commandTopic) * 输入参数:uint8_t *commandTopic 订阅的主题 * 输出参数:无 * 返回值:无 * 函数作用:读出采集到的数据进行上报,若未采集到数据则不进行任何处理 */ void MQTTSubTopic(uint8_t *commandTopic) { char AT_SUB[100]; sprintf(AT_SUB, "AT+QMTSUB=0,1,\"%s\",0\r\n", commandTopic); bool success = false; uint8_t retry_count = 0; do { EC800MSendCmd(AT_SUB, strlen(AT_SUB)); success = WaitResponse(RSP_OK, 1000); retry_count++; } while (!success && retry_count < 3); } #define AT_DELETE_FILE "AT+QFDEL=\"UFS:http.txt\"\r\n" void delete_config_file() { dma_config(); EC800MSendCmd(AT_DELETE_FILE, strlen(AT_DELETE_FILE)); WaitResponse("OK", 1000); }