一直想使用arduino平台来控制ESP8266模块,现在终于差不多实现了,从网上找来了一个相关的库文件,已经实现了大部分功能,但仍有部分功能需要优化,比如smartlink部分未加入。
在这里首先感谢ITEAD提供的文章帮助,http://www.arduino.cn/thread-7540-1-1.html。
我的平台是arduino uno ,只有一个串口,为了方便仿真,我选择使用软件来串口来与ESP8266通信,注意软串口缓存默认是64byte , 需要改为128 byte或更高,来适应wifi串口。
文件SoftwareSerial.h
#define _SS_MAX_RX_BUFF 128 // RX buffer size for wifi
于是有如下定义:
SoftwareSerial mySerial(3, 2); /* RX:D3, TX:D2 */
ESP8266 wifi(mySerial,115200);//刚开始默认波特率为115200
D3口用作RX,D2口用作TX
经过测试软串口只有在发送的时候可以支持到115200的波特率,在接收时会有乱码,但是wifi模块出厂默认是115200的波特率,所以我们需要发送指令将115200改为9600。
wifi.SetBaud(9600);//设置波特率
wifi.SetBaud(9600);
mySerial.begin(9600);
建议多将指令发送几次,保证wifi模块接收到指令,完成后将自身的波特率改到9600。
串口改变指令原来的库里是没有的,这里要更改库文件,添加如下方法:
ESP8266.cpp
/*******************************************************************************
* 函 数 名 :SetBaud
* 函数功能 :设置波特率
* 输 入 :baud - 波特率
* 输 出 :true success false - fail
*******************************************************************************/
bool ESP8266::SetBaud(uint32_t baud)
{
return eATUART(baud);
}
bool ESP8266::eATUART(uint32_t baud)
{
rx_empty();
m_puart->print("AT+UART=");
m_puart->print(baud);
m_puart->println(",8,1,0,0");
return recvFind("OK");
}
接下来在同样的文件下我们来实现smartlink功能,smartlink需要在30s内完成,需要注意的是若smartlink失败,需要使用smartstop指令来关闭这个连接
//add by LC 2016.01.05 16:27
bool ESP8266::smartLink(uint8_t type,String &link_msg)
{
return eATCWSMARTSTART(type,link_msg);
}
//add by LC 2016.01.05 16:27
bool ESP8266::stopSmartLink(void)
{
return eATCWSMARTSTOP();
}
/*******************************************************************************
* 函 数 名 :eATCWSMARTSTART
* 函数功能 :启动smartlink模式,需要在30s内连接
* 输 入 :type 启动方式 0 -AL-LINK 1 - ESP-TOUCH 2 - AIR-KISS
link_msg 返回的SSID和PSD
* 输 出 :无
*******************************************************************************/
bool ESP8266::eATCWSMARTSTART(uint8_t type,String &link_msg)//add by LC 2016.01.05 16:27
{
bool flag;
rx_empty();
m_puart->print("AT+CWSMARTSTART=");
m_puart->println(type);
flag = recvFind("OK");
if(flag == false) return flag;
delay(50);//延时之后等待自动连接
rx_empty();
return recvFindAndFilter("OK", "SMART SUCCESS", "\r\n\r\nOK", link_msg,30000);
}
/*******************************************************************************
* 函 数 名 :eATCWSMARTSTOP
* 函数功能 :停止smartlink
* 输 入 :无
* 输 出 :无
*******************************************************************************/
bool ESP8266::eATCWSMARTSTOP(void)//add by LC 2016.01.05 16:27
{
rx_empty();
m_puart->println("AT+CWSMARTSTOP");
return recvFind("OK");
}
下面就是使用方法,在smartlink.ino 文件,该函数必须在初始化或断线的时候调用
/*******************************************************************************
* 函 数 名 :AutoLink
* 函数功能 :自动连接,前10s自动连接,若连接失败则进入smartlink模式30s,若依然失败
* 则再次回到自动连接,直到连接成功
* 输 入 :无
* 输 出 :无
*******************************************************************************/
void AutoLink(void)
{
int8_t status = STATUS_LOSTIP;
while(status != STATUS_GETIP)
{
uint32_t start_time = millis();
Serial.println("start auto link");
//10s自动连接时间
while((millis() - start_time < 10000) && status != STATUS_GETIP)
{
status = wifi.getSystemStatus();
delay(500);
}
//连接失败进入smartlink模式 30s
if(status != STATUS_GETIP)
{
String link_msg;
Serial.println("start smartlink");
wifi.stopSmartLink();
if(true == wifi.smartLink((uint8_t)AIR_LINK,link_msg))
{
Serial.println(link_msg);
start_time = millis();//等待获取IP
while((millis() - start_time < 5000) && status != STATUS_GETIP)
{
status = wifi.getSystemStatus();
delay(500);
}
}else
{
wifi.stopSmartLink();
delay(500);
Serial.println("link AP fail");
}
}
}
Serial.println("link AP OK");
}
下面简单介绍下几个重要的方法:
ESP8266(SoftwareSerial &uart, uint32_t baud = 9600)
初始化与wifi模块连接的串口,注意波特率
bool restart(void)
复位模块方法,建议在初始化时调用,并在设置波特率之后
String getIPStatus(void)
该方法在不同的连接状态下返回值和格式不同,如下:
AT+CIPSTATUS
STATUS:3
+CIPSTATUS:0,"TCP","192.168.31.136",8080,0
OK
AT+CIPSTATUS
STATUS:2
OK
新增的方法,获取系统当前状态,直接返回值,方便前端调用和判断
实现方法如下:
#define STATUS_GETIP 2 //获取到IP
#define STATUS_GETLINK 3 //建立连接
#define STATUS_LOSTLINK 4 //失去连接
#define STATUS_LOSTIP 5 //未获取到IP
/*******************************************************************************
* 函 数 名 :getSystemStatus
* 函数功能 :获取系统状态
* 输 入 :无
* 输 出 :返回状态
*******************************************************************************/
int8_t ESP8266::getSystemStatus(void)
{
String list;
eATCIPSTATUS(list);
int32_t index = list.indexOf("STATUS:");
if (index != -1) {
index += 7;
char status = list.charAt(index);
return status - 0x30;//返回状态
}else
{
return -1;
}
}
uint32_t recv(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout = 1000)
接收网络数据,返回的是实际接收的长度,注意这里的timout参数,具有死延时的问题,也就是在1s内只能接收一帧数据,建议把这个值调小,但不能调为0,不然无法接收数据。
OK,关于该文章的相关库文件和工程下载地址:http://download.youkuaiyun.com/detail/liucheng5037/9400821。如有什么问题,欢迎大家交流!