這次期末的課程設(shè)計(jì)做了一個(gè)智能燈光控制系統(tǒng),系統(tǒng)整體的功能不在此贅述,系統(tǒng)主要是要實(shí)現(xiàn)下位機(jī)同上位機(jī)的通信,上位機(jī)選用的是Android手機(jī)端,下位機(jī)是52單片機(jī),通過(guò)藍(lán)牙模塊實(shí)現(xiàn)通信。雖然系統(tǒng)很簡(jiǎn)單,但還是第一次完成的走完從下位機(jī)數(shù)據(jù)采集,數(shù)據(jù)傳輸,再到上位機(jī)的處理這個(gè)流程,故在這里做一個(gè)記錄,也希望能夠幫到有需要的人。
一、下位機(jī)通信下位機(jī)選用的是52單片機(jī),數(shù)據(jù)來(lái)自幾個(gè)傳感器,傳感器采集到數(shù)據(jù)后通過(guò)串口發(fā)送到藍(lán)牙模塊,然后藍(lán)牙模塊發(fā)送到上位機(jī)。因代碼量較大,所以只在這里貼出傳輸有關(guān)的函數(shù)。
//利用串口發(fā)送一個(gè)字符
void SendOneByte(unsigned char c)
{
SBUF = c;
while(!TI);
TI = 0;
}
//重寫(xiě)putchar函數(shù),就可以直接調(diào)用printf()函數(shù)向串口發(fā)送數(shù)據(jù),程序自動(dòng)將printf()中的數(shù)據(jù)轉(zhuǎn)換成char調(diào)用putchar發(fā)送
char putchar(char ch)
{
ES=0;
SBUF=ch;
while(!TI);
TI=0;
ES=1;
return 0;
}
//初始化串口
void InitUART()
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFD;
TL1 = 0xFD;
TR1 = 1;
ES = 1;
EA = 1;
}
//串口中斷
void UARTInterrupt() interrupt 4
{
//RI為1則表示串口接收到數(shù)據(jù)
if(RI)
{
RI = 0;
r_buf = SBUF;
//價(jià)格SBUF中的數(shù)據(jù)賦給r_buf,然后就可以對(duì)數(shù)據(jù)進(jìn)行處理
}
}
void main()
{
InitUART();
while(1)
{
}
}
藍(lán)牙模塊我選用的是HC-05,這個(gè)模塊我之前也沒(méi)用使用過(guò),查詢(xún)了一些資料后就能夠上手了,感覺(jué)還是很好用。模塊有六個(gè)引腳,如果用的是帶一個(gè)小按鈕的HC-05,EN就不用接;然后VCC和GND分別接電源和地;TXD 和 RXD在配置AT指令的時(shí)候分別接單片機(jī)的TXD和RXD,但是在正常使用時(shí),HC-05的TXD和RXD分別接單片機(jī)的RXD和TXD,這個(gè)需要注意;還有一個(gè)引腳是state,當(dāng)有藍(lán)牙連接的時(shí)候會(huì)置1,將其隨意連接到單片機(jī)的引腳上。
使用前先利用AT指令集配置模塊,設(shè)置波特率和主從模式等,然后就可以連線(xiàn)使用。連接后藍(lán)牙模塊會(huì)進(jìn)入快閃模式,進(jìn)入AT指令集后會(huì)進(jìn)入慢閃模式,當(dāng)有藍(lán)牙設(shè)備連接后會(huì)進(jìn)入雙閃模式。
Android端主要就是接受數(shù)據(jù),做出一定處理,還需發(fā)送指令給單片機(jī)。我用的代碼也是在網(wǎng)上找的然后又做了一些修改,源代碼出處找不到了。主要代碼如下:
1、DeveiceListActivity類(lèi) public class DeviceListActivity extends Activity { // 調(diào)試用 private static final String TAG = "DeviceListActivity"; private static final boolean D = true; // 返回時(shí)數(shù)據(jù)標(biāo)簽 public static String EXTRA_DEVICE_ADDRESS = "設(shè)備地址"; // 成員域 private BluetoothAdapter mBtAdapter; private ArrayAdapter2、Client類(lèi) public class BTClient extends Activity { private final static int REQUEST_CONNECT_DEVICE = 1; //宏定義查詢(xún)?cè)O(shè)備句柄 private final static String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB"; //SPP服務(wù)UUID號(hào) private InputStream is; //輸入流,用來(lái)接收藍(lán)牙數(shù)據(jù) private EditText edit0; //發(fā)送數(shù)據(jù)輸入句柄 private TextView lightSwitch; private TextView lightStrength; private TextView lightMode; private TextView lightPower; private String switchMsg= ""; private String strengthMsg= ""; private String modeMsg= ""; BluetoothDevice _device = null; //藍(lán)牙設(shè)備 BluetoothSocket _socket = null; //藍(lán)牙通信socket boolean bRun = true; boolean bThread = false; boolean timesign=false; private BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter(); //獲取本地藍(lán)牙適配器,即藍(lán)牙設(shè)備 /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //設(shè)置畫(huà)面為主畫(huà)面 main.xml edit0 = (EditText)findViewById(R.id.Edit0); //得到輸入框句柄 lightSwitch = (TextView) findViewById(R.id.lightSwitch); lightStrength=(TextView) findViewById(R.id.lightStrength); lightMode=(TextView) findViewById(R.id.lightMode); lightPower=(TextView) findViewById(R.id.lightpower); lightSwitch.setText("關(guān)閉"); lightStrength.setText("8"); lightMode.setText("時(shí)間調(diào)節(jié)模式"); lightPower.setText("無(wú)數(shù)據(jù)"); //如果打開(kāi)本地藍(lán)牙設(shè)備不成功,提示信息,結(jié)束程序 if (_bluetooth == null){ Toast.makeText(this, "無(wú)法打開(kāi)手機(jī)藍(lán)牙,請(qǐng)確認(rèn)手機(jī)是否有藍(lán)牙功能!", Toast.LENGTH_LONG).show(); finish(); return; } // 設(shè)置設(shè)備可以被搜索 new Thread(){ public void run(){ if(_bluetooth.isEnabled()==false) { _bluetooth.enable(); } } }.start(); } //發(fā)送按鍵響應(yīng) public void onSendButtonClicked(View v){ try{ OutputStream os = _socket.getOutputStream(); //藍(lán)牙連接輸出流 modeMsg=edit0.getText().toString(); if(modeMsg.equals("1")||modeMsg.equals("2")||modeMsg.equals("3")) { if(modeMsg.equals("1")) { lightMode.setText("手動(dòng)調(diào)節(jié)模式"); lightPower.setText("無(wú)數(shù)據(jù)"); timesign=false; } else if(modeMsg.equals("2")) { lightMode.setText("自動(dòng)調(diào)節(jié)模式"); timesign=false; } else if(modeMsg.equals("3")) { lightMode.setText("時(shí)間調(diào)節(jié)模式"); lightPower.setText("無(wú)數(shù)據(jù)"); } } if(timesign) { final int timec = Integer.valueOf(modeMsg).intValue() * 1000; // CountDownTimer cdt = new CountDownTimer(timec, timec) { // @Override // public void onTick(long millisUntilFinished) { // } // // @Override // public void onFinish() { // edit0.setText("3"); // } // }; // cdt.start(); try{ Thread.currentThread().sleep(timec); } catch (InterruptedException e) { e.printStackTrace(); } edit0.setText("3"); } if(modeMsg.equals("3")&& !timesign) timesign=true; byte[] bos = edit0.getText().toString().getBytes(); edit0.setText(""); os.write(bos); }catch(IOException e){ } } //接收活動(dòng)結(jié)果,響應(yīng)startActivityForResult() public void onActivityResult(int requestCode, int resultCode, Intent data) { switch(requestCode){ case REQUEST_CONNECT_DEVICE: //連接結(jié)果,由DeviceListActivity設(shè)置返回 // 響應(yīng)返回結(jié)果 if (resultCode == Activity.RESULT_OK) { //連接成功,由DeviceListActivity設(shè)置返回 // MAC地址,由DeviceListActivity設(shè)置返回 String address = data.getExtras() .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS); // 得到藍(lán)牙設(shè)備 _device = _bluetooth.getRemoteDevice(address); // 用服務(wù)號(hào)得到socket try{ _socket = _device.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID)); }catch(IOException e){ Toast.makeText(this, "連接失?。?, Toast.LENGTH_SHORT).show(); } //連接socket Button btn = (Button) findViewById(R.id.Button03); try{ _socket.connect(); Toast.makeText(this, "連接"+_device.getName()+"成功!", Toast.LENGTH_SHORT).show(); btn.setText("斷開(kāi)"); }catch(IOException e){ try{ Toast.makeText(this, "連接失敗!", Toast.LENGTH_SHORT).show(); _socket.close(); _socket = null; }catch(IOException ee){ Toast.makeText(this, "連接失敗!", Toast.LENGTH_SHORT).show(); } return; } //打開(kāi)接收線(xiàn)程 try{ is = _socket.getInputStream(); //得到藍(lán)牙數(shù)據(jù)輸入流 }catch(IOException e){ Toast.makeText(this, "接收數(shù)據(jù)失??!", Toast.LENGTH_SHORT).show(); return; } if(bThread==false){ ReadThread.start(); bThread=true; }else{ bRun = true; } } break; default:break; } } //接收數(shù)據(jù)線(xiàn)程 Thread ReadThread=new Thread(){ public void run(){ int num = 0; byte[] buffer = new byte[1024]; bRun = true; //接收線(xiàn)程 while(true){ try{ while(is.available()==0){ while(bRun == false){} } while(true){ num = is.read(buffer); //讀入數(shù)據(jù) String s=new String(buffer,0,num); switchMsg=s; strengthMsg=s; if(is.available()==0)break; //短時(shí)間沒(méi)有數(shù)據(jù)才跳出進(jìn)行顯示 } //發(fā)送顯示消息,進(jìn)行顯示刷新 handler.sendMessage(handler.obtainMessage()); }catch(IOException e){ } } } }; //消息處理隊(duì)列 Handler handler= new Handler(){ public void handleMessage(Message msg){ super.handleMessage(msg); } }; //關(guān)閉程序掉用處理部分 public void onDestroy(){ super.onDestroy(); if(_socket!=null) //關(guān)閉連接socket try{ _socket.close(); }catch(IOException e){} } //連接按鍵響應(yīng)函數(shù) public void onConnectButtonClicked(View v){ if(_bluetooth.isEnabled()==false){ //如果藍(lán)牙服務(wù)不可用則提示 Toast.makeText(this, " 打開(kāi)藍(lán)牙中...", Toast.LENGTH_LONG).show(); return; } //如未連接設(shè)備則打開(kāi)DeviceListActivity進(jìn)行設(shè)備搜索 Button btn = (Button) findViewById(R.id.Button03); if(_socket==null){ Intent serverIntent = new Intent(this, DeviceListActivity.class); //跳轉(zhuǎn)程序設(shè)置 startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE); //設(shè)置返回宏定義 } else{ try{ //關(guān)閉連接socket _socket.close(); is.close(); _socket = null; bRun = false; btn.setText("連接"); }catch(IOException e){} } return; } //退出按鍵響應(yīng)函數(shù) public void onQuitButtonClicked(View v){ finish(); } }
電子發(fā)燒友App



















評(píng)論