#include "CONFIG.h" #if ESP32 #include "stm32f10x.h" #include #include #include #include #include "esp32.h" #include "Common_Util.h" #include "Log_Module.h" #include "At_Module.h" /******************************************* 基于ESP32_C3模组的相关方法声明 *******************************************/ void esp32_reset(void); //1.重置状态。该文件中的方法共用状态,在使用下面的方法前需要重置一下状态。 void esp32_exit_deepsleep(void); //2.退出深休眠 void esp32_enter_deepsleep(void); //3.进入深休眠 void esp32_exit_lightsleep(void); //4.退出浅休眠 void esp32_enter_lightsleep(void); //5.进入浅休眠 enum Result esp32_set_lightsleep_wakeup(uint8_t source, uint8_t gpio, uint8_t mode); //6.设置浅睡眠唤醒源 enum Result esp32_set_lightsleep_wakeup_sync(uint8_t source, uint8_t gpio, uint8_t mode); //7.设置浅睡眠唤醒源-同步 enum Result esp32_set_sleep(uint8_t mode); //8.设置睡眠模式 enum Result esp32_set_sleep_sync(uint8_t mode); //9.设置睡眠模式-同步 enum Result esp32_connect_ap(char * id, char * password); //10.连接AP enum Result esp32_connect_ap_sync(char * id, char * password); //11.连接AP-同步 enum Result esp32_set_cipmode(uint8_t mode); //12.设置传输模式 enum Result esp32_set_cipmode_sync(uint8_t mode); //13.设置传输模式-同步 enum Result esp32_connect_network(char * service_type, char * IP_address, uint16_t remote_port); //14.连接TCP/UDP服务器 enum Result esp32_connect_network_sync(char * service_type, char * IP_address, uint16_t remote_port); //15.连接TCP/UDP服务器-同步 enum Result esp32_query_id_signal(char * ID, int * RSSI); //16.查询指定ID的WiFi信号强度 enum Result esp32_query_id_signal_sync(char * ID, int * RSSI); //17.查询指定ID的WiFi信号强度-同步 enum Result esp32_close_network(void); //18.关闭TCP/UDP连接 enum Result esp32_close_network_sync(void); //19.关闭TCP/UDP连接-同步 enum Result esp32_autoconnect_ap(uint8_t mode); //20.是否自动连接AP enum Result esp32_autoconnect_ap_sync(uint8_t mode); //21.是否自动连接AP-同步 enum Result esp32_close_ap(void); //22.关闭AP连接 enum Result esp32_close_ap_sync(void); //23.关闭AP连接-同步 enum Result esp32_query_signal(int * RSSI); //24.查询已连接WiFi的信号强度 enum Result esp32_query_signal_sync(int * RSSI); //25.查询已连接WiFi的信号强度-同步 enum Result esp32_ready(void); //26.模块是否启动-初始化处理专用 enum Result esp32_ready_sync(void); //27.模块是否启动-同步 enum Result esp32_handle_data(uint8_t * data, uint16_t send_data_length, uint16_t *recv_data_length); //28.处理数据(数据发送+等待发送结果) enum Result esp32_handle_data_sync(uint8_t * data, uint16_t send_data_length, uint16_t *recv_data_length); //29.处理数据(数据发送+等待发送结果)-同步 enum Result esp32_recv_ready(void); //30.判断模块是否正常启动 enum Result esp32_recv_ready_with_time(uint32_t time_out); //31.判断模块是否正常启动+等待时间 /*************************************************** AT指令相关函数 ***************************************************/ //AT指令数组 static char AT_CMD[256]; //发送AT指令 二进制 static void send_data(uint8_t * data, uint16_t length) { AT_Send_Bytes(data, length); } // 发送AT指令 字符串 static uint8_t send_at_string(char * cmd) { uint8_t state = 0; if(AT_Get_Status() == AT_Status_None) { // 发送AT指令 AT_Send_String(cmd); state = 1; } return state; } /******************************************* 基于ESP32_C3模组的相关执行函数 *********************************************/ // 获取状态 static enum STATUS getStatus(void) { return esp32.status; } // 设置状态 static void setStatus(enum STATUS status) { esp32.status = status; } // 获取定时 static uint32_t getTimerMs(void) { return time_get_delay(&esp32.timer); } // 清除定时 static void clearTimer(void) { time_clear(&esp32.timer); } // 设置定时 //static void setTimerMs(uint32_t time) //{ // esp32.timer_ms = time; //} // 获取ID static uint8_t getActiveID(void) { return esp32.activeID; } //设置ID static void setActiveID(uint8_t activeID) { esp32.activeID = activeID; } // 验证ID static uint8_t verifyActiveID(uint8_t activeID) { if(getActiveID() == 0 || getActiveID() == activeID){ return 1; } else { Log_Printf_Debug("activeID repetition!\r\n"); return 0; } } // 返回超时结果 static enum Result overtime(void) { setStatus(Status_Overtime); // 超时 return Result_Failed; // 结果 } // 返回成功结果 static enum Result success(void) { setStatus(Status_Success); //成功 return Result_Success; //结果 } // 返回成功结果 static enum Result success_no_log(void) { // 成功 setStatus(Status_Success); // 结果 return Result_Success; } //// 返回失败结果 //static enum Result failed(void) //{ // setStatus(Status_Failed); //失败 // return Result_Failed; //结果 //} // 返回失败结果 static enum Result failed(int type) { // 失败 setStatus(Status_Failed); if(type == 1) { Log_Printf_Debug("activeID: %d, error: 接收结果过期,请重置状态\r\n", esp32.activeID); // 打印日志 } else if(type == 2) { // 发送日志 Log_Printf_Debug("activeID: %d, AT接收失败: %d\r\n", esp32.activeID, AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); } else { Log_Printf_Debug("activeID: %d, error: 未知错误类型\r\n", esp32.activeID); // 打印日志 } // 失败结果 return Result_Failed; } // 发送指令并改变状态 enum Result send_at(char * cmd, uint8_t activeID) { Log_Printf_Debug(cmd); // 打印AT指令 if(send_at_string(cmd)) // 发送AT指令 { setActiveID(activeID); // 活动ID setStatus(Status_Sending); // 设置已发送 clearTimer(); // 重置计时 return Result_None; // 未知结果 } else { Log_Printf_Debug("AT指令发送失败\r\n"); // 打印日志 return Result_Failed; // 失败结果 } } // 1.重置状态 void esp32_reset(void) { setStatus(Status_None); // 重置状态 setActiveID(0); // 重置ID clearTimer(); // 重置计时 AT_Clear(); // 清除AT指令 } //2.退出深休眠 void esp32_exit_deepsleep(void) { GPIO_SetBits(WAKE_GPIO, WAKE_GPIO_Pin); // 拉高IO口,使能ESP32_C3模组 } //3.进入深休眠 void esp32_enter_deepsleep(void) { GPIO_ResetBits(WAKE_GPIO, WAKE_GPIO_Pin); // 拉低IO口,使ESP32_C3模组失能 } //4.退出浅休眠 (使用此功能需先配置浅休眠模式) void esp32_exit_lightsleep(void) { // GPIO_SetBits(WAKE_GPIO, LIGHT_SLEEP_GPIO_Pin); // 拉高IO口,使ESP32_C3模组退出浅休眠 } //5.进入浅休眠 (使用此功能需先配置浅休眠模式) void esp32_enter_lightsleep(void) { // GPIO_ResetBits(WAKE_GPIO, LIGHT_SLEEP_GPIO_Pin);// 拉低IO口,使ESP32_C3模组进入浅休眠 } /****************************************************************************** * 6.设置浅睡眠唤醒源 * param1: source 代表唤醒源 (0:保留配置 1:保留配置 2:GPIO唤醒) * param2: gpio (唤醒源为GPIO时,代表GPIO管脚) * param3: mode (唤醒源为GPIO时,该参数表示唤醒电平。 0:低电平唤醒 1:高电平唤醒) * *******************************************************************************/ enum Result esp32_set_lightsleep_wakeup(uint8_t source, uint8_t gpio, uint8_t mode) { enum Result result = Result_None; int activeID = 11, time=500; // 活动ID, 超时时间 //校验参数 if(source != 2) //本模块浅休眠唤醒模式采用GPIO唤醒 { Log_Printf_Debug("set lightsleep wakeup error!\r\n"); return Result_Failed; } // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { sprintf(AT_CMD, "AT+SLEEPWKCFG=%d,%d,%d\r\n",source,gpio,mode); // 拼接AT指令 result = send_at(AT_CMD, activeID); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 result = overtime(); // 超时 } else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = success(); // 成功 } else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = failed(2); // 失败 } return result; } //7.设置浅睡眠唤醒源-同步 enum Result esp32_set_lightsleep_wakeup_sync(uint8_t source, uint8_t gpio, uint8_t mode) { enum Result result = Result_None; while(1) { result = esp32_set_lightsleep_wakeup(source, gpio, mode); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /****************************************************************************** * 8.设置睡眠模式 * param1: mode 代表睡眠模式 (0:禁用睡眠模式 1:Modem-sleep模式 2:Light-sleep模式 3:Modem-sleep listen interval模式) * *******************************************************************************/ enum Result esp32_set_sleep(uint8_t mode) { enum Result result = Result_None; int activeID = 12, time=500; // 活动ID, 超时时间 //校验参数 if(mode != 2) //本模块采用浅休眠模式 { Log_Printf_Debug("set sleep mode error!\r\n"); return Result_Failed; } // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { sprintf(AT_CMD, "AT+SLEEP=%d\r\n",mode); // 拼接AT指令 result = send_at(AT_CMD, activeID); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 result = overtime(); // 超时 } else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = success(); // 成功 } else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = failed(2); // 失败 } return result; } //9.设置睡眠模式-同步 enum Result esp32_set_sleep_sync(uint8_t mode) { enum Result result = Result_None; while(1) { result = esp32_set_sleep(mode); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /****************************************************************************** * 10.连接AP * param1: id 目标名称 * param2: password 密码 * *******************************************************************************/ enum Result esp32_connect_ap(char * id, char * password) { enum Result result = Result_None; int activeID = 13, time=5000; // 活动ID, 超时时间 // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { sprintf(AT_CMD, "AT+CWJAP=\"%s\",\"%s\"\r\n", id, password); // 拼接AT指令 result = send_at(AT_CMD, activeID); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 result = overtime(); // 超时 } else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = success(); // 成功 } else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = failed(2); // 失败 } return result; } //11.连接AP-同步 enum Result esp32_connect_ap_sync(char * id, char * password) { enum Result result = Result_None; while(1) { result = esp32_connect_ap(id, password); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /************************************************************************************* * 12.设置数据传输模式 * param1: mode(0:普通传输模式 1:WiFi透传接收模式,支持TCP单连接、UDP固定通信对端的情况) * **************************************************************************************/ enum Result esp32_set_cipmode(uint8_t mode) { enum Result result = Result_None; int activeID = 14, time=500; // 活动ID, 超时时间 //校验参数 if(mode != 0) //本模块采用普通模式 { Log_Printf_Debug("set cipmode error!\r\n"); return Result_Failed; } // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { sprintf(AT_CMD, "AT+CIPMODE=%d\r\n", mode); // 拼接AT指令 result = send_at(AT_CMD, activeID); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 result = overtime(); // 超时 } else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = success(); // 成功 } else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = failed(2); // 失败 } return result; } //13.设置传输模式-同步 enum Result esp32_set_cipmode_sync(uint8_t mode) { enum Result result = Result_None; while(1) { result = esp32_set_cipmode(mode); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /****************************************************************************** * 14.连接TCP/UDP服务器 * param1: host远程地址 * param2: port远程端口 * *******************************************************************************/ enum Result esp32_connect_network(char * service_type, char * IP_address, uint16_t remote_port) { enum Result result = Result_None; int activeID = 15, time=5000; // 活动ID, 超时时间 // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { sprintf(AT_CMD, "AT+CIPSTART=\"%s\",\"%s\",%d\r\n", service_type, IP_address, remote_port); // 拼接AT指令 result = send_at(AT_CMD, activeID); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 result = overtime(); // 超时 } else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = success(); // 成功 } else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = failed(2); // 失败 } return result; } //15.连接TCP/UDP服务器服务器-同步 enum Result esp32_connect_network_sync(char * service_type, char * IP_address, uint16_t remote_port) { enum Result result = Result_None; while(1) { result = esp32_connect_network(service_type, IP_address, remote_port); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /****************************************************************************** * 16.查询指定ID的WiFi信号强度 * param1: ID 指定的WIFI名称 * *******************************************************************************/ enum Result esp32_query_id_signal(char * ID, int * RSSI) { enum Result result = Result_None; int activeID = 66, time=5000; // 活动ID, 超时时间 // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { sprintf(AT_CMD, "AT+CWLAP=\"%s\"\r\n",ID); // 拼接AT指令 result = send_at(AT_CMD, activeID); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 result = overtime(); // 超时 } else if(strstr((char * )AT_result(), "OK") != NULL) // 查询是否返回 { if(strstr((char * )AT_result(), "CWLAP") != NULL) { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); // 处理返回结果 char * saveptr = NULL; char * split = ","; strtok_r((char * )AT_result(), split, &saveptr); strtok_r(NULL, split, &saveptr); * RSSI = atoi(strtok_r(NULL, split, &saveptr)); //打印信号强度值 Log_Printf_Debug("指定ID的WiFi强度值:%d\r\n", * RSSI); result = success(); // 成功 } else { // 发送日志 Log_Printf_Debug("返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = failed(2); // 失败 } } return result; } //17.查询指定ID的WiFi信号强度-同步 enum Result esp32_query_id_signal_sync(char * ID, int * RSSI) { enum Result result = Result_None; while(1) { result = esp32_query_id_signal(ID, RSSI); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /****************************************************************************** * 18.关闭TCP/UDP链接 * *******************************************************************************/ enum Result esp32_close_network(void) { enum Result result = Result_None; int activeID = 17, time=1000; // 活动ID, 超时时间 // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { sprintf(AT_CMD, "AT+CIPCLOSE\r\n"); // 拼接AT指令 result = send_at(AT_CMD, activeID); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 result = overtime(); // 超时 } else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = success(); // 成功 } else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); Log_Printf_Debug("当前无UDP网络连接\r\n"); result = success(); // 同样返回成功 } return result; } //19.关闭TCP/UDP连接-同步 enum Result esp32_close_network_sync(void) { enum Result result = Result_None; while(1) { result = esp32_close_network(); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /****************************************************************************** * 20.是否自动连接AP * param1: mode(0:上电不自动连接AP 1:上电自动连接 AP) 本设置保存到NVS区域 * *******************************************************************************/ enum Result esp32_autoconnect_ap(uint8_t mode) { enum Result result = Result_None; int activeID = 18, time=500; // 活动ID, 超时时间 //校验参数 if(mode != 0) //本系统关闭自动连接AP模式 { Log_Printf_Debug("set autoconnect mode error!\r\n"); return Result_Failed; } // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { sprintf(AT_CMD, "AT+CWAUTOCONN=%d\r\n", mode); // 拼接AT指令 result = send_at(AT_CMD, activeID); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 result = overtime(); // 超时 } else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = success(); // 成功 } else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = failed(2); // 失败 } return result; } //21.是否自动连接AP-同步 enum Result esp32_autoconnect_ap_sync(uint8_t mode) { enum Result result = Result_None; while(1) { result = esp32_autoconnect_ap(mode); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /****************************************************************************** * 22.关闭AP连接 * *******************************************************************************/ enum Result esp32_close_ap(void) { enum Result result = Result_None; int activeID = 17, time=500; // 活动ID, 超时时间 // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { sprintf(AT_CMD, "AT+CWQAP\r\n"); // 拼接AT指令 result = send_at(AT_CMD, activeID); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 result = overtime(); // 超时 } else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = success(); // 成功 } else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = failed(2); // 失败 } return result; } //23.关闭AP连接-同步 enum Result esp32_close_ap_sync(void) { enum Result result = Result_None; while(1) { result = esp32_close_ap(); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /****************************************************************************** * 24.查询WiFi信号强度 * param1: RSSI信号强度值 * *******************************************************************************/ enum Result esp32_query_signal(int * RSSI) { enum Result result = Result_None; int activeID = 19, time=5000; // 活动ID, 超时时间 // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { sprintf(AT_CMD, "AT+CWJAP?\r\n"); // 拼接AT指令 result = send_at(AT_CMD, activeID); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 result = overtime(); // 超时 } else if(strstr((char * )AT_result(), "OK") != NULL) // 查询是否返回 { if(strstr((char * )AT_result(), "CWJAP") != NULL) { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); // 处理返回结果 char * saveptr = NULL; char * split = ","; strtok_r((char * )AT_result(), split, &saveptr); strtok_r(NULL, split, &saveptr); strtok_r(NULL, split, &saveptr); * RSSI = atoi(strtok_r(NULL, split, &saveptr)); //打印信号强度值 Log_Printf_Debug("WiFi信号强度RSSI值: %d\r\n", *RSSI); result = success(); // 成功 } else { // 发送日志 Log_Printf_Debug("返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = failed(2); // 失败 } } else if(strstr((char * )AT_result(), "ERROR") != NULL) { // 发送日志 Log_Printf_Debug("返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = failed(2); // 失败 } return result; } //25.查询WiFi信号强度-同步 enum Result esp32_query_signal_sync(int * RSSI) { enum Result result = Result_None; while(1) { result = esp32_query_signal(RSSI); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /****************************************************************************** * 26.模块是否重启 * *******************************************************************************/ enum Result esp32_ready(void) { if(AT_Get_Status() != AT_Status_None) { return Result_None; } enum Result result = Result_None; // 判断是否接收到 if(strstr((char *)AT_result(),"ready") != 0) { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); // 成功结果 result = Result_Success; // 清理一下AT返回结果缓存 AT_Clear_Result(); } return result; } // 27.模块是否重启 enum Result esp32_ready_sync(void) { enum Result result = Result_None; while(1) { result = esp32_ready(); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /****************************************************************************** * 28.数据处理 * *******************************************************************************/ enum Result esp32_handle_data(uint8_t * data, uint16_t send_data_length, uint16_t *recv_data_length) { enum Result result = Result_None; int activeID = 30, time=5000; // 活动ID, 超时时间 // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { sprintf(AT_CMD, "AT+CIPSEND=%d\r\n",send_data_length); // 拼接AT指令 result = send_at(AT_CMD, activeID); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 result = overtime(); // 超时 } else if(strstr((char * )AT_result(), "OK\r\n\r\n>") != NULL) // 有响应 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); //发送数据 send_data(data, send_data_length); // 清理一下AT返回结果缓存 AT_Clear_Result(); // memset(data, 0, send_data_length); } else if(strstr((char * )AT_result(), "+IPD") != NULL) { // 防止接收不完整 uint32_t last_time = AT_wait_time(); if(last_time > 20) // 过10ms之后再取数据,避免数据截断。 { // 发送日志 Log_Printf_Debug("\r\nAT返回: %d, time_diff: %d\r\n", AT_result_length(), last_time); // Log_SendHex(AT_result(), AT_result_length()); char * saveptr1 = NULL; char * saveptr2 = NULL; char * split1 = ","; char * split2 = ":"; char * line1 = strtok_r((char * )AT_result(), split2, &saveptr1); uint8_t Line1_Len = strlen(line1); strtok_r(line1, split1, &saveptr2); char * length = strtok_r(NULL, split1, &saveptr2); * recv_data_length = strtoul(length, NULL, 10); //判断数据是否完整接收 if(* recv_data_length > AT_result_length()) { Log_Printf_Debug("数据接收出错!!!\r\n"); // 失败 result = Result_Failed; // 清理一下AT返回结果缓存 AT_Clear_Result(); return result; } uint16_t line_length = Line1_Len+1; // 内存拷贝 memcpy(data, AT_result() + line_length, * recv_data_length); // 成功 result = Result_Success; // 清理一下AT返回结果缓存 AT_Clear_Result(); } } else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回 { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); result = failed(2); // 失败 } return result; } //29.数据处理-同步 enum Result esp32_handle_data_sync(uint8_t * data, uint16_t send_data_length, uint16_t *recv_data_length) { enum Result result = Result_None; while(1) { result = esp32_handle_data( data, send_data_length, recv_data_length); if(result != Result_None) { // 重置 esp32.reset(); break; } } return result; } /****************************************************************************** * 30.判断模块是否正常启动 * *******************************************************************************/ enum Result esp32_recv_ready(void) { // 设置AT为使用中,防止被其他程序占用 AT_Set_Status(AT_Status_Using); enum Result result = Result_None; // 校验参数 char cmp[20]; sprintf(cmp, "ready"); // 拼接AT指令 // 判断是否接收到 if(strstr((char * )AT_result(), cmp) != NULL) { // 发送日志 Log_Printf_Debug("AT返回: %d\r\n", AT_result_length()); Log_SendArray_Debug(AT_result(), AT_result_length()); // 成功 result = Result_Success; // 清理一下AT返回结果缓存 AT_Clear_Result(); } return result; } //31.判断模块是否正常启动+等待时间 enum Result esp32_recv_ready_with_time(uint32_t time_out) { enum Result result = Result_None; int activeID = 99, time = time_out; // 活动ID, 超时时间 // 校验ID if(!verifyActiveID(activeID)){ return Result_Failed; } // 判断状态 if(getStatus() == Status_None) // 空闲状态 { setStatus(Status_Sending); } else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 { result = failed(1); // 失败 } else if(getTimerMs() > time) // 正在发送状态。判断超时 { result = overtime(); // 超时 } else { // 接收数据 result = esp32.recv_ready(); if(result == Result_Success) { result = success_no_log(); // 成功 } } return result; } ///***************************************** 测试用*****************************************/ //enum Result esp32_at(void) //{ // enum Result result = Result_None; // int activeID = 88, time=500; // 活动ID, 超时时间 // // // 校验ID // if(!verifyActiveID(activeID)){ return Result_Failed; } // // 判断状态 // if(getStatus() == Status_None) // 空闲状态 // { // sprintf(AT_CMD, "AT\r\n"); // 拼接AT指令 // result = send_at(AT_CMD, activeID); // } // else if(getStatus() != Status_Sending) // 上一次的结果没有清除,返回错误,为了保证时效性,需要重置状态。重新调用 // { // Log_Printf_Debug("返回结果过期,请重置状态\r\n");// 打印日志 // result = failed(); // 失败 // } // else if(getTimerMs() > time) // 正在发送状态。判断超时 // { // Log_Printf_Debug("AT指令返回超时\r\n"); // 打印日志 // result = overtime(); // 超时 // } // else if(strstr((char * )AT_result(), "OK\r\n") != NULL) // 查询是否返回 // { // // 发送日志 // Log_Printf_Debug("测试命令AT返回: %d\r\n", AT_result_length()); // Log_SendArray_Debug(AT_result(), AT_result_length()); // result = success(); // 成功 // // } // else if(strstr((char * )AT_result(), "ERROR\r\n") != NULL) // 查询是否返回 // { // // 发送日志 // Log_Printf_Debug("测试命令AT返回: %d\r\n", AT_result_length()); // Log_SendArray_Debug(AT_result(), AT_result_length()); // result = failed(); // 失败 // } // return result; //} //enum Result esp32_at_sync(void) //{ // enum Result result = Result_None; // while(1) // { // result = esp32_at(); // if(result != Result_None) // { // // 重置 // esp32.reset(); // break; // } // } // return result; //} /***************************************** 基于ESP32_C3模组的相关结构体声明 *****************************************/ struct ESP32_Struct esp32= { .timer = { .time = 0, .flag = 0 }, .reset = esp32_reset, .exit_deepsleep = esp32_exit_deepsleep, .enter_deepsleep = esp32_enter_deepsleep, .exit_lightsleep = esp32_exit_lightsleep, .enter_lightsleep = esp32_enter_lightsleep, .set_lightsleep_wakeup = esp32_set_lightsleep_wakeup, .set_lightsleep_wakeup_sync = esp32_set_lightsleep_wakeup_sync, .set_sleep = esp32_set_sleep, .set_sleep_sync = esp32_set_sleep_sync, .connect_ap = esp32_connect_ap, .connect_ap_sync = esp32_connect_ap_sync, .set_cipmode = esp32_set_cipmode, .set_cipmode_sync = esp32_set_cipmode_sync, .connect_network = esp32_connect_network, .connect_network_sync = esp32_connect_network_sync, .close_network = esp32_close_network, .close_network_sync = esp32_close_network_sync, .query_id_signal = esp32_query_id_signal, .query_id_signal_sync = esp32_query_id_signal_sync, .autoconnect_ap = esp32_autoconnect_ap, .autoconnect_ap_sync = esp32_autoconnect_ap_sync, .close_ap = esp32_close_ap, .close_ap_sync = esp32_close_ap_sync, .query_signal = esp32_query_signal, .query_signal_sync = esp32_query_signal_sync, .ready = esp32_ready, .ready_sync = esp32_ready_sync, .handle_data = esp32_handle_data, .handle_data_sync = esp32_handle_data_sync, .recv_ready = esp32_recv_ready, .recv_ready_with_time = esp32_recv_ready_with_time, }; #endif