APP同過ESP8266與51單片機通信

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單片機接收不到的情況。

發佈了3 篇原創文章 · 獲贊 1 · 訪問量 8255
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章