源: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

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

BLE 安卓APP控制LED灯的实现(转)的更多相关文章

  1. 嵌入式Linux学习入门:控制LED灯

    记录自己linux学习过程,让自己能够一直坚持下去 1.原理图分析: nLED_1, nLED_2, nLED_4, 给低电平则对应LED灯亮,高电平则对应LED灯灭, S3C2440芯片GPF4-G ...

  2. arduino 红外遥控器控制LED灯

    /* 日期:2016.9.1 功能:红外遥控器控制LED灯 开,关,闪烁,呼吸 元件: 跳线公公头 * 5 led 220欧电阻 红外接收管,红外遥控 接线: 红外灯面向自己从左到右分别接 IO3 , ...

  3. arduino入门学习实现语音控制LED灯

    需要的准备的硬件arduino+PC+麦克风实现语音命令控制LED灯的亮灭. 首先需要将写好的arduino程序烧录到arduino uno主板中,下面是代码如下: int val;//定义变量val ...

  4. C#与Arduino通过串口通信来控制LED灯的状态

    一.引言 最近摆弄了一段时间的Arduino,发现Arduino做一些电子类项目.监控.机器人.电子玩具比较容易,并且Arduino与.NET程序集成也不难.接下来介绍一个简单的小程序,C#做的一个W ...

  5. enc28J60 网页控制LED灯

    软件IDE:Arduino 1.6.3 1.库的安装: 从https://github.com/jcw/ethercard 下载源码包,解压,复制ethercard-master文件夹到Arduino ...

  6. 云中树莓派(4):利用声音传感器控制Led灯

    云中树莓派(1):环境准备 云中树莓派(2):将传感器数据上传到AWS IoT 并利用Kibana进行展示 云中树莓派(3):通过 AWS IoT 控制树莓派上的Led 云中树莓派(4):利用声音传感 ...

  7. 树莓派开机运行Python脚本 控制LED灯闪烁

    一.新建一个开机运行文件 在 /home/pi/.config 下创建一个文件夹,名称为 autostart,并在该文件夹下创建一个led.desktop文件(文件名以.desktop结尾) 编辑le ...

  8. Arduino控制LED灯(开关控制)

    问题:当使用"digitalRead(BUT) == 1"控制LED灯时会出现"digitalWrite(LED, ledState);"的值出现跳动. 原因: ...

  9. 利用DoHome APP和音箱控制LED灯实验参考步骤

    准备材料: Arduino Uno 一块 Arduino 扩展板        购买链接 DT-06模块一个       购买链接 安卓手机一个 小度音箱一个 小灯珠一个 杜邦线若干 1.DT-06固 ...

随机推荐

  1. HDU 1054 Strategic Game 最小点覆盖

     最小点覆盖概念:选取最小的点数覆盖二分图中的所有边. 最小点覆盖 = 最大匹配数. 证明:首先假设我们求的最大匹配数为m,那么最小点覆盖必然 >= m,因为仅仅是这m条边就至少需要m个点.然后 ...

  2. unity中的update、Lateupdate和FixedUpdate。

    MonoBehaviour.Update 更新 当MonoBehaviour启用时,其Update在每一帧被调用. MonoBehaviour.FixedUpdate 固定更新 当MonoBehavi ...

  3. MySQL常用命令总结2

    USE db_name; //使用(打开)数据库 SELECT DATABASE(); //查看当前打开的数据库 CREATE TABLE tb_name( column_name data_type ...

  4. editplus 正则删换行

    editplus regular expression  ctrl+h 1.替换开始是空行 ^[\t ]*\n 2.替换换行 \n 3.替换包含某字符 .*@126.* excel去重复(或者保留一个 ...

  5. width为auto或者100%的区别

    一.四个理论 1. 某div不显示设置宽度,那么width为auto. 2. 某div的width在默认情况设置的是盒子模型中content的值 3. 某div的width为100%表示的是此div盒 ...

  6. hdu_5648_DZY Loves Math

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5648 题意:给你n,m 让你求出 for(1-n)for(1-m)gcd(i&j,i|j)的s ...

  7. C#实现http断点下载

    我们寄希望于万能的解决方案,但是现实的情况总是很糟糕.在软件编程的世界中,技术分散的情况尤为严重,且不说各种语言拥有的优势不能融合,单就一门语言而言,就拥有众多的技术和相关技术需要学习.网络编程就是这 ...

  8. elisp

    cons cell? 构建内存对象! 通过寄存器的基地址car和偏移地址cdr来--寻址内存对象,我是这样理解的. http://wiki.dourok.info/doku.php/%E5%B7%A5 ...

  9. Kafka 在行动:7步实现从RDBMS到Hadoop的实时流传输

    原文:https://coyee.com/article/11095-kafka-in-action-7-steps-to-real-time-streaming-from-rdbms-to-hado ...

  10. php 缓存之 APC 和apcu

    php opcode 缓存 apc. 其实,我自己的理解, php apc 缓存其实分两部分, 一部分是 缓存 类似于 java 编译的中间的 字节码, 不同于c 语言编译之后的二进制的机器码. ph ...