#include "ec800m.h" #include "usart.h" #include "systick.h" #include "cJson.h" #include "string.h" #include "log.h" #include "systick.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() { WaitResponse(RSP_READY, 0); } /* * 函数名: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(200); } /* * 函数名:bool EC800MGetUrl(char *url) * 输入参数:url 网址信息 * 输出参数:无 * 返回值:无 * 函数作用:从对应的http获取信息 */ bool EC800MGetUrl(char *url,char *dmaBuffer,uint32_t bufferSize) { // Set url 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; // Send get request delay_1ms(200); EC800MSendCmd(CMD_GET, strlen(CMD_GET)); // 向服务器发送get请求 if (WaitResponse("QHTTPGET:", 5000) == false) return false; // 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; // get data from UFS delay_1ms(1000); dma_config_change(dmaBuffer,bufferSize); delay_1ms(1000); EC800MSendCmd(CMD_READ_FILE, strlen(CMD_READ_FILE)); //"AT+QFDWL=http.txt\r\n" delay_1ms(6000); 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 * 输出参数:无 * 返回值:无 * 函数作用:与服务器建立连接 */ void ConnectMQTTSever(uint8_t *host, uint16_t port, uint8_t keepalive, uint8_t *clientid) { char cmd[150]; bool success = false; int retry_count = 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); retry_count++; } while (!success && retry_count < 3); if (success) { retry_count = 0; sprintf(cmd, "AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n", clientid, "", ""); // 后两个为username password do { EC800MSendCmd(cmd, strlen(cmd)); success = WaitResponse("QMTCONN: 0,0,0", 1000); retry_count++; } while (!success && retry_count < 3); } } /* * 函数名: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(25*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)); WaitResponse("QMTPUBEX", 1000); delay_1ms(50); EC800MSendCmd(payload_out, strlen(payload_out)); } 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); }