智能家居简单实现---使用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.   
  6. public class SendAsyncTask extends AsyncTask<String, Void, Void> {  
  7.       
  8.     //这里是连接ESP8266的IP和端口号,IP是通过指令在单片机开发板查询到,而端口号可以自行设置,也可以使用默认的,333就是默认的  
  9.     private static final String IP = "192.168.4.1";  
  10.     private static final int PORT = 333;  
  11.   
  12.   
  13.   
  14.     private Socket client = null;  
  15.     private PrintStream out = null;  
  16.   
  17.   
  18.     @Override  
  19.     protected Void doInBackground(String... params) {  
  20.         String str = params[0];  
  21.         try {  
  22.             client = new Socket(IP, PORT);  
  23.             client.setSoTimeout(5000);  
  24.             // 获取Socket的输出流,用来发送数据到服务端  
  25.             out = new PrintStream(client.getOutputStream());  
  26.             out.print(str);  
  27.             out.flush();  
  28.   
  29.             if (client == null) {  
  30.                 return null;  
  31.             } else {  
  32.                 out.close();  
  33.                 client.close();  
  34.             }  
  35.   
  36.         } catch (IOException e) {  
  37.             e.printStackTrace();  
  38.         }  
  39.   
  40.         return null;  
  41.     }  
  42.       
  43. }  

在手机端建立一个作为接受ESP8266发送的消息的服务器:

  1. public class MobileServer implements Runnable {  
  2.     private ServerSocket server;  
  3.     private DataInputStream in;  
  4.     private byte[] receice;  
  5.   
  6.     private Handler handler = new Handler();  
  7.   
  8.     public MobileServer() {  
  9.     }  
  10.   
  11.     public void setHandler(Handler handler) {  
  12.         this.handler = handler;  
  13.     }  
  14.   
  15.     @Override  
  16.     public void run() {  
  17.   
  18.         try {  
  19.             //5000是手机端开启的服务器的端口号,ESP8266进行TCP连接时使用的端口,而IP也是通过指令查询的联入设备的IP  
  20.             server = new ServerSocket(5000);  
  21.             while (true) {  
  22.                 Socket client = server.accept();  
  23.                 in = new DataInputStream(client.getInputStream());  
  24.                 receice = new byte[50];  
  25.                 in.read(receice);  
  26.                 in.close();  
  27.                   
  28.                 Message message = new Message();  
  29.                 message.what = 1;  
  30.                 message.obj = new String(receice);  
  31.                 handler.sendMessage(message);  
  32.             }  
  33.   
  34.         } catch (IOException e) {  
  35.             e.printStackTrace();  
  36.         }  
  37.         try {  
  38.             server.close();  
  39.         } catch (IOException e) {  
  40.             e.printStackTrace();  
  41.         }  
  42.     }  
  43. }  

布局文件:

  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.   
  7.     <TextView  
  8.         android:id="@+id/tv_content"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="25dp"  
  11.         android:layout_centerHorizontal="true"  
  12.         android:layout_marginTop="10dp"  
  13.         android:background="#fe9920"  
  14.         android:gravity="center"  
  15.         android:text="接收的内容" />  
  16.   
  17.     <Button  
  18.         android:id="@+id/bt_send"  
  19.         android:layout_width="match_parent"  
  20.         android:layout_height="wrap_content"  
  21.         android:layout_below="@id/tv_content"  
  22.         android:layout_centerHorizontal="true"  
  23.         android:layout_marginTop="40dp"  
  24.         android:text="发送" />  
  25.   
  26.     <TextView  
  27.         android:id="@+id/tv_send_text"  
  28.         android:layout_width="wrap_content"  
  29.         android:layout_height="wrap_content"  
  30.         android:layout_below="@id/bt_send"  
  31.         android:layout_centerHorizontal="true"  
  32.         android:layout_marginTop="33dp"  
  33.         android:text="发送的内容" />  
  34.   
  35. </RelativeLayout>  

最后是MainActivity:

  1. public class MainActivity extends ActionBarActivity implements OnClickListener {  
  2.     private TextView tv_content, tv_send_text;  
  3.     private Button bt_send;  
  4.   
  5.     @Override  
  6.     protected void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.         setContentView(R.layout.activity_main);  
  9.   
  10.         InitView();  
  11.   
  12.         //开启服务器  
  13.         MobileServer mobileServer = new MobileServer();  
  14.         mobileServer.setHandler(handler);  
  15.         new Thread(mobileServer).start();  
  16.   
  17.     }  
  18.   
  19.     private void InitView() {  
  20.         tv_content = (TextView) findViewById(R.id.tv_content);  
  21.         tv_send_text = (TextView) findViewById(R.id.tv_send_text);  
  22.         bt_send = (Button) findViewById(R.id.bt_send);  
  23.   
  24.         bt_send.setOnClickListener(this);  
  25.   
  26.     }  
  27.   
  28.     @Override  
  29.     public void onClick(View v) {  
  30.         switch (v.getId()) {  
  31.         case R.id.bt_send:  
  32.             String str = "Sent to the ESP8266";  
  33.             new SendAsyncTask().execute(str);  
  34.             tv_send_text.setText(str);  
  35.             break;  
  36.         }  
  37.   
  38.     }  
  39.   
  40.     Handler handler = new Handler() {  
  41.         @Override  
  42.         public void handleMessage(Message msg) {  
  43.             switch (msg.what) {  
  44.             case 1:  
  45.                 tv_content.setText("WiFi模块发送的:" + msg.obj);  
  46.                 Toast.makeText(MainActivity.this"接收到信息", Toast.LENGTH_LONG)  
  47.                         .show();  
  48.             }  
  49.         }  
  50.     };  
  51.   
  52. }  

最后不要忘了添加网路权限:

  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。

以上就是远程控制的大致过程要点,想要实现就各自去完成了。当初我还是在别的平台问人问到的实现方案,网上根本没有相应的资料,或者是方案。以上的实现方案虽然有点繁杂,但是并不复杂,慢慢实现是没有很大难度的。


评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值