【转载】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

posted @ 2024-07-08 09:15  FBshark  阅读(19)  评论(0编辑  收藏  举报