1. 程式人生 > >智慧家居簡單實現---使用ESP8266簡單實現和APP通訊

智慧家居簡單實現---使用ESP8266簡單實現和APP通訊

轉載於:http://blog.csdn.net/jsagacity/article/details/78531819

前段時間,公司利用 ESP8266 這個WiFi模組,做了好多小產品。從手機 APP 直連這個 ESP8266 進行通訊,再到實現遠端控制。中間實現過程磕磕碰碰,雖然這方面已經做得非常成熟,但是網上的資料少之又少。現在把實現方式展示出來,同時也算是做一個筆記。
首先這裡要實現的是Android端的APP直連ESP8266進行雙向通訊。


首先我們來說一下這個ESP8266,這個在淘寶上非常便宜,10塊左右,安信可的產品。這個WiFi模組已經做得非常的成熟,下面介紹一下它的基本使用,首先這個模組有三種模式:
1:STA 模式:

ESP8266模組通過路由器連線網際網路,手機或電腦通過網際網路實現對裝置的遠端控制。
2:AP 模式:ESP8266模組作為熱點,實現手機或電腦直接與模組通訊,實現區域網無線控制。
3:STA+AP 模式:兩種模式的共存模式,即可以通過網際網路控制可實現無縫切換,方便操作。

今天的實現用AP模式就夠了,指令有下面這幾個就夠了:
1、設定wifi模式:AT+CWMODE=2
2、重啟生效:AT+RST
3、啟動多連線:AT+CIPMUX=1
4、建立server:AT+CIPSERVER=1


另外還有非常多的指令可以修改這個模組的引數,甚至還可以修改裡面的程式重新燒錄,更多的詳情就參考安信可的官網。這個就需要電子比較厲害的人才會適合了,我是Android開發的,所以這方面不太瞭解,還望海涵。

這是裝置:


接下來通過串列埠傳送指令開啟ESP8266的WiFi:



傳送完這四個指令之後,開啟手機就可以看到相應的WiFi開啟了(這個WiFi名給我改過):


好了,硬體準備完畢,接下來我們準備APP軟體,針對Android端的。新建一個Android專案,專案結構:


新增一個非同步處理類:

  1. /** 
  2.  * Created by Layne_Yao on 2017/5/12. 
  3.  * CSDN:http://blog.csdn.net/Jsagacity 
  4.  */
  5. publicclass SendAsyncTask extends AsyncTask<String, Void, Void> {  
  6.     //這裡是連線ESP8266的IP和埠號,IP是通過指令在微控制器開發板查詢到,而埠號可以自行設定,也可以使用預設的,333就是預設的
  7.     privatestaticfinal String IP = "192.168.4.1";  
  8.     privatestaticfinalint PORT = 333;  
  9.     private Socket client = null;  
  10.     private PrintStream out = null;  
  11.     @Override
  12.     protected Void doInBackground(String... params) {  
  13.         String str = params[0];  
  14.         try {  
  15.             client = new Socket(IP, PORT);  
  16.             client.setSoTimeout(5000);  
  17.             // 獲取Socket的輸出流,用來發送資料到服務端
  18.             out = new PrintStream(client.getOutputStream());  
  19.             out.print(str);  
  20.             out.flush();  
  21.             if (client == null) {  
  22.                 returnnull;  
  23.             } else {  
  24.                 out.close();  
  25.                 client.close();  
  26.             }  
  27.         } catch (IOException e) {  
  28.             e.printStackTrace();  
  29.         }  
  30.         returnnull;  
  31.     }  
  32. }  

在手機端建立一個作為接受ESP8266傳送的訊息的伺服器:
  1. publicclass MobileServer implements Runnable {  
  2.     private ServerSocket server;  
  3.     private DataInputStream in;  
  4.     privatebyte[] receice;  
  5.     private Handler handler = new Handler();  
  6.     public MobileServer() {  
  7.     }  
  8.     publicvoid setHandler(Handler handler) {  
  9.         this.handler = handler;  
  10.     }  
  11.     @Override
  12.     publicvoid run() {  
  13.         try {  
  14.             //5000是手機端開啟的伺服器的埠號,ESP8266進行TCP連線時使用的埠,而IP也是通過指令查詢的聯入裝置的IP
  15.             server = new ServerSocket(5000);  
  16.             while (true) {  
  17.                 Socket client = server.accept();  
  18.                 in = new DataInputStream(client.getInputStream());  
  19.                 receice = newbyte[50];  
  20.                 in.read(receice);  
  21.                 in.close();  
  22.                 Message message = new Message();  
  23.                 message.what = 1;  
  24.                 message.obj = new String(receice);  
  25.                 handler.sendMessage(message);  
  26.             }  
  27.         } catch (IOException e) {  
  28.             e.printStackTrace();  
  29.         }  
  30.         try {  
  31.             server.close();  
  32.         } catch (IOException e) {  
  33.             e.printStackTrace();  
  34.         }  
  35.     }  
  36. }  

佈局檔案:
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:tools="http://schemas.android.com/tools"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     tools:context="com.itman.connectesp8266.MainActivity" >  
  6.     <TextView  
  7.         android:id="@+id/tv_content"
  8.         android:layout_width="match_parent"
  9.         android:layout_height="25dp"
  10.         android:layout_centerHorizontal="true"
  11.         android:layout_marginTop="10dp"
  12.         android:background="#fe9920"
  13.         android:gravity="center"
  14.         android:text="接收的內容" />  
  15.     <Button  
  16.         android:id="@+id/bt_send"
  17.         android:layout_width="match_parent"
  18.         android:layout_height="wrap_content"
  19.         android:layout_below="@id/tv_content"
  20.         android:layout_centerHorizontal="true"
  21.         android:layout_marginTop="40dp"
  22.         android:text="傳送" />  
  23.     <TextView  
  24.         android:id="@+id/tv_send_text"
  25.         android:layout_width="wrap_content"
  26.         android:layout_height="wrap_content"
  27.         android:layout_below="@id/bt_send"
  28.         android:layout_centerHorizontal="true"
  29.         android:layout_marginTop="33dp"
  30.         android:text="傳送的內容" />  
  31. </RelativeLayout>  

最後是MainActivity:
  1. publicclass MainActivity extends ActionBarActivity implements OnClickListener {  
  2.     private TextView tv_content, tv_send_text;  
  3.     private Button bt_send;  
  4.     @Override
  5.     protectedvoid onCreate(Bundle savedInstanceState) {  
  6.         super.onCreate(savedInstanceState);  
  7.         setContentView(R.layout.activity_main);  
  8.         InitView();  
  9.         //開啟伺服器
  10.         MobileServer mobileServer = new MobileServer();  
  11.         mobileServer.setHandler(handler);  
  12.         new Thread(mobileServer).start();  
  13.     }  
  14.     privatevoid InitView() {  
  15.         tv_content = (TextView) findViewById(R.id.tv_content);  
  16.         tv_send_text = (TextView) findViewById(R.id.tv_send_text);  
  17.         bt_send = (Button) findViewById(R.id.bt_send);  
  18.         bt_send.setOnClickListener(this);  
  19.     }  
  20.     @Override
  21.     publicvoid onClick(View v) {  
  22.         switch (v.getId()) {  
  23.         case R.id.bt_send:  
  24.             String str = "Sent to the ESP8266";  
  25.             new SendAsyncTask().execute(str);  
  26.             tv_send_text.setText(str);  
  27.             break;  
  28.         }  
  29.     }  
  30.     Handler handler = new Handler() {  
  31.         @Override
  32.         publicvoid handleMessage(Message msg) {  
  33.             switch (msg.what) {  
  34.             case1:  
  35.                 tv_content.setText("WiFi模組傳送的:" + msg.obj);  
  36.                 Toast.makeText(MainActivity.this"接收到資訊", Toast.LENGTH_LONG)  
  37.                         .show();  
  38.             }  
  39.         }  
  40.     };  
  41. }  

最後不要忘了新增網路許可權:
  1. <uses-permission android:name="android.permission.INTERNET"/>  

執行到真機,確保手機連線上ESP8266的WiFi,就可以進行手機發送資訊到ESP8266了。手機APP傳送過去的:


ESP8266接收到的:


接下來是ESP8266傳送資料到APP。首先ESP要使用到的指令有:

1、建立TCP連線:AT+CIPSTART=0,"TCP","192.168.4.2",5000
2、確定傳送資料的長度:AT+CIPSEND=0,19
3、傳送資訊:Sent to the Android

操作指令:


APP端接受到的資訊:


以上是簡單的實現APP和ESP8266直連通訊的實現。

如果想要實現遠端控制,過程是比較繁雜的,但是並不複雜。

這裡只簡單的說明一下大致的實現方式:

1、要實現遠端控制就必須得租用一個伺服器,當然自己電腦也可以作為伺服器,就是需要配置。最簡單的方式是租用雲伺服器,比如阿里雲的ECS,如果是學生,還有學生價。

2、接下來是最麻煩的步驟:

1)手機發資料到雲伺服器,這個不用多說了,使用json資料的網路通訊;

2)接著就是雲伺服器繼續把手機發送過來的轉發的ESP8266,而云伺服器和ESP8266之間的通訊是需要使用TCP長連線的。因為ESP8266這邊的IP是會變化的所以只能使用長連線;

3)ESP8266發資料到雲伺服器就不用再多說了,就第2點中的長連線。但是雲伺服器怎麼推送資料到APP呢?答案也是長連線的,這裡可以使用別人整合好的框架mina。

以上就是遠端控制的大致過程要點,想要實現就各自去完成了。當初我還是在別的平臺問人問到的實現方案,網上根本沒有相應的資料,或者是方案。以上的實現方案雖然有點繁雜,但是並不複雜,慢慢實現是沒有很大難度的。