尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于BlueNRG-LP的BLE抽屉灯控制Android应用开发实践

基于BlueNRG-LP的BLE抽屉灯控制Android应用开发实践 近期在做的一块板子是ST的STEVAL-LLL005V1评估板需求是给它配一个Android端的控制应用。这个板子不是那种通用开发板它被ST定位成抽屉灯场景的智能LED驱动参考设计抽屉拉开灯带自动亮起抽屉合上灯自动熄灭。板上的主控是ST自家的BLE SoC BlueNRG-LP上面还集成了一颗低功耗加速度传感器通过检测姿态变化来判断抽屉的开关状态。Android应用这端要做的就是通过BLE连接板子把亮度、触发阈值、工作模式这些参数下发下去同时把设备状态和传感器数据展示出来。这篇文章是从我接到需求、分析硬件、扒协议到把App跑通的全过程复盘。适合两类人看一类是拿到评估板但不太清楚怎么开发手机端的嵌入式工程师另一类是Android开发想了解BLE设备对接中那些文档里不写的坑。大部分内容不局限于这块板子换成其他BLE控制的IoT设备同样能套用。1. 项目背景STEVAL-LLL005V1与抽屉灯App要做什么1.1 评估板硬件到底有哪些关键资源STEVAL-LLL005V1这个型号从命名上能看出它属于ST的照明评估板产品线后缀V1代表第一版。硬件上最核心的是BlueNRG-LP它是一颗带BLE 5.2协议的片上系统里面除了射频部分还有一个可编程的MCU内核跑设备端的基础逻辑。板子上还有一颗LIS2DH12这类超低功耗加速度传感器用来感知抽屉的开合动作LED驱动单元负责把输入电源转换成适合灯带的恒定电流保证LED亮度稳定供电部分支持外部适配器输入实际使用时大多接12V左右的电源。这块板子有意思的地方在于它并不是单纯做个无线开关而是把传感器、驱动、通信都集成到了一起。对做Android应用的人来说驱动电路怎么设计可以暂时不管但BLE端暴露了哪些服务、传感器数据用什么格式上报、控制命令需要走哪个特征值这些东西必须在写代码前弄清楚。硬件是固定的App能不能顺利跑起来完全取决于对这些协议细节的把握。抽屉灯这个应用场景虽然小但很有代表性。它涉及到传感器阈值判断、低功耗无线通信、LED恒流驱动、电源管理几乎是一个微型智能家居设备该有的全部模块。把这个项目吃透后续做其他BLE智能照明或者传感器类设备很多代码和思路都是能复用过去的。1.2 Android应用在整套方案里承担什么角色那就说回这个“LED Drawer Android application”的需求。最开始我收到的信息比较简单只说“给STEVAL-LLL005V1做一个Android应用”但仔细一拆需求其实是分层的。第一层是演示。板子本身默认固件里有一套自动逻辑上电就能干活不需要App。但演示给客户看的时候如果只能看到“灯亮了”说服力有限。App一打开设备列表扫出来点进去能看见开关状态、能调节亮度、能看传感器实时数值整个方案才算完整。第二层是配置。抽屉灯要落地参数必须可调。比如不同的抽屉安装角度不一样传感器触发阈值不能写死LED灯带长度不同亮度上限不一样有的客户希望抽屉打开后灯延迟几秒再熄灭这些都需要通过App下发配置。没有App就只能每次插下载器改固件开发效率和用户体验都很差。第三层是调试诊断。联调阶段最大的痛苦是不知道设备端到底发生了什么。App如果能显示日志、显示收发数据帧甚至做简单的数据分析会节省大量时间。我这次做控制页时特意把串口调试常用的十六进制日志也加进去了界面看起来不炫但联调时非常有用。从应用架构上看这个App的核心链路就是扫描设备、建立连接、发现服务、读写特征、订阅通知、解析数据、更新UI。如果把这条链路跑通外围的UI设计、参数校验、状态展示都是围绕它做文章。1.3 技术路线选择为什么直接用Android原生做Android BLE应用首先面临一个选择用原生框架还是跨平台框架。我这次选了Kotlin配合Android原生BLE接口没有引入第三方蓝牙库。原因不是第三方库不好而是BLE通信是一个状态机非常密集的过程扫描、连接、断开、服务发现、特征读写每一步都可能失败。用原生接口能在出错时拿到最直接的异常回调定位问题的时候不用多绕一层。用Flutter或者React Native做跨平台UI开发效率确实高但蓝牙这块的插件层往往会屏蔽掉一些底层状态细节。设备连接失败时你看到的是插件封装后的错误码而不是BluetoothGattCallback里具体的错误原因。对于这种以通信稳定性为核心的IoT应用原生开发更合适。开发环境上就是标准的Android Studio建立Kotlin工程minSdkVersion建议设到26也就是Android 8.0以上覆盖市面上绝大多数手机。targetSdkVersion跟着当前编译版本走比如设到33或34这样能在开发阶段就强制处理新版系统的权限兼容。如果手里还没有装Android Studio装一个稳定版就行SDK组件用默认的不需要额外配置额外的Haxm这类加速模块用模拟器跑BLE本身也不现实开发调试全程用真机。2. 开发前必须摸清的关键点BLE协议、数据帧与状态机2.1 第一个动作不是写代码是用nRF Connect扒广播包很多人拿到BLE设备就急着写代码我建议先花半天时间用手机上的nRF Connect或者LightBlue这类通用BLE调试工具把设备扫一遍。这一步能解决后面一大堆问题。把STEVAL-LLL005V1板子通电后打开nRF Connect扫描设备列表里能看到广播名称、MAC地址、广播包里携带的服务UUID。我这次看到的广播名称类似“ST LED Drawer”这种自定义名称广播包里除了系统必备的GAP服务还能看到一个自定义Service UUID后面所有控制通道都挂在这个服务下。用调试工具扫描还有一个重要原因是确认过滤条件。Android端的BLE扫描如果直接扫全部设备回调会非常频繁列表里会出现大量无关设备。通常做法是用ScanFilter按Service UUID过滤或者至少按广播名称过滤。但这个过滤条件一定要拿真实广播数据来校准不能照抄文档。我曾经遇到过板子固件版本更新后广播名称没变但服务UUID变了的情况如果当时代码里写死了旧UUID扫描就会完全失效排查起来相当隐蔽。还要注意一点BLE的MAC地址在Android 6以上是随机化处理的同一个设备每次广播的MAC都可能不一样不能拿MAC地址当设备唯一标识存数据库只能作为一次会话里的临时标识。设备唯一标识应该用广播名称、Service UUID或者其他业务字段来配合判断。2.2 GATT服务结构把特征表整理出来再动手用nRF Connect连上设备以后工具会自动做GATT服务发现把设备端的服务和特征全部列出来。这时不要急着看代码先把每个特征值的属性、支持的操作记下来整理成一张表。特征属性很关键Write、Read、Notify、Indicate每一种属性对应不同的使用方式漏掉一个都会导致联调失败。我这次整理出的结构大致是这样的特征名称属性用途LED控制特征Write下发开关、亮度、模式等控制命令状态特征Read读取设备当前工作状态传感器数据特征Notify主动上报加速度计数据和判断结果参数配置特征Write / Read读写触发阈值、延时等配置项注意看传感器数据特征属性是Notify这意味着设备主动往手机推数据App只需要订阅通知。但订阅通知不是调一个方法就完事很多设备还需要往CCCD描述符里写一个值来使能通知。这个值通常是0x0001在nRF Connect里就对应“启用通知”按钮。App代码里如果只调了setCharacteristicNotification没写CCCD通知还是会收不到。这个坑几乎每个BLE项目都会踩一次。另外一个容易被忽略的是MTU协商。BLE默认一个数据包的负载只有23字节扣掉协议头实际可用的大概20字节。如果一帧控制命令超过20字节或者设备上报的传感器数据比较长就需要先把MTU协商到更大的值常见的是Android端请求MTU到247。MTU协商是异步流程必须等协商完成再开始大包收发否则会出现数据被截断的诡异问题。2.3 数据帧格式与控制命令一段压缩的二进制协议App和设备之间的通信不是直接发字符串就能解决的。嵌入式端对字符串解析的成本很高所以BLE设备通常会定义一套紧凑的二进制帧协议。帧头、命令字、数据长度、数据区、校验和五段式结构App端按协议拼字节数组设备端收到后按协议解析两端解耦。举个例子设置亮度这种命令
返回列表