基于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[i]=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来开发的,界面比较简单,通过编辑框输入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();
                }
            });
        }
    }
}
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bbxyliyang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值