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

这次期末的课程设计做了一个智能灯光控制系统,系统整体的功能不在此赘述,系统主要是要实现下位机同上位机的通信,上位机选用的是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 mPairedDevicesArrayAdapter;
    private ArrayAdapter 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(this, R.layout.device_name);
        mNewDevicesArrayAdapter = new ArrayAdapter(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();
    }
}

你可能感兴趣的:(Android)