Android Studio设计APP实现与51单片机通过WIFI模块(ESP8266-01S)通讯控制LED灯亮灭的设计源码【详解】

目录

一、前言

二、效果展示

1、APP界面展示

 2、C51硬件展示

三、Android Studio APP源代码

1、AndroidManifest.xml

1、请求联网:

2、开放明文传输:

2、MainActivity.java

3、Layout页面布局文件 activity_main.xml

四、Keil C51单片机源码

五、WIFI模块(ESP8266-01S)注意事项

六、后述     

一、前言

        本文将详细介绍如何利用Android Studio设计 APP 实现与C51单片机通过WIFI模块通讯控制LED灯亮灭,本人也是新手刚入门,找了很多资料,但都不得要领,最后终于靠着摸索学习实现了手机与C51模块的WIFI通讯,特来与大家分享,希望对各位能有所帮助。废话不多说,先看效果。

二、效果展示

1、APP界面展示

Android Studio设计APP实现与51单片机通过WIFI模块(ESP8266-01S)通讯控制LED灯亮灭的设计源码【详解】_第1张图片

 2、C51硬件展示

 

        可以看到,该APP基本实现了手机与C51单片机之间的WIFI通讯,手机端可以发送和接收数据,可以选择直接给WIFI发送数据,也可以将发送的数据的发送代码固化为按键,比如我上面的四个LED按键其实底层代码就是按下分别发送“1”、“2”、“3”、“4”来控制四个灯的亮灭。本app只是用来实验手机与C51单片机之间的WIFI通讯,目前来说算是成功了,后续可以通过修改调用该程序实现更复杂的内容,目前我也在朝着这个方向努力`(*>﹏<*)′

 

三、Android Studio APP源代码

1、AndroidManifest.xml

首先需要联网别忘了给 Android 添加网络连接权限:




    
     //需要对WiFi进行操作,所以需要设置网络权限

    
        
            
                

                
            
        
    

1、请求联网:

 

2、开放明文传输:

android:usesCleartextTraffic="false"

2、MainActivity.java

package com.example.tcp_led;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class MainActivity extends AppCompatActivity {
    String a;
    int b;
    connectthread lianjie;
    TextView receive;
    Socket socket=null;
    Button connect;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText ip=findViewById(R.id.mEtIP);
        EditText port=findViewById(R.id.mEtPort);
        EditText out=findViewById(R.id.mEtOut);
        receive=findViewById(R.id.receive);
        connect=findViewById(R.id.mBt1);
        Button send=findViewById(R.id.mBt7);
        Button LED1=findViewById(R.id.mBt3);
        Button LED2=findViewById(R.id.mBt4);
        Button LED3=findViewById(R.id.mBt5);
        Button LED4=findViewById(R.id.mBt6);
        Button Clear=findViewById(R.id.mBt8);

        // 连接 按键底层代码
        connect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                a=ip.getText().toString();
                String c=port.getText().toString();
                if("".equals(a)||"".equals(c)){
                    Toast.makeText(MainActivity.this,"请输入ip和端口号",Toast.LENGTH_SHORT).show();
                    receive.append("请输入ip和端口号" + "\r\n");
                }
                else{b=Integer.parseInt(c);
                    lianjie=new connectthread();
                    lianjie.start();}
            }
        });

        // 发送数据 按键底层代码
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //子线程中进行网络操作
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        if(socket!=null){
                            try {
                                String text=out.getText().toString();
                                lianjie.outputStream.write(text.getBytes());
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();

                            }
                        }else{
                            runOnUiThread(new Runnable()//不允许其他线程直接操作组件,用提供的此方法可以
                            {
                                public void run()
                                {
                                    // TODO Auto-generated method stub
                                    Toast.makeText(MainActivity.this,"请先建立连接",Toast.LENGTH_SHORT).show();
                                    receive.append("请先建立连接" + "\r\n");
                                }
                            });
                        }
                    }
                }).start();

            }
        });
        // LED1 按键底层代码 其实就是发送数据按键代码基础上修改的,后面三个按键都是
        LED1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //子线程中进行网络操作
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        if(socket!=null){
                            try {
                                String text="1";
                                lianjie.outputStream.write(text.getBytes());
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();

                            }
                        }else{
                            runOnUiThread(new Runnable()//不允许其他线程直接操作组件,用提供的此方法可以
                            {
                                public void run()
                                {
                                    // TODO Auto-generated method stub
                                    Toast.makeText(MainActivity.this,"请先建立连接",Toast.LENGTH_SHORT).show();
                                    receive.append("请先建立连接" + "\r\n");
                                }
                            });
                        }
                    }
                }).start();
            }
        });
        // LED2 按键底层代码 
        LED2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //子线程中进行网络操作
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        if(socket!=null){
                            try {
                                String text="2";
                                lianjie.outputStream.write(text.getBytes());
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();

                            }
                        }else{
                            runOnUiThread(new Runnable()//不允许其他线程直接操作组件,用提供的此方法可以
                            {
                                public void run()
                                {
                                    // TODO Auto-generated method stub
                                    Toast.makeText(MainActivity.this,"请先建立连接",Toast.LENGTH_SHORT).show();
                                    receive.append("请先建立连接" + "\r\n");
                                }
                            });
                        }
                    }
                }).start();
            }
        });
        // LED3 按键底层代码 
        LED3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //子线程中进行网络操作
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        if(socket!=null){
                            try {
                                String text="3";
                                lianjie.outputStream.write(text.getBytes());
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();

                            }
                        }else{
                            runOnUiThread(new Runnable()//不允许其他线程直接操作组件,用提供的此方法可以
                            {
                                public void run()
                                {
                                    // TODO Auto-generated method stub
                                    Toast.makeText(MainActivity.this,"请先建立连接",Toast.LENGTH_SHORT).show();
                                    receive.append("请先建立连接" + "\r\n");
                                }
                            });
                        }
                    }
                }).start();
            }
        });
        // LED4 按键底层代码 
        LED4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //子线程中进行网络操作
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        if(socket!=null){
                            try {
                                String text="4";
                                lianjie.outputStream.write(text.getBytes());
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();

                            }
                        }else{
                            runOnUiThread(new Runnable()//不允许其他线程直接操作组件,用提供的此方法可以
                            {
                                public void run()
                                {
                                    // TODO Auto-generated method stub
                                    Toast.makeText(MainActivity.this,"请先建立连接",Toast.LENGTH_SHORT).show();
                                    receive.append("请先建立连接" + "\r\n");
                                }
                            });
                        }
                    }
                }).start();
            }
        });
        Clear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                receive.setText("");
            }
        });

       // onCreate
    }
    //子线程中进行网络相关操作
    // 联网子线程
    class connectthread extends Thread {

        OutputStream outputStream=null;
        InputStream inputStream=null;
        @SuppressWarnings("InfiniteLoopStatement")
        @Override
        public void run() {

            //连接
            try {
                socket=new Socket(a, b);
                runOnUiThread(new Runnable()//不允许其他线程直接操作组件,用提供的此方法可以
                {
                    public void run()
                    {
                        // TODO Auto-generated method stub
                        Toast.makeText(MainActivity.this,"连接成功",Toast.LENGTH_SHORT).show();
                        receive.append("连接成功" + "\r\n");

                    }
                });
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                runOnUiThread(new Runnable()//不允许其他线程直接操作组件,用提供的此方法可以
                {
                    public void run()
                    {
                        // TODO Auto-generated method stub
                        Toast.makeText(MainActivity.this,"连接失败",Toast.LENGTH_SHORT).show();
                        receive.append("连接失败" + "\r\n");
                    }
                });
                e.printStackTrace();
            }catch (IOException e) {
                e.printStackTrace();
                runOnUiThread(new Runnable()//不允许其他线程直接操作组件,用提供的此方法可以
                {
                    public void run()
                    {
                        // TODO Auto-generated method stub
                        Toast.makeText(MainActivity.this,"连接失败",Toast.LENGTH_SHORT).show();
                        receive.append("连接失败" + "\r\n");
                    }
                });
            }
            if(socket!=null){
                //获取输出流对象
                try {
                    outputStream=socket.getOutputStream();
                    outputStream.write(123);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                try{
                    do {
                        final byte[] buffer = new byte[1024];//创建接收缓冲区
                        inputStream = socket.getInputStream();
                        final int len = inputStream.read(buffer);//数据读出来,并且返回数据的长度
                        runOnUiThread(new Runnable()//不允许其他线程直接操作组件,用提供的此方法可以
                        {
                            public void run() {
                                // TODO Auto-generated method stub
                                receive.append(new String(buffer, 0, len) + "\r\n");
                            }
                        });
                    } while (true);
                }
                catch (IOException ignored) {

                }
            }
        }
    }
    // MainActivity
}

3、Layout页面布局文件 activity_main.xml




    
        
        
        
        
        
        
        
            

布局预览:

Android Studio设计APP实现与51单片机通过WIFI模块(ESP8266-01S)通讯控制LED灯亮灭的设计源码【详解】_第2张图片

        如此app上位机端操作就基本大功告成了,接下来就是下位机C51方面的程序了。 

四、Keil C51单片机源码

#include "reg51.h"
#define uchar unsigned char
#define uint unsigned int
	
sbit SW1=P1^0;    //S1按键
sbit LED1=P1^1;
sbit LED2=P1^2;
sbit LED3=P1^3;
sbit LED4=P1^4;

//ESP8266  EN、vcc脚接 vcc 3.3 GND 接地,必须和51共地
//ESP8266  TX 接P3^0, RX 接P3^1


bit flag=0;

uchar SendBuf[9]="LED1 ON! ";
uchar RecBuf[15];
uchar RecNum=0;

void delay_10us(uint us); //延时
void delay(uint n);   //延时
void UART_Init();   
void UART_SendByte(uchar dat);
void ESP8266_SendCmd(uchar *pbuf);
void ESP8266_SendData(uchar *pbuf); 
void ESP8266_ModeInit(void);    //WIFI模块初始化
void UART_Irq( );    // 接收信号

void delay_10us(uint us)
{
	while(us--);
}

void delay(uint n)
{
	uint i,j;
	for(i=0;i,
	for(i=0;i<=8;i++)
	{
		UART_SendByte(*pbuf);
		delay_10us(5);
		pbuf++;	
	}
}

void ESP8266_ModeInit(void)    //WIFI模块初始化
{
	
	ESP8266_SendCmd("AT+CWMODE=3");    //设置路由器模式 1:Station,,2:AP,3:Station+AP
	ESP8266_SendCmd("AT+CWSAP=\"百行\",\"12345678\",11,0");  //设置WIFI热点名称及密码
	ESP8266_SendCmd("AT+CIPAP=\"192.168.4.2\"");   //设置AP的IP地址
	ESP8266_SendCmd("AT+RST");                  //重新启动wifi模块
	ESP8266_SendCmd("AT+CIPMUX=1");	        //开启多连接模式
	ESP8266_SendCmd("AT+CIPSERVER=1,8080");	   //启动TCP/IP 端口为8080
	
}

void main()
{	
   P1=0x01;
	 while(SW1);       				//等待S1键按下
   LED1=LED2=LED3=LED4=1;
	 UART_Init();      				//串口初始化
	 ESP8266_ModeInit();
	
	 ES=1;             			//允许串口中断
	
	 while(1)
	 {
		 if(flag==1)
		 {
			 flag = 0;
			 ESP8266_SendData(SendBuf); 
		 }
		 delay(10);
	 }		
}

void UART_Irq( ) interrupt 4   // 接收信号
{
	if(RI)
	{
		RI=0;
		RecBuf[RecNum]=SBUF;   //接收到网络数据:+IPD,0,1<数据长度>:F<接收的数据>
		if(RecBuf[0]=='+')
			RecNum++;
		else 
			RecNum=0;
		if(RecNum==10)
		{
			RecNum=0;
			if(RecBuf[0]=='+'&&RecBuf[1]=='I'&&RecBuf[2]=='P'&&RecBuf[3]=='D')
			{
				switch(RecBuf[9])
				{
					case '1': P1 = 0xfD;break;   
					case '2': P1 = 0xfB;break;
					case '3': P1 = 0xf7;break;
					case '4': P1 = 0xef;break;
					default:P1 = 0xe0;						
				}
				SendBuf[3] = RecBuf[9];
				flag = 1;
 			}
		}				
	}
}

五、WIFI模块(ESP8266-01S)注意事项

        相比于编写代码,硬件方面就简单多了,就是有一些需要格外注意的事项,也是我在实践中遇到的问题,现在分享给大家。

Android Studio设计APP实现与51单片机通过WIFI模块(ESP8266-01S)通讯控制LED灯亮灭的设计源码【详解】_第3张图片

ESP8266-01S WIFI模块 接线
                    TX RXD(P3^0)
                    RX TXD(P3^1)
                    EN 3.3V
                    VCC 3.3V
                    GND GND

        这里需要特别注意在TX和RX中,TX代表WIFI模块发送数据,应该和单片机串行数据接收端RXD相连接,RX代表WIFI模块接受数据,应该和单片机串行数据发送端TXD相连接。EN、VCC必须接3.3V电源,另外WIFI模块工作时会发热,属于正常情况。GND接地需要特别注意,WIFI模块必须和51单片机共地,否则单片机将无法正常读取数据。其他引脚悬空就可以了,也就是说WIFI模块只需和51连接三根线即可,两根串行数据线,一根共地线。

六、后述
      

         以上就是今天要讲的内容,本文简单介绍了如何利用Android Studio设计 APP 实现与C51单片机通过WIFI模块通讯控制LED灯亮灭,由于本人也是刚开始学习,本文还有很多不足的地方,目前我的程序也还在开发中,后续我会随时更新文章中不足的部分,欢迎各位有需要的订阅我的这个专栏获取最新内容。

代码已开源:(其实以上就是全部内容了)

Github 源码资源免费下载https://github.com/SHUGEX/TCP_LED

CSDN 源码资源积分下载https://download.csdn.net/download/weixin_45694843/85238966

 

 

 

你可能感兴趣的:(C51单片机学习笔记,Android,Studio学习笔记,android,c语言,51单片机,android,studio)