859 lines
31 KiB
C
859 lines
31 KiB
C
#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;
|
||
// 缓冲区定义
|
||
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, 128);
|
||
}
|
||
}
|
||
|
||
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");
|
||
// 获取初始信号强度
|
||
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 = value;
|
||
break;
|
||
|
||
case MODE_FLUSH:
|
||
FLUSH_HIGH_PUMP_ON_TIME = 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)
|
||
{
|
||
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)
|
||
{
|
||
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)
|
||
{
|
||
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)
|
||
{
|
||
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; // 重置计时器
|
||
// printf("设置臭氧开启时间: %d分钟\n", value);
|
||
}
|
||
// 臭氧关闭时间设置
|
||
else if (sscanf(jsonStr, "{\"X21\":%d}", &value) == 1)
|
||
{
|
||
OZONE_OFF_TIME = value;
|
||
ozone_timer = 0; // 重置计时器
|
||
// 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_running = 1;
|
||
phosphorus_timer = 0;
|
||
polarity_state = !polarity_state;
|
||
electrode_Init(value); // 调用函数启用除磷
|
||
}
|
||
else
|
||
{
|
||
// 停止除磷
|
||
electrode_Init(value); // 调用函数禁用除磷
|
||
phosphorus_running = 0;
|
||
}
|
||
}
|
||
else if (sscanf(jsonStr, "{\"X51\":%d}", &value) == 1)
|
||
{
|
||
Set_Phosphorus_Runtime(value); // 设置运行时间
|
||
// printf("设置除磷运行时间为:%d分钟\n", value);
|
||
}
|
||
// 设置除磷停止时间(X34)
|
||
else if (sscanf(jsonStr, "{\"X52\":%d}", &value) == 1)
|
||
{
|
||
Set_Phosphorus_StopTime(value); // 设置停止时间
|
||
// printf("设置除磷停止时间为:%d分钟\n", value);
|
||
}
|
||
// 添加培菌模式专用控制按钮
|
||
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();
|
||
Print_Temperature();
|
||
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
|
||
"}",
|
||
// 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
|
||
bizohi, // 光伏市电检测状态 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
|
||
// Get_System_State(), // 排泥状态 X59
|
||
base_energy // 将电量值添加到JSON中 X300
|
||
);
|
||
|
||
// 发送数据
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
|