Android Studio设计APP实现与51单片机通过WIFI模块(ESP8266-01S)通讯控制LED灯亮灭的设计源码详解
Posted "殇影
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Studio设计APP实现与51单片机通过WIFI模块(ESP8266-01S)通讯控制LED灯亮灭的设计源码详解相关的知识,希望对你有一定的参考价值。
目录
3、Layout页面布局文件 activity_main.xml
一、前言
本文将详细介绍如何利用android Studio设计 APP 实现与C51单片机通过WIFI模块通讯控制LED灯亮灭,本人也是新手刚入门,找了很多资料,但都不得要领,最后终于靠着摸索学习实现了手机与C51模块的WIFI通讯,特来与大家分享,希望对各位能有所帮助。废话不多说,先看效果。
二、效果展示
1、APP界面展示
2、C51硬件展示
可以看到,该APP基本实现了手机与C51单片机之间的WIFI通讯,手机端可以发送和接收数据,可以选择直接给WIFI发送数据,也可以将发送的数据的发送代码固化为按键,比如我上面的四个LED按键其实底层代码就是按下分别发送“1”、“2”、“3”、“4”来控制四个灯的亮灭。本app只是用来实验手机与C51单片机之间的WIFI通讯,目前来说算是成功了,后续可以通过修改调用该程序实现更复杂的内容,目前我也在朝着这个方向努力`(*>﹏<*)′
三、Android Studio APP源代码
1、AndroidManifest.xml
首先需要联网别忘了给 Android 添加网络连接权限:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.tcp_led">
<uses-permission android:name="android.permission.INTERNET"/> //需要对WiFi进行操作,所以需要设置网络权限
<application
android:usesCleartextTraffic="false" //开放明文传输
android:allowBackup="true"
android:icon="@drawable/bh"
android:label="@string/app_name"
android:roundIcon="@drawable/bh_round"
android:supportsRtl="true"
android:theme="@style/Theme.TCP_LED"
tools:ignore="UnusedAttribute">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
1、请求联网:
<uses-permission android:name="android.permission.INTERNET"/>
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");
elseb=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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#f1f3f4">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TCP客户端"
android:textSize="50dp"
android:background="#ffffff"
android:gravity="center"
/>
<EditText
android:id="@+id/mEtIP"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:inputType="textWebEditText"
android:hint="请输入服务器IP"
android:drawableStart="@drawable/ic_tree"
android:drawablePadding="20dp"
android:layout_gravity="center"
android:textSize="20sp"
android:autofillHints="" />
<!--端口 -->
<EditText
android:id="@+id/mEtPort"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:inputType="date"
android:hint="请输入服务器端口"
android:drawableStart="@drawable/ic_tree"
android:drawablePadding="20dp"
android:layout_gravity="center"
android:textSize="20sp"
android:autofillHints="" />
<!--发送 -->
<EditText
android:id="@+id/mEtOut"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:inputType="date"
android:hint="请输入发送数据"
android:drawableStart="@drawable/ic_tree"
android:drawablePadding="20dp"
android:layout_gravity="center"
android:textSize="20sp"
android:autofillHints="" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<Button
android:id="@+id/mBt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="连接"
tools:ignore="UsingOnClickInXml" />
<Button
android:id="@+id/mBt7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送数据"
tools:ignore="UsingOnClickInXml" />
<Button
android:id="@+id/mBt8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="清除"
tools:ignore="UsingOnClickInXml" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<Button
android:id="@+id/mBt3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LED1"
tools:ignore="UsingOnClickInXml" />
<Button
android:id="@+id/mBt4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LED2"
tools:ignore="UsingOnClickInXml" />
<Button
android:id="@+id/mBt5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LED3"
tools:ignore="UsingOnClickInXml" />
<Button
android:id="@+id/mBt6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LED4"
tools:ignore="UsingOnClickInXml" />
</LinearLayout>
<TextView
android:id="@+id/receive"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
布局预览:
如此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<n;i++)
for(j=0;j<100;j++);
void UART_Init()
SCON=0X50; //串口:工作方式1
TMOD=0X20; //定时器:工作方式2
TH1=0xFD; //波特率:9600
TL1=0xFD;
ES=0; //禁止串口中断
EA=1; //使能总中断
TR1=1; //启动计数器
void UART_SendByte(uchar dat)
ES=0; //禁止串口中断
SBUF=dat; //串口发送
while(TI==0); //等待发送结束
TI=0; //发送标志位清零
ES=1; //使能串口中断
void ESP8266_SendCmd(uchar *pbuf)
while(*pbuf!='\\0') //遇到空格跳出循环
UART_SendByte(*pbuf);
delay_10us(5);
pbuf++;
delay_10us(5);
UART_SendByte('\\r'); //回车
delay_10us(5);
UART_SendByte('\\n'); //换行
delay(1000);
void ESP8266_SendData(uchar *pbuf)
uchar i=0;
ESP8266_SendCmd("AT+CIPSEND=0,9"); //发送数据:AT+CIPSEND=<id>,<length>
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<id>,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)注意事项
相比于编写代码,硬件方面就简单多了,就是有一些需要格外注意的事项,也是我在实践中遇到的问题,现在分享给大家。
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
Android Studio 实现单选对话框
上效果图
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="单选对话框"
android:textSize="20sp"
android:layout_marginTop="30dp"
android:gravity="center"
android:id="@+id/tv"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置字体大小"
android:id="@+id/btn"
android:layout_marginTop="20dp"
android:layout_gravity="center"
/>
</LinearLayout>
MainActivity.java
package com.example.singlechoicedialog;
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener
private AlertDialog dialog;
private TextView textView;
private int[] textSizeArr = 10,20,25,30,40;//存储字体大小
private String[] fontStyleArr= "小号","默认","中号","大号","超大";//存储样式
int textSize = 1; //单选列表中默认选择的位置
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//设置监听
findViewById(R.id.btn).setOnClickListener(this); //为id为btn的按钮邦定监听
textView = (TextView) findViewById(R.id.tv);
@Override
public void onClick(View view)
// 创建对话框并设置其样式(这里采用链式方程)
AlertDialog.Builder builder = new AlertDialog.Builder(this)//设置单选框列表
.setTitle("设置字体的大小") //设置标题
.setIcon(R.drawable.bdd) //设置图标
.setSingleChoiceItems(fontStyleArr, textSize, new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialogInterface, int i)
textSize=i; //在OnClick方法中得到被点击的序号 i
)
.setPositiveButton("确定", new DialogInterface.OnClickListener() //在对话框中设置“确定”按钮
@Override
public void onClick(DialogInterface dialogInterface, int i)
//为TextView设置在单选对话框中选择的字体大小
textView.setTextSize(textSizeArr[textSize]);
//设置好字体大小后关闭单选对话框
dialog.dismiss();
)
.setNegativeButton("取消", new DialogInterface.OnClickListener() //在对话框中设置”取消按钮“
@Override
public void onClick(DialogInterface dialogInterface, int i)
dialog.dismiss();
);
dialog = builder.create();
dialog.show();
以上是关于Android Studio设计APP实现与51单片机通过WIFI模块(ESP8266-01S)通讯控制LED灯亮灭的设计源码详解的主要内容,如果未能解决你的问题,请参考以下文章
基于Android studio+SSH的单词记忆(背单词)APP设计
Android studio课程设计开发实现---日记APP
基于Android的家庭理财系统的设计与实现.rar(毕业论文设计+程序源码) android studio导入可直接打开