【APP】App Inventor 开发BLE应用
1. 文章1:搭建环境的介绍:
【深海王国】小学生都能做的APP?AppInventor、BLE蓝牙、Arduino联合开发你的第一个手机远程控制程序(1)
链接:https://blog.csdn.net/D13162580021/article/details/139026624?spm=1001.2014.3001.5502
2. 文章2:BLE基本知识的介绍:
【深海王国】小学生都能做的APP?AppInventor、BLE蓝牙、Arduino联合开发你的第一个手机远程控制程序(3)
链接:https://blog.csdn.net/D13162580021/article/details/139046680?spm=1001.2014.3001.5502
摘抄:
BLE低功耗蓝牙的通讯流程:
大都督温馨提示:以下知识较为深入,仅供有兴趣的的同学参考学习,时间比较赶的同学可以只看BLE蓝牙通讯流程图和下面的解释。
低功耗蓝牙的特性,让它非常适合那些长时间靠电池供电,只偶尔发送少量数据的小设备。比如健康手环、追踪标签、物联网传感器等等。在BLE通信模式中,存在两类设备:BLE服务端(BLE Server)和BLE客户端(BLE Client)。通信时,BLE服务端向外发送信号,可以被附近的BLE客户端发现,一个BLE客户端可以连接特定的服务端,然后读取服务端发送的信号数据。
理解BLE通信还需要几个概念,最重要的就是GATT,GATT全称为Generic Attributes。可以简单地为BLE蓝牙通信的基础数据结构。
BLE Service:GATT结构里最上层的是Profile,一个Profile包含至少一个BLE Service,通常一个BLE设备是包含多个Service的。
这些BLE Service并不可自行设定,而是由蓝牙技术联盟(Bluetooth Special Interest Group)为了规范而事先统一制定的。比如有显示电量的Service,还有心跳、血压、计重等等各种Service。
BLE Characteristic:每个Service下面包含一个或者多个特征(Characteristic),这些Characteristic包含特征的声明(Declaration)、数据值(Value)和描述符(Descriptor)。这些特征组成可以完整地描述一个Characteristic如何被使用,常见的操作如:Broadcast、Read、Write without response、Write、Notify、Indicate、Authenticated Signed Writes、Extended Properties等。
UUID:在BLE GATT中,每个Service、每个Characteristic和每个Descriptor都有一个特定的128比特的UUID表示,就是类似下面的一串数字: 0x0000xxxx-0000-1000-8000-00805F9B34FB 为了简化,蓝牙技术联盟定义了16位UUID代替上面的基本UUID的‘x’部分。例如,心率测量特性使用0X2A37作为它的16位UUID,因此它完整的128位UUID为: 0x00002A37-0000-1000-8000-00805F9B34FB
值得注意的是蓝牙技术联盟所用的基本UUID不能用于任何自定义的属性、服务和特性。另外对于自定义UUID,必须使用另外完整的128位UUID。
如果你看不懂上面的知识点也没关系,你只需要把这张通信流程图看懂,并且明白两个最重要的概念服务UUID:serviceUuid和特征UUID:characteristicUuid就够了啦。
简单来说BLE(低功耗蓝牙)通讯中,有个东西叫做GATT,我们可以把它想象成一本大书,这本书记录了BLE蓝牙所有的通讯规则和数据格式而服务UUID:serviceUuid就像是书中的一个章节。一本关于蓝牙设备的书,可能有不同的章节,比如“显示电量”章节、“心跳监测”章节等等。每个章节(或者说serviceUuid)就是为了处理一类特定的信息或功能。
而在每个章节(service)下面,会有不同的小节,这在BLE通讯中就是特征UUID:characteristicUuid。如果serviceUuid是“心跳监测”这个章节,那么它下面的characteristicUuid可能包括“实时心跳速率”、“心跳速率记录”等小节。小节里则详细指明了如何读取心跳速率,或者如何记录下来。
所以,serviceUuid就是指示一大块功能区域的唯一标识符,而characteristicUuid则是具体到这个功能区域下的一项具体功能或信息的唯一标识符。每一个都由一个特定的UUID(一串数字标识)来标识,就像每个章节和小节在目录里有唯一的编号一样。
你看,是不是会啦,哈哈,其实很多东西没有你想象的那么难,加油!
BLE 与传统蓝牙的区别
3、文章3 APP Inventor 如何使用 BLE
使用BLE,主要包括两方面的内容——BLE的扫描与连接
3-1 BLE的扫描
3-2 BLE的连接
3-3 BLE的通信(读写)
其中:
- values - 表示待发送的数据(这里是单字节0x01,表示高电平)
- signed - 表示values数据是否是有符号的数值(假表示无符号)
- serviceUuid - 服务UUID,通俗来讲它就是硬件的唯一身份ID
- characteristicUuid - 特性UUID,通俗来讲它是硬件中某一功能的唯一身份ID
UUID的获取途径:
上面代码中的两个UUID仅仅是我们测试对象的硬件的IO控制口的UUID,不同的硬件UUID是不同的,具体可以查看硬件提供的文档或厂商提供的java源码,一般会有提供。
一个硬件UUID示例如下:
4. 文章4:如何让单片机响应发送过来的数据
可以看下面的例程(Arduino 框架、ESP32-C3已验证):可以通过蓝牙控制LED的亮灭。
#include <ArduinoBLE.h>
#define BLE_LINK_WAIT_TIMEOUT 3000
uint16_t BLE_LINK_WAIT=BLE_LINK_WAIT_TIMEOUT; //蓝牙连接需要等待的时间,需要等待3S
BLEService ledService("6e400001-b5a3-f393-e0a9-e50e24dcca9e"); //创建服务UUID
BLEByteCharacteristic RXCharacteristic("6e400002-b5a3-f393-e0a9-e50e24dcca9e", BLERead | BLEWrite); //蓝牙接收特征UUID
BLEByteCharacteristic TXCharacteristic("6e400003-b5a3-f393-e0a9-e50e24dcca9e", BLERead | BLENotify); //蓝牙发送特征UUID
const int ledPin = LED_BUILTIN;
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(ledPin, OUTPUT);
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
while (1);
}
BLE.setLocalName("BLE_TEST"); //蓝牙名称
ledService.addCharacteristic(TXCharacteristic); //将特征添加到服务下
ledService.addCharacteristic(RXCharacteristic);
RXCharacteristic.setEventHandler(BLEWritten, RXCharacteristicWritten); //注册接收事件,当蓝牙收到数据就会触发RXCharacteristicWritten函数
BLE.addService(ledService); //添加服务
TXCharacteristic.writeValue(0); //初始化特征值
RXCharacteristic.writeValue(0);
BLE.setAdvertisedService(ledService); //将上面配置的名字/服务/特征等等设置到广播中,以便被搜索到,注意这条语句必须最后设置,否则有可能广播时不广播服务UUID
BLE.advertise(); //开启广播
Serial.println("BLE START!!!");
}
uint16_t i=0;
void loop(){
BLEDevice central = BLE.central();
if (central)
{
while(BLE_LINK_WAIT>0) //在这里需要等待,因为下面的操作可能需要耗费大量时间,导致蓝牙可能无法连接,因此先等待连接成功再执行耗时的处理
{ //这跟arduino底层相关,事件的触发会被delay阻塞
BLE_LINK_WAIT--; //所以在loop函数中,尽量将你想要的操作设计得快速
BLE.poll();
delay(1);
return;
}
Serial.print("Connected to central: ");
Serial.println(central.address());
while (central.connected())
{
//delay(5000); //比如这里消耗大量时间,前面蓝牙不等待的话很可能连接失败
delay(500);
TXCharacteristic.writeValue(i++); //每隔500ms主动发送数据
}
// when the central disconnects, turn off the LED:
Serial.print("Disconnected from central: ");
Serial.println(central.address());
BLE_LINK_WAIT=BLE_LINK_WAIT_TIMEOUT; //断开连接后需要恢复等待计时
}
}
//当蓝牙收到数据就会执行这里
void RXCharacteristicWritten(BLEDevice central, BLECharacteristic characteristic)
{
Serial.print("Characteristic event, written: ");
Serial.println(RXCharacteristic.value()); //串口打印接收到的数据
if (RXCharacteristic.value() == '1') //这里用的字符1(0x31)来控制指示灯
{
digitalWrite(ledPin, HIGH);
}
else
{
digitalWrite(ledPin, LOW);
}
}
参考文章:
1.App Inventor 2 低功耗蓝牙(BLE) 硬件接入、数据通信及IO控制:https://blog.csdn.net/zqp2013/article/details/135957853
2.App inventor:使用BLE蓝牙 https://blog.csdn.net/INT_TANG/article/details/124758332
作者:INT_TANG