bbxyliyang01 发表于 2023-7-5 14:30

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

基于51单片机Android WiFi控制LED开关设计与实现一、系统方案手机APP通过ESP8266 WIFI模块与51单片机通信控制LED灯、蜂鸣器的开关。下位机由单片机、ESP8266模块和LED灯组成,上位机由Android手机APP承担。我们在APP上发送LED灯、蜂鸣器的开关控制指令,ESP8266将收到的数据发送给单片机,从而实现对LED灯、蜂鸣器进行开关控制。
设计好的实物是这个样子: 二、硬件设计 ESP8266模块作为一个透传模块使用,RXD、TXD分别连接51单片机的TXD和RXD,VCC接3.3V电压,GND接地,只需要连接这些管脚,ESP8266模块就可以正常工作了。在单片机P16口上连接蜂鸣器、P26、P27连接两个3mm的LED灯,我们的目的是通过手机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个客户端同时连接,也就是说客户端编号是0到4,在本设计中由于只有一个客户端与esp8266相连,所以客户端编号是0;5代表收到的字符长度;hello是收到的字符。在本例中esp8266发送给单片机的数据是+IPD,0,1:1,我们把接收到的字符串缓存到字符数组中,所以在处理收到的数据逻辑中,首先判断是否是以'+'开始的,否则视作无效数据,然后判断数组中的第十个数据,因为第十个数据才是手机APP发送过来的数据。void uart() interrupt 4{    if(RI == 1)       {      RI = 0;   //清除串口接收标志位        receiveTable=SBUF;        if(receiveTable=='+')        {                i++;        }        else        {                i=0;        }        if(i==10)        {                i=0;                switch(receiveTable)                {                        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来开发的,界面比较简单,通过编辑框输入esp8266的IP地址和端口号,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();                  }                });            }      }    }
页: [1]
查看完整版本: 基于51单片机Android WiFi控制LED开关设计与实现