泰凌微ble mesh蓝牙模组天猫精灵学习之旅④如何在Android开发低功耗蓝牙ble控制 TB-02 模块,代码工程全部开源!(附带Demo)

Ona ·
更新时间:2024-11-13
· 563 次阅读

本<泰凌微ble mesh蓝牙模组天猫精灵学习之旅>系列博客学习由半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。

1、小白也痴迷,如何在 Linux环境搭建编译烧录 安信可TB02,点亮一盏LED灯;
2、如何实现 微信小程序蓝牙控制 Ble Mesh模组 安信可TB02,全部开源!
3、简单入门安信可TB-02开发开发板轻松接入天猫精灵,语音控制冷暖灯so easy!
4、如何在Android开发低功耗蓝牙ble控制 TB-02 模块,代码工程全部开源!

文章目录前言一、材料准备二、蓝牙模块初始化三、App开发过程4.1 搜索设备4.2 连接设备4.3 获取服务列表和其特征列表4.4 主动订阅通知4.5 如何接受设备发来的数据4.6 如何发送数据到设备另外,不要把我的博客作为学习标准,我的只是笔记,难有疏忽之处,如果有,请指出来,也欢迎留言哈!

在这里插入图片描述

前言

    工作了三年,职业之路不能偏离方向,当海浪掀起,周围会有一些美丽的风景在吸引着你,抑或有诱惑在向你招手,请不要沉迷,请不要迷恋,走走停停,每一段旅程都应该有它的归属;

    一直在从事智能家居领域,对无线对接语音平台,微信控制什么的,小家电很熟,但是对 Linux 驱动等一些工业级的应用开发,一窍不通;这是我这个月的反思,等做好这个Ble Mesh的熟悉之后,会逐渐地转 Linux 和 服务器开发,因为我个人是喜欢敲代码的,即使老去了,看着曾经敲过的代码,无比喜悦!

    好了,今天就给大家我最近做的一个《安信可Android蓝牙APP控制TB02》的过程分享吧!

    最后共勉大家一句话: 生命意义在于折腾,生命价值在于奉献;

在这里插入图片描述

一、材料准备

    这里务必声明一下,硬件对接需要一点成本请自行出资,并不像纯软件就可以搞的!下面推荐的蓝牙模块自行某宝购买哈!

ble蓝牙模块一个,可从淘宝购买!我使用的是安信可TB02模块开发版; Android Java开发,用的是 AndroidStudio工具!请自行入门Android开发哦!

在这里插入图片描述

在这里插入图片描述

    这里不涉及到单片机编程,直接用串口助手模拟单片机;

蓝牙模块开启 从机模式,等待连接; 安卓APP开始搜索设备,之后成功连接; 之后读取设备服务service列表,再读取指定服务的特征列表 characters; 根据硬件厂商指定通讯的特征通道来做数据的收、发和通知特性;

     注意:一个ble蓝牙设备可拥有多个服务和特征,涉及到读取设备的服务和特征,都是需要需要设备厂商指定的!如果未能列出,那么此特征的权限是 可读可写可通知,一般为一个特征拥有此三个权限;如果不是,那需要具体问设备厂商啦!!

二、蓝牙模块初始化

     如果您的板子并没烧录AT固件,请按照第一篇文章,编译 example/at 工程,烧录到板子即可!

     默认波特率等设置,上电后会有信息打印,如下图所示:在这里插入图片描述

     本人不玩AT指令开发,因做微信小程序,所以需了解此设备的AT指令,如需了解具体的AT指令集,点我:
     下面为大家列下主要指令:

序号 指令 功能
1 AT 测试 AT
2 ATE 开关回显
3 AT+GMR 查询固件版本
4 AT+RST 重启模组
5 AT+SLEEP 深度睡眠
6 AT+ RESTORE 恢复出厂设置 恢复后将重启
7 AT+BAUD 查询或设置波特率 重启后生效
8 AT+NAME 查询或设置蓝牙广播名称 重启后生效
9 AT+MAC 设置或查询模组 MAC 地址 重启后生效
10 AT+STATE 查询蓝牙连接状态
11 AT+SEND AT 模式下发送数据
12 +DATA AT 模式下收到数据
三、App开发过程

     Android开发的蓝牙ble API文档还是很齐全的!为了减少开发工作量,我使用了第三方库,实现 动态授权和 ble连接发现以及设备通讯;

     APP源码已经在底部贴出,请知悉!

4.1 搜索设备

     搜索前务必要开启 蓝牙权限,而在安卓 6.0(包括6.0) 系统以上,务必开启定位权限,否则也是无法搜索到蓝牙设备的呢!

//动态授权 PermissonUtil.checkPermission(this, new PermissionListener() { @Override public void havePermission() { initBleScan(); } @Override public void requestPermissionFail() { Toast.makeText(mContext, "您拒绝了开启权限", Toast.LENGTH_SHORT).show(); finish(); } }, Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.ACCESS_FINE_LOCATION);

     第一步肯定是搜索设备,通过 调用 object.scanBle() 来发现设备,入参可以指定 UUID,注意设备列表的回调是通过 onSuccess() 方法回调。

mBleController.scanBle(0, new ScanCallback() { @Override public void onSuccess() { //判断获取到的设备蓝牙列表是否大于0 if (bluetoothDevices.size() > 0) { mDeviceList.setAdapter(new DeviceListAdapter(MainActivity.this, bluetoothDevices)); mDeviceList.setOnItemClickListener(MainActivity.this); } else { Toast.makeText(MainActivity.this, "Search Device Lists empty!", Toast.LENGTH_SHORT).show(); } } @Override public void onScanning(BluetoothDevice device, int rssi, byte[] scanRecord) { //过滤是否含有 Ai-Thinker 名字的蓝牙设备 if (device.getName() != null && device.getName().contains("Ai-Thinker")) if (!bluetoothDevices.contains(device)) { bluetoothDevices.add(device); } } }); 4.2 连接设备

    上步我们已经拿到了周围的蓝牙设备列表,那么如何判断哪个是我们想要的呢?一般为名字,TB02的广播名字一般为 Ai-Thinker,于是乎,调用 connect() ,入参为搜索到的设备的 mac地址!

//连接设备 mBleController.connect(0, address, new ConnectCallback() { @Override public void onConnSuccess() { Toast.makeText(MainActivity.this, "connected!", Toast.LENGTH_SHORT).show(); } @Override public void onConnFailed() { Toast.makeText(MainActivity.this, "connect fail!", Toast.LENGTH_SHORT).show(); } }); 4.3 获取服务列表和其特征列表

    上面说了,一个设备可拥有多个服务service,我们在获取时候,是在已连接成功的情况下再获取哦!

    下面获取到了服务列表,并通过判断其 uuid 是否和我们一致,从而判断是否Tb01设备,否则,就是连接了其他设备。

    也许你会问,如何获取这个uuid是否一致。参考uuid一般是厂商提供的,如下:

//TODO 这里是TB02开发板提供的各种UUID,请勿修改 private static final String BLUETOOTH_S = "00010203-0405-0607-0809-0a0b0c0d1910"; private static final String BLUETOOTH_NOTIFY_C = "00010203-0405-0607-0809-0a0b0c0d2b10"; private static final String BLUETOOTH_WRITE_C = "00010203-0405-0607-0809-0a0b0c0d2b10";

    如果获取了服务,那么我们下一步就是要获此这个服务下的特征列表;

    同样道理,也是要获取到其特征的uuid,在 TB01模块里面的这个服务,只有一个特征好吧。所以只取元素第一个即可!

    下面是代码,其实这些早已经封装在另外一个库了,如有兴趣可以去翻阅看看品读;

//服务被发现了 @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (null != mBluetoothGatt && status == BluetoothGatt.GATT_SUCCESS) { List services = mBluetoothGatt.getServices(); int serviceSize = services.size(); for (int i = 0; i < serviceSize; i++) { HashMap charMap = new HashMap(); BluetoothGattService bluetoothGattService = services.get(i); String serviceUuid = bluetoothGattService.getUuid().toString(); List characteristics = bluetoothGattService.getCharacteristics(); int characteristicSize = characteristics.size(); for (int j = 0; j < characteristicSize; j++) { charMap.put(characteristics.get(j).getUuid().toString(), characteristics.get(j)); if (characteristics.get(j).getUuid().toString().equals(BLUETOOTH_NOTIFY_C)) { if (enableNotification(true, characteristics.get(j))) { isConnectResponse = true; connSuccess(); } else { reConnect(); } } } servicesMap.put(serviceUuid, charMap); } } } 4.4 主动订阅通知

    下面程序中的调用 wx.notifyBLECharacteristicValueChange()方法目的是 主动监听此通道的数值变化,通俗来说就是:设备一旦发送数据在此通道,就会立刻收到通知;

if (!mBluetoothGatt.setCharacteristicNotification(characteristic, enable)) return false; 4.5 如何接受设备发来的数据

    上一点已经主动监听到了某通道的数值变化,这点必须要做的;

    然后,就可以调用下面方法,接收到数据打印出来。注意:接收到的是十六进制格式,还需要转下!

// TODO 接收数据的监听 mBleController.registReciveListener(REQUESTKEY_SENDANDRECIVEACTIVITY, new OnReceiverCallback() { @Override public void onRecive(byte[] value) { // 这里为了演示方便,把 byte数组转字符串显示 String string = new String(value); mReciveString.append(string + "\r\n"); mReciveText.setText(mReciveString.toString()); } }); 4.6 如何发送数据到设备

    发送数据时候,必须确定所在的通道是否可写 write ;发送数据时候,务必把字符串转为byte数组,再传进去;

String sendText = mSendEdit.getText().toString().trim(); if (TextUtils.isEmpty(sendText)) { Toast.makeText(this, "send text cannot be null" , Toast.LENGTH_SHORT).show(); return; } else { //这里把字符串格式转byte数组 byte[] bytes = sendText.getBytes(); mBleController.writeBuffer(bytes, new OnWriteCallback() { @Override public void onSuccess() { Toast.makeText(SendAndReciveActivity.this, "send OK!", Toast.LENGTH_SHORT).show(); } @Override public void onFailed(int state) { Toast.makeText(SendAndReciveActivity.this, "send Fail!", Toast.LENGTH_SHORT).show(); } }); } 最后共勉,源码地址:https://github.com/Ai-Thinker-Open/AiTBxxForWeChat 编译后可直接安装的APK:https://docs.ai-thinker.com/_media/ble/spec/ai-thinker_ble_tool.rar 另外,不要把我的博客作为学习标准,我的只是笔记,难有疏忽之处,如果有,请指出来,也欢迎留言哈! 玩转esp8266带你飞、加群QQ群,不喜的朋友勿喷勿加:434878850 个人邮箱:xuhongv@yeah.net 24小时在线,有发必回复! esp8266源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp8266 esp32源代码学习汇总(持续更新,欢迎star):https://github.com/xuhongv/StudyInEsp32 关注下面微信公众号二维码,干货多多,第一时间推送!

在这里插入图片描述


作者:半颗心脏



开源 天猫精灵 天猫 模块 工程 学习 mesh ble demo android开发 Android

需要 登录 后方可回复, 如果你还没有账号请 注册新账号