esp8266串口wifi,估计很多朋友都有。废话不多说,直接切入正题吧



esp-01,就是某宝上最常见的那款,通过uart接口,可以由arduino发送AT命令控制其功能。8266有两种工作模式,分别是station模式以及ap模式,简单来说,station模式是连你家无线路由器的,ap模式是8266作为热点由手机去连接它(或者无线路由器)。如无意外,在家里使用都会用station模式。当然,这两种模式可以同时进行,但是据我观察,我手头有好几块8266,有的可以正常工作,有的不能同时工作在两个模式。所以,以下教程是以station模式为例


某宝上直接买的8266,固件通常都比较老旧,查看固件版本的命令是AT+GMR,0.22版本以下的固件,http无法正常工作,因此如果你固件低于0.22,需要帮8266刷机。下面是0.50刷机教程。如果你的版本较高,可以跳过,直接运行代码

====================================================

刷机接线可参考http://jingyan.baidu.com/article/0964eca21d33ad8285f53632.html


另外,如果只有uno,而没有usb转串口板,可以像我一样,直接使用uno来进行串口刷机

方法是,  gnd--gnd vcc--3.3v   rxd--RX txd--TX chpd--3.3v  io0--gnd,另外,uno板子上的RESET请接gnd,防止arduino占用串口


懒得画图了,凑合看吧

________________
 |   _     _    _    __   |
 |  |  |_|  |_|  |_|      |
 |  |----------------      |
 |    ____       ___     |
 |   |       |    |     |    |
 |   |____|     -----     |
 |                            |
 |     ■    ○    ○    ○   |
 |     ○    ○    ○    ○   |
 =============
    gnd   io2  io0  rxd
    txd   chpd rst  vcc


正常连接以后,应该可以ide里面打开串口,设置波特率115200,选both NL&CR,输入AT然后回车,应该能看到串口回应OK


打开附件的工具,按如下参数设置添加文件,都在附件里面,注意COM PORT改成自己的


lua控制esp8266代码 esp8266 wifi控制_串口



lua控制esp8266代码 esp8266 wifi控制_html_02

ESP8266.rar (7.49 MB, 下载次数: 716)


之后,点击START,拔插一下vcc就会开始刷机。如果提示失败,检查一下是否将串口窗口关闭了


刷机完成后,拔掉io0的线,输入AT,看看是否有反应,如果没反应,拔插一下vcc再试试。如果有提示OK,则刷机完成,输入AT+GMR回车,应该提示版本是0.50了。正常烧录程序后让arduino控制esp8266时,记得让RX--TXD  TX-RXD,交叉接线。

====================================================

esp-01 常用AT命令,主要是这么几个:

AT+CWMODE=x       设置模式为x,1:station模式  2:ap模式  3:同时
 AT+RST                   复位
 AT+CWDHCP=x,y     开启dhcp,y=0关闭,1开启,x为0时是ap,1是station, 2是二者同时
 AT+CWJAP="xxx","yyy"    当作为station模式时,加入热点xxx,xxx是热点SSID,yyy是热点密码
 AT+CIPMUX=x         开启mux多路连接,如果要设置为服务器时,必须开启
 AT+CIPSERVER=x,y   开始服务器,x为1时开启,0关闭,y为开启的端口,http协议所用的端口为80
 AT+CIFSR                查看获得的ip
 AT+GMR                  查看固件版本
 AT+CIPSEND=x,y     发送tcp信息,x为连接的IPD值,y为信息长度
 AT+CIPCLOSE=x      关闭某个tcp连接

 HTTP是一个基于TCP的文本传输协议,我们在地址栏里面输入http://a.b.c.d/的时候,实际上是向a.b.c.d这个ip发送一个HTTP GET信息,这个信息如下(chrome浏览器)
 GET / HTTP/1.1
 Host: 192.168.1.107
 Connection: keep-alive
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
 Upgrade-Insecure-Requests: 1
 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36
 Accept-Encoding: gzip, deflate, sdch
 Accept-Language: zh-CN,zh;q=0.8


后面的不用管,是一系列附加信息。主要在于第一行,GET / 是发送的实际起作用的信息。这里我们地址栏什么都没输入,所以是空的。假如不是空的呢?比如,http://a.b.c.d/ABCD ,发送的信息如下

GET /ABCD HTTP/1.1

Host: 192.168.1.107

Connection: keep-alive

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36

Accept-Encoding: gzip, deflate, sdch

Accept-Language: zh-CN,zh;q=0.8


看到没有,GET后面有了ABCD这个信息。因为esp8266只管tcp协议,因此http信息他原封不动的送给我们。我们要做的就是检测这一段GET信息,来实现不同的功能


除此之外,我们也可以给浏览器返回一个页面。页面实际上就是一段html代码,当我们接收到IPD的连接信息时,我们就用AT+IPSEND来发送这一段html代码给他,对方的浏览器就会显示这段html页面了。我们希望,这个页面里面,有两个按钮,一个是ON,一个是OFF,分别控制uno 13引脚的led


8266的接法是正常接法,vcc-3.3 gnd-gnd tx-rxd rx-txd chpd-3.3

下面是代码时间。

1. char mypage[] ="<html><body><a href="/ON"><input type="Button" value="ON" style="position:absolute;top:50%;left:40%"></input></a><a href="/OFF"><input type="Button" value="OFF" style="position:absolute;top:50%;left:60%"></input></a></body></html>";
2. int pagelength;
3. #define SSID "mySSID"
4. #define PSWD "myPSWD"
5. #define BUFFERSIZE 32
6. #define PORT 80          //http port 80
7. char SearchBuffer[BUFFERSIZE];
8. char ok[] ="OK";
9. char ipd[] = "+IPD,";
10. char rdy[] = "ready";
11. char GET[] = "GET /";
12. char on[] = "ON";
13. char off[] = "OFF";
14. void setup() {

15.   pinMode(13,OUTPUT);
16.   // put your setup code here, to run once:
17.   memset(SearchBuffer,0,BUFFERSIZE);
18.   Serial.begin(115200);
19.   Serial.println(F("AT+RST"));
20.   waitForStr(ok,5000);
21.   Serial.println(F("ATE0"));           //disable echo
22.   waitForStr(ok,1000);
23.   Serial.println(F("AT+CWMODE=1"));    //station, AP+STATION is 3
24.   waitForStr(ok, 1000);
25.   Serial.println(F("AT+CWDHCP=1,1"));    //AP+STATION DHCP is 2 1
26.   waitForStr(ok, 2000);
27.   //Serial.println(F("AT+RST"));         //RESET
28.   //waitForStr(ok,5000);
29.   //waitForStr(rdy,5000);
30.   Serial.println(F("AT+CWJAP?"));
31.   bool ret= waitForStr(SSID,1000);
32.   if(!ret){

33.     Serial.print(F("AT+CWJAP=""));      //link
34.     Serial.print(SSID);
35.     Serial.print(F("",""));
36.     Serial.print(PSWD);
37.     Serial.println(F("""));
38.     waitForStr(ok,10000);
39.   }
40.   //if(!stringCompare(Search+(n-2)%BUFFERSIZE,ok))
41.     //while(1);   //error
42.   Serial.println(F("AT+CIPMUX=1"));    //mux
43.   waitForStr(ok,1000);
44.   Serial.print(F("AT+CIPSERVER=1,"));
45.   Serial.println(PORT);
46.   waitForStr(ok,1000);
47.  
48.   pagelength=getStrLength(mypage);
49. }
50.  
51. void loop() {

52.   // put your main code here, to run repeatedly:
53.   static char mux;
54.   waitForStr(ipd);
55.   mux=Serial.read();
56.   waitForStr(GET);
57.   readTillSpace(SearchBuffer,10000);
58.   if(stringCompare(SearchBuffer,on)==true)
59.     digitalWrite(13,HIGH);
60.   else if(stringCompare(SearchBuffer,off)==true)
61.     digitalWrite(13,LOW);
62.   delay(10);
63.   emptyRxToBuffer(SearchBuffer, BUFFERSIZE);
64.   Serial.print(F("AT+CIPSEND="));
65.   Serial.print(mux);
66.   Serial.print(",");
67.   Serial.println(pagelength);
68.   waitForStr(">");
69.   Serial.println(mypage);
70.   waitForStr(ok,10000);
71.   Serial.print(F("AT+CIPCLOSE="));
72.   Serial.println(mux);
73.   waitForStr(ok,1000);
74. }
75. void waitForStr(char* str){

76.   waitForStr(str,-1);
77. }
78. bool waitForStr(char* str, long timeout){

79.   long intime=millis();
80.   int i=0,j=0,cur=0,index=0;
81.   int len=getStrLength(str);
82.   bool ret=true;
83.   char* temp=new char(len);
84.   while(str[i]!='\0'){

85.     while(j-cur<len){

86.       if(timeout>0)
87.         if(millis()-intime>timeout){

88.           ret=false;
89.           goto OUT;
90.         }
91.       if(Serial.available()){

92.         index=j%len;
93.         temp[index]=Serial.read();
94.         j++;  
95.       }
96.     }
97.     index=(cur+i)%len;
98.     if(str[i]==temp[index])
99.       i++;
100.     else
101.       i=0,cur++;
102.   }
103. OUT:
104.   delete temp;
105.   return ret;
106. }
107.  
108. int emptyRxToBuffer(char* buf, int bufsize) {

109.   int i=0,ret=-1;
110.   if(Serial.available()){

111.     while(Serial.available()){

112.       i=i+1;
113.       buf[i%bufsize]=Serial.read();
114.     }
115.     ret=i;
116.   }
117.   return ret;
118. }
119.  
120. bool stringCompare(char* a, char* b){

121.   int i=0;
122.   //Serial.println(a);
123.   //Serial.println(b);
124.   if(getStrLength(a)!=getStrLength(b))
125.     return false;
126.   while(b[i]!='\0'){

127.     if(a[i]!=b[i]){

128.       //Serial.println("false");
129.       return false;
130.     }
131.     i++;
132.   }
133.   //Serial.println("true");
134.   return true;
135. }
136.  
137. int getStrLength(char* str){

138.   int i=0;
139.   while(str[i]!='\0'){

140.     i++;
141.   }
142.   return i;
143. }
144.  
145. void readTillSpace(char* buf,long timeout){

146.   long intime=millis();
147.   int i=0;
148.   while(1){

149.     if(Serial.available()){

150.       if((buf[i]=Serial.read())!=' ')
151.         i++;
152.       else break;
153.     }
154.     if(millis()-intime>timeout)
155.       break;
156.   }
157.   buf[i]='\0';
158.   //Serial.println(buf);
159. }
160.

复制代码


程序本身很简单,先初始化一下8266的模式,接着开始服务器接收,如果有收到连进来的IPD号码,记住这个号码,然后向其返回一个html页面,此页面由mypage数组保存。并且,对连接进来的GET进行分析,如果是ON则开启led,如果是OFF则关闭

请将SSID和PSWD替换为自己路由器的SSID和密码。烧录程序后上电,过一会儿等它连接好,打开路由器,看看esp8266被分配了哪个ip,之后开启浏览器输入 http://*这个ip*/,成功后,就可以看到一个页面,上面有ON OFF两个按钮,控制13脚的led

至此,我们完成了一个最简单的8266 http服务器,通过浏览器页面来控制arduino的行为。大家如果脑洞够大,应该可以想到更复杂一些的页面,当然需要一定网页设计知识