huyongji1.1-system/Inf/Inf_4G.c

916 lines
33 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Inf_4G.h"
// 在Irrigation.h或单独的config.h中定义这些参数
// AT命令状态
typedef enum
{
AT_IDLE,
AT_SENDING,
AT_WAITING,
AT_COMPLETE
} AT_State_t;
uint8_t force_pump_off = 0; // 水泵强制关闭标志
uint8_t force_fan_off = 0; // 风机强制关闭标志
AT_State_t at_state = AT_IDLE;
uint32_t at_start_time = 0;
char sim_iccid[ICCID_LENGTH] = {0}; // 初始化ICCID变量
// 缓冲区定义
uint8_t rxBuff[RX_BUFFER_SIZE]; /* 缓冲一次中断接收的数据 */
uint16_t rxDataSize; /* 一次中断接收数据量 */
uint8_t responseBuff[RESPONSE_BUFFER_SIZE]; /* 缓冲一次中断接收的数据 */
uint16_t responseDataSize; /* 一次中断接收数据量 */
void Publish_Power_Data(void);
volatile uint8_t need_upload = 0;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size)
{
if (huart->Instance == USART2)
{
rxDataSize = size;
HAL_UARTEx_ReceiveToIdle_IT(&huart2, rxBuff, 1024);
}
}
void Inf_4G_Init(void)
{
/* 初始化串口2 */
MX_USART2_UART_Init();
HAL_UARTEx_ReceiveToIdle_IT(&huart2, rxBuff, 1024);
Inf_4G_SendAtCmd("AT+CFUN=1\r\n");
HAL_Delay(2000);
Inf_4G_SendAtCmd("AT\r\n");
// 获取ICCID
Get_ICCID();
// 获取初始信号强度
Get_Signal_Strength();
}
void Inf_4G_SendAtCmd(uint8_t *atcmd)
{
// 清空缓冲区
memset(responseBuff, 0, sizeof(responseBuff));
responseDataSize = 0;
rxDataSize = 0;
// 发送AT命令
HAL_UART_Transmit(&huart2, atcmd, strlen((char *)atcmd), 500);
// 等待响应
uint16_t timeout = 1000; // 1秒超时
while (timeout--)
{
if (rxDataSize > 0)
{
// 检查响应
if (strstr((char *)rxBuff, "OK") || strstr((char *)rxBuff, "ERROR"))
{
return; // 收到响应直接返回
}
rxDataSize = 0; // 清空数据大小
}
HAL_Delay(1); // 1ms延时
}
// 超时处理
printf("AT命令超时: %s\n", atcmd);
}
// void Inf_EC800_4GInit(void)
// {
// // 初始化4G模块
// Inf_4G_SendAtCmd("AT+CSQ\r\n");
// Inf_4G_SendAtCmd("AT+CPIN?\r\n");
// Inf_4G_SendAtCmd("AT+CEREG?\r\n");
// }
void Inf_EC800_MQTT_Publish(const char *topic, const char *payload)
{
char atCmd[128];
snprintf(atCmd, sizeof(atCmd), "AT+QMTPUB=0,0,0,0,\"%s\"\r\n", topic);
// 发送AT命令并等待">"提示符
Inf_4G_SendAtCmd((uint8_t *)atCmd);
// 发送消息内容
HAL_UART_Transmit(&huart2, (uint8_t *)payload, strlen(payload), 1000);
HAL_UART_Transmit(&huart2, (uint8_t *)"\x1A", 1, 1000); // Ctrl+Z
// 等待发布完成的响应
HAL_Delay(1000);
}
void Inf_EC800_ReadData(void)
{
if (rxDataSize > 0)
{
printf("接收到的原始数据: %s\n", rxBuff);
if (strstr((char *)rxBuff, "+QMTRECV:"))
{
char *jsonStart = strchr((char *)rxBuff, '{');
char *jsonEnd = strrchr((char *)rxBuff, '}');
if (jsonStart && jsonEnd && jsonEnd > jsonStart)
{
int jsonLen = jsonEnd - jsonStart + 1;
char jsonStr[256] = {0};
strncpy(jsonStr, jsonStart, jsonLen);
int value = 0;
// LED控制命令解析
// 模式切换
if (sscanf(jsonStr, "{\"X10\":%d}", &value) == 1)
{
switch (value)
{
case 1: // 冲厕模式
Switch_Mode(MODE_FLUSH);
printf("切换到冲厕模式\n");
rxDataSize = 0;
memset(rxBuff, 0, sizeof(rxBuff));
break;
case 2: // 灌溉模式
Switch_Mode(MODE_IRRIGATION);
printf("切换到灌溉模式\n");
rxDataSize = 0;
memset(rxBuff, 0, sizeof(rxBuff));
break;
case 3: // 直排模式
Switch_Mode(MODE_DIRECT);
printf("切换到直排模式\n");
rxDataSize = 0;
memset(rxBuff, 0, sizeof(rxBuff));
break;
default:
// printf("无效的模式值: %d\n", value);
break;
}
}
// 修改水泵开启时间
else if (sscanf(jsonStr, "{\"X24\":%d}", &value) == 1)
{
// 1. 先停止定时器中断
HAL_TIM_Base_Stop_IT(&htim2); // 假设使用的是TIM2根据实际情况修改
switch (current_mode)
{
case MODE_IRRIGATION:
HIGH_LEVEL_PUMP_ON_TIME = (uint32_t)value;
break;
case MODE_FLUSH:
FLUSH_HIGH_PUMP_ON_TIME = (uint32_t)value;
break;
case MODE_DIRECT:
DIRECT_HIGH_PUMP_ON_TIME = (uint32_t)value;
break;
}
Time_Save(); // 保存修改后的时间
// 3. 关闭所有设备
Control_WaterPump(0);
Control_Fan1(0);
Control_Fan2(0);
// 4. 完全重置所有计时变量
pump_timer = 0;
fan_timer = 0;
// timer_count = 0; // 如果有总的计时器计数也要清零
// 5. 清除定时器计数器值
__HAL_TIM_SET_COUNTER(&htim2, 0);
// 重置水泵计时器
Restart_Current_Mode(); // 重启当前模式
HAL_TIM_Base_Start_IT(&htim2);
}
// 修改水泵停止时间
else if (sscanf(jsonStr, "{\"X25\":%d}", &value) == 1)
{
// 1. 先停止定时器中断
HAL_TIM_Base_Stop_IT(&htim2); // 假设使用的是TIM2根据实际情况修改
switch (current_mode)
{
case MODE_IRRIGATION:
HIGH_LEVEL_PUMP_OFF_TIME = value;
// printf("灌溉模式水泵停止时间修改为:%d分钟\n", value);
break;
case MODE_FLUSH:
FLUSH_HIGH_PUMP_OFF_TIME = value;
// printf("冲厕模式水泵停止时间修改为:%d分钟\n", value);
break;
case MODE_DIRECT:
DIRECT_HIGH_PUMP_OFF_TIME = value;
// printf("直排模式水泵停止时间修改为:%d分钟\n", value);
break;
}
Time_Save(); // 保存修改后的时间
// 3. 关闭所有设备
Control_WaterPump(0);
Control_Fan1(0);
Control_Fan2(0);
// 4. 完全重置所有计时变量
pump_timer = 0;
fan_timer = 0;
// timer_count = 0; // 如果有总的计时器计数也要清零
// 5. 清除定时器计数器值
__HAL_TIM_SET_COUNTER(&htim2, 0);
// 重置水泵计时器
Restart_Current_Mode(); // 重启当前模式
HAL_TIM_Base_Start_IT(&htim2);
}
else if (sscanf(jsonStr, "{\"X54\":%d}", &value) == 1)
{
// 1. 先停止定时器中断
HAL_TIM_Base_Stop_IT(&htim2); // 假设使用的是TIM2根据实际情况修改
switch (current_mode)
{
case MODE_IRRIGATION:
HIGH_LEVEL_FAN_ON_TIME = value;
break;
case MODE_FLUSH:
FLUSH_HIGH_FAN_ON_TIME = value;
break;
case MODE_DIRECT:
DIRECT_HIGH_FAN_ON_TIME = value;
break;
}
Time_Save(); // 保存修改后的时间
// 3. 关闭所有设备
Control_WaterPump(0);
Control_Fan1(0);
Control_Fan2(0);
// 4. 完全重置所有计时变量
pump_timer = 0;
fan_timer = 0;
// timer_count = 0; // 如果有总的计时器计数也要清零
// 5. 清除定时器计数器值
__HAL_TIM_SET_COUNTER(&htim2, 0);
// 重置水泵计时器
Restart_Current_Mode(); // 重启当前模式
HAL_TIM_Base_Start_IT(&htim2);
}
// 修改高液位风机停止时间
else if (sscanf(jsonStr, "{\"X55\":%d}", &value) == 1)
{
switch (current_mode)
{
case MODE_IRRIGATION:
HIGH_LEVEL_FAN_OFF_TIME = value;
break;
case MODE_FLUSH:
FLUSH_HIGH_FAN_OFF_TIME = value;
break;
case MODE_DIRECT:
DIRECT_HIGH_FAN_OFF_TIME = value;
break;
}
Time_Save(); // 保存修改后的时间
// 3. 关闭所有设备
Control_WaterPump(0);
Control_Fan1(0);
Control_Fan2(0);
// 4. 完全重置所有计时变量
pump_timer = 0;
fan_timer = 0;
// timer_count = 0; // 如果有总的计时器计数也要清零
// 5. 清除定时器计数器值
__HAL_TIM_SET_COUNTER(&htim2, 0);
// 重置水泵计时器
Restart_Current_Mode(); // 重启当前模式
HAL_TIM_Base_Start_IT(&htim2);
}
// 修改低液位风机运行时间
else if (sscanf(jsonStr, "{\"X56\":%d}", &value) == 1)
{
// 1. 先停止定时器中断
HAL_TIM_Base_Stop_IT(&htim2); // 假设使用的是TIM2根据实际情况修改
switch (current_mode)
{
case MODE_IRRIGATION:
LOW_LEVEL_FAN_ON_TIME = value;
break;
case MODE_FLUSH:
FLUSH_LOW_FAN_ON_TIME = value;
break;
case MODE_DIRECT:
DIRECT_LOW_FAN_ON_TIME = value;
break;
}
Time_Save(); // 保存修改后的时间
// 3. 关闭所有设备
Control_WaterPump(0);
Control_Fan1(0);
Control_Fan2(0);
// 4. 完全重置所有计时变量
pump_timer = 0;
fan_timer = 0;
// timer_count = 0; // 如果有总的计时器计数也要清零
// 5. 清除定时器计数器值
__HAL_TIM_SET_COUNTER(&htim2, 0);
// 重置水泵计时器
Restart_Current_Mode(); // 重启当前模式
HAL_TIM_Base_Start_IT(&htim2);
}
// 修改低液位风机停止时间
else if (sscanf(jsonStr, "{\"X57\":%d}", &value) == 1)
{
// 1. 先停止定时器中断
HAL_TIM_Base_Stop_IT(&htim2); // 假设使用的是TIM2根据实际情况修改
switch (current_mode)
{
case MODE_IRRIGATION:
LOW_LEVEL_FAN_OFF_TIME = value;
break;
case MODE_FLUSH:
FLUSH_LOW_FAN_OFF_TIME = value;
break;
case MODE_DIRECT:
DIRECT_LOW_FAN_OFF_TIME = value;
break;
}
Time_Save(); // 保存修改后的时间
// 3. 关闭所有设备
Control_WaterPump(0);
Control_Fan1(0);
Control_Fan2(0);
// 4. 完全重置所有计时变量
pump_timer = 0;
fan_timer = 0;
// timer_count = 0; // 如果有总的计时器计数也要清零
// 5. 清除定时器计数器值
__HAL_TIM_SET_COUNTER(&htim2, 0);
// 重置水泵计时器
Restart_Current_Mode(); // 重启当前模式
HAL_TIM_Base_Start_IT(&htim2);
}
else if (sscanf(jsonStr, "{\"X15\":%d}", &value) == 1)
{
if (value == 1)
{
ozone_running = 1; // 启动臭氧
ozone_timer = 0; // 重置计时器
Ozone_Control(1); // 立即开启臭氧
// printf("臭氧启动运行\n");
}
else if (value == 0)
{
ozone_running = 0; // 停止臭氧运行
ozone_timer = 0; // 重置计时器
Ozone_Control(0); // 立即关闭臭氧
// printf("臭氧停止运行\n");
}
}
// 臭氧开启时间设置
else if (sscanf(jsonStr, "{\"X20\":%d}", &value) == 1)
{
OZONE_ON_TIME = value;
ozone_timer = 0; // 重置计时器
Save_Ozone_Time_To_EEPROM(OZONE_ON_TIME, OZONE_OFF_TIME);
// printf("设置臭氧开启时间: %d分钟\n", value);
}
// 臭氧关闭时间设置
else if (sscanf(jsonStr, "{\"X21\":%d}", &value) == 1)
{
OZONE_OFF_TIME = value;
ozone_timer = 0; // 重置计时器
Save_Ozone_Time_To_EEPROM(OZONE_ON_TIME, OZONE_OFF_TIME); // 保存到EEPROM
// printf("设置臭氧关闭时间: %d分钟\n", value);
}
// 水泵控制
else if (sscanf(jsonStr, "{\"X12\":%d}", &value) == 1)
{
if (value == CMD_ON || value == CMD_OFF)
{
force_pump_off = (value == CMD_OFF); // 设置强制关闭标志
// 如果是开启命令,先确保强制关闭标志被清除
if (value == CMD_ON) {
force_pump_off = 0;
Control_WaterPump(1);
printf("水泵强制开启\n");
} else {
force_pump_off = 1;
Control_WaterPump(0);
printf("水泵强制关闭\n");
}
rxDataSize = 0;
memset(rxBuff, 0, sizeof(rxBuff));
}
}
// 风机1控制
else if (sscanf(jsonStr, "{\"X13\":%d}", &value) == 1)
{
if (value == CMD_ON || value == CMD_OFF)
{
force_fan_off = (value == CMD_OFF); // 设置强制关闭标志
// 如果是开启命令,先确保强制关闭标志被清除
if (value == CMD_ON) {
force_fan_off = 0;
Control_Fan1(1);
printf("风机1强制开启\n");
} else {
force_fan_off = 1;
Control_Fan1(0);
printf("风机1强制关闭\n");
}
// printf("风机1控制: %s\n", value ? "开启" : "关闭");
}
}
// 风机2控制
else if (sscanf(jsonStr, "{\"X14\":%d}", &value) == 1)
{
if (value == CMD_ON || value == CMD_OFF)
{
// 风机2的控制也需要考虑强制关闭标志
if (value == CMD_ON) {
force_fan_off = 0; // 清除强制关闭标志
Control_Fan2(1);
printf("风机2强制开启\n");
} else {
force_fan_off = 1; // 设置强制关闭标志
Control_Fan2(0);
printf("风机2强制关闭\n");
}
}
}
// 加热膜控制 (比如使用 X16 作为控制指令)
else if (sscanf(jsonStr, "{\"X18\":%d}", &value) == 1)
{
if (value == CMD_ON || value == CMD_OFF)
{
Control_Heater((uint8_t)value);
// printf("加热膜控制: %s\n", value ? "开启" : "关闭");
}
}
else if (sscanf(jsonStr, "{\"X22\":%d}", &value) == 1)
{
temp_lower_limit = (float)value;
// printf("设置温度下限为: %.1f℃\n", temp_lower_limit);
}
// 设置温度上限
else if (sscanf(jsonStr, "{\"X23\":%d}", &value) == 1)
{
temp_upper_limit = (float)value;
// printf("设置温度上限为: %.1f℃\n", temp_upper_limit);
}
// 总开关
else if (sscanf(jsonStr, "{\"X59\":%d}", &value) == 1)
{
if (value == CMD_ON || value == CMD_OFF)
{
Control_All_Devices(value); // 调用总开关控制函数
}
}
// 控制除磷开关X32
else if (sscanf(jsonStr, "{\"X49\":%d}", &value) == 1)
{
if (value == 1)
{
// 启动除磷
phosphorus_timer = 0;
polarity_state = !polarity_state;
Control_Phosphorus_Polarity(); // 设置初始极性
Phosphorus_Control_Update();
}
else
{
Control_Phosphorus(0); // 关闭除磷
}
}
else if (sscanf(jsonStr, "{\"X51\":%d}", &value) == 1)
{
PHOSPHORUS_RUN_TIME=value;
// printf("设置除磷运行时间为:%d分钟\n", value);
}
// 设置除磷停止时间X34
else if (sscanf(jsonStr, "{\"X52\":%d}", &value) == 1)
{
PHOSPHORUS_STOP_TIME=value;
// printf("设置除磷停止时间为:%d分钟\n", value);
}
// 添加排泥远程控制处理
if (sscanf(jsonStr, "{\"X53\":%d}", &value) == 1)
{
if (value == 1) // 开启排泥
{
Control_Dredge(1);
}
else if (value == 0) // 关闭排泥
{
Control_Dredge(0);
}
}
// 添加培菌模式专用控制按钮
else if (sscanf(jsonStr, "{\"X58\":%d}", &value) == 1)
{
if (value == 1)
{
// 启动培菌模式
Switch_Mode(MODE_SPECIAL);
// printf("启动培菌模式\n");
}
else if (value == 0)
{
Switch_Mode(MODE_DIRECT);
// 停止培菌模式,切换到直排模式
printf("停止培菌模式,切换到直排模式\n");
}
rxDataSize = 0;
memset(rxBuff, 0, sizeof(rxBuff));
}
}
}
if (parameters_changed)
{
// Restart_Current_Mode();
// parameters_changed = 0; // 重置标志
}
rxDataSize = 0;
memset(rxBuff, 0, sizeof(rxBuff));
}
}
// MQTT初始化函数
void Inf_EC800_MQTT_Init(void)
{
char mqtt_cmd[128]; // 用于存储AT命令的缓冲区
// 先断开可能存在的连接
Inf_4G_SendAtCmd((uint8_t *)"AT+QMTDISC=0\r\n");
HAL_Delay(300);
Inf_4G_SendAtCmd((uint8_t *)"AT+QMTCLOSE=0\r\n");
HAL_Delay(300);
// 配置接收模式
Inf_4G_SendAtCmd((uint8_t *)"AT+QMTCFG=\"recv/mode\",0,0,0\r\n");
HAL_Delay(100);
// 配置keepalive时间为60秒
Inf_4G_SendAtCmd((uint8_t *)"AT+QMTCFG=\"keepalive\",0,60\r\n");
HAL_Delay(100);
// 连接MQTT服务器
sprintf(mqtt_cmd, "AT+QMTOPEN=0,\"%s\",%s\r\n", MQTT_SERVER_IP, MQTT_SERVER_PORT);
Inf_4G_SendAtCmd((uint8_t *)mqtt_cmd);
HAL_Delay(2000);
// 连接MQTT服务器并使用唯一的客户端ID
sprintf(mqtt_cmd, "AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"\r\n",
MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD);
Inf_4G_SendAtCmd((uint8_t *)mqtt_cmd);
HAL_Delay(1000);
// 订阅主题
sprintf(mqtt_cmd, "AT+QMTSUB=0,1,\"%s\",1\r\n", MQTT_TOPIC);
Inf_4G_SendAtCmd((uint8_t *)mqtt_cmd);
HAL_Delay(1000);
}
// 上传数据
// 数据上传函数
// 定义缓冲区
#define TX_BUFFER_SIZE 256
uint8_t txBuff[TX_BUFFER_SIZE]; // 发送缓冲区
// MQTT数据发送函数
// MQTT发送数据函数
void Inf_EC800_SendMqttData(uint16_t id, uint8_t data[], uint16_t dataLen)
{
memset(txBuff, 0, sizeof(txBuff));
sprintf((char *)txBuff, "AT+QMTPUB=0,0,0,0,\"%s\"\r\n", MQTT_PUB_TOPIC);
Inf_4G_SendAtCmd(txBuff);
HAL_UART_Transmit(&huart2, data, dataLen, 1000);
HAL_UART_Transmit(&huart2, (uint8_t *)"\x1A", 1, 1000);
HAL_Delay(100);
}
// 数据上传函数
void Upload_Device_Data(void)
{
uint8_t payload[256];
uint16_t dataLen;
Update_All_Status(); // 更新状态并打印
Check_Power_Source();
uint8_t power_type = Get_Power_Type();
Print_Temperature(data1);
Get_Signal_Strength();
// 处理电量数据
// 获取当前模式的水泵时间参数
uint32_t current_pump_on = 0;
uint32_t current_pump_off = 0;
// 获取当前风机运行的时间参数
// 添加高液位风机时间参数
uint32_t current_high_fan_on = 0;
uint32_t current_high_fan_off = 0;
// 添加低液位风机时间参数
uint32_t current_low_fan_on = 0;
uint32_t current_low_fan_off = 0;
switch (current_mode)
{
case MODE_IRRIGATION:
current_pump_on = HIGH_LEVEL_PUMP_ON_TIME;
current_pump_off = HIGH_LEVEL_PUMP_OFF_TIME;
current_high_fan_on = HIGH_LEVEL_FAN_ON_TIME;
current_high_fan_off = HIGH_LEVEL_FAN_OFF_TIME;
current_low_fan_on = LOW_LEVEL_FAN_ON_TIME; // 灌溉模式低液位风机时间
current_low_fan_off = LOW_LEVEL_FAN_OFF_TIME;
break;
case MODE_FLUSH:
current_pump_on = FLUSH_HIGH_PUMP_ON_TIME;
current_pump_off = FLUSH_HIGH_PUMP_OFF_TIME;
current_high_fan_on = FLUSH_HIGH_FAN_ON_TIME;
current_high_fan_off = FLUSH_HIGH_FAN_OFF_TIME;
current_low_fan_on = FLUSH_LOW_FAN_ON_TIME; // 冲厕模式低液位风机时间
current_low_fan_off = FLUSH_LOW_FAN_OFF_TIME;
break;
case MODE_DIRECT:
current_pump_on = DIRECT_HIGH_PUMP_ON_TIME;
current_pump_off = DIRECT_HIGH_PUMP_OFF_TIME;
current_high_fan_on = DIRECT_HIGH_FAN_ON_TIME;
current_high_fan_off = DIRECT_HIGH_FAN_OFF_TIME;
current_low_fan_on = DIRECT_LOW_FAN_ON_TIME; // 直排模式低液位风机时间
current_low_fan_off = DIRECT_LOW_FAN_OFF_TIME;
break;
case MODE_SPECIAL:
// 风机参数设置(与直排模式相同)
current_high_fan_on = DIRECT_HIGH_FAN_ON_TIME; // 40分钟
current_high_fan_off = DIRECT_HIGH_FAN_OFF_TIME; // 2分钟
current_low_fan_on = DIRECT_LOW_FAN_ON_TIME; // 10分钟
current_low_fan_off = DIRECT_LOW_FAN_OFF_TIME; // 20分钟
// 根据特殊模式阶段设置水泵参数
switch(special_phase) {
case SPECIAL_INITIAL_STOP:
printf("特殊模式初始阶段 - 24小时停止\n");
current_pump_on = 0;
current_pump_off = SPECIAL_INITIAL_STOP_TIME; // 1440分钟
break;
case SPECIAL_FIRST_PHASE:
printf("特殊模式第一阶段 - 6小时循环\n");
current_pump_on = SPECIAL_PUMP_RUN_TIME; // 1分钟
current_pump_off = SPECIAL_FIRST_STOP_TIME; // 359分钟
break;
case SPECIAL_SECOND_PHASE:
printf("特殊模式第二阶段 - 4小时循环\n");
current_pump_on = SPECIAL_PUMP_RUN_TIME; // 1分钟
current_pump_off = SPECIAL_SECOND_STOP_TIME; // 239分钟
break;
default:
printf("错误:无效的特殊模式阶段\n");
break;
}
break;
}
// 打印当前参数值
// printf("\n当前参数值:\n");
// printf("模式: %d\n", current_mode);
// printf("水泵开启时间: %d分钟\n", current_pump_on);
// printf("水泵关闭时间: %d分钟\n", current_pump_off);
// printf("高位风机开启时间: %d分钟\n", current_high_fan_on);
// printf("高位风机关闭时间: %d分钟\n", current_high_fan_off);
// printf("低位风机开启时间: %d分钟\n", current_low_fan_on);
// printf("低位风机关闭时间: %d分钟\n", current_low_fan_off);
// 构建JSON数据添加电量base_energy
dataLen = sprintf((char *)payload,
"{"
"\"X4\":%d," // 信号强度 X4
"\"X10\":%d," // 上传当前模式 X10
"\"X12\":%d," // 水泵 X12
"\"X13\":%d," // 风机1 X13
"\"X14\":%d," // 风机2 X14
"\"X15\":%d," // 臭氧运行状态 X15
"\"X18\":%d," // 加热膜控制 X18
"\"X20\":%d," // 上传臭氧开启时间 X20
"\"X21\":%d," // 上传臭氧关闭时间 X21
"\"X5\":%.2f," // 温度 X5
"\"X22\":%.1f," // 温度下限 X22
"\"X23\":%.1f," // 温度上限 X23
"\"X24\":%d," // 当前水泵开启时间 X24
"\"X25\":%d," // 当前水泵关闭时间 X25
"\"X35\":%d," //当前水泵的故障 X35
"\"X37\":%d," //当前风机1的故障 X37
"\"X38\":%d," //当前水泵的故障 X38
"\"X44\":%d," // 当前水泵关闭时间 X44
"\"X46\":%d," // 市电检测 X46
"\"X47\":%d," // X47
"\"X49\":%d," // 除磷控制 X49
"\"X50\":%d," // 除磷状态 X50
"\"X51\":%d," // 极板运行时间 X51
"\"X52\":%d," // 极板停止时间 X52
"\"X53\":%d," // 排泥 X53
"\"X54\":%d," // 高液位风机开启时间 X54
"\"X55\":%d," // 高液位风机关闭时间 X55
"\"X56\":%d," // 低液位风机开启时间
"\"X57\":%d," // 低液位风机关闭时间
"\"X58\":%d," // 低液位风机关闭时间
"\"X59\":%d," // 系统状态
"\"X300\":%.6f," // 添加电量字段 X300
"\"X001\":\"%s\"" // 添加ICCID字段
"}",
// device_status[11], // 水量 X1
gsm_signal_strength, // 信号强度 X4
current_mode, // 上传当前模式 X10
device_status[1], // 水泵 X12
device_status[2], // 风机1 X13
device_status[3], // 风机2 X14
ozone_running, // 臭氧运行状态 X15
device_status[7], // 加热膜状态 X18
OZONE_ON_TIME, // 当前臭氧开启时间 X20
OZONE_OFF_TIME, // 当前臭氧关闭时间 X21
temperature, // 将温度值添加到JSON中 X5
temp_lower_limit, // 温度下限 X22
temp_upper_limit, // 温度上限 X23
current_pump_on, // 只上传水泵时间 X24
current_pump_off, // 只上传水泵时间 X25
device_fault.pump_fault, // 添加故障状态 0:正常 1:故障 X35
device_fault.fan1_fault, //风机1的故障 X37
device_fault.fan2_fault, //风机2的故障 X38
device_status[5], // 低液位水泵状态 X44
device_status[8], // 市电检测 X46
power_type, // 光伏市电检测状态 X47
Dephosphorization_state, // 除磷控制状态 X49
device_status[9], // 除磷状态 X50
PHOSPHORUS_RUN_TIME, // 当前设置的运行时间
PHOSPHORUS_STOP_TIME, // 当前设置的停止时间
device_status[10], // 排泥状态 X53
current_high_fan_on, // X54
current_high_fan_off, // X55
current_low_fan_on, // X56
current_low_fan_off, // X57
(current_mode == MODE_SPECIAL) ? 1 : 0, // 培菌模式阶段(新增) x58
device_status[11], // 系统状态 X59
base_energy, // 将电量值添加到JSON中 X300
sim_iccid // ICCID值
);
// 发送数据
Inf_EC800_SendMqttData(0, payload, dataLen);
// 添加调试打印
// printf("数据发送完成 - 发送的水量值:%d\r\n", device_status[11]);
// 发送后再清零
// pump_flow = 0;
// device_status[11] = 0;
// flow_to_upload = 0;
}
// 添加信号强度变量
int8_t gsm_signal_strength = 0;
// 获取信号强度函数
void Get_Signal_Strength(void)
{
memset(rxBuff, 0, sizeof(rxBuff));
rxDataSize = 0;
Inf_4G_SendAtCmd("AT+CSQ\r\n");
// 解析信号强度
char *ptr = strstr((char *)rxBuff, "+CSQ:");
if (ptr)
{
int csq;
if (sscanf(ptr, "+CSQ: %d", &csq) == 1)
{
gsm_signal_strength = csq;
}
}
}
// ... existing code ...
// 新增网络状态检查和重连函数
// ... existing code ...
// 添加全局变量
static uint32_t last_check_time = 0;
static uint8_t reconnect_count = 0;
#define MAX_RECONNECT_ATTEMPTS 3
#define CHECK_INTERVAL 60000 // 60秒检查一次
// 新增网络状态检查和重连函数
void Check_4G_Connection(void)
{
uint32_t current_time = HAL_GetTick();
// 每60秒检查一次连接状态
if(current_time - last_check_time >= CHECK_INTERVAL)
{
last_check_time = current_time;
// 清空缓冲区
memset(rxBuff, 0, sizeof(rxBuff));
rxDataSize = 0;
// 检查MQTT连接状态
Inf_4G_SendAtCmd("AT+QMTCONN?\r\n");
HAL_Delay(100);
// 只有当MQTT未连接时才进行重连
if(!strstr((char *)rxBuff, "+QMTCONN: 0,3"))
{
// printf("MQTT连接断开尝试重新连接...\n");
if(reconnect_count < MAX_RECONNECT_ATTEMPTS)
{
reconnect_count++;
Inf_EC800_MQTT_Init(); // 只重新初始化MQTT连接
// printf("MQTT重连尝试 %d/%d\n", reconnect_count, MAX_RECONNECT_ATTEMPTS);
}
else
{
// printf("MQTT重连失败次数过多请检查网络状态\n");
}
}
else
{
// 连接正常,重置重连计数
reconnect_count = 0;
}
}
}
// 添加获取ICCID的函数
void Get_ICCID(void)
{
memset(rxBuff, 0, sizeof(rxBuff));
rxDataSize = 0;
Inf_4G_SendAtCmd("AT+QCCID\r\n");
HAL_Delay(100);
// 解析ICCID
char *ptr = strstr((char *)rxBuff, "+QCCID:");
if (ptr)
{
// 跳过"+QCCID: "直接获取ICCID
ptr += 8; // 跳过"+QCCID: "
// 去除可能的空格和换行符
while (*ptr == ' ') ptr++;
// 复制ICCID到sim_iccid变量
strncpy(sim_iccid, ptr, ICCID_LENGTH - 1);
sim_iccid[ICCID_LENGTH - 1] = '\0'; // 确保字符串结束
}
}