当前位置:网站首页>Lianshengde W801 series 6-Analyze the Bluetooth communication source code of W801 from the perspective of WeChat applet (indicate method)

Lianshengde W801 series 6-Analyze the Bluetooth communication source code of W801 from the perspective of WeChat applet (indicate method)

2022-08-11 01:40:00 hwd00001

  1. W801Bluetooth communication source code source:作者: Mr.赵,CSND博客:W801/W800蓝牙收发数据与控制设计(一)-INDICATE ;源码:代码仓库
  2. WeChat applet source code source:作者:cwlgoodman,码云仓库: 微信小程序源代码,这个仓库有4个工程,We use the first one:

1.bluetooth_demo
2.bluetooth_lock
3.glucometer
4.wechat_api

  1. This article should be read in conjunction with another:《联盛德W801系列5-微信小程序与W801Bluetooth communication routines(阅读笔记)

1.蓝牙BLE GATT协议(转载)

这里摘录一段《ESP32学习笔记(30)——BLE GATT服务端自定义服务和特征》的内容:

1.1 通用属性协议(GATT)

GATT是用Attribute Protocal(属性协议)定义的一个service(服务)框架.这个框架定义了Services以及它们的Characteristics的格式和规程.规程就是定义了包括发现、读、写、通知、指示以及配置广播的characteristics.

为实现配置文件(Profile)的设备定义了两种角色:Client(客户端)、Server(服务器).esp32(W801)的ble一般就处于Server模式.

一旦两个设备建立了连接,GATT就开始发挥效用,同时意味着GAP协议管理的广播过程结束了.

1.1.1 Profile(规范)

profile 可以理解为一种规范,建立的蓝牙应用任务,蓝牙任务实际上分为两类:标准蓝牙任务规范 profile(公有任务),非标准蓝牙任务规范 profile(私有任务).

标准蓝牙任务规范 profile:指的是从蓝牙特别兴趣小组 SIG 的官网上已经发布的 GATT 规范列表,包括警告通知(alert notification),血压测量(blood pressure),心率(heart rate),电池(battery)等等.它们都是针对具体的低功耗蓝牙的应用实例来设计的.目前蓝牙技术联盟还在不断的制定新的规范,并且发布.

非标准蓝牙任务规范 profile:指的是供应商自定义的任务,在蓝牙 SIG 小组内未定义的任务规范.

1.1.2 Service(服务)

service 可以理解为一个服务,在 BLE 从机中有多个服务,例如:电量信息服务、系统信息服务等;
每个 service 中又包含多个 characteristic 特征值;
每个具体的 characteristic 特征值才是 BLE 通信的主题,比如当前的电量是 80%,电量的 characteristic 特征值存在从机的 profile 里,这样主机就可以通过这个 characteristic 来读取 80% 这个数据.
GATT 服务一般包含几个具有相关的功能,比如特定传感器的读取和设置,人机接口的输入输出.组织具有相关的特性到服务中既实用又有效,因为它使得逻辑上和用户数据上的边界变得更加清晰,同时它也有助于不同应用程序间代码的重用.

1.1.3 Characteristic(特征)

characteristic 特征,BLE 主从机的通信均是通过 characteristic 来实现,可以理解为一个标签,通过这个标签可以获取或者写入想要的内容.

1.1.4 UUID(通用唯一识别码)

uuid 通用唯一识别码,我们刚才提到的 service 和 characteristic 都需要一个唯一的 uuid 来标识;
每个从机都会有一个 profile,不管是自定义的 simpleprofile,还是标准的防丢器 profile,他们都是由一些 service 组成,每个 service 又包含了多个 characteristic,主机和从机之间的通信,均是通过characteristic来实现.

=================================Transcription ends

GATTStructure consists of nestedProfile、Service、Characteristics组成,如下图:
在这里插入图片描述

2.W801in the bluetooth routineble_gatt_svc_def结构体

《\src\app\bleapp\wm_ble_server_api_demo.c》 中的结构体:

#define WM_GATT_SVC_UUID 0xFFF0
#define WM_GATT_INDICATE_UUID 0xFFF1
#define WM_GATT_WRITE_UUID 0xFFF2
static const struct ble_gatt_svc_def gatt_demo_svr_svcs[] = {
    
    {
    
        /* Service: uart */
        .type = BLE_GATT_SVC_TYPE_PRIMARY,
        .uuid = BLE_UUID16_DECLARE(WM_GATT_SVC_UUID),
        .characteristics = (struct ble_gatt_chr_def[]) {
     {
    
                .uuid = BLE_UUID16_DECLARE(WM_GATT_WRITE_UUID),
                .val_handle = &g_ble_demo_attr_write_handle,
                .access_cb = gatt_svr_chr_demo_access_func,
                .flags = BLE_GATT_CHR_F_WRITE,
            },{
    
                .uuid = BLE_UUID16_DECLARE(WM_GATT_INDICATE_UUID),
                .val_handle = &g_ble_demo_attr_indicate_handle,
                .access_cb = gatt_svr_chr_demo_access_func,
                .flags = BLE_GATT_CHR_F_INDICATE,
            },{
    
              0, /* No more characteristics in this service */
            } 
         },
    },

    {
    
        0, /* No more services */
    },
};

在这里插入图片描述

2.1微信小程序API函数 wx.onBluetoothDeviceFound

wx.onBluetoothDeviceFound,查找设备API,可以获得以下信息:

{
    "devices":
	[
		{
    
			"deviceId":"28:6D:CD:D1:5C:30",
			"name":"WM-D1:5C:30",
			"RSSI":-52,
			"connectable":true,
			"advertisData":{
    },
			"advertisServiceUUIDs":["0000FFF0-0000-1000-8000-00805F9B34FB"],
			"localName":"WM-D1:5C:30",
			"serviceData":{
    }
		}
	]
}

其中 deviceId为蓝牙MAC地址,nameGenerated for the code below《\src\app\bleapp\wm_bt_app.c》第22行:

int tls_ble_gap_init(void)
{
    
    char default_device_name[MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH)];
    uint8_t bt_mac[6];
    int ret_len = 0;
    
    g_scan_state = WM_BLE_SCAN_STOP;
    memset(&adv_params_dft, 0, sizeof(adv_params_dft)); 
    adv_params_dft.conn_mode = BLE_GAP_CONN_MODE_UND;  //default conn mode;
    adv_params_dft.disc_mode = BLE_GAP_DISC_MODE_GEN;  //default disc mode;
    memset(&disc_params_dft, 0, sizeof(disc_params_dft));
    memset(&direct_adv_addr, 0, sizeof(direct_adv_addr));
    dl_list_init(&report_evt_list.list);
    ble_npl_mutex_init(&report_evt_list.list_mutex);
    
    if(btif_config_get_str("Local", "Adapter", "Name", default_device_name, &ret_len))
    {
    
        ble_svc_gap_device_name_set(default_device_name);
    }else
    {
    
        tls_get_bt_mac_addr(bt_mac);
        sprintf(default_device_name, "WM-%02X:%02X:%02X", bt_mac[3], bt_mac[4], bt_mac[5]);
        ble_svc_gap_device_name_set(default_device_name);
    }
    return 0;
}

2.2微信小程序API函数wx.getBLEDeviceServices

wx.getBLEDeviceServices获取服务信息API,Get the following:

{
    
	"services":
	[
		{
    
			"uuid":"0000FFF0-0000-1000-8000-00805F9B34FB",
			"isPrimary":true
		}
	],
	"errCode":0,
	"errno":0,
	"errMsg":"getBLEDeviceServices:ok"
}

对应下面的内容:
在这里插入图片描述

2.3微信小程序API函数wx.getBLEDeviceCharacteristics

wx.getBLEDeviceCharacteristics获取特征值API,获取以下内容:

{
    "characteristics":
	[
		{
    "uuid":"0000FFF2-0000-1000-8000-00805F9B34FB",
		"handle":3,
		"properties":
			{
    
				"read":false,
				"write":true,
				"notify":false,
				"indicate":false,
				"writeNoResponse":false,
				"writeDefault":true
			}
		},
		{
    "uuid":"0000FFF1-0000-1000-8000-00805F9B34FB",
		"handle":5,
		"properties":
			{
    
				"read":false,
				"write":false,
				"notify":false,
				"indicate":true,
				"writeNoResponse":false,
				"writeDefault":false
			}
		}
	],
	"errCode":0,
	"errno":0,
	"errMsg":"getBLEDeviceCharacteristics:ok"
}

The obtained eigenvalues ​​are determined by the following source code:
在这里插入图片描述

2.4 微信小程序API函数 wx.notifyBLECharacteristicValueChange

wx.notifyBLECharacteristicValueChange Enables monitoring for changes in the content of a feature value,如果有变化,会触发事件,调用 wx.onBLECharacteristicValueChange
我们判断到 properties.indicate == true,Explain that this is an indication attribute,对这个uuid进行监听.

......
              if (item.properties.indicate) {
    
              //可读数据
                wx.notifyBLECharacteristicValueChange({
    
                  state: true,
                  deviceId: options.connectedDeviceId,
                  serviceId: that.data.services[0].uuid,
                  characteristicId: item.uuid,
                  success: function (res) {
    
                    console.log('启用notify成功')
                  }
                })
......                

wx.onBLECharacteristicValueChange函数里面,Display the monitored data.

    wx.onBLECharacteristicValueChange(function (res) {
    
      var receiveText = app.buf2string(res.value)
      console.log('接收到数据:' + receiveText)
      that.setData({
    
        receiveText: receiveText
      })
    })

2.5 微信小程序API函数 wx.writeBLECharacteristicValue

在本例中,"uuid"为【0000FFF2-0000-1000-8000-00805F9B34FB】The characteristics can be written,When the phone wants to be rightW801写入数据时使用wx.writeBLECharacteristicValue(注意第7行):

  sendCmd:function(buff){
    
    var that = this
    if (that.data.connected) {
    
      wx.writeBLECharacteristicValue({
    
        deviceId: that.data.connectedDeviceId,
        serviceId: that.data.services[0].uuid,
        characteristicId: that.data.characteristics[0].uuid,
        value: buff,
        success: function (res) {
    
          console.log('发送成功')
        }
      })
    }
    else {
    
      wx.showModal({
    
        title: '提示',
        content: '蓝牙已断开',
        showCancel: false,
        success: function (res) {
    
          that.setData({
    
            searching: false
          })
        }
      })
    }

3.W801Receive mobile phone command controlLED

在Mr.Zhao's routine,使用3bytes are controlled separately3个灯(绿框),如图:
在这里插入图片描述
W801接收到数据后,控制LED的代码:

		//接收手机发送的数据,注意是数据是按照字节进行的接收
		tls_os_queue_receive(ble_q,&msg, 0, 0);
		//打印ble收到数据的长度
		printf("ble revice len:%d\n",msg[0]);
		//依次打印收到的ble数据
		for(u8 i=0;i<msg[0];i++){
    
			printf("%x ",msg[i+1]);
			send_data[i] = msg[i+1];
		}printf("\n");
		
		//Judge the data of the first three bytes respectively,对应开关灯:00 开 其他数据 关
		if(msg[1] != 0)
			tls_gpio_write(WM_IO_PB_05,1);
		else
			tls_gpio_write(WM_IO_PB_05,0);
		if(msg[2] != 0)
			tls_gpio_write(WM_IO_PB_25,1);
		else
			tls_gpio_write(WM_IO_PB_25,0);
		if(msg[3] != 0)
			tls_gpio_write(WM_IO_PB_26,1);
		else
			tls_gpio_write(WM_IO_PB_26,0);

The WeChat applet lights up1个LED(PB5)的代码:

  onLed1on:function(){
    
    var that = this
    if (that.data.connected) {
    
      var buffer = new ArrayBuffer(3)  
      var dataView = new Uint8Array(buffer) 
      
      that.data.gbuff[0] = 0  // 全局变量,输出低电平--灯亮
      dataView[0]  = that.data.gbuff[0];
      dataView[1]= that.data.gbuff[1];
      dataView[2] = that.data.gbuff[2];
      console.log('发送内容'+dataView[0]+dataView[1]+dataView[2]);
      that.sendCmd(buffer);
    }    
  },

4.W801Send data to WeChat applet

如果W801The status needs to be reported to the mobile terminal,Just call the function below,can be monitored by the mobile phone:

int tls_ble_server_demo_api_send_msg(uint8_t *data, int data_len)
{
    
    int rc;
    struct os_mbuf *om;
    
    //TLS_BT_APPL_TRACE_DEBUG("### %s len=%d\r\n", __FUNCTION__, data_len);
    if(g_send_pending) return BLE_HS_EBUSY;

    if(data_len<=0 || data == NULL)
    {
    
        return BLE_HS_EINVAL;
    }
    
    om = ble_hs_mbuf_from_flat(data, data_len);
    if (!om) {
    
        return BLE_HS_ENOMEM;
    }
    rc = ble_gattc_indicate_custom(g_ble_demo_conn_handle,g_ble_demo_attr_indicate_handle, om); 
    if(rc == 0)
    {
    
        g_send_pending = 1;
    }
    return rc;
}
原网站

版权声明
本文为[hwd00001]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/223/202208110123422036.html