APP通过ESP8266与单片机通信
简述
本项目中是用ESP8266作为热点,工作在MODE2模式,手机作为station接入ESP8266的网络进行数据传输,同时,ESP8266与52单片机之间通过串口进行数据传输。
本项目中只需要APP向WIFI发送数据,所以在APP的程序中没有接收WIFI数据的程序。在文章最后,则是笔者在写代码的过程中遇到的一个问题,51单片机不能接收WIFI数据,但能向WIFI发送AT指令的问题。
手机端实现
建立连接线程
以下为APP与ESP8266建立连接的线程,建立连接时只要获取其对象即可。其中的IP和port为ESP8266的IP地址和端口号,IP一般默认为192.168.0.1,端口号默认为8080,端口号可以自己设置。
private class ConnectThred extends Thread{
private String ip;
private int port;
public ConnectThred(String ip,int port){
this.ip = ip;
this.port = port;
}
public void run(){
//接收数据可用子线程也可直接在此线程操作
char[] buffer=new char[256];//定义数组接收输入流数据
String bufferString="";//定义一个字符接收数组数据
int conut =0;//初始化buffer数组长度为0
int tag=0;//初时写入数组的位置
try {
//建立连接
socket = new Socket(ip,port);
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d("Controler","runOnUI");
bt_link.setText("断开连接");
bt_link.setBackgroundColor(Color.GREEN);
Toast.makeText(Controler.this,"连接成功",Toast.LENGTH_LONG).show();
}
});
//读取输入流
bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//获取输出流
OutputStream=socket.getOutputStream();
//获取socket的输出流,接收数据
InputStream = socket.getInputStream();
while (true) {
//当输入流写入buffer数组的长度大于0时即接收到数据时
while ((conut=bufferedReader.read(buffer))>0) {
//将buffer数组的数据全部写入bufferString字符类型
while ( tag<buffer.length) {
bufferString=bufferString+buffer[tag];
tag++;
}
//将数据给messageHandler刷新UI界面
Message msgMessage =new Message();
msgMessage.obj=bufferString;
msgMessage.what=1;
messageHandler.sendMessage(msgMessage);
//初始化数据,以便处理下一条输入流信息
tag=0;
bufferString="";
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Controler.this,"连接错误",Toast.LENGTH_LONG).show();
}
});
}
}
}
发送数据线程
以下是APP向ESP8266发送数据的代码,同样在一个子线程中执行。需要发送数据时通过对象调用此方法即可。
//向服务器发送数据子程序
public class Send extends Thread{
public void run(){
if(socket != null){
try{
if (msg_send != null && msg_send.length()>0){
OutputStream.write(msg_send.getBytes("utf-8"));
OutputStream.flush();
msg_send="";
}
else{
Looper.prepare();
Toast.makeText(Controler.this,"发送的数据不能为空",Toast.LENGTH_LONG).show();
Looper.loop();
}
}
catch (IOException e){
e.printStackTrace();
}
}
}
}
通过按钮建立或断开连接
定义相关变量
private static final String IP = "192.168.4.1";//服务端IP
private static final int PORT = 8080; //端口号
Socket socket; //创建一个socket
Boolean IsConnected = false; //连接标志
ConnectThred mConnectThread; //TCP连接线程
//输入输出流
OutputStream OutputStream = null;//数据输出流,发送数据
BufferedReader bufferedReader;//声明输入流对象
InputStream InputStream = null;//定义数据输入流,用于接收数据
通过按钮实现连接:
bt_link.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) { //连接按钮,点击与ESP8266芯片连接或断开
if (socket ==null || !socket.isConnected()){
mConnectThread = new ConnectThred(IP,PORT);
mConnectThread.start();
}
if (socket!=null && socket.isConnected()){
try {
socket.close();
socket = null;
bt_link.setText("点击连接");
bt_link.setBackgroundColor(Color.GRAY);
Toast.makeText(Controler.this,"连接已断开",Toast.LENGTH_LONG).show();
}catch (IOException e){
e.printStackTrace();
}
}
}
});
通过按钮发送数据:
通过new一个发送数据线程的对象,调用start方法启动发送数据线程即可发送数据。
select_mode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mode_count++;
if (mode_count > 4)
mode_count=0;
mode = mode_arr[mode_count];
msg_send = "mod"+Integer.toString(mode_count)+"/n";
new Send().start();
tempmode.setText(mode); //设置模式
}
});
下位机端接收WIFI数据
下位机端使用51单片机实现,下位机端与ESP8266之间通过串口进行通信,传输数据。所以下位机接收WIFI数据时使用的是串口接收程序。
void UartConfiguration()
{
TMOD=0x20; // 设置计数器1工作模式2
TH1=0xfd; //计数器1初值
TL1=0xfd; //计数器1初值 两个初值决定波特率,此处设置波特率9600
PCON=0x00; //波特率倍增0x00不加倍,0x80加倍
SCON=0x50; //
EA=1; //
ES=1; //
TR1=1; //
TI=1;
}
将接收到的数据存入一个数组中然后进行处理
void ESP_UART() interrupt 4
{
static uchar i=0;
// led1=~led1;
if(RI==1)
{
RI=0; //½ÓÊÕ±êÖ¾
Recive_table[i]=SBUF;
sendByte(Recive_table[i]);
i++;
if((Recive_table[i-1]=='\n'))
{
Recive_table[i]='\0';
i=0;
}
}
else
TI=0;
}
处理接收到的数据
void getData()
{
if(Recive_table[0]=="+")
sendString(Recive_table);
if((Recive_table[0]=='+')&&(Recive_table[1]=='I')&&(Recive_table[2]=='P'))
{
if((Recive_table[3]=='D')&&(Recive_table[6]==','))
{
if(Recive_table[9]=='0')//&& Recive_table[10]=='0' //
{
Shutdown();
}
else if(Recive_table[9]=='1')//&& Recive_table[10]=='1' //
{
MakeNum(Recive_table[10],Recive_table[11]);
Startup();
}
else if(Recive_table[9]=='d')//&& Recive_table[10]=='1' //
{
MakeNum(Recive_table[10],Recive_table[11]);
}
else if(Recive_table[9]=='e')//&& Recive_table[10]=='1' //
{
MakeNum(Recive_table[10],Recive_table[11]);
}
else if(Recive_table[9]=='o'&& Recive_table[10]=='d') //
{
m_index=Recive_table[11]-'0';
SetMode(m_index);
}
else if(Recive_table[9]=='f')//&& Recive_table[10]=='1' //
{
SetSweep(Recive_table[10]-'0');
}
else if(Recive_table[9]=='p')//&& Recive_table[10]=='1' //
{
SetSpeed(Recive_table[10]-'0');
}
else if(Recive_table[9]=='i')//&& Recive_table[10]=='1' //
{
SetDirect(Recive_table[10]-'0');
}
memset(Recive_table,0,50);
}
}
}
注意
当ESP8266与51单片机通信时,51单片机不能使用CH340芯片进行串口数据的传输,不然会出现ESP8266发送的数据51单片机接收不到的情况。
来源:CSDN
作者:追猫的蝴蝶
链接:https://blog.csdn.net/Z_X_L_/article/details/104080014