micro_climate/Drivers/EC801E/EC801E.c

512 lines
15 KiB
C
Raw Permalink 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.

#include "EC801E.h"
#include "stdio.h"
#include "usart.h"
#include "string.h"
#include "cJSON.h"
#include "uart_dev.h"
#include "anemometer_dev.h"
#define USE_UTC 1
// ID
uint8_t g_devic_id[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
// 客户端名字
char g_cilent_name[] = "Test_cilent";
// 连接用户名
char g_cilent_user_name[] = "12345";
// 连接密码
char g_cilent_paaword[] = "12345";
// 服务器IP
char g_server_ip[] = "199.7.140.10,1883";
// 订阅主题名
char g_topic_name[] = "Test_Topic_1";
// 时间戳
uint32_t g_time_stamp;
// 最新一条信息发送时的时间戳
uint32_t trans_time_stamp;
// 打开客户端网络标志
int flag_open_net = 0;
// 连接服务器标志
int flag_connect = 0;
// 订阅成功网络标志
int flag_sub = 0;
// 发布信息标志
int flag_pubex = 0;
void parse_json(uint8_t *json_buff);
//控制上电并开机
void EC801E_Power_ON()
{
// PWR_KEY_4G_Pin低电平上电自动开机
HAL_GPIO_WritePin(GPIO_4G_PWR_KEY_GPIO_Port, GPIO_4G_PWR_KEY_Pin, GPIO_PIN_SET);
//上电
HAL_GPIO_WritePin(GPIO_4G_PWR_CTRL_GPIO_Port, GPIO_4G_PWR_CTRL_Pin, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIO_4G_PWR_CTRL_GPIO_Port, GPIO_4G_PWR_CTRL_Pin, GPIO_PIN_SET);
}
//开机状态检测
//HAL_OK:正常开机
uint8_t Read_Status()
{
uint8_t temp_status = HAL_ERROR;
temp_status = HAL_GPIO_ReadPin(GPIO_4G_STATUS_GPIO_Port, GPIO_4G_STATUS_Pin) == GPIO_PIN_SET ? HAL_OK : HAL_ERROR;
return temp_status;
}
//串口重定向打印
size_t __write(int handle, const unsigned char * buffer, size_t size)
{
if(HAL_OK == HAL_UART_Transmit(&huart1,(uint8_t *)buffer,size,100000))
{
return size;
}
else
{
return -1;
}
}
// MQTT打开客户端网络.连接MQTT服务器.订阅
// ip,端口客户端ID(0-5),客户端名称,用户名,密码,订阅主题名
void MQTT_Config()
{
// 确保4G模块完全开机
osDelay(5000);
// 打开客户端网络
while(!flag_open_net)
{
// uart_sendstr(g_ec801_uart_handle, "AT+QMTOPEN=0,199.7.140.10,1883\r\n");
uart_sendstr(g_ec801_uart_handle, "AT+QMTOPEN=0,");
uart_sendstr(g_ec801_uart_handle, g_server_ip);
uart_sendstr(g_ec801_uart_handle, "\r\n");
osDelay(5000);
}flag_open_net = 0;
// 连接服务器
while(!flag_connect)
{
uart_sendstr(g_ec801_uart_handle, "AT+QMTCONN=0,");
uart_sendstr(g_ec801_uart_handle, g_cilent_name);
uart_sendstr(g_ec801_uart_handle, ",");
uart_sendstr(g_ec801_uart_handle, g_cilent_user_name);
uart_sendstr(g_ec801_uart_handle, ",");
uart_sendstr(g_ec801_uart_handle, g_cilent_paaword);
uart_sendstr(g_ec801_uart_handle, "\r\n");
osDelay(5000);
}flag_connect = 0;
// 订阅主题
while(!flag_sub)
{
uart_sendstr(g_ec801_uart_handle, "AT+QMTSUB=0,0,");
uart_sendstr(g_ec801_uart_handle, g_topic_name);
uart_sendstr(g_ec801_uart_handle, ",0\r\n");
osDelay(5000);
}flag_sub = 0;
}
void EC801_start()
{
EC801E_Power_ON();
osDelay(5000);
while(!EC801_GET_Time());
MQTT_Config();
}
// MQTT发送数据
void MQTT_Trans_Data()
{
//字符串长度
uint8_t str_len = 0;
char str_len_str[32];
//创建获取数据指针
float32_t *ptr = (float32_t *)&g_stMcs_Para;
// 创建JSON数组及对象
char *cjson_str = NULL;
cJSON * JsonRoot = cJSON_CreateObject();
cJSON * DataArray = cJSON_CreateArray();
//将uint8的ID存到字符串内
char deviId_str[15];
snprintf(deviId_str, sizeof(deviId_str), "%X%X%X%X%X%X%X", g_devic_id[0], \
g_devic_id[1], \
g_devic_id[2], \
g_devic_id[3], \
g_devic_id[4], \
g_devic_id[5], \
g_devic_id[6]);
trans_time_stamp = g_time_stamp;// 将发送时时间戳存入最新发送时间时间戳
cJSON_AddStringToObject(JsonRoot, "deviId", deviId_str);
cJSON_AddStringToObject(JsonRoot, "frameType", "item_type");
cJSON_AddNumberToObject(JsonRoot, "timeStamp", g_time_stamp);
cJSON_AddNumberToObject(JsonRoot, "version", 10);
cJSON_AddItemToObject(JsonRoot, "data", DataArray);//添加data数组
for(int i = 0; i < sizeof(mcs_para)/sizeof(float32_t) - 2; i++)// 雨量光辐射还是空气
{
cJSON_AddItemToArray(DataArray, cJSON_CreateNumber(((float)((int )(ptr[i] * 100 + 0.5)))/100.0));// 四舍五入两位小数
}
// 对象转字符串
cjson_str = cJSON_Print(JsonRoot);
str_len = strlen(cjson_str) + 2 + 4;
sprintf(str_len_str, "%d", str_len);
while(!flag_pubex)
{
// 发送发数据包命令
uart_sendstr(g_ec801_uart_handle, "AT+QMTPUBEX=0,0,0,0,");
uart_sendstr(g_ec801_uart_handle, g_topic_name);
uart_sendstr(g_ec801_uart_handle, ",");
uart_sendstr(g_ec801_uart_handle, str_len_str);
uart_sendstr(g_ec801_uart_handle, "\r\n");
//发送数据包
osDelay(2000);
uart_sendstr(g_ec801_uart_handle, cjson_str);
HAL_Delay(3000);
}flag_pubex = 0;
//释放
vPortFree(cjson_str);
cJSON_Delete(JsonRoot);
}
// 判断闰年1闰0平
uint16_t fml_leap_year(uint16_t year)
{
return (((year % 4 == 0)&&(year % 100 != 0)) || (year % 400 == 0));
}
//日期转时间戳
uint32_t fml_time_to_stamp(int year, int month, int day, int hour, int minute, int second)
{
static uint32_t dax = 0;
static uint32_t day_count = 0;
uint16_t leap_year_count = 0;
uint16_t i;
// 计算闰年数
for (i = 1970; i < year; i++)
{
if (fml_leap_year(i))
{
leap_year_count++;
}
}
// 计算年的总天数
day_count = leap_year_count * 366 + (year - 1970 - leap_year_count) * 365;
uint8_t mouthday[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 计算当年到当前月的所有天数
for (i = 1; i < month; i++)
{
day_count += mouthday[i];
}
if(fml_leap_year(year))
{
day_count += 1;
}
// 累加计算当月的天数
day_count += (day - 1);
dax = (uint32_t)(day_count * 86400) + (uint32_t)((uint32_t)hour * 3600) + (uint32_t)((uint32_t)minute * 60) + (uint32_t)second;
return dax;
}
//时间获取完成变量用于控制是否开始MQTT信息接收
uint8_t time_get_ok = 0;
// 生成时间戳
int EC801_GET_Time()
{
int year, month, day, hour, minute, second;
if(USE_UTC)
{
uart_sendstr(g_ec801_uart_handle, "AT+QLTS=0\r\n");
}else
{
uart_sendstr(g_ec801_uart_handle, "AT+QLTS=2\r\n");
}
osDelay(1000);
char time[100] = {0};int index = 0;
// 第一个“后是时间,前面不要
do{
time[index] = uart_dev_in_char(g_ec801_uart_handle);
}while(time[index++] != '"' && uart_dev_char_present(g_ec801_uart_handle));
// 丢掉前面的
memcpy(time, time + index - 1, index);
index = 1;
// "前面是时间
do{
time[index] = uart_dev_in_char(g_ec801_uart_handle);
}while(time[index++] != '"' && uart_dev_char_present(g_ec801_uart_handle));
// 字符提取成int
sscanf(time, "\"%d/%d/%d,%d:%d:%d\"", &year, &month, &day, &hour, &minute, &second);
if(year)
{
time_get_ok = 1;
}
// 生成时间戳
g_time_stamp = fml_time_to_stamp(year, month, day, hour, minute, second);
return year;
}
#define JSON_BUFFER_SIZE 200
// 解析收到的4g模块数据
void parse_4g_receive_data()
{
if(uart_dev_char_present(g_ec801_uart_handle)){
int temp_5_index = 0;
char temp_5_char[5] = {0};
int AT_Command_flag = 0;
int Command_index = 0;
char AT_Command[10] = {0};
int AT_Command_ok_flag = 0;
int AT_data_ok_flag = 0;
uint8_t temp_buff[JSON_BUFFER_SIZE];
int temp_buff_index = 0; // 索引
char c = 0;
int inJson = 0;
memset(temp_buff, '\0', sizeof(temp_buff));//每次接受前清空一下BUFF
for(; uart_dev_char_present(g_ec801_uart_handle);)
{
// 思路挨个解析每次解析3个字符存入BUFFER依次后移检测到+后看前面两个
// 如果前面两个是AT则继续解析
// 如果前面两个不是AT则将从+开始到的内容都存入命令BUFF
// 根据 命令BUFF 处理后面的数据
c = uart_dev_in_char(g_ec801_uart_handle);
temp_5_char[temp_5_index] = c;
if(c == '+')
{
if(temp_5_char[(temp_5_index + 4)%5] == 'T' && temp_5_char[(temp_5_index + 3)%5] == 'A')// 判断 + 前是不是AT
{
}
else
{
AT_Command_flag = 1;
}
}
temp_5_index = (temp_5_index + 1)%5;//更新索引
// 读命令
if(AT_Command_flag){
AT_Command[Command_index] = c;// 存入命令Buff
if(AT_Command[Command_index] == ':')// :后面是状态
{
AT_Command_flag = 0;// 命令读完
AT_Command_ok_flag = 1;
}
Command_index ++;
}
// 命令读完,根据命令匹配反馈数据
if(AT_Command_ok_flag)
{
// term_printf(AT_Command);
// 打开QMTT客户端反馈
if(strstr(AT_Command, "QMTOPEN"))
{
temp_buff[temp_buff_index] = c;
if(temp_buff[temp_buff_index] == '\r'||temp_buff[temp_buff_index] == '\n')
{
// 处理完归零
AT_Command_ok_flag = 0;
memset(AT_Command, 0, 10);
// 处理读完之后的数据
int client_idx, result;
sscanf(temp_buff, ": %d,%d", &client_idx, &result);
// 打开完成
if(result == 0)
{
flag_open_net = 1;
}
return;
}
temp_buff_index ++;
}
// 连接服务器反馈
if(strstr(AT_Command, "QMTCONN"))
{
temp_buff[temp_buff_index] = c;
if(temp_buff[temp_buff_index] == '\r'||temp_buff[temp_buff_index] == '\n')
{
// 处理完归零
AT_Command_ok_flag = 0;
memset(AT_Command, 0, 10);
// 处理读完之后的数据
int client_idx, result, ret_code;
sscanf(temp_buff, ": %d,%d,%d", &client_idx, &result, &ret_code);
// 连接完成
if(result == 0 && ret_code == 0)
{
flag_connect = 1;
}
return;
}
temp_buff_index ++;
}
// 订阅主题反馈
if(strstr(AT_Command, "QMTSUB"))
{
temp_buff[temp_buff_index] = c;
if(temp_buff[temp_buff_index] == '\r'||temp_buff[temp_buff_index] == '\n')
{
// 处理完归零
AT_Command_ok_flag = 0;
memset(AT_Command, 0, 10);
// 处理读完之后的数据
int client_idx, msgID, result, value;
sscanf(temp_buff, ": %d,%d,%d,%d", &client_idx, &msgID, &result, &value);
// 连接完成
if(result == 0)
{
flag_sub = 1;
}
return;
}
temp_buff_index ++;
}
// 发布消息反馈
if(strstr(AT_Command, "QMTPUBEX"))
{
temp_buff[temp_buff_index] = c;
if(temp_buff[temp_buff_index] == '\r'||temp_buff[temp_buff_index] == '\n')
{
// 处理完归零
AT_Command_ok_flag = 0;
memset(AT_Command, 0, 10);
// 处理读完之后的数据
int client_idx, msgID, result, value;
sscanf(temp_buff, ": %d,%d,%d,%d", &client_idx, &msgID, &result, &value);
// 连接完成
if(result == 0 || result == 1)
{
flag_pubex = 1;
}
return;
}
temp_buff_index ++;
}
// 收到消息反馈+++++收到json
if(strstr(AT_Command, "QMTRECV"))
{
if (c == '{')
{
AT_data_ok_flag = 1;
}
if (AT_data_ok_flag == 1)
{
temp_buff[temp_buff_index] = c;
if (temp_buff[temp_buff_index] == '}')
{
// 处理完归零
AT_data_ok_flag = 0;
memset(AT_Command, 0, 10);
// 接收完了
if(temp_buff[0] != '\0')
{
parse_json(temp_buff);
}
// term_printf(temp_buff);
return;
}
temp_buff_index ++;
}
}
}
}
}
}
extern int trans_4g_flag;
// 收到json数据处理
void parse_json(uint8_t *json_buff)
{
cJSON* cjson_root = cJSON_Parse(json_buff);
if(cjson_root == NULL)
{
term_printf("parse fail.\n");
return;
}
cJSON* cjson_id = cJSON_GetObjectItem(cjson_root, "deviId");
cJSON* cjson_type = cJSON_GetObjectItem(cjson_root, "frameType");
cJSON* cjson_version = cJSON_GetObjectItem(cjson_root, "version");
cJSON* cjson_response = cJSON_GetObjectItem(cjson_root, "response");
cJSON* cjson_time = cJSON_GetObjectItem(cjson_root, "timeStamp");
cJSON* cjson_cmd = cJSON_GetObjectItem(cjson_root, "cmd");
// 取出数据
char *temp_id = cjson_id -> valuestring;
char *temp_type = cjson_type -> valuestring;
int temp_version = cjson_version -> valueint;
int temp_response = cjson_response -> valueint;
int temp_time = cjson_time -> valueint;
int temp_cmd = cjson_cmd -> valueint;
term_printf("deviId=%s\n frameType=%s\n version=%d\n response=%d\n timeStamp=%d\n cmd=%d", temp_id, temp_type, temp_version, temp_response, temp_time, temp_cmd);
cJSON_Delete(cjson_root);
// 与发送时间不一样才处理
if(temp_time != trans_time_stamp)
{
term_printf("1111");
if(temp_cmd == 1)
{
trans_4g_flag = 1;
}
}
// 数据处理
// if(abs(temp_time - g_time_stamp) >= 120)
// {
// g_time_stamp = temp_time;
// }
}