本文轉自CSDN,地址 https://blog.csdn.net/jsagacity/article/details/78531819java
全文以下 :android
前段時間,公司利用 ESP8266 這個WiFi模塊,作了好多小產品。從手機 APP 直連這個 ESP8266 進行通信,再到實現遠程控制。中間實現過程磕磕碰碰,雖然這方面已經作得很是成熟,可是網上的資料少之又少。如今把實現方式展現出來,同時也算是作一個筆記。json
首先這裏要實現的是Android端的APP直連ESP8266進行雙向通信。服務器
若是想了解Android端的APP遠程鏈接與ESP8266進行雙向通訊的,實現真正的智能家居,能夠參與這場Chat:智能家居遠程控制,實現APP與ESP8266遠程通訊網絡
首先咱們來講一下這個ESP8266,這個在淘寶上很是便宜,10塊左右,安信可的產品。這個WiFi模塊已經作得很是的成熟,下面介紹一下它的基本使用,首先這個模塊有三種模式:
1:STA 模式:ESP8266模塊經過路由器鏈接互聯網,手機或電腦經過互聯網實現對設備的遠程控制。
2:AP 模式:ESP8266模塊做爲熱點,實現手機或電腦直接與模塊通訊,實現局域網無線控制。
3:STA+AP 模式:兩種模式的共存模式,便可以經過互聯網控制可實現無縫切換,方便操做。框架
今天的實現用AP模式就夠了,指令有下面這幾個就夠了:
一、設置wifi模式:AT+CWMODE=2
二、重啓生效:AT+RST
三、啓動多鏈接:AT+CIPMUX=1
四、創建server:AT+CIPSERVER=1異步
另外還有很是多的指令能夠修改這個模塊的參數,甚至還能夠修改裏面的程序從新燒錄,更多的詳情就參考安信可的官網。這個就須要電子比較厲害的人才會適合了,我是Android開發的,因此這方面不太瞭解,還望海涵。ide
這是設備:佈局
接下來經過串口發送指令開啓ESP8266的WiFi:this
發送完這四個指令以後,打開手機就能夠看到相應的WiFi開啓了(這個WiFi名給我改過):
好了,硬件準備完畢,接下來咱們準備APP軟件,針對Android端的。新建一個Android項目,項目結構:
添加一個異步處理類:
/** * Created by Layne_Yao on 2017/5/12. * CSDN:http://blog.csdn.net/Jsagacity */ public class SendAsyncTask extends AsyncTask<String, Void, Void> { //這裏是鏈接ESP8266的IP和端口號,IP是經過指令在單片機開發板查詢到,而端口號能夠自行設置,也能夠使用默認的,333就是默認的 private static final String IP = "192.168.4.1"; private static final int PORT = 333; private Socket client = null; private PrintStream out = null; @Override protected Void doInBackground(String... params) { String str = params[0]; try { client = new Socket(IP, PORT); client.setSoTimeout(5000); // 獲取Socket的輸出流,用來發送數據到服務端 out = new PrintStream(client.getOutputStream()); out.print(str); out.flush(); if (client == null) { return null; } else { out.close(); client.close(); } } catch (IOException e) { e.printStackTrace(); } return null; } }
在手機端創建一個做爲接受ESP8266發送的消息的服務器:
public class MobileServer implements Runnable { private ServerSocket server; private DataInputStream in; private byte[] receice; private Handler handler = new Handler(); public MobileServer() { } public void setHandler(Handler handler) { this.handler = handler; } @Override public void run() { try { //5000是手機端開啓的服務器的端口號,ESP8266進行TCP鏈接時使用的端口,而IP也是經過指令查詢的聯入設備的IP server = new ServerSocket(5000); while (true) { Socket client = server.accept(); in = new DataInputStream(client.getInputStream()); receice = new byte[50]; in.read(receice); in.close(); Message message = new Message(); message.what = 1; message.obj = new String(receice); handler.sendMessage(message); } } catch (IOException e) { e.printStackTrace(); } try { server.close(); } catch (IOException e) { e.printStackTrace(); } } }
佈局文件:
<TextView android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="25dp" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:background="#fe9920" android:gravity="center" android:text="接收的內容" /> <Button android:id="@+id/bt_send" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/tv_content" android:layout_centerHorizontal="true" android:layout_marginTop="40dp" android:text="發送" /> <TextView android:id="@+id/tv_send_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/bt_send" android:layout_centerHorizontal="true" android:layout_marginTop="33dp" android:text="發送的內容" />
最後是MainActivity:
public class MainActivity extends ActionBarActivity implements OnClickListener {
private TextView tv_content, tv_send_text;
private Button bt_send;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); InitView(); //開啓服務器 MobileServer mobileServer = new MobileServer(); mobileServer.setHandler(handler); new Thread(mobileServer).start(); } private void InitView() { tv_content = (TextView) findViewById(R.id.tv_content); tv_send_text = (TextView) findViewById(R.id.tv_send_text); bt_send = (Button) findViewById(R.id.bt_send); bt_send.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bt_send: String str = "Sent to the ESP8266"; new SendAsyncTask().execute(str); tv_send_text.setText(str); break; } } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: tv_content.setText("WiFi模塊發送的:" + msg.obj); Toast.makeText(MainActivity.this, "接收到信息", Toast.LENGTH_LONG) .show(); } } };
}
最後不要忘了添加網路權限:
運行到真機,確保手機鏈接上ESP8266的WiFi,就能夠進行手機發送信息到ESP8266了。手機APP發送過去的:
ESP8266接收到的:
接下來是ESP8266發送數據到APP。首先ESP要使用到的指令有:
一、創建TCP鏈接:AT+CIPSTART=0,"TCP","192.168.4.2",5000
二、肯定發送數據的長度:AT+CIPSEND=0,19
三、發送信息:Sent to the Android
操做指令:
APP端接受到的信息:
以上是簡單的實現APP和ESP8266直連通信的實現。
若是想要實現遠程控制,過程是比較繁雜的,可是並不複雜。
這裏只簡單的說明一下大體的實現方式:
一、要實現遠程控制就必須得租用一個服務器,固然本身電腦也能夠做爲服務器,就是須要配置。最簡單的方式是租用雲服務器,好比阿里雲的ECS,若是是學生,還有學生價。
二、接下來是最麻煩的步驟:
1)手機發數據到雲服務器,這個不用多說了,使用json數據的網絡通訊;
2)接着就是雲服務器繼續把手機發送過來的轉發的ESP8266,而云服務器和ESP8266之間的通信是須要使用TCP長鏈接的。由於ESP8266這邊的IP是會變化的因此只能使用長鏈接;
3)ESP8266發數據到雲服務器就不用再多說了,就第2點中的長鏈接。可是雲服務器怎麼推送數據到APP呢?答案也是長鏈接的,這裏能夠使用別人集成好的框架mina。
以上就是遠程控制的大體過程要點,想要實現就各自去完成了。當初我仍是在別的平臺問人問到的實現方案,網上根本沒有相應的資料,或者是方案。以上的實現方案雖然有點繁雜,可是並不複雜,慢慢實現是沒有很大難度的