目錄
一、系統方案
二、硬體設計
三、單片機軟體設計
四、Android APP軟體設計
一、系統方案
手機APP通過ESP8266 WIFI模塊與51單片機通信控制四路繼電器,下位機由單片機、ESP8266模塊和繼電器模塊組成,上位機由Android手機APP承擔,我們在APP上發送繼電器的開關控制指令,ESP8266將收到的資料發送給單片機,從而實作對繼電器進行開關控制,

二、硬體設計
ESP8266模塊作為一個透傳模塊使用,RXD、TXD分別連接51單片機的TXD和RXD,VCC和EN管腳接3.3V電壓,GND接地,只需要連接這些管腳,ESP8266模塊就可以正常作業了,
單片機的P2^0,P2^1,P2^2,P2^3輸出高低電瓶控制四路繼電器,繼電器模塊是從網上購買的已經焊接好的模塊,其他地方為手工萬用板焊接,

三、單片機軟體設計
單片機代碼主要是串口初始化、ESP8266的初始化和串口中斷,
1.串口和ESP8266初始化:
/**
*發送單個字符
*/
void sendChar(uchar a)
{
SBUF = a;
while(TI==0);
TI=0;
}
/**
*發送字串
*/
void sendString(uchar *s)
{
while(*s!='\0')
{
sendChar(*s);
s++;
}
}
/**
*初始化ESP8266模塊
*/
void initEsp()
{
TMOD=0x20; //定時器1作業在方式2
TH1 = 0xfd; //波特率9600
TL1 = 0xfd;
SM0=0; //串口作業在方式1
SM1=1;
EA = 1; //開總中斷
REN = 1; //使能串口
TR1 = 1; //定時器1開始計時
delayms(200);
sendString("AT+CWMODE=2\r\n"); //AP模式
delayms(200);
sendString("AT+CIPMUX=1\r\n"); //允許多連接
delayms(200);
sendString("AT+CIPSERVER=1\r\n"); //建立TCP Server
delayms(200);
ES = 1; //開串口中斷
}
sendString("AT+CWMODE=2\r\n") ----- 單片機發送AT指令到ESP8266模塊,AT+CWMODE=2是將ESP8266設定為AP模式,\r\n是換行,因為AT指令加換行才能生效,
sendString("AT+CIPMUX=1\r\n") ---- 允許多連接
sendString("AT+CIPSERVER=1\r\n") ---- 建立TCP Server
2.串口中斷函式,負責處理App發送給單片機的指令:
/**
* 串口中斷函式,負責處理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': //打開繼電器
JDQ4=0;
break;
case '2': //關閉繼電器
JDQ4=1;
break;
case '3':
JDQ3=0;
break;
case '4':
JDQ3=1;
break;
case '5':
JDQ2=0;
break;
case '6':
JDQ2=1;
break;
case '7':
JDQ1=0;
break;
case '8':
JDQ1=1;
break;
}
}
}
}
esp8266在收到資料并轉發給單片機時的資料格式:+IPD,<client號>,<收到的字符長度>:收到的字符,比如+IPD,0,5:hello,其中+PID是固定的;0代表的是TCP客戶端編號,esp8266最多支持5個客戶端同時連接,也就是說客戶端編號是0到4,在本設計中由于只有一個客戶端與esp8266相連,所以客戶端編號是0;5代表收到的字符長度;hello是收到的字符,在本例中esp8266發送給單片機的資料是+IPD,0,1:1,我們把接收到的字串快取到字符陣列中,所以在處理收到的資料邏輯中,首先判斷是否是以'+'開始的,否則視作無效資料,然后判斷陣列中的第十個資料,因為第十個資料才是上位機發送過來的資料,
四、Android APP軟體設計
Android APP是借助Android Studio來開發的,界面比較清新,esp8266默認的IP地址是192.168.4.1,埠號是333,四個開關控制四路繼電器,其中長按開關的名字可以編輯開關名稱,APP界面截圖如下所示:

負責連接ESP8266的按鈕點擊回呼方法:
/**
* 連接按鈕點擊事件回呼方法
* @param v
*/
@Override
public void onClick(View v) {
if(v.getId()==R.id.btn_connect){
if (mSocket == null || !mSocket.isConnected()) {
new Thread(){
@Override
public void run() {
try {
mSocket = new Socket("192.168.4.1", 333);
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();
}
});
}
}
}.start();
}
if (mSocket != null && mSocket.isConnected()) {
try {
mSocket.close();
mBtnConnect.setText("連接");
mSocket = null;
} catch (IOException e) {
e.printStackTrace();
mSocket = null;
}
}
}
}
滑動開關點擊回呼方法,發送指令到單片機控制繼電器的開關:
/**
* 滑動按鈕監聽事件,發送指令到單片機控制繼電器開關
* @param buttonView
* @param isChecked
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
switch (buttonView.getId()) {
case R.id.switch1:
if (isChecked) {
//turn on
Log.d(TAG, "onCheckedChanged: send1");
sendData("1");
} else {
//turn off
Log.d(TAG, "onCheckedChanged: send2");
sendData("2");
}
break;
case R.id.switch2:
if (isChecked) {
//turn on
Log.d(TAG, "onCheckedChanged: send3");
sendData("3");
} else {
//turn off
Log.d(TAG, "onCheckedChanged: send4");
sendData("4");
}
break;
....
....
....
}
}
本文完!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/92505.html
標籤:其他
