本文转自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。
以上就是远程控制的大体过程要点,想要实现就各自去完成了。当初我仍是在别的平台问人问到的实现方案,网上根本没有相应的资料,或者是方案。以上的实现方案虽然有点繁杂,可是并不复杂,慢慢实现是没有很大难度的