AliOS-Things+ESP32 BLE篇 (1)BLE peripheral

由于STM32的板子没有自带蓝牙和wifi模组,所以外设方面的demo,我选择放到乐鑫的ESP32模组上。一方面是由于ESP32这块板子有丰富的BT/WIFI的实现例程,还因为乐鑫的这款SOC扩展性很强,自身的SDK: ESP-IDF也比较成熟。
BLE Peripheral指的是蓝牙外设,比如蓝牙手环,蓝牙电视遥控器等,都是这类走蓝牙低功耗的外设设备。与外设设备相对应的就是BLE Central,指的是蓝牙中心设备,比如用户用的手机。通过手机去获得外设的信息,信息传输的发起方主要是手机(Central),而信息的提供方主要是外设(Peripheral)。外设会提供各种各样的蓝牙服务。比如就拿蓝牙手环举例,通过手环,我们可以获取用户的

  1. 心跳信息
  2. 行动步数
  3. 电池电量
    以上三类信息,在BLE传输协议中,可以认为是三个GATT service。其中心跳信息和电池电量信息的信息协议其实已经有官方定义,见 GATT Services , 每个协议具体规范见GATT Specifications,另外,每个service中的characteristic 也按照官方定义GATT Characteristic。所以,peripheral只要按照协议的要求,定制相应的service uuid,descriptor,和characteristics等,host连接后就可以查询到相应服务就可以知道获取到的信息是心跳信息(0x180D),电池电量(0x180F)等。
    但是对于行动步数,由于规范上并没有定义,所以这类信息只能按照私自约定的方式定义,不要和官方定义的service,characteristics等冲突就行。
    比如我们可以定义步数的service和characteristic如下:
#define BT_UUID_PRIV_DATA                 BT_UUID_DECLARE_16(0xfff0)
#define BT_UUID_PRIV_DATA_VAL             0xfff0  //步数service

#define BT_UUID_PRIV_CHW_DATA             BT_UUID_DECLARE_16(0xfff1)
#define BT_UUID_PRIV_CHW_DATA_VAL         0xfff1  //host写,用于步数清零

#define BT_UUID_PRIV_CHR_DATA             BT_UUID_DECLARE_16(0xfff2)
#define BT_UUID_PRIV_CHR_DATA_VAL         0xfff2 //host读,用于读取当前步数

#define BT_UUID_PRIV_CHN_DATA             BT_UUID_DECLARE_16(0xfff3)
#define BT_UUID_PRIV_CHN_DATA_VAL         0xfff3 //notify,host打开后,
										  //步数每累计超过5,peripheral就主动更新当前步数给host

这里我们定义了一个service和其中三个characteristic, 用于模拟手环peripheral和host同步步数信息。BLE三种主要的同步手段是write, read, notify。当然还有其他同步方式,有兴趣可以自己了解。
我们用两个byte用于记录步数(最大可以记录65535步)。具体设备端demo可以参考https://github.com/13xiaobang/AliOS-Things 上13xiaobang_modify分支上的blebanddemo用例

设备端的步数service核心code, 也就是att的设置如下:

/* Step Service Declaration */
static struct bt_gatt_attr attrs[] = {
	//主服务的service UUID为0xfff0
	BT_GATT_PRIMARY_SERVICE(BT_UUID_PRIV_DATA),
	//设置0xfff1 characteristic的可写属性
	BT_GATT_CHARACTERISTIC(BT_UUID_PRIV_CHW_DATA, BT_GATT_CHRC_WRITE), 
	//设置0xfff1描述符,权限为可写,并设置host端写时的回调,用于步数清零。
	BT_GATT_DESCRIPTOR(BT_UUID_PRIV_CHW_DATA, BT_GATT_PERM_WRITE, NULL,
			   write_blsc, NULL),
	//设置0xfff2 characteristic的可读属性
	BT_GATT_CHARACTERISTIC(BT_UUID_PRIV_CHR_DATA, BT_GATT_CHRC_READ),
	//设置0xfff2描述符,权限为可读,并设置host端读时的回调,用于返回读值。
	BT_GATT_DESCRIPTOR(BT_UUID_PRIV_CHR_DATA, BT_GATT_PERM_READ,
			   read_blsc, NULL, NULL),
	//设置0xfff3 characteristic的notify属性
	BT_GATT_CHARACTERISTIC(BT_UUID_PRIV_CHN_DATA, BT_GATT_CHRC_NOTIFY),
	//设置 0xfff3 characteristic的可读属性
	BT_GATT_DESCRIPTOR(BT_UUID_PRIV_CHN_DATA, BT_GATT_PERM_READ, NULL,
			   NULL, NULL),
	//设置0xfff3 characteristic 属性变换后的回调函数
	BT_GATT_CCC(privc_ccc_cfg, privc_ccc_cfg_changed),
};

接着我们设计host读写device的接口,每当执行读操作,读回当前priv_step p值,每当执行写操作,priv_step 置零,重新开始计数

static ssize_t read_blsc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			 void *buf, u16_t len, u16_t offset)
{
	printf("host read=%d\n", priv_step);
	return bt_gatt_attr_read(conn, attr, buf, len, offset, &priv_step,
				 sizeof(priv_step));
}

static ssize_t write_blsc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			const void *buf, u16_t len, u16_t offset, u8_t flags)
{
	int i = 0;
	printf("host write: \n");
	for(; i<len; i++)
	{
		printf("%x ", ((char*)buf)[i]);
	}
	printf("\n");
    //every time host write, reset step.
    priv_step = 0;
        
}

最后,我们为了demo简便,每隔1s,将priv_step++,并且当notify打开情况下,每隔5s向host上报一次当前priv_step值。

 void ble_sample(void)
{
    int err = 0;

    hci_driver_init();
    err = bt_enable(bt_ready);
    if (err) {
        printf("Bluetooth init failed (err %d)\n", err);
        return;
    }

#ifdef CONFIG_BT_SMP
    //bt_conn_auth_cb_register(&auth_cb_display);
#endif
    bt_conn_cb_register(&conn_callbacks);

    while (1) {
        aos_msleep(1000);
		priv_notify();
    }

    printf("Advertising successfully started\n");
}

void priv_notify(void)
{
	int err = 0;
	/* step increase 1 every second*/

    priv_step++;

        //if notify close ,return.
	if (!simulate_priv) {
		return;
	}

    if(priv_step%5  == 0) {
	    err = bt_gatt_notify(NULL, &attrs[6], &priv_step, sizeof(priv_step));
	    printf("simulate_priv notify = %d, err = %d\n", priv_step, err);
    }
}

设置完成后,我们可以通过手机侧安装的host的demo app(可以参考https://github.com/13xiaobang/bledebugger或者安装蓝牙调试助手等apk),连接esp32上运行的程序来进行读写操作。

esp32上code:https://github.com/13xiaobang/AliOS-Things 上13xiaobang_modify分支
编译方式:
aos make bluetooth.blebanddemo@esp32devkitc -c config && aos make
烧录方式:
下载esp32烧录工具:
https://www.espressif.com/zh-hans/support/download/other-tools

烧录工具设置
注意flash下载地址:编译出的镜像放在0x10000, bootloader和分区表分别放0x1000和0x8000
在这里插入图片描述
然后,我们就可以通过手机,对esp32板子做读,写和监控notify操作了:
fff0为我们自定义的手环私有service:
在这里插入图片描述
自定义service中的3个characteristic
在这里插入图片描述

写操作
在这里插入图片描述
读操作
在这里插入图片描述
监控notify
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值