51单片机通过WIFI模块ESP8266控制LED灯

一、系统方案

手机APP通过ESP8266 WIFI模块与51单片机通信控制LED灯的开关。下位机由单片机、ESP8266模块和LED灯组成,上位机由Android手机APP承担。我们在APP上发送LED灯的开关控制指令,ESP8266将收到的数据发送给单片机,从而实现对LED灯进行开关控制。

设计好的实物是这个样子:

二、硬件设计

ESP8266模块作为一个透传模块使用,RXD、TXD分别连接51单片机的TXD和RXD,VCC和CH_PD管脚接3.3V电压,GND接地,只需要连接这些管脚,ESP8266模块就可以正常工作了。在单片机P2口上连接了三个5mm的LED灯,分别是红黄蓝三种颜色,我们的目的是通过手机APP上的开关控制着三个LED灯的亮灭。

ESP8266实物管脚图

三、单片机软件设计

硬件的连接不复杂,接下来主要是单片机和手机APP代码的编写。

单片机代码主要是串口初始化、串口中断和ESP8266的初始化。首先是串口初始化:

        TMOD=0x20;		//定时器1工作在方式2
	TH1 = 0xfd;		//波特率9600
	TL1 = 0xfd;
	SM0=0;                  //串口工作在方式1
	SM1=1;
	EA = 1;			//开总中断
	REN = 1;		//使能串口
	TR1 = 1;		//定时器1开始计时

然后是ESP8266初始化:

        delayms(1000);                        //延时
	sendString("AT+CWMODE=2\r\n");        //设置ESP8266工作在station模式下,具体的AT指令可网上搜素一下
	delayms(1000);	
	sendString("AT+CIOBAUD=9600\r\n");    //设置9600波特率,因为esp8266波特率默认是115200
	delayms(1000);	
	sendString("AT+CIPMUX=1\r\n");        //允许多连接
	delayms(1000);	
	sendString("AT+CIPSERVER=1\r\n");     //建立服务器
	delayms(1000);	
	ES = 1;				      //esp8266初始化之后开串口中断

贴上51单片机负责串口发送的两个函数:

//发送一个字节
void sendChar(uchar a)
{
	SBUF = a;
	while(TI==0);
	TI=0;
	
}

//发送字符串
void sendString(uchar *s)
{
	while(*s!='\0')
	{
		sendChar(*s);
		s++;
	}
		
}

在串口中断中处理接收到的数据:

1:打开红色灯    2:关闭红色灯

3:打开黄色灯    4:关闭黄色灯

5:打开蓝色灯    6:关闭蓝色灯

esp8266在收到数据并转发给单片机时的数据格式:+IPD,<client号>,<收到的字符长度>:收到的字符,比如+IPD,0,5:hello,其中+PID是固定的;0代表的是TCP客户端编号,esp8266最多支持5个客户端同时连接,也就是说客户端编号是0到4,在本设计中由于只有一个客户端与esp8266相连,所以客户端编号是0;5代表收到的字符长度;hello是收到的字符。在本例中esp8266发送给单片机的数据是+IPD,0,1:1,我们把接收到的字符串缓存到字符数组中,所以在处理收到的数据逻辑中,首先判断是否是以'+'开始的,否则视作无效数据,然后判断数组中的第十个数据,因为第十个数据才是上位机发送过来的数据。

void uart() interrupt 4
{
    if(RI == 1)   
    {
        RI = 0;     //清除串口接收标志位
	receiveTable[i]=SBUF;
	if(receiveTable[0]=='+')
	{
		i++;
	}
	else
	{
		i=0;
	}
	if(i==10)
	{
		i=0;
		switch(receiveTable[9])
		{
			case '1':
				RedLED=0;
				break;
			case '2':
				RedLED=1;
				break;
			case '3':
				YellowLED=0;
				break;
			case '4':
				YellowLED=1;
				break;
			case '5':
				BlueLED=0;
				break;
			case '6':
				BlueLED=1;
				break;
		}
	}
    
  }
}

四、Android APP软件设计

Android APP是借助Android Studio来开发的,界面比较简单,通过编辑框输入esp8266的IP地址和端口号,esp8266默认的IP地址是192.168.4.1,端口号是333,这些都可以通过AT指令进行修改。布局页面的xml代码我们就不贴了,熟悉Android开发的读者很快就能根据截图编写出来,放上一个APP界面的截图:

我们主要看一下逻辑代码部分:

首先是控件的初始化和按钮点击事件回调的绑定

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtnConnect = (Button) findViewById(R.id.btn_connect);
        mEtIP = (EditText) findViewById(R.id.et_ip);
        mEtPort = (EditText) findViewById(R.id.et_port);
        mBtnRedOn = (Button) findViewById(R.id.btn_red_on);
        mBtnRedOff = (Button) findViewById(R.id.btn_red_off);
        mBtnYellowOn = (Button) findViewById(R.id.btn_yellow_on);
        mBtnYellowOff = (Button) findViewById(R.id.btn_yellow_off);
        mBtnBlueOn = (Button) findViewById(R.id.btn_blue_on);
        mBtnBlueOff = (Button) findViewById(R.id.btn_blue_off);
        mBtnConnect.setOnClickListener(this);
        mBtnRedOn.setOnClickListener(this);
        mBtnRedOff.setOnClickListener(this);
        mBtnYellowOn.setOnClickListener(this);
        mBtnYellowOff.setOnClickListener(this);
        mBtnBlueOn.setOnClickListener(this);
        mBtnBlueOff.setOnClickListener(this);

    }

按钮的点击回调方法:

    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_connect:
                //连接
                if (mSocket == null || !mSocket.isConnected()) {
                    String ip = mEtIP.getText().toString();
                    int port = Integer.valueOf(mEtPort.getText().toString());
                    mConnectThread = new ConnectThread(ip, port);
                    mConnectThread.start();
                }
                if (mSocket != null && mSocket.isConnected()) {
                    try {
                        mSocket.close();
                        mBtnConnect.setText("连接");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                break;
            case R.id.btn_red_on:         //开红灯
                if (out != null) {
                    out.print("1");
                    out.flush();
                }
                break;
            case R.id.btn_red_off:        //关红灯
                if (out != null) {
                    out.print("2");
                    out.flush();
                }
                break;
            case R.id.btn_yellow_on:
                if (out != null) {
                    out.print("3");
                    out.flush();
                }
                break;
            case R.id.btn_yellow_off:
                if (out != null) {
                    out.print("4");
                    out.flush();
                }
                break;
            case R.id.btn_blue_on:
                if (out != null) {
                    out.print("5");
                    out.flush();
                }
                break;
            case R.id.btn_blue_off:
                if (out != null) {
                    out.print("6");
                    out.flush();
                }
                break;
        }
    }
 

负责连接esp8266的线程:

private class ConnectThread extends Thread {
        private String ip;
        private int port;

        public ConnectThread(String ip, int port) {
            this.ip = ip;
            this.port = port;
        }

        @Override
        public void run() {
            try {
                mSocket = new Socket(ip, port);
                out = new PrintStream(mSocket.getOutputStream());
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mBtnConnect.setText("断开");
                    }
                });
                new HeartBeatThread().start();
            } catch (IOException e) {
                e.printStackTrace();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "连接失败", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        }
    }

系统的整个设计过程如上所述,我已经把该设计的实物挂在了淘宝上,如果想买来玩一玩,欢迎大家点击以下链接:

https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-3312521594.4.21332cf8PkANkW&id=571994783680

下面这个二维码是我的微信,加我之后我会把大家拉近单片机物联网技术的讨论群里。

猜你喜欢

转载自blog.csdn.net/tongxin082/article/details/80710642