Android端 同 单片机 利用蓝牙模块的通信实现

来源:互联网 发布:多核编程的艺术 编辑:程序博客网 时间:2024/06/05 03:11

这次期末的课程设计做了一个智能灯光控制系统,系统整体的功能不在此赘述,系统主要是要实现下位机同上位机的通信,上位机选用的是Android手机端,下位机是52单片机,通过蓝牙模块实现通信。虽然系统很简单,但还是第一次完成的走完从下位机数据采集,数据传输,再到上位机的处理这个流程,故在这里做一个记录,也希望能够帮到有需要的人。

一、下位机通信

下位机选用的是52单片机,数据来自几个传感器,传感器采集到数据后通过串口发送到蓝牙模块,然后蓝牙模块发送到上位机。因代码量较大,所以只在这里贴出传输有关的函数。

//利用串口发送一个字符void SendOneByte(unsigned char c) {    SBUF = c;    while(!TI);    TI = 0;}//重写putchar函数,就可以直接调用printf()函数向串口发送数据,程序自动将printf()中的数据转换成char调用putchar发送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则表示串口接收到数据    if(RI)    {    RI = 0;    r_buf = SBUF;//价格SBUF中的数据赋给r_buf,然后就可以对数据进行处理    }}void main(){InitUART();while(1){}}

、蓝牙模块

蓝牙模块我选用的是HC-05,这个模块我之前也没用使用过,查询了一些资料后就能够上手了,感觉还是很好用。模块有六个引脚,如果用的是带一个小按钮的HC-05,EN就不用接;然后VCC和GND分别接电源和地;TXD 和 RXD在配置AT指令的时候分别接单片机的TXD和RXD,但是在正常使用时,HC-05的TXD和RXD分别接单片机的RXD和TXD,这个需要注意;还有一个引脚是state,当有蓝牙连接的时候会置1,将其随意连接到单片机的引脚上。

使用前先利用AT指令集配置模块,设置波特率和主从模式等,然后就可以连线使用。连接后蓝牙模块会进入快闪模式,进入AT指令集后会进入慢闪模式,当有蓝牙设备连接后会进入双闪模式。


三、Android端程序

Android端主要就是接受数据,做出一定处理,还需发送指令给单片机。我用的代码也是在网上找的然后又做了一些修改,源代码出处找不到了。主要代码如下:

1、DeveiceListActivity类

public class DeviceListActivity extends Activity {    // 调试用    private static final String TAG = "DeviceListActivity";    private static final boolean D = true;    // 返回时数据标签    public static String EXTRA_DEVICE_ADDRESS = "设备地址";    // 成员域    private BluetoothAdapter mBtAdapter;    private ArrayAdapter<String> mPairedDevicesArrayAdapter;    private ArrayAdapter<String> mNewDevicesArrayAdapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // 创建并显示窗口        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);  //设置窗口显示模式为窗口方式        setContentView(R.layout.device_list);        // 设定默认返回值为取消        setResult(Activity.RESULT_CANCELED);        // 设定扫描按键响应        Button scanButton = (Button) findViewById(R.id.button_scan);        scanButton.setOnClickListener(new OnClickListener() {            public void onClick(View v) {                doDiscovery();                v.setVisibility(View.GONE);            }        });        // 初使化设备存储数组        mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);        mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);        // 设置已配队设备列表        ListView pairedListView = (ListView) findViewById(R.id.paired_devices);        pairedListView.setAdapter(mPairedDevicesArrayAdapter);        pairedListView.setOnItemClickListener(mDeviceClickListener);        // 设置新查找设备列表        ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);        newDevicesListView.setAdapter(mNewDevicesArrayAdapter);        newDevicesListView.setOnItemClickListener(mDeviceClickListener);        // 注册接收查找到设备action接收器        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);        this.registerReceiver(mReceiver, filter);        // 注册查找结束action接收器        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);        this.registerReceiver(mReceiver, filter);        // 得到本地蓝牙        mBtAdapter = BluetoothAdapter.getDefaultAdapter();    }    @Override    protected void onDestroy() {        super.onDestroy();        // 关闭服务查找        if (mBtAdapter != null) {            mBtAdapter.cancelDiscovery();        }        // 注销action接收器        this.unregisterReceiver(mReceiver);    }    public void OnCancel(View v){        finish();    }    /**     * 开始服务和设备查找     */    private void doDiscovery() {        if (D)            Log.d(TAG, "doDiscovery()");        // 在窗口显示查找中信息        setProgressBarIndeterminateVisibility(true);        setTitle("查找设备中...");        // 显示其它设备(未配对设备)列表        findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);        // 关闭再进行的服务查找        if (mBtAdapter.isDiscovering()) {            mBtAdapter.cancelDiscovery();        }        //并重新开始        mBtAdapter.startDiscovery();    }    // 选择设备响应函数    private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {        public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {            // 准备连接设备,关闭服务查找            mBtAdapter.cancelDiscovery();            // 得到mac地址            String info = ((TextView) v).getText().toString();            String address = info.substring(info.length() - 17);            // 设置返回数据            Intent intent = new Intent();            intent.putExtra(EXTRA_DEVICE_ADDRESS, address);            // 设置返回值并结束程序            setResult(Activity.RESULT_OK, intent);            finish();        }    };    // 查找到设备和搜索完成action监听器    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            String action = intent.getAction();            // 查找到设备action            if (BluetoothDevice.ACTION_FOUND.equals(action)) {                // 得到蓝牙设备                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);                // 如果是已配对的则略过,已得到显示,其余的在添加到列表中进行显示                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {                    mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());                }else{  //添加到已配对设备列表                    mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());                }                // 搜索完成action            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {                setProgressBarIndeterminateVisibility(false);                setTitle("选择要连接的设备");                if (mNewDevicesArrayAdapter.getCount() == 0) {                    String noDevices = "没有找到新设备";                    mNewDevicesArrayAdapter.add(noDevices);                }            }        }    };}


2、Client类

public class BTClient extends Activity {    private final static int REQUEST_CONNECT_DEVICE = 1;    //宏定义查询设备句柄    private final static String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";   //SPP服务UUID号    private InputStream is;    //输入流,用来接收蓝牙数据    private EditText edit0;    //发送数据输入句柄    private TextView lightSwitch;    private TextView lightStrength;    private TextView lightMode;    private TextView lightPower;    private String switchMsg= "";    private String strengthMsg= "";    private String modeMsg= "";    BluetoothDevice _device = null;     //蓝牙设备    BluetoothSocket _socket = null;      //蓝牙通信socket    boolean bRun = true;    boolean bThread = false;    boolean timesign=false;    private BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter();    //获取本地蓝牙适配器,即蓝牙设备    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);   //设置画面为主画面 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("关闭");        lightStrength.setText("8");        lightMode.setText("时间调节模式");        lightPower.setText("无数据");        //如果打开本地蓝牙设备不成功,提示信息,结束程序        if (_bluetooth == null){            Toast.makeText(this, "无法打开手机蓝牙,请确认手机是否有蓝牙功能!", Toast.LENGTH_LONG).show();            finish();            return;        }        // 设置设备可以被搜索        new Thread(){            public void run(){                if(_bluetooth.isEnabled()==false)                {                    _bluetooth.enable();                }            }        }.start();    }    //发送按键响应    public void onSendButtonClicked(View v){        try{            OutputStream os = _socket.getOutputStream();   //蓝牙连接输出流            modeMsg=edit0.getText().toString();            if(modeMsg.equals("1")||modeMsg.equals("2")||modeMsg.equals("3"))            {                if(modeMsg.equals("1")) {                    lightMode.setText("手动调节模式");                    lightPower.setText("无数据");                    timesign=false;                }                else if(modeMsg.equals("2")) {                    lightMode.setText("自动调节模式");                    timesign=false;                }                else if(modeMsg.equals("3")) {                    lightMode.setText("时间调节模式");                    lightPower.setText("无数据");                }            }            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){        }    }    //接收活动结果,响应startActivityForResult()    public void onActivityResult(int requestCode, int resultCode, Intent data) {        switch(requestCode){            case REQUEST_CONNECT_DEVICE:     //连接结果,由DeviceListActivity设置返回                // 响应返回结果                if (resultCode == Activity.RESULT_OK) {   //连接成功,由DeviceListActivity设置返回                    // MAC地址,由DeviceListActivity设置返回                    String address = data.getExtras()                            .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);                    // 得到蓝牙设备                    _device = _bluetooth.getRemoteDevice(address);                    // 用服务号得到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("断开");                    }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;                    }                    //打开接收线程                    try{                        is = _socket.getInputStream();   //得到蓝牙数据输入流                    }catch(IOException e){                        Toast.makeText(this, "接收数据失败!", Toast.LENGTH_SHORT).show();                        return;                    }                    if(bThread==false){                        ReadThread.start();                        bThread=true;                    }else{                        bRun = true;                    }                }                break;            default:break;        }    }    //接收数据线程    Thread ReadThread=new Thread(){        public void run(){            int num = 0;            byte[] buffer = new byte[1024];            bRun = true;            //接收线程            while(true){                try{                    while(is.available()==0){                        while(bRun == false){}                    }                    while(true){                        num = is.read(buffer);         //读入数据                        String s=new String(buffer,0,num);                        switchMsg=s;                        strengthMsg=s;                        if(is.available()==0)break;  //短时间没有数据才跳出进行显示                    }                    //发送显示消息,进行显示刷新                    handler.sendMessage(handler.obtainMessage());                }catch(IOException e){                }            }        }    };    //消息处理队列    Handler handler= new Handler(){        public void handleMessage(Message msg){            super.handleMessage(msg);        }    };    //关闭程序掉用处理部分    public void onDestroy(){        super.onDestroy();        if(_socket!=null)  //关闭连接socket            try{                _socket.close();            }catch(IOException e){}    }    //连接按键响应函数    public void onConnectButtonClicked(View v){        if(_bluetooth.isEnabled()==false){  //如果蓝牙服务不可用则提示            Toast.makeText(this, " 打开蓝牙中...", Toast.LENGTH_LONG).show();            return;        }        //如未连接设备则打开DeviceListActivity进行设备搜索        Button btn = (Button) findViewById(R.id.Button03);        if(_socket==null){            Intent serverIntent = new Intent(this, DeviceListActivity.class); //跳转程序设置            startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);  //设置返回宏定义        }        else{            try{                //关闭连接socket                _socket.close();                is.close();                _socket = null;                bRun = false;                btn.setText("连接");            }catch(IOException e){}        }        return;    }    //退出按键响应函数    public void onQuitButtonClicked(View v){        finish();    }}

阅读全文
1 0
原创粉丝点击