zoukankan      html  css  js  c++  java
  • BLE 安卓APP控制LED灯的实现(转)

    源:BLE 安卓APP控制LED灯的实现

    //注:参考AmoMcu源代码修改。

     打开APP,检查蓝牙是否打开

    BluetoothAdapter mBluetoothAdapter;
    
    
     final BluetoothManager bluetoothManager =(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
           mBluetoothAdapter = bluetoothManager.getAdapter();
    
    // Ensures Bluetooth is available on the device and it is enabled. If not,
    // displays a dialog requesting user permission to enable Bluetooth.
    if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
       Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
       startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    }

    蓝牙扫描

    private void scanLeDevice(final boolean enable) {
    if (enable) {
         // Stops scanning after a pre-defined scan period.
                 mHandler.postDelayed(new Runnable() {
                     @Override
                     public void run() {
                         mScanning = false;
                         mBluetoothAdapter.stopLeScan(mLeScanCallback);
                     }
                 }, SCAN_PERIOD);
    
    
                 mScanning = true;
                 mBluetoothAdapter.startLeScan(mLeScanCallback);
             } else {
                 mScanning = false;
                 mBluetoothAdapter.stopLeScan(mLeScanCallback);
             }
         }

    连接GATT服务
    绑定一个服务

    Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
        bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
    注:BluetoothLeService.java,属于安卓源代码,可以到网上下载回来。
    // Code to manage Service lifecycle.
         private final ServiceConnection mServiceConnection = new ServiceConnection() {
             @Override
             public void onServiceConnected(ComponentName componentName, IBinder service) {
                 mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
                 if (!mBluetoothLeService.initialize()) {
                     Log.e(TAG, "Unable to initialize Bluetooth");
                     finish();
                 }
                 // Automatically connects to the device upon successful start-up initialization.
                 mBluetoothLeService.connect(mDeviceAddress);
             }
             @Override
             public void onServiceDisconnected(ComponentName componentName) {
                 mBluetoothLeService = null;
             }  
         };

    点击某个特征值的响应:
    获取前面的数据,不用再次扫描,由扫描页面得到的数据,传过来的

    b=getIntent().getExtras();
     tv_addr.setText(b.getString(EXTRAS_DEVICE_ADDRESS));
     mDeviceAddress=b.getString(EXTRAS_DEVICE_ADDRESS);
     tv_name.setText(b.getString(EXTRAS_DEVICE_NAME));
     mDeviceName=b.getString(EXTRAS_DEVICE_NAME);
     tv_rssi.setText(b.getString(EXTRAS_DEVICE_RSSI));
    
     lv=(ExpandableListView)this.findViewById(R.id.expandableListView1);
     lv.setOnChildClickListener(servicesListClickListner);
    
    
     private final ExpandableListView.OnChildClickListener servicesListClickListner =
               new ExpandableListView.OnChildClickListener() {
                   @Override
                   public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
                                               int childPosition, long id) {
                                   
    
                       if (mGattCharacteristics != null) {
                           final BluetoothGattCharacteristic characteristic =
                                   mGattCharacteristics.get(groupPosition).get(childPosition);
                           
                           //当前目标特征值
                           target_chara=characteristic;
                           
                           
                           final int charaProp = characteristic.getProperties();
                       
                           if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                               mNotifyCharacteristic = characteristic;
                               
                               mBluetoothLeService.setCharacteristicNotification(
                                      characteristic, true);
                           }
                          tv_uuid.setText(characteristic.getUuid().toString());
                          Intent intent=new Intent();
                          b.putString("CONNET_SATE", status);
                          b.putString("UUID", characteristic.getUuid().toString());
                          intent.putExtras(b);
                          intent.setClass(MyGattDetail.this, LEDControl.class);
                          startActivity(intent);
                          
                    
                    return true;
                       }
                 
                       return false;
                   
                  }
                            
       };

    读写特征值的数据
    读数据:

    private static BluetoothGattCharacteristic myCharacteristic=null;
     private static BluetoothLeService mBluetoothLeService;
     mBluetoothLeService.readCharacteristic(myCharacteristic);

    注释:readCharacteristic该函数会调用BluetoothGatt.readCharacteristic(BluetoothGattCharacteristic characteristic)

    写数据:
    mBluetoothLeService.writeCharacteristic(myCharacteristic);
    注释:writeCharacteristic该函数会调用BluetoothGatt.writeCharacteristic(BluetoothGattCharacteristic characteristic)


    示例代码:

    private char[] buffer =new char [] {0x6F,0x0F,0x0F,0x0F,0x0F,0x0F};
     private void send() { 
    MyGattDetail.write(ConvertString(buffer));
     }
    
    
     private String ConvertString(char buffer[]){
    String nRcvString;
         StringBuffer tStringBuf=new StringBuffer ();
         tStringBuf.append(buffer);      
         nRcvString=tStringBuf.toString();     
         return  nRcvString;
     }
    
    
     device_name = (TextView) findViewById(R.id.ledpage_devname);
    
    ledButton1 = (ToggleButton) findViewById(R.id.ledpage_led1);
    ledButton1.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView,
    boolean isChecked) {
    if(isChecked){
    buffer[1]=0x01;
    }else{
    buffer[1]=0x00;
    }
    send();
    }
    });
    
    ledButton2 = (ToggleButton) findViewById(R.id.ledpage_led2);
    ledButton2.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView,
    boolean isChecked) {
    if(isChecked){
    buffer[2]=0x01;
    
    }else{
    buffer[2]=0x00;
    }
    send();
    }
    });
    ledButton3 = (ToggleButton) findViewById(R.id.ledpage_led3);
    ledButton3.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView,
    boolean isChecked) {
    // TODO Auto-generated method stub
    if(isChecked){
    buffer[3]=0x01;
    }else{
    buffer[3]=0x00;
    }
    send();
    }
    });
    
    ledButton4 = (ToggleButton) findViewById(R.id.ledpage_led4);
    ledButton4.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView,
    boolean isChecked) {
    // TODO Auto-generated method stub
    if(isChecked){
    buffer[4]=0x01;
    }else{
    buffer[4]=0x00;
    }
    send();
    }
    });

    使用ToggleButton控件控制LED:

    问题:

    使用TI的demo会发现打开一个LED会比较慢,偶尔还会失效。也就是说会掉帧,考虑大之前的所写的关于延时值的设置,如下:

    Connection Interval(GAPROLE_MIN_CONN_INTERVAL && GAPROLE_MAX_CONN_INTERVAL)- 连接间隔,在BLE的两个设备的连接中使用跳频机制。两个设备使用特定的信道发送和接收数据,然后过一段时间后再使用新的信道(BLE协议栈的链路层处理信道的切换)。两个设备在切换信道后发送和接收数据称为一个连接事件。尽管没有应用数据被发送和接收,两个设备仍旧会交换链路层数据来维持连接。这个连接间隔就是这个两个连接事件的之间的时间间隔。间隔以1.25ms为单元,连接间隔的范围的6-3200既7.5ms-4s(4000ms)之间。

    由此可以看出:间隔小,适用于那些需要快速反应的任务。LED灯需要快速的反应,所以经过设置如下:

    // Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled

    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     6//80

    // Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled

    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     80//800

    这样子实时体验就有大大的提升。

  • 相关阅读:
    蛙蛙请教:问几个面向对象设计的问题
    推荐一些flash和asp.net结合开发的文章
    写一个跟踪的类库
    蛙蛙推荐:有关随机数的一些讨论
    蛙蛙推荐:用ASP.NET WEB Services和Flash MX 2004打造MP3播放器
    HiveQL学习
    Linux rpm 命令参数使用详解[介绍和应用]
    java.util.concurrent.locks.Condition 例子程序探讨
    [转]sudoers设置
    配置linux电脑
  • 原文地址:https://www.cnblogs.com/LittleTiger/p/4580050.html
Copyright © 2011-2022 走看看