#include "esp8266.h"
#include "main.h" // 添加此头文件以解决DebugPrint声明问题
#include <string.h>
#include <stdio.h>
// 全局变量定义
uint8_t wifiConnected = 0;
uint8_t oneNetConnected = 0;
uint8_t remote_led_command = 0;
uint8_t remote_motor_command = 0;
uint8_t new_remote_command = 0;
uint32_t uploadSuccessCount = 0;
uint32_t uploadFailCount = 0;
// 使用串口3 (PB10, PB11)
extern UART_HandleTypeDef huart3;
// 私有函数声明
static void ESP8266_Transmit(const char *data);
static void ESP8266_Flush(void);
static uint8_t ESP8266_WaitResponse(const char *expected, uint32_t timeout);
// 使用您提供的参数
const char* ONENET_HOST = "mqtts.heclouds.com";
const int ONENET_PORT = 1883;
const char* ONENET_CLIENT_ID = "jiaju";
const char* ONENET_USERNAME = "3n8QY47l17";
const char* ONENET_PASSWORD = "version=2018-10-31&res=products%2F3n8QY47l17%2Fdevices%2Fjiaju&et=2052972807&method=md5&sign=s1lLnOPwHXQNilx%2FJrdi6g%3D%3D";
const char* ONENET_TOPIC_PUB = "$sys/3n8QY47l17/jiaju/thing/property/post";
const char* ONENET_TOPIC_CMD = "$sys/3n8QY47l17/jiaju/cmd/request/#"; // 修改后的命令主题
void ESP8266_Init(void) {
// 确保串口已初始化
HAL_Delay(500);
// 清空串口缓冲区
ESP8266_Flush();
// 发送复位命令
ESP8266_SendCommand("AT+RST\r\n", "ready", 3000);
HAL_Delay(2000);
// 设置WiFi模式为STA
ESP8266_SendCommand("AT+CWMODE=1\r\n", "OK", 1000);
// 关闭回显
ESP8266_SendCommand("ATE0\r\n", "OK", 500);
// 启用MQTT透传模式
ESP8266_SendCommand("AT+MQTTCONNCFG=0,120,1,\"\"\r\n", "OK", 1000);
// 设置MQTT协议版本为3.1.1
ESP8266_SendCommand("AT+MQTTUSERCFG=0,4,\"\",\"\",\"\",0,0,\"\"\r\n", "OK", 1000);
}
void ESP8266_ConnectWiFi(const char* ssid, const char* password) {
char cmd[128];
sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, password);
if(ESP8266_SendCommand(cmd, "OK", 15000)) {
wifiConnected = 1;
} else {
wifiConnected = 0;
}
}
void ESP8266_ConnectOneNet(void) {
char cmd[256];
sprintf(cmd, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n",
ONENET_CLIENT_ID, ONENET_USERNAME, ONENET_PASSWORD);
if(!ESP8266_SendCommand(cmd, "OK", 2000)) {
return;
}
sprintf(cmd, "AT+MQTTCONN=0,\"%s\",%d,1\r\n", ONENET_HOST, ONENET_PORT);
if(ESP8266_SendCommand(cmd, "+MQTTCONNECTED", 10000)) {
oneNetConnected = 1;
// 订阅新的命令主题(带#通配符)
sprintf(cmd, "AT+MQTTSUB=0,\"%s\",1\r\n", ONENET_TOPIC_CMD);
ESP8266_SendCommand(cmd, "OK", 2000);
} else {
oneNetConnected = 0;
}
}
void ESP8266_SendData(float temp, float humi, uint8_t led_status, uint8_t motor_status) {
static uint32_t request_id = 1;
char cmd[200];
char value_str[20];
// 1. 发送温度
snprintf(value_str, sizeof(value_str), "%.1f", temp);
sprintf(cmd,
"AT+MQTTPUB=0,\"%s\","
"\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":"
"{\\\"temperature\\\":{\\\"value\\\":%s}}}\","
"1,0\r\n",
ONENET_TOPIC_PUB, request_id++, value_str);
ESP8266_SendCommand(cmd, "OK", 2000);
// 2. 发送湿度
snprintf(value_str, sizeof(value_str), "%.1f", humi);
sprintf(cmd,
"AT+MQTTPUB=0,\"%s\","
"\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":"
"{\\\"humidity\\\":{\\\"value\\\":%s}}}\","
"1,0\r\n",
ONENET_TOPIC_PUB, request_id++, value_str);
ESP8266_SendCommand(cmd, "OK", 2000);
// 3. 发送LED状态
const char* led_value = led_status ? "true" : "false";
sprintf(cmd,
"AT+MQTTPUB=0,\"%s\","
"\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":"
"{\\\"led\\\":{\\\"value\\\":%s}}}\","
"1,0\r\n",
ONENET_TOPIC_PUB, request_id++, led_value);
ESP8266_SendCommand(cmd, "OK", 2000);
// 4. 发送电机状态
sprintf(cmd,
"AT+MQTTPUB=0,\"%s\","
"\"{\\\"id\\\":\\\"%lu\\\"\\,\\\"params\\\":"
"{\\\"motor\\\":{\\\"value\\\":%d}}}\","
"1,0\r\n",
ONENET_TOPIC_PUB, request_id++, motor_status);
ESP8266_SendCommand(cmd, "OK", 2000);
// 更新上传统计
uploadSuccessCount += 4;
}
uint8_t ESP8266_SendCommand(const char *cmd, const char *expected, uint32_t timeout) {
ESP8266_Transmit(cmd);
uint8_t result = ESP8266_WaitResponse(expected, timeout);
// 增强错误处理 - 记录错误响应
if (!result) {
// 使用串口直接输出错误信息(因为DebugPrint可能不可用)
char errorMsg[128];
snprintf(errorMsg, sizeof(errorMsg), "CMD Error: %s\r\n", cmd);
HAL_UART_Transmit(&huart3, (uint8_t *)errorMsg, strlen(errorMsg), HAL_MAX_DELAY);
}
return result;
}
static void ESP8266_Transmit(const char *data) {
HAL_UART_Transmit(&huart3, (uint8_t *)data, strlen(data), HAL_MAX_DELAY);
}
static void ESP8266_Flush(void) {
uint8_t dummy;
while (HAL_UART_Receive(&huart3, &dummy, 1, 10) == HAL_OK) {}
}
static uint8_t ESP8266_WaitResponse(const char *expected, uint32_t timeout) {
char response[256] = {0};
uint32_t start = HAL_GetTick();
uint8_t index = 0;
uint8_t found = 0;
while ((HAL_GetTick() - start) < timeout) {
if (HAL_UART_Receive(&huart3, (uint8_t *)&response[index], 1, 10) == HAL_OK) {
if (strstr(response, expected) != NULL) {
found = 1;
break;
}
if (strstr(response, "ERROR") != NULL ||
strstr(response, "FAIL") != NULL) {
break;
}
if (index < sizeof(response) - 1) {
index++;
} else {
memmove(response, response + 128, 128);
index = 128;
}
}
}
return found;
}
void ESP8266_SendPing(void) {
ESP8266_SendCommand("AT+MQTTPING=0\r\n", "OK", 1000);
}
void ESP8266_ProcessResponses(void) {
static char response[512] = {0};
static uint8_t index = 0;
uint8_t received;
if (HAL_UART_Receive(&huart3, (uint8_t *)&received, 1, 0) == HAL_OK) {
if (index < sizeof(response) - 1) {
response[index++] = received;
response[index] = '\0';
if (index >= 2 && response[index-2] == '\r' && response[index-1] == '\n') {
response[index-2] = '\0';
// 检查连接状态消息
if (strstr(response, "WIFI GOT IP")) {
wifiConnected = 1;
}
if (strstr(response, "+MQTTCONNECTED")) {
oneNetConnected = 1;
}
if (strstr(response, "+MQTTDISCONNECTED")) {
oneNetConnected = 0;
}
// 处理订阅的消息(使用新的命令主题)
if (strstr(response, "+MQTTSUBRECV:") && strstr(response, "cmd/request")) {
// 解析远程命令
ParseRemoteCommand(response);
}
index = 0;
response[0] = '\0';
}
} else {
index = 0;
response[0] = '\0';
}
}
}
void ParseRemoteCommand(const char *message) {
// 重置命令状态
remote_led_command = 0;
remote_motor_command = 0;
// 定义本地变量用于解析(修复未定义错误)
char* led_ptr = NULL;
char* motor_ptr = NULL;
char received_command = 0;
// 查找JSON消息体
char* msg_body = strstr(message, "\"body\":");
if (!msg_body) {
// 尝试旧格式处理
led_ptr = strstr(message, "\"led\":");
if (led_ptr) {
remote_led_command = (strstr(led_ptr, "true") || strstr(led_ptr, "1")) ? 1 : 0;
}
motor_ptr = strstr(message, "\"motor\":");
if (motor_ptr) {
if (strstr(motor_ptr, "1")) {
remote_motor_command = 1;
} else if (strstr(motor_ptr, "2")) {
remote_motor_command = 2;
}
}
} else {
// 新版JSON格式处理(带"body"结构)
led_ptr = strstr(msg_body, "\"led\":");
if (led_ptr) {
// 向前移动到值位置
char* value_start = strchr(led_ptr, ':') + 1;
// 跳过空格
while (*value_start == ' ') value_start++;
if (strncmp(value_start, "true", 4) == 0 ||
*value_start == '1') {
remote_led_command = 1;
} else if (strncmp(value_start, "false", 5) == 0 ||
*value_start == '0') {
remote_led_command = 0;
}
}
motor_ptr = strstr(msg_body, "\"motor\":");
if (motor_ptr) {
// 向前移动到值位置
char* value_start = strchr(motor_ptr, ':') + 1;
// 跳过空格
while (*value_start == ' ') value_start++;
if (*value_start == '1') {
remote_motor_command = 1;
} else if (*value_start == '2') {
remote_motor_command = 2;
} else if (*value_start == '0') {
remote_motor_command = 0;
}
}
}
// 检查是否接收到有效命令
if (led_ptr || motor_ptr) {
new_remote_command = 1;
received_command = 1;
// 通过串口输出命令内容(因为DebugPrint可能不可用)
char cmd_info[80];
snprintf(cmd_info, sizeof(cmd_info), "Received CMD: led=%d, motor=%d\r\n",
remote_led_command, remote_motor_command);
HAL_UART_Transmit(&huart3, (uint8_t *)cmd_info, strlen(cmd_info), HAL_MAX_DELAY);
}
// 检查平台属性设置响应
if (strstr(message, "SetProperty")) {
// 通过串口输出属性设置响应
char response_msg[60];
snprintf(response_msg, sizeof(response_msg), "Property set: %s\r\n",
strstr(message, "success") ? "Success" : "Failure");
HAL_UART_Transmit(&huart3, (uint8_t *)response_msg, strlen(response_msg), HAL_MAX_DELAY);
}
}
这是我现在的代码,还是报错1022,请检查哪里有错误
最新发布