#include "esp8266.h"
#include "main.h"
#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);
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) == 0) {
return;
}
sprintf(cmd, "AT+MQTTCONN=0,\"%s\",%d,1\r\n", ONENET_HOST, ONENET_PORT);
if(ESP8266_SendCommand(cmd, "+MQTTCONNECTED", 10000)) {
oneNetConnected = 1;
// 订阅命令主题(使用下行命令主题)
uint8_t retry = 3;
while(retry-- > 0) {
sprintf(cmd, "AT+MQTTSUB=0,\"%s\",1\r\n", ONENET_TOPIC_CMD);
if(ESP8266_SendCommand(cmd, "OK", 2000)) {
break;
}
HAL_Delay(500);
}
} 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);
return ESP8266_WaitResponse(expected, timeout);
}
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, "/thing/command/post")) {
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;
// 查找JSON起始位置
char* json_start = strchr(message, '{');
if (!json_start) return;
// 查找LED命令
char* led_ptr = strstr(json_start, "\"led\"");
if (led_ptr) {
char* value_ptr = strchr(led_ptr, ':');
if (value_ptr) {
value_ptr++;
// 跳过空格
while(*value_ptr == ' ') value_ptr++;
if (strncmp(value_ptr, "true", 4) == 0 ||
*value_ptr == '1') {
remote_led_command = 1;
}
}
}
// 查找电机命令
char* motor_ptr = strstr(json_start, "\"motor\"");
if (motor_ptr) {
char* value_ptr = strchr(motor_ptr, ':');
if (value_ptr) {
value_ptr++;
// 跳过空格
while(*value_ptr == ' ') value_ptr++;
if (*value_ptr == '1') {
remote_motor_command = 1;
} else if (*value_ptr == '2') {
remote_motor_command = 2;
} else if (*value_ptr == '0') {
remote_motor_command = 0;
}
}
}
// 设置新命令标志
if (led_ptr || motor_ptr) {
new_remote_command = 1;
}
}
设备名称(clientID):jiaju
产品ID(username):3n8QY47l17
password:version=2018-10-31&res=products%2F3n8QY47l17%2Fdevices%2Fjiaju&et=2052972807&method=md5&sign=s1lLnOPwHXQNilx%2FJrdi6g%3D%3D
url:mqtts.heclouds.com
端口号:1883
订阅:$sys/3n8QY47l17/jiaju/thing/property/post/reply
发布:$sys/3n8QY47l17/jiaju/thing/property/post
检查我哪里有错
最新发布