打印

基于51单片机Android WiFi控制LED开关设计与实现

[复制链接]
604|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
基于51单片机Android WiFi控制LED开关设计与实现
一、系统方案
手机APP通过ESP8266 WIFI模块与51单片机通信控制LED灯、蜂鸣器的开关。下位机由单片机、ESP8266模块和LED灯组成,上位机由Android手机APP承担。我们在APP上发送LED灯、蜂鸣器的开关控制指令,ESP8266将收到的数据发送给单片机,从而实现对LED灯、蜂鸣器进行开关控制。

设计好的实物是这个样子:
二、硬件设计
ESP8266模块作为一个透传模块使用,RXDTXD分别连接51单片机的TXDRXDVCC3.3V电压,GND接地,只需要连接这些管脚,ESP8266模块就可以正常工作了。在单片机P16口上连接蜂鸣器、P26P27连接两个3mmLED灯,我们的目的是通过手机APP上的开关控制着LED灯的亮灭以及蜂鸣器打开与关闭。
原理图如下:

三、单片机软件设计
硬件的连接不复杂,接下来主要是单片机和手机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工作在AP模式下
        delayms(1000);       
        sendString("AT+CIPMUX=1\r\n");        //允许多连接
        delayms(1000);       
        sendString("AT+CIPSERVER=1,8080\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个客户端同时连接,也就是说客户端编号是04,在本设计中由于只有一个客户端与esp8266相连,所以客户端编号是05代表收到的字符长度;hello是收到的字符。在本例中esp8266发送给单片机的数据是+IPD,0,1:1,我们把接收到的字符串缓存到字符数组中,所以在处理收到的数据逻辑中,首先判断是否是以'+'开始的,否则视作无效数据,然后判断数组中的第十个数据,因为第十个数据才是手机APP发送过来的数据。
void uart() interrupt 4
{
    if(RI == 1)   
    {
        RI = 0;     //清除串口接收标志位
        receiveTable=SBUF;
        if(receiveTable[0]=='+')
        {
                i++;
        }
        else
        {
                i=0;
        }
        if(i==10)
        {
                i=0;
                switch(receiveTable[9])
                {
                        case '1':
                                BEEP=0;
                                break;
                        case '2':
                                BEEP=1;
                                break;
                        case '3':
                                RedLED=0;
                                break;
                        case '4':
                                RedLED=1;
                                break;
                        case '5':
                                GreenLED=0;
                                break;
                        case '6':
                                GreenLED=1;
                                break;
                }
        }
   
  }
}
四、Android APP软件设计
Android APP是借助Android Studio来开发的,界面比较简单,通过编辑框输入esp8266IP地址和端口号,esp8266默认的IP地址是192.168.4.1,端口号是8080,这些都可以通过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();
                    }
                });
            }
        }
    }

使用特权

评论回复
评论
bbxyliyang01 2023-7-16 22:13 回复TA
@王栋春 :VX18326681813 
bbxyliyang01 2023-7-16 15:34 回复TA
@王栋春 :好的 
王栋春 2023-7-5 23:00 回复TA
学习了,程序最好标注一下。 

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

28

帖子

0

粉丝